API overview

This guide will help you get familiar with core Mantine concepts. Please read this guide, theming and styles sections before starting development to learn about all of the available theming and styling features.

MantineProvider

MantineProvider is required to be rendered at the root of your application. It is responsible for:

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

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

Theme object

Theme object stores design tokens, components default props, context styles and other data that can be accessed by any Mantine component. Most of the theme values are exposed as CSS variables and can be accessed both in JavaScript and CSS.

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

// Your theme configuration is merged with default theme
const theme = createTheme({
  fontFamily: 'Montserrat, sans-serif',
  defaultRadius: 'md',
});

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

Access theme values in styles:

.demo {
  background: var(--mantine-color-red-1);
  color: var(--mantine-color-red-9);
  font-family: var(--mantine-font-family);
  border-radius: var(--mantine-radius-md);
}

Access theme values in JavaScript:

import { lighten, useMantineTheme } from '@mantine/core';

function Demo() {
  const theme = useMantineTheme();

  const style = {
    // You can use CSS variables in inline styles
    background: 'var(--mantine-color-red-9)',

    // Or use values from theme object if you need to modify them
    color: lighten(theme.colors.red[9], 0.2),
  };

  return <div style={style} />;
}

Colors

Colors are stored in theme.colors object and are exposed as CSS variables. Each color must have at least 10 shades. You can generate new colors based on a single color value with the colors generator.

Colors are numbered from 0 to 9 where 0 is the lightest and 9 is the darkest color. Example of blue color from the default theme:

blue 0

#e7f5ff

blue 1

#d0ebff

blue 2

#a5d8ff

blue 3

#74c0fc

blue 4

#4dabf7

blue 5

#339af0

blue 6

#228be6

blue 7

#1c7ed6

blue 8

#1971c2

blue 9

#1864ab

To access colors in styles use CSS variables:

.demo {
  background: var(--mantine-color-blue-9);
  color: var(--mantine-color-blue-0);
}

CSS modules

All Mantine components use CSS modules for styling. It is recommended to use CSS modules in your project as well, but it is not required – Mantine components are fully compatible with any third-party styling solution and native CSS.

CSS modules are available in most modern frameworks out of the box. To use them, create a file with .module.css extension:

/* Button.module.css */
.button {
  color: red;
}

And then import it in your component:

import classes from './Button.module.css';

function Demo() {
  return (
    <button className={classes.button} type="button">
      Button
    </button>
  );
}

PostCSS preset

postcss-preset-mantine provides several CSS functions and mixins to simplify your styles. It is not required to use it, but highly recommended. All demos that feature styles assume that you have this preset installed.

postcss-preset-mantine allows you to use functions and mixins in .css files:

.demo {
  padding: rem(20px); /* Convert px to rem */

  /* Convert px to em (for media queries) */
  @media (max-width: em(500px)) {
  }

  /* light and dark mixins to apply styles based on Mantine color scheme */
  @mixin light {
    background-color: var(--mantine-color-white);
  }

  @mixin dark {
    background-color: var(--mantine-color-black);
  }

  /* light-dark function as an inline shortcut for light and dark mixins */
  background: light-dark(
    var(--mantine-color-white),
    var(--mantine-color-black)
  );

  /* rtl mixin to apply styles for right-to-left direction */
  padding-left: 1rem;
  @mixin rtl {
    padding-left: 0;
    padding-right: 1rem;
  }
}

Vanilla extract

Vanilla extract is a good alternative to CSS modules if you prefer to write styles in JavaScript. Mantine provides Vanilla extract integration with @mantine/vanilla-extract package.

CSS variables

Theme values are converted to CSS variables and are available to use in your styles. All Mantine CSS variables are prefixed with --mantine-, for example:

  • theme.fontFamily--mantine-font-family
  • theme.colors.blue[9]--mantine-color-blue-9
  • theme.spacing.xl--mantine-spacing-xl

Most of Mantine components have associated CSS variables that can be customized in theme or inline with vars prop. Example of customizing Button CSS variables to add new xxl and xxs sizes:

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

const theme = createTheme({
  components: {
    Button: Button.extend({
      vars: (theme, props) => {
        if (props.size === 'xxl') {
          return {
            root: {
              '--button-height': rem(60),
              '--button-padding-x': rem(30),
              '--button-fz': rem(24),
            },
          };
        }

        if (props.size === 'xxs') {
          return {
            root: {
              '--button-height': rem(24),
              '--button-padding-x': rem(10),
              '--button-fz': rem(10),
            },
          };
        }

        return { root: {} };
      },
    }),
  },
});

function Demo() {
  return (
    <MantineProvider theme={theme}>
      <Group>
        <Button size="xxl">XXL Button</Button>
        <Button size="xxs">XXS Button</Button>
      </Group>
    </MantineProvider>
  );
}

Styles API

Styles API is a set of props and techniques that allows you to customize styles of any element inside Mantine component inline or with theme object. All Mantine components that have styles support Styles API.

Every Mantine component has a set of elements names that can be used to apply styles to inner elements inside the component. Example of TextInput component selectors:

SelectorStatic selectorDescription
wrapper.mantine-TextInput-wrapperRoot element of the Input
input.mantine-TextInput-inputInput element
section.mantine-TextInput-sectionLeft and right sections
root.mantine-TextInput-rootRoot element
label.mantine-TextInput-labelLabel element
required.mantine-TextInput-requiredRequired asterisk element, rendered inside label
description.mantine-TextInput-descriptionDescription element
error.mantine-TextInput-errorError element

These selectors can be used to apply styles to inner elements with classNames or styles props:

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

function Demo() {
  const [value, setValue] = useState('');
  const [focused, setFocused] = useState(false);
  const floating = focused || value.length > 0 || undefined;

  return (
    <TextInput
      label="Floating label input"
      labelProps={{ 'data-floating': floating }}
      classNames={{
        root: classes.root,
        input: classes.input,
        label: classes.label,
      }}
      onFocus={() => setFocused(true)}
      onBlur={() => setFocused(false)}
      value={value}
      onChange={(event) => setValue(event.currentTarget.value)}
    />
  );
}

Color scheme

All Mantine components support light, dark and auto color schemes. By default, the color scheme is light, it can be changed by the user and will be persisted in localStorage.

You can use configure the default color scheme on MantineProvider:

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

function Demo() {
  return (
    <MantineProvider defaultColorScheme="dark">
      <App />
    </MantineProvider>
  );
}

And use useMantineColorScheme hook to create color scheme toggle control:

import { ActionIcon, useMantineColorScheme, useComputedColorScheme } from '@mantine/core';
import { IconSun, IconMoon } from '@tabler/icons-react';
import cx from 'clsx';
import classes from './Demo.module.css';

function Demo() {
  const { setColorScheme } = useMantineColorScheme();
  const computedColorScheme = useComputedColorScheme('light', { getInitialValueInEffect: true });

  return (
    <ActionIcon
      onClick={() => setColorScheme(computedColorScheme === 'light' ? 'dark' : 'light')}
      variant="default"
      size="xl"
      aria-label="Toggle color scheme"
    >
      <IconSun className={cx(classes.icon, classes.light)} stroke={1.5} />
      <IconMoon className={cx(classes.icon, classes.dark)} stroke={1.5} />
    </ActionIcon>
  );
}

Unstyled components

You can use Mantine as a headless UI library. To do that, simply do not import @mantine/*/styles.css in your application. Then you will be able to apply styles to Mantine components using the Styles API with a styling solution of your choice.

All components also support unstyled prop that removes all library styles from the component:

Chat panel
import { Tabs } from '@mantine/core';

function Demo() {
  return (
    <Tabs defaultValue="chat" unstyled>
      <Tabs.List>
        <Tabs.Tab value="chat">Chat</Tabs.Tab>
        <Tabs.Tab value="gallery">Gallery</Tabs.Tab>
        <Tabs.Tab value="account">Account</Tabs.Tab>
      </Tabs.List>

      <Tabs.Panel value="chat">Chat panel</Tabs.Panel>
      <Tabs.Panel value="gallery">Gallery panel</Tabs.Panel>
      <Tabs.Panel value="account">Account panel</Tabs.Panel>
    </Tabs>
  );
}