reactjsmaterial-uistyled-components

Media Queries in Material-UI Using Styled-Components


Material UI has a nice set of built-in media queries: https://material-ui.com/customization/breakpoints/#css-media-queries

Material UI also allows us to use Styled-Components with Material UI: https://material-ui.com/guides/interoperability/#styled-components

I want to know how to combine the two together. That is, how can I make media queries using Styled Components and Material-UI's built-in breakpoints?

Thanks.

UPDATE:

Here is an example of what I am trying to do:

import React, { useState } from 'react'
import styled from 'styled-components'


import {
  AppBar as MuiAppBar,
  Drawer as MuiDrawer,
  Toolbar,
} from '@material-ui/core'


const drawerWidth = 240

const AdminLayout = ({ children }) => {

  return (
    <BaseLayout>
      <AppBar position="static">
        <Toolbar>
          TOOLBAR
        </Toolbar>
      </AppBar>
      <Drawer>
        DRAWER
      </Drawer>
      {children}
    </BaseLayout>
  )
}

AdminLayout.propTypes = {
  children: PropTypes.node.isRequired,
}

export default AdminLayout

// ------- STYLES -------
const AppBar = styled(MuiAppBar)`
  /* Implement appBar styles from useStyles */
`

const Drawer = styled(MuiDrawer)`
  /* Implement drawer styles from useStyles */
`

// STYLES THAT I WANT TO CONVERT TO STYLED-COMPONENTS
const useStyles = makeStyles(theme => ({
  root: {
    display: 'flex',
  },
  drawer: {
    [theme.breakpoints.up('sm')]: {
      width: drawerWidth,
      flexShrink: 0,
    },
  },
  appBar: {
    [theme.breakpoints.up('sm')]: {
      width: `calc(100% - ${drawerWidth}px)`,
      marginLeft: drawerWidth,
    },
  },
  toolbar: theme.mixins.toolbar,
}))

Solution

  • Below is an example showing one way of leveraging the Material-UI theme breakpoints with styled-components. This is passing the Material-UI theme to the styled-components ThemeProvider in order to make it available as a prop within the styles. The example also uses StylesProvider with the injectFirst prop so that the Material-UI styles will occur at the beginning of the <head> rather than the end, so that the styled-components styles occur after the Material-UI styles and therefore win when specificity is otherwise equal.

    import React from "react";
    import styled, { ThemeProvider as SCThemeProvider } from "styled-components";
    import { useTheme, StylesProvider } from "@material-ui/core/styles";
    import MuiAppBar from "@material-ui/core/AppBar";
    
    const AppBar = styled(MuiAppBar)`
      background-color: red;
      ${props => props.theme.breakpoints.up("sm")} {
        background-color: orange;
      }
      ${props => props.theme.breakpoints.up("md")} {
        background-color: yellow;
        color: black;
      }
      ${props => props.theme.breakpoints.up("lg")} {
        background-color: green;
        color: white;
      }
    `;
    export default function App() {
      const muiTheme = useTheme();
      return (
        <StylesProvider injectFirst>
          <SCThemeProvider theme={muiTheme}>
            <AppBar>Sample AppBar</AppBar>
          </SCThemeProvider>
        </StylesProvider>
      );
    }
    

    Edit MUI theme breakpoints with styled-components

    Related documentation: