Styles API

All Mantine components support styling of each component part with inline styles or by passing classes.

Styling with classNames

Let's say you want to make Slider component look like this:

20%
50%
80%

But default slider has completely different styles:

20%
50%
80%
Type
Color
Size
xs
sm
md
lg
xl
Radius
xs
sm
md
lg
xl

To apply your styles to Slider component, go to "Styles API" tab under component documentation and find styles names table. The name column will tell you how to target a specific element inside the component:

NameStatic selectorDescription
root.mantine-Slider-rootRoot element
track.mantine-Slider-trackTrack element, contains all other elements
bar.mantine-Slider-barFilled part of the track
thumb.mantine-Slider-thumbMain control
dragging.mantine-Slider-draggingStyles added to thumb while dragging
label.mantine-Slider-labelLabel element, displayed above thumb
markWrapper.mantine-Slider-markWrapperWrapper around mark, contains mark and mark label
mark.mantine-Slider-markMark displayed on the track
markFilled.mantine-Slider-markFilledStyles added to mark when it is located in filled area
markLabel.mantine-Slider-markLabelMark label, displayed below track

For example, if you want to add styles to slider thumb:

// Add className to thumb
<Slider classNames={{ thumb: 'my-slider-thumb' }} />
// Add inline styles to thumb
<Slider styles={{ thumb: { backgroundColor: 'red' } }} />

Now you can write styles for your component with createStyles function or any other styling tools and languages:

import { Slider, createStyles } from '@mantine/core';
const useStyles = createStyles((theme) => ({
track: {
backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[3] : theme.colors.blue[1],
},
mark: {
width: 6,
height: 6,
borderRadius: 6,
transform: 'translateX(-3px) translateY(-2px)',
borderColor: theme.colorScheme === 'dark' ? theme.colors.dark[3] : theme.colors.blue[1],
},
markFilled: {
borderColor: theme.colors.blue[6],
},
markLabel: { fontSize: theme.fontSizes.xs, marginBottom: 5, marginTop: 0 },
thumb: {
height: 16,
width: 16,
backgroundColor: theme.white,
borderWidth: 1,
boxShadow: theme.shadows.sm,
},
}));
function MyCustomSlider() {
const { classes } = useStyles();
return (
<Slider
classNames={{
track: classes.track,
mark: classes.mark,
markFilled: classes.markFilled,
markLabel: classes.markLabel,
thumb: classes.thumb,
}}
/>
);
}

Styling with inline styles

Same as in the above example – to make this twitter button you will need to use styles API:

Styles names for button component:

NameStatic selectorDescription
root.mantine-Button-rootRoot button element
outline.mantine-Button-outlineOutline variant root element modifier
filled.mantine-Button-filledFilled variant root element modifier
light.mantine-Button-lightLight variant root element modifier
default.mantine-Button-defaultDefault variant root element modifier
subtle.mantine-Button-subtleDefault variant root element modifier
gradient.mantine-Button-gradientGradient variant root element modifier
white.mantine-Button-whiteWhite variant root element modifier
loading.mantine-Button-loadingLoading root element modifier
icon.mantine-Button-iconShared icon styles
leftIcon.mantine-Button-leftIconLeft icon
rightIcon.mantine-Button-rightIconRight icon
inner.mantine-Button-innerContains label, left and right icons
label.mantine-Button-labelContains button children

For this button, extra styles are required only for root element and left icon:

import { Button } from '@mantine/core';
import { BrandTwitter } from 'tabler-icons-react';
function Demo() {
return (
<Button
component="a"
target="_blank"
rel="noopener noreferrer"
href="https://twitter.com/mantinedev"
leftIcon={<BrandTwitter size={18} />}
styles={(theme) => ({
root: {
backgroundColor: '#00acee',
border: 0,
height: 42,
paddingLeft: 20,
paddingRight: 20,
'&:hover': {
backgroundColor: theme.fn.darken('#00acee', 0.05),
},
},
leftIcon: {
marginRight: 15,
},
})}
>
Follow on Twitter
</Button>
);
}

Styles API with MantineProvider

You can also use Styles API in MantineProvider with styles prop. All styles defined there will be added to each component rendered inside provider.

Dot badge
import { MantineProvider, Button, Badge, ButtonStylesParams } from '@mantine/core';
function Demo() {
return (
<MantineProvider
styles={{
Button: (theme, params: ButtonStylesParams) => ({
// Shared button styles are applied to all buttons
root: { height: 42, padding: '0 30px' },
filled: {
// subscribe to component params
color: theme.colors[params.color || theme.primaryColor][1],
},
// These styles are applied only to buttons with outline variant
outline: {
// You can use any selectors inside (the same way as in createStyles function)
'&:hover': {
backgroundColor:
theme.colorScheme === 'dark' ? theme.colors.dark[8] : theme.colors.gray[0],
},
},
}),
// Use raw styles object if you do not need theme dependency
Badge: {
dot: {
borderWidth: 2,
},
},
}}
>
<Button variant="outline">Outline button</Button>
<Button variant="filled" color="cyan">Filled button</Button>
<Badge variant="dot">Dot badge</Badge>
</MantineProvider>
);
}

Static class names

Apart from classNames and styles props, each component also has static classes on each element. You can use them to apply your styles if you do not use CSS modules or just do not want to pass classNames prop.

More examples

Calendar component

Calendar component customization with styles API:

Mo
Tu
We
Th
Fr
Sa
Su
import { useState } from 'react';
import { Calendar } from '@mantine/dates';
function Demo() {
const [value, setValue] = useState(new Date());
return (
<Calendar
value={value}
onChange={setValue}
month={value}
fullWidth
size="xl"
styles={(theme) => ({
cell: {
border: `1px solid ${
theme.colorScheme === 'dark' ? theme.colors.dark[4] : theme.colors.gray[2]
}`,
},
day: { borderRadius: 0, height: 70, fontSize: theme.fontSizes.lg },
weekday: { fontSize: theme.fontSizes.lg },
weekdayCell: {
fontSize: theme.fontSizes.xl,
backgroundColor:
theme.colorScheme === 'dark' ? theme.colors.dark[5] : theme.colors.gray[0],
border: `1px solid ${
theme.colorScheme === 'dark' ? theme.colors.dark[4] : theme.colors.gray[2]
}`,
height: 70,
},
})}
/>
);
}

Tabs component

Tabs component customization with styles API:

import { TabsProps, Tabs } from '@mantine/core';
import { Photo, MessageCircle, Settings } from 'tabler-icons-react';
function StyledTabs(props: TabsProps) {
return (
<Tabs
variant="unstyled"
styles={(theme) => ({
tabControl: {
backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[6] : theme.white,
color: theme.colorScheme === 'dark' ? theme.colors.dark[0] : theme.colors.gray[9],
border: `1px solid ${theme.colorScheme === 'dark' ? theme.colors.dark[6] : theme.colors.gray[4]}`,
fontSize: theme.fontSizes.md,
padding: `${theme.spacing.lg}px ${theme.spacing.xl}px`,
'&:not(:first-of-type)': {
borderLeft: 0,
},
'&:first-of-type': {
borderTopLeftRadius: theme.radius.md,
borderBottomLeftRadius: theme.radius.md,
},
'&:last-of-type': {
borderTopRightRadius: theme.radius.md,
borderBottomRightRadius: theme.radius.md,
},
},
tabActive: {
backgroundColor: theme.colors.blue[7],
borderColor: theme.colors.blue[7],
color: theme.white,
},
})}
{...props}
/>
);
}
function Demo() {
return (
<StyledTabs>
<Tabs.Tab label="Settings" icon={<Settings size={16} />} />
<Tabs.Tab label="Messages" icon={<MessageCircle size={16} />} />
<Tabs.Tab label="Gallery" icon={<Photo size={16} />} />
</StyledTabs>
);
}

Accordion component

Accordion component customization with styles API:

Colors, fonts, shadows and many other parts are customizable to fit your design needs

import { Accordion, AccordionProps, createStyles } from '@mantine/core';
import { Plus } from 'tabler-icons-react';
const useStyles = createStyles((theme, _params, getRef) => ({
icon: { ref: getRef('icon') },
control: {
ref: getRef('control'),
border: 0,
opacity: 0.6,
color: theme.colorScheme === 'dark' ? theme.white : theme.black,
'&:hover': {
backgroundColor: 'transparent',
opacity: 1,
},
},
item: {
borderBottom: 0,
overflow: 'hidden',
transition: `box-shadow 150ms ${theme.transitionTimingFunction}`,
border: '1px solid transparent',
borderRadius: theme.radius.sm,
},
itemOpened: {
backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[5] : theme.white,
borderColor: theme.colorScheme === 'dark' ? theme.colors.dark[5] : theme.colors.gray[3],
[`& .${getRef('control')}`]: {
opacity: 1,
},
[`& .${getRef('icon')}`]: {
transform: 'rotate(45deg)',
},
},
content: {
paddingLeft: 0,
},
}));
function StyledAccordion(props: AccordionProps) {
const { classes } = useStyles();
return <Accordion classNames={classes} icon={<Plus size={16} />} {...props} />;
}
function Demo() {
return (
<StyledAccordion initialItem={0}>
{/* <Accordion.Item /> components */}
</StyledAccordion>
);
}