I'm using React and MaterialUI to build a system that will display widgets inside another (not React-based) web site. I'd like to make the widgets responsive, but they need to respond to their own container width rather than the window width, as I won't know how much of the page the widget will take up.
Options I've considered:
These all seem rather ugly solutions to me. Is there an elegant way to do what I want?
Responsive layouts in Material Design adapt to any possible screen size. We provide the following helpers to make the UI responsive: Grid: The Material Design responsive layout grid adapts to screen size and orientation, ensuring consistency across layouts. Container: The container centers your content horizontally.
Always keep the common breakpoints for responsive design in mind. The former usually matches common screen sizes (480px, 768px, 1024px, and 1280px). Before choosing major breakpoints, use website analytics to discern the most commonly used devices from which your site is accessed.
maxWidth value defines the width of the screen that we are targeting. xl: 1920px(extra large) lg: 1280px(large) md: 960px(medium) sm: 600px(small)
Instead of breakpoints you can listen to changes to the component size. You can use react-use hook useMeasure to achieve that (it relies on ResizeObserver, which is supported by all major browsers), like in the following example:
/** @jsx jsx */
import { css, jsx } from '@emotion/core';
import { faAddressBook, faCoffee } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { useMeasure } from 'react-use';
const useMyComponentStyle = (params) => {
const { color } = params;
const [ref, { width }] = useMeasure();
const borderColor = width < 150 ? 'red' : width < 400 ? 'yellow' : 'green';
const icon = width < 250 ? faCoffee : faAddressBook;
const style = css`
color: ${color};
padding: 10px;
border: 1px solid ${borderColor};
`;
return {
ref,
style,
icon,
width,
};
};
export const MyComponent = (props) => {
const { ref, style, icon, width } = useMyComponentStyle(props);
return (
<div ref={ref} css={style}>
<FontAwesomeIcon icon={icon} />
{props.children} [[{parseInt('' + width)}px]]
</div>
);
};
const containerStyle = css`
padding: 100px 200px;
border: 1px solid blue;
`;
export const MyContainer = () => (
<div css={containerStyle}>
<MyComponent color='blue'></MyComponent>
</div>
);
ReactDOM.render(<MyContainer />, document.getElementById('root'));
The example above uses emotion for the css styles, but the style could be defined using another library, like jss or styled components, or even plain react inline style.
The component MyComponent
is included inside the container component MyContainer
that has left and right padding
with value 200px
, and you can see as you resize your browser view that the border
color of MyComponent
is based on the size of the component itself (red
if the width of the component is less than 150px
, yellow
if it's less than 400px
, otherwise it's green
), not based on the size of the window.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With