I'm having trouble getting media queries to work with media templates and styled components. I defined a MediaQueries template straight from the docs:
import { css } from "styled-components";
const sizes = {
desktop: 992,
tablet: 768,
phone: 576
};
// Iterate through the sizes and create a media template
const media = Object.keys(sizes).reduce((acc, label) => {
acc[label] = (...args) => css`
@media (max-width: ${sizes[label] / 16}em) {
${css(...args)}
}
`;
return acc;
}, {});
export default media;
And here's the test file:
import React from "react";
import styled from "styled-components";
import media from "./MediaQueries";
const Desktop = styled.h1`
color: red;
${media.phone`
display: none;
`}
`;
const Mobile = styled.h1`
color: blue;
${media.desktop`
display: none;
`}
`;
function App() {
return (
<div>
<Mobile>Mobile</Mobile>
<Desktop>Desktop</Desktop>
</div>
);
}
export default App;
What I'm expecting is for the [Desktop] title to be shown on large screens, and [Mobile] to be shown on smaller ones.
What I'm getting is the opposite: I get both titles on large screens, then while shrinking the window [Mobile] disappears first, then [Desktop].
My goal is to have one and only one of the components visible at all times. What am I doing wrong?
To apply the media query in a styled component just add it to the styling.
CSS declared inline This may be the reason why your media queries aren't working. That is to say, you may have declared CSS within your HTML document. So if this is the case, simply go through the HTML document and remove the CSS declared inline. Alternatively, you can override the inline CSS with !
The styled method works perfectly on all of your own or any third-party component, as long as they attach the passed className prop to a DOM element.
Styled components are a good choice for building a UI library since everything can be in one file and easily be exported and reused. If you prefer writing pure CSS, use CSS modules. You can have separate CSS files, and it locally scopes styles by default.
I think you got the rules mixed. If you want to toggle them based on size then one of them should start off with display:none
, then you switch them.
Something similar to this:
const Desktop = styled.h1`
color: red;
${media.phone`
display: none;
`}
`;
const Mobile = styled.h1`
color: blue;
display: none;
${media.phone`
display: block;
`}
`;
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