Breakpoints are a crucial concept in responsive design. They allow us to define the application’s appearance on different screen sizes. In this tutorial, we will learn how to use and customize Material UI (MUI) breakpoints to create responsive designs.
Using theme breakpoints
We can use the theme
object to access the MUI breakpoints when styling components. It’s an object available in the props
of all styled-components.
We can access them using the theme.breakpoints
object. It has the following keys:
xs
: Extra small devices (less than 600px)sm
: Small devices (600px and up)md
: Medium devices (900px and up)lg
: Large devices (1200px and up)xl
: Extra large devices (1536px and up)
Here’s a simple example of how to add the breakpoint styles to a component:
<Box
sx={(theme) => ({
textAlign: 'center',
[theme.breakpoints.up('md')]: { textAlign: 'left' },
})}
>
TEXT
</Box>
theme.breakpoints.up('md')
is a function that returns a CSS media query string. It’s equivalent to @media (min-width: 900px)
. So, the above code will set the textAlign
to left
for screen sizes greater than 900px
.
Let’s see another example with a more practical use case. We will create a header component that will align the logo to the left for screen sizes greater than 600px
and center it for smaller screen sizes.
import * as React from 'react';
import Typography from '@mui/material/Typography';
import { Stack, Toolbar, AppBar } from '@mui/material';
import LogoDev from '@mui/icons-material/LogoDev';
function ResponsiveHeader() {
return (
<AppBar position="static">
<Toolbar
sx={(theme) => ({
[theme.breakpoints.up('xs')]: { justifyContent: 'center' },
[theme.breakpoints.up('sm')]: { justifyContent: 'left' },
})}
>
<Stack direction="row" alignItems="center">
<LogoDev fontSize="large" />
<Typography
variant="h6"
sx={{
ml: 0.5,
}}
>
LOGO
</Typography>
</Stack>
</Toolbar>
</AppBar>
);
}
export default ResponsiveHeader;
The example above has a resize handle at the bottom right corner. If we resize the window, we can see the logo move to the center when the screen size is less than 600px
.
theme.breakpoints
object also provides different options to create media queries. Here’s a list of all the options:
up
: min-widthdown
: max-widthbetween
: between min-width and max-widthonly
: only the given breakpointnot
: not between min-width and max-width
Using SX shortcut syntax
sx
provides a shortcut syntax to access the theme and add component styles. It provides a more straightforward way to add breakpoints. Here’s an example:
<Box
sx={{
textAlign: { xs: 'center', md: 'left' },
}}
>
TEXT
</Box>
Using md
or sm
is equivalent to theme.breakpoints.up('md')
or theme.breakpoints.up('sm')
, and they’re used as a key of the CSS property value. So the above code will set the textAlign
to left
for screen sizes greater than 900px
.
This syntax is cleaner and easier to read, but it has a limitation. We can only use the up
option and can’t use down
, between
or only
options.
Let’s create the header example again using the sx
shortcut syntax.
import * as React from 'react';
import Typography from '@mui/material/Typography';
import { Stack, Toolbar, AppBar, Box } from '@mui/material';
import LogoDev from '@mui/icons-material/LogoDev';
function ResponsiveHeader() {
return (
<AppBar position="static">
<Toolbar
sx={{
justifyContent: { xs: 'center', sm: 'left' },
}}
>
<Stack direction="row" alignItems="center">
<LogoDev fontSize="large" />
<Typography
variant="h6"
sx={{
ml: 0.5,
}}
>
LOGO
</Typography>
</Stack>
</Toolbar>
</AppBar>
);
}
export default ResponsiveHeader;
Using media query hook
useMediaQuery
is a hook that returns a boolean value based on the current screen size. It’s helpful if we want to use JavaScript to access the breakpoints and do more complex logic.
Here’s an example of how to use useMediaQuery
hook:
import React from 'react';
import useMediaQuery from '@mui/material/useMediaQuery';
import { useTheme } from '@mui/material/styles';
const MyComponent = () => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
return (
<div>
{isMobile ? (
<div>Mobile View: More simplified layout or content</div>
) : (
<div>Desktop View: More complex layout or additional content</div>
)}
</div>
);
};
export default MyComponent;
In the above example, we’re using useMediaQuery
to check if the screen size is less than 600px
. If it’s true, we’re rendering a simplified layout. Otherwise, we’re rendering a more complex layout.
Customizing breakpoints
The breakpoints we used in the previous examples are the default breakpoints provided by MUI. Sometimes, we need to modify the breakpoints to match the design requirements or create new ones.
We can customize the values using the createTheme
object.
import { createTheme } from '@mui/material/styles';
const theme = createTheme({
breakpoints: {
values: {
xs: 0,
sm: 600,
md: 960,
lg: 1280,
xl: 1920,
xxl: 2000,
},
},
});
In the above example, we customized the default breakpoints and added a new one called xxl
xxl
with a value of 2000px
. We can now use this breakpoint in our components.
<Box
sx={(theme) => ({
textAlign: 'center',
[theme.breakpoints.up('xxl')]: { textAlign: 'left' },
})}
>
TEXT
</Box>
For more details about customizing the theme in MUI, this tutorial delves deeper into the topic: Customizing Theme, Palette, and Colors
Complete example
Let’s create a responsive header component with more features:
- The header will have a logo, a navigation menu, and an email contact icon.
- The logo will be aligned to the left for screen sizes greater than
600px
and centered for smaller screen sizes. - The navigation menu will be aligned next to the logo for screen sizes greater than
600px
and hidden for smaller screen sizes. - A menu icon will appear and be aligned to the left for screen sizes smaller than
600px
and hidden for larger screen sizes. - The menu icon is just a placeholder for this example and has no functionality, but in a real application, it will open a navigation drawer.
import * as React from 'react';
import Typography from '@mui/material/Typography';
import { Stack, Toolbar, AppBar, Container, Box } from '@mui/material';
import EmailIcon from '@mui/icons-material/Email';
import LogoDev from '@mui/icons-material/LogoDev ';
import MenuIcon from '@mui/icons-material/Menu';
function ResponsiveHeader() {
return (
<AppBar position="static">
<Container>
<Toolbar
disableGutters
sx={{
justifyContent: 'space-between',
}}
>
<MenuIcon sx={{ display: { xs: 'block', sm: 'none' } }} />
<Stack direction="row" alignItems="center">
<LogoDev sx={{ mr: 1, fontSize: { xs: '2rem', sm: '2.6rem' } }} />
<Typography
variant="h6"
sx={{
mr: 2,
fontWeight: 700,
letterSpacing: { xs: '0.1rem', sm: '0.2rem' },
fontSize: { xs: '1rem', sm: '1.2rem' },
}}
>
LOGO
</Typography>
<Stack
direction="row"
alignItems="center"
gap={2}
sx={{ display: { xs: 'none', sm: 'flex' } }}
>
<Typography>Home</Typography>
<Typography>About</Typography>
<Typography>Blog</Typography>
</Stack>
</Stack>
<EmailIcon />
</Toolbar>
</Container>
</AppBar>
);
}
export default ResponsiveHeader;
Summary
In this tutorial, we learned how to use and customize MUI breakpoints to create responsive designs. While MUI provides a simple way to add breakpoints using the theme.breakpoints
object, we can also use the sx
shortcut syntax or useMediaQuery
hook to access the breakpoints. Additionally, we can customize the breakpoints values by using a createTheme
object for other screen sizes.
Bye for now 👋