# StylesPerformance

# Styles performance

## CSS modules

[CSS modules](https://mantine.dev/llms/styles-css-modules.md) is the most performant way to apply styles –
this approach generates static CSS that is never re-evaluated. 99% of Mantine component
styles are generated with CSS modules – components are optimized out of the box.

In most cases, it is recommended to use [CSS modules](https://mantine.dev/llms/styles-css-modules.md) to style your components as well.
You can apply styles to HTML elements with the `className` prop and to Mantine components with the `className`
and `classNames` props.

Applying styles with the `className`:

```tsx
import { Box } from '@mantine/core';
import classes from './Demo.module.css';

function Demo() {
  return (
    <Box className={classes.box}>
      Box component with <span className={classes.highlight}>some styles</span>
    </Box>
  );
}
```


Applying styles with `classNames` (see the [Styles API guide](https://mantine.dev/llms/styles-styles-api.md) to learn more):

```tsx
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)}
    />
  );
}
```


## Inline styles

Inline styles (`style` and `styles` props) are less performant than CSS modules, but still
performant enough to be used in most cases if they are your preferred way of styling in your project.

Inline styles caveats:

* Styles are not reused between components; each component will generate its own styles. For example,
  if you have 100 buttons with the same styles, CSS modules will generate 1 class for all of them,
  while inline styles will generate 100 `style` attributes
* If inline styles are overused, they can increase bundle size and output HTML size
* *Not performance related*: inline styles have higher specificity than CSS modules, so if you want
  to override inline styles you will have to use `!important` or use other inline styles

Example of inline styles:

```tsx
import { Button } from '@mantine/core';

function Demo() {
  const gradient =
    'linear-gradient(45deg, var(--mantine-color-pink-filled) 0%, var(--mantine-color-orange-filled) 50%, var(--mantine-color-yellow-filled) 100%)';

  return (
    <Button
      styles={{
        root: {
          padding: 2,
          border: 0,
          backgroundImage: gradient,
        },

        inner: {
          background: 'var(--mantine-color-body)',
          color: 'var(--mantine-color-text)',
          borderRadius: 'calc(var(--button-radius) - 2px)',
          paddingLeft: 'var(--mantine-spacing-md)',
          paddingRight: 'var(--mantine-spacing-md)',
        },

        label: {
          backgroundImage: gradient,
          WebkitBackgroundClip: 'text',
          WebkitTextFillColor: 'transparent',
        },
      }}
    >
      Gradient button
    </Button>
  );
}
```


## Style props

[Style props](https://mantine.dev/llms/styles-style-props.md) transform component props into inline styles. Style props have
the same caveats as inline styles. It is not recommended to use them as the primary means of styling
your components. Usually, style props are used to apply 1–3 styles to a component – using them
this way does not impact performance.

## Responsive style props

Responsive [style props](https://mantine.dev/llms/styles-style-props.md) have worse performance than regular style props
because they require injecting a `<style />` tag next to the component. It is fine to use responsive
style props to apply styles to several components, but it is not recommended to use
them in large lists of components. For example, if you have 1000 inputs with responsive margins,
it is better to refactor to use the `classNames` prop:

```tsx
import { TextInput } from '@mantine/core';

// Ok, style props are used to apply margin-top property to several components
function StyleProps() {
  return (
    <>
      <TextInput label="Input 1" />
      <TextInput label="Input 2" mt={{ base: 10, md: 20 }} />
      <TextInput label="Input 3" mt={{ base: 10, md: 20 }} />
    </>
  );
}

// Worse, 1000 separate `<style />` tags will be generated
// Better to refactor to use the className prop
function StylePropsArray() {
  const inputs = Array(1000)
    .fill(0)
    .map((_, index) => (
      <TextInput
        key={index}
        label={`Input ${index}`}
        mt={{ base: 10, md: 20 }}
      />
    ));

  return <>{inputs}</>;
}
```

### Deduplicating responsive style props

If you have many components with the same responsive style props, you can enable
`deduplicateInlineStyles` on [MantineProvider](https://mantine.dev/llms/theming-mantine-provider.md) to
automatically share `<style />` tags between components with identical responsive styles.
This uses React 19 style hoisting to deduplicate and hoist styles to `<head />`:

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

function Demo() {
  return (
    <MantineProvider deduplicateInlineStyles>
      {/* Components with the same responsive style props
          will now share a single <style /> tag */}
    </MantineProvider>
  );
}
```

Note that deduplication only helps when multiple components share the **same** responsive
style prop values. If every component has unique responsive values, each still requires
its own `<style />` tag.

Currently, deduplication applies to [style props](https://mantine.dev/llms/styles-style-props.md) on all components
and to responsive props on the [Flex](https://mantine.dev/llms/core-flex.md) component. Components like
[Grid](https://mantine.dev/llms/core-grid.md) and [SimpleGrid](https://mantine.dev/llms/core-simple-grid.md) are not yet covered.

## Components responsive props

Some components, like [SimpleGrid](https://mantine.dev/llms/core-simple-grid.md) and [Grid](https://mantine.dev/llms/core-grid.md),
rely on the same mechanism as responsive style props to apply styles. The limitations are the same
– it is fine to use several of these components on a page, but it is not recommended to use
them in large lists of components.
