Responsive styles

Media queries

Demo
.demo {
  background-color: var(--mantine-color-blue-filled);
  color: var(--mantine-color-white);
  padding: var(--mantine-spacing-md);
  text-align: center;

  @media (min-width: em(750px)) {
    background-color: var(--mantine-color-red-filled);
  }
}

Configure breakpoints

theme.breakpoints are used in all responsive Mantine components. Breakpoints are expected to be set in em units. You can configure these values with MantineProvider:

import { MantineProvider, createTheme } from '@mantine/core';

const theme = createTheme({
  breakpoints: {
    xs: '30em',
    sm: '48em',
    md: '64em',
    lg: '74em',
    xl: '90em',
  },
});

function Demo() {
  return (
    <MantineProvider theme={theme}>
      <App />
    </MantineProvider>
  );
}

Default theme.breakpoints values:

BreakpointViewport widthValue in px
xs36em576px
sm48em768px
md62em992px
lg75em1200px
xl88em1408px

Breakpoints variables in CSS modules

It is not possible to use CSS variables inside media queries – these values cannot be dynamically generated by MantineProvider. To use Mantine theme breakpoints in your .css files, you will need postcss-simple-vars package:

yarn add --dev postcss-simple-vars

Add it to your PostCSS config in postcss.config.js:

module.exports = {
  plugins: {
    'postcss-preset-mantine': {},
    'postcss-simple-vars': {
      variables: {
        'mantine-breakpoint-xs': '36em',
        'mantine-breakpoint-sm': '48em',
        'mantine-breakpoint-md': '62em',
        'mantine-breakpoint-lg': '75em',
        'mantine-breakpoint-xl': '88em',
      },
    },
  },
};

Then you will be able to access these variables in your .css files:

.demo {
  @media (max-width: $mantine-breakpoint-xs) {
    background-color: red;
  }
}

Will be transformed to:

@media (max-width: 36em) {
  .demo {
    background-color: red;
  }
}

Dynamic breakpoints are not supported

Values that are defined in postcss-simple-vars config are static and are not connected to the theme – if values change, you will need to update them manually in both theme override and postcss config.

hiddenFrom and visibleFrom props

All Mantine components that have a root element support hiddenFrom and visibleFrom props. These props accept breakpoint (xs, sm, md, lg, xl) and hide the component when viewport width is less than or greater than the specified breakpoint:

import { Button, Group } from '@mantine/core';

function Demo() {
  return (
    <Group justify="center">
      <Button hiddenFrom="sm" color="orange">
        Hidden from sm
      </Button>
      <Button visibleFrom="sm" color="cyan">
        Visible from sm
      </Button>
      <Button visibleFrom="md" color="pink">
        Visible from md
      </Button>
    </Group>
  );
}

Component size based on media query

Some components support size prop, which changes various aspects of component appearance. size prop is not responsive – it is not possible to define different component sizes for different screen sizes. Instead, you can render multiple components with different sizes and show/hide them based on media query:

import { TextInput } from '@mantine/core';
import classes from './Demo.module.css';

function Demo() {
  return (
    <>
      <TextInput
        label="My input"
        placeholder="My input"
        size="xs"
        className={classes['input-mobile']}
      />
      <TextInput
        label="My input"
        placeholder="My input"
        size="xl"
        className={classes['input-desktop']}
      />
    </>
  );
}

use-media-query hook

You can use use-media-query hook to change some of component props based on media query. Note that this approach is not recommended for most of the cases if you have ssr in your application (you use Next.js, Remix, Gatsby or any other framework that includes ssr) as it may cause hydration mismatch. If you do not have ssr in your application (for example, if you use Vite), then you can safely use this hook to change props of components or conditionally render components based on hook return value.

use-media-query hook can be safely used to change props of components that are not rendered on server side (modals, tooltips, etc.). In the following example, it is safe to use useMediaQuery hook to change Tooltip props as it is not rendered on server side:

import { Tooltip, Button, em } from '@mantine/core';
import { useMediaQuery } from '@mantine/hooks';

function Demo() {
  const isMobile = useMediaQuery(`(max-width: ${em(750)})`);

  return (
    <Tooltip label={isMobile ? 'Mobile' : 'Desktop'}>
      <Button>Hover me</Button>
    </Tooltip>
  );
}