0

I have defined sass variable $mobile

$mobile: "(min-width: 320px) and (max-width:479px)";

so in every place in scss file where I need to use @media query, I can use it in the following way:

@media #{$mobile}  {
      max-width: 100%;
      width: 100%;
      height: 100%;
    }

Is it possible to use in the same way $mobile variable with styled-componenents?

I have tried to export this variable like I do with other sass variables:

:root {
  --c-global-red: #{$c-global-red};
  --mobile: #{$mobile};
}

Now if I need to use for example $c-global-red in styled-component, I can do it as following:

const StyledDiv = styled.div`
    color: var(--c-global-red);
`

Can I use same approach to use --mobile variable with @media tag? Something like this:

const StyledDiv = styled.div`
    color: var(--c-global-red);
    @media var(--mobile) {
        color: blue;
    }
`
Anatoly
  • 5,056
  • 9
  • 62
  • 136

1 Answers1

1

While you can reference global CSS variables within a styled-component, you can't reference sass variables nor global CSS variables containing strings. Instead, you'll want to leverage the ThemeProvider with theme variables.


Demo

Within the Codesandbox editor, adjust the middle scrollbar by moving it left and right to see changes in the Button.

Edit Styled-Component Global Vars

The reason this works is because theme.mobile is interpolated to "(min-width: 320px) and (max-width:479px)" when the styles are created:

@media (min-width: 320px) and (max-width:479px) { ... }

Whereas, var(--example) is just interpolated to the string "var(--example)", which is invalid CSS syntax:

@media var(--mobile) { ... }

On that note, this may or may be considered anti-pattern since you're reliant upon global CSS variables within a global CSS stylesheet. You can completely avoid using CSS by just using theme variables.


Code

App.js

import { ThemeProvider, css } from "styled-components";
import Button from "./Button";
import "./styles.css";

const theme = {
  mobile: "(min-width: 320px) and (max-width:479px)"
};

export default function App() {
  return (
    <div className="app">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <Button>No Theme</Button>
      <br />
      <ThemeProvider theme={theme}>
        <Button>With Theme</Button>
      </ThemeProvider>
    </div>
  );
}

Button.js

import styled from "styled-components";

const Button = styled.button`
  cursor: pointer;
  color: var(--white);
  background: var(--blue);
  outline: 0;
  border: 0;
  margin: 10px 0;
  border-radius: 3px;
  padding: 20px;

  :hover {
    background: var(--darkblue);
  }
  
  ${({ theme }) =>
          `@media ${theme.mobile} {
          ${css`
             background: var(--pink);

            :hover {
              background: var(--darkpink);
            }
          `}
    }`}
`;

export default Button;

styles.css

.app {
  font-family: sans-serif;
  text-align: center;
}

body {
  margin: 0;
  padding: 0;
}

:root {
  --blue: #1e87f0;
  --darkblue: #0f7ae5;
  --white: #ffffff;
  --pink: #ff93ac;
  --darkpink: #ff6289;
}
Anatoly
  • 5,056
  • 9
  • 62
  • 136
Matt Carlotta
  • 18,972
  • 4
  • 39
  • 51