Responsive styles

@mantine/core package exports several components that can help you organize responsive styles without writing CSS. Note that in most cases that are not covered in this guide, the best way to make your app responsive is to add styles with createStyles function.

Configure breakpoints

theme.breakpoints are used in all responsive Mantine components. Breakpoints are expected to be set in em units (1em == 16px by default). You can configure these values with MantineProvider:

import { MantineProvider } from '@mantine/core';
function Demo() {
return (
<MantineProvider
withGlobalStyles
withNormalizeCSS
theme={{
breakpoints: {
xs: '30em',
sm: '48em',
md: '64em',
lg: '74em',
xl: '90em',
},
}}
>
<App />
</MantineProvider>
);
}

Default theme.breakpoints values:

BreakpointViewport width
xs36em
sm48em
md62em
lg75em
xl88em

Media queries in createStyles

In most cases using createStyles function is cleanest way to add responsive styles to any element. Consider using it first before hacking your way out of writing CSS with other approaches:

import { createStyles, getBreakpointValue, rem, em } from '@mantine/core';
const useStyles = createStyles((theme) => ({
container: {
height: rem(100),
backgroundColor: theme.colors.blue[6],
// Media query with value from theme
[`@media (max-width: ${em(getBreakpointValue(theme.breakpoints.xl) - 1)})`]: {
backgroundColor: theme.colors.pink[6],
},
// Simplify media query writing with theme functions
[theme.fn.smallerThan('lg')]: {
backgroundColor: theme.colors.yellow[6],
},
// Static media query
[`@media (max-width: ${em(800)})`]: {
backgroundColor: theme.colors.orange[6],
},
},
}));
function Demo() {
const { classes } = useStyles();
return <div className={classes.container} />;
}

MediaQuery component

MediaQuery component lets you apply styles to given component or element if given media query matches:

(max-width: 75em) and (min-width: 50em) breakpoints
import { MediaQuery, Text, rem } from '@mantine/core';
function Demo() {
return (
<MediaQuery
query="(max-width: 75em) and (min-width: 50em)"
styles={{ fontSize: rem(20), '&:hover': { backgroundColor: 'silver' } }}
>
<Text>(max-width: 75em) and (min-width: 50em) breakpoints</Text>
</MediaQuery>
);
}

Changing component size based on media query

Most of Mantine components support size prop with xs, sm, md, lg and xl values. You cannot change these values within component props. Instead you can use MediaQuery component to render different components based on media query:

<>
<MediaQuery smallerThan="sm" styles={{ display: 'none' }}>
<TextInput size="xl" />
</MediaQuery>
<MediaQuery largerThan="sm" styles={{ display: 'none' }}>
<TextInput size="md" />
</MediaQuery>
</>

The approach with MediaQuery component will work with SSR. If you do not need SSR support the more cleaner way to change size is to use use-media-query hook:

import { TextInput } from '@mantine/core';
import { useMediaQuery } from '@mantine/hooks';
function Demo() {
// Will always return false during ssr, use only when you do not have ssr
const largeScreen = useMediaQuery('(min-width: 60em)');
return <TextInput size={largeScreen ? 'xl' : 'md'} />;
}

Inline media queries with sx

All Mantine components support sx prop with which you can add styles (including responsive styles) to root component element:

import { TextInput } from '@mantine/core';
function Demo() {
return (
<TextInput
sx={(theme) => ({
background: theme.colors.gray[0],
padding: theme.spacing.md,
'@media (max-width: 40em)': {
padding: theme.spacing.sm,
},
})}
/>
);
}

If you want to add styles with sx prop to non-Mantine component, you can wrap it in Box:

// Example with react-router-dom Link
import { Link } from 'react-router-dom';
import { Box } from '@mantine/core';
function Demo() {
return (
<Box
component={Link}
to="/some-path/"
sx={(theme) => ({
fontSize: theme.fontSizes.md,
'@media (max-width: 40em)': {
fontSize: theme.fontSizes.sm,
},
})}
>
Styled react-router link
</Box>
);
}