not the screen I want to apply this if the component is of width 600px I'm trying to change some styling if the component is in a Modal I only want to change flex-direction from column to row-reverse so I can't see a point in doing another component my code
const wrapper = styled.div`
display: flex;
flex-direction: column;
@media screen and (max-width: 600px) {
flex-direction: row-reverse;
}
}
`
This obviously doesn't since it is checking the screen
@container
queriesUsing container queries requires creating a parent container element that the Wrapper
component can be rendered into. This is supported in styled-components@6
.
Example:
const Container = styled.div`
container-type: inline-size;
`;
const Wrapper = styled.div`
display: flex;
flex-direction: column;
@container (max-width: 600px) {
flex-direction: row-reverse;
}
`;
Usage:
<Container>
<Wrapper>
...wrapped content...
</Wrapper>
</Container>
Or a bit more succinct using an anonymous inline function:
const Div = styled((props) => (
<div className="container">
<div {...props} />
</div>
))`
display: flex;
flex-direction: column;
@container (max-width: 600px) {
flex-direction: row-reverse;
}
.container:has(> &) {
container-type: inline-size;
}
`;
Usage:
<Wrapper>
...wrapped content...
</Wrapper>
If your project or environment doesn't support container queries then you will need to measure the div
HTML node to check its width to see if it is less than or equal to 600 pixels or not.
Here's an example implementation using a wrapper component to do the measuring of the styled div
element:
Custom hook to measure DOMNode by React ref and return its width.
const useElementWidth = () => {
const ref = useRef();
const [width, setWidth] = useState();
useEffect(() => {
const handler = () => {
setWidth(ref.current.getBoundingClientRect().width);
};
handler();
window.addEventListener("resize", handler, true);
return () => {
window.removeEventListener("resize", handler, true);
};
}, []);
return {
ref,
width
};
};
Wrapper to attach ref and set CSS classname for when the "media query" condition is met.
import { clsx } from "clsx";
const Wrapper = (props) => {
const { ref, width } = useElementWidth();
return (
<InnerWrapper
ref={ref}
className={clsx({ mobile: width <= 600 })}
{...props}
/>
);
};
The original div
styled component.
const InnerWrapper = styled.div`
display: flex;
flex-direction: column;
&.mobile {
flex-direction: row-reverse;
}
`;
Element under 600px
Element over 600px
Element in parent element with max-width of 700px