MRT logoMantine React Table

On This Page

    Customize Component Styles Guide

    There are a few ways in which you can style the internal components of Mantine React Table. Some ways are much easier and faster than others. This guide will cover the new MRT CSS variable system, how you customize your Mantine Theme, how you can write your own CSS with CSS modules, or how to pass in custom styles to the components.

    If all you care about is changing the background color of the table, you should try to use the MRT CSS variables first. They are the easiest and fastest way to change the background color of the table.

    MRT CSS Variables

    Before you try to write a bunch of overriding CSS (with className or style props), you should try to customize the MRT CSS variables first, especially if all you want to do is change the background color of some parts of the table.

    MRT CSS Variables List

    Here is a list of all of the MRT CSS variables that are set in the :root of your document once you import the MRT styles.css file from 'mantine-react-table':

    • --mrt-base-background-color: default background color for everything

    • --mrt-striped-row-background-color: background color for striped rows

    • --mrt-row-hover-background-color: background color for row hover

    • --mrt-striped-row-hover-background-color: background color for striped row hover

    • --mrt-selected-row-background-color: background color for selected row

    • --mrt-selected-row-hover-background-color: background color for selected row hover

    • --mrt-pinned-row-background-color: background color for pinned row

    • --mrt-pinned-row-hover-background-color: background color for pinned row hover

    • --mrt-pinned-column-background-color: background color for pinned column

    • --mrt-dragging-hovered-border-color: border color for dragging hovered cell

    • --mrt-dragging-drag-border-color: border color for dragging cell

    • --mrt-resize-column-border-color: border color for column resize

    These CSS variables are automatically calculated with intelligent defaults based on light and dark mode.

    How to set MRT CSS Variables

    You can override these CSS variables on a per table basis, or globally in your app from a higher up root element. MRT already defines these CSS variables in the :root of the document, so if you try to override them there in your own CSS, you may have some issues. Instead, you can either just override them in the style surrounding the MRT table components, or by defining them in a class and passing the classes to the className of the most "root" MRT component that you are using. Usually, this is the mantinePaperProps table option.

    If you do start changing some CSS variables like the --mrt-base-background-color, make sure to also redefine the other CSS variables that derive from it, like --mrt-striped-row-background-color, --mrt-row-hover-background-color, etc. Otherwise, those CSS variables will still be calculated based on the default --mrt-base-background-color. Row hovers will have gray backgrounds instead of lighted or darkened versions of your new --mrt-base-background-color.

    1. Define MRT CSS Variables in a CSS Class (Recommended)
    /* Define MRT CSS variables in your CSS */
    .root {
      /* You can account for both light and dark mode with the Mantine mixins */
      @mixin dark {
        --mrt-base-background-color: rgb(33, 24, 44);
      }
      @mixin light {
        --mrt-base-background-color: rgb(244, 233, 255);
      }
      /* It's also best to redefine all of the other MRT CSS variables that derive from --mrt-base-background-color */
      /* ... */
    }

    You can copy the MRT CSS variable definitions from the MRT Source Code

    const table = useMantineReactTable({
      columns,
      data,
      mantinePaperProps: { className: classes.root },
    });
    2. Define MRT CSS Variables in Style Props
    const table = useMantineReactTable({
      columns,
      data,
      mantinePaperProps: {
        style: { '--mrt-base-background-color': 'rgb(33, 24, 44)' },
      },
    });
    
    // OR
    <div style={{ '--mrt-base-background-color': 'rgb(33, 24, 44)' }}>
      <MantineReactTable table={table} />
    </div>;
    Pin
    First Name
    Last Name
    Address
    City
    State
    DylanMurray261 Erdman FordEast DaphneKentucky
    RaquelKohler769 Dominic GroveColumbusOhio
    ErvinReinger566 Brakus InletSouth LindaWest Virginia
    BrittanyMcCullough722 Emie StreamLincolnNebraska
    BransonFrami32188 Larkin TurnpikeCharlestonSouth Carolina

    Rows per page

    1-5 of 5

    import '@mantine/core/styles.css';
    import '@mantine/dates/styles.css'; //if using mantine date picker features
    import 'mantine-react-table/styles.css'; //make sure MRT styles were imported in your app root (once)
    import classes from './CSS.module.css'; //import your custom css
    import { useMemo } from 'react';
    import {
      MantineReactTable,
      useMantineReactTable,
      type MRT_ColumnDef,
    } from 'mantine-react-table';
    import { data, type Person } from './makeData';
    import { MantineProvider, useMantineTheme } from '@mantine/core';
    
    const Example = () => {
      const columns = useMemo<MRT_ColumnDef<Person>[]>(
        () => [
          {
            accessorKey: 'firstName',
            header: 'First Name',
          },
          {
            accessorKey: 'lastName',
            header: 'Last Name',
          },
    
          {
            accessorKey: 'address',
            header: 'Address',
          },
          {
            accessorKey: 'city',
            header: 'City',
          },
          {
            accessorKey: 'state',
            header: 'State',
          },
        ],
        [],
      );
    
      const parentTheme = useMantineTheme();
    
      const table = useMantineReactTable({
        columns,
        data,
        enableRowSelection: true,
        enableColumnPinning: true,
        enableRowPinning: true,
        mantineTableProps: { striped: 'even' },
        mantinePaperProps: { className: classes.paper },
        mantineTopToolbarProps: { className: classes.toolbars },
        mantineBottomToolbarProps: { className: classes.toolbars },
      });
    
      return (
        // Changing the Mantine Theme just for this table and not the whole app
        <MantineProvider theme={{ ...parentTheme, primaryColor: 'pink' }}>
          <MantineReactTable table={table} />
        </MantineProvider>
      );
    };
    
    export default Example;

    Mantine Theme

    Mantine React Table respects your Mantine Theme. If you have already set up Mantine and a global Mantine Theme, you should already be set. But if you have not, you should visit the official Mantine Theming Docs to learn how to set that up.

    function App() {
      //Have you setup your Mantine Theme globally in your app root?
      return (
        <MantineProvider theme={createTheme({...})}>
          ...rest of your application
        </MantineProvider>
      );
    }

    Customize Theme Just for your Table

    Thanks to Mantine allowing you to nest multiple Theme Providers, you can change your Mantine Theme just for the <MantineReactTable /> component by wrapping a <MantineProvider theme={{...}}> around just your table. The values in this theme will only effect the <MantineReactTable /> component, and not the rest of your site. It will also inherit values from your global theme, so you do not have to redefine everything again. You can just tweak the values you want to change.

    import { MantineProvider } from '@mantine/core';
    //in one of your normal components
    return (
      <MantineProvider
        theme={{
          primaryColor: 'blue',
          primaryShade: 8,
          colors: {
            blue: [
              //define 9 custom blue shades
            ],
          },
        }}
      >
        <MantineReactTable columns={columns} data={data} />
      </MantineProvider>
    );

    CSS Modules with MRT

    Anytime that you want to style the components inside of Mantine React Table, you can just do it with CSS. It's (usually) just that easy.

    All internal components of any significance have specific mrt- classNames or mantine- classNames that you can target from your CSS or CSS modules. If you are using CSS modules and you are trying to target the pre-defined MRT classNames, you will need to use the :global() selector to target the internal MRT classNames so that the classNames do not get hashed.

    Note: If overriding background colors, try to customize the MRT CSS variables first. There is somewhat complicated logic that goes into calculating the background colors of the table components that solve edge cases with multiple features enabled. It's best to let MRT handle that for you.

    /* Example CSS Module */
    .head-cells {
      font-weight: bold;
      color: indigo;
    }
    
    /* Target an internal MRT class already defined */
    .toolbar {
      /* Use :global() to make sure this className does not get hashed */
      :global(.mrt-toolbar-internal-buttons) {
        gap: 0.5rem;
      }
    }
    import classes from './MyTable.module.css';
    
    const table = useMantineReactTable({
      columns,
      data,
      //connect your CSS module to the MRT component
      mantineTableHeadCellProps: { className: classes['head-cells'] },
      mantineTopToolbarProps: { className: classes.toolbar },
    });

    Target Conditional data- attributes

    MRT makes use of a lot of data- attributes to conditionally style the table components. You can target these data- attributes in your CSS or CSS modules to style the components based on their state.

    /* Target a data- attribute */
    .body-row {
      /* Target a row that is selected */
      &[data-selected='true'] {
        font-weight: bold;
      }
    }

    Here is a list of just some of the data- attributes that MRT uses:

    • data-column-pinned: position of the pinned column if it is pinned

    • data-dragging-column: true if the column is being dragged

    • data-dragging-row: true if the row is being dragged

    • data-first-right-pinned: true if the column is the first right pinned column

    • data-hovered-column-target: true if the column is being hovered

    • data-hovered-row-target: true if the row is being hovered

    • data-index: the index of the row or column

    • data-last-left-pinned: true if the column is the last left pinned column

    • data-last-row: true if the row is the last row

    • data-resizing: true if the column is being resized

    • data-row-pinned: position of the pinned row if it is pinned

    • data-selected: true if the row is selected

    • data-striped: true if the row is striped

    This list is subject to change as MRT evolves, but you can always inspect the table components in your browser to see what data- attributes are being used.

    Pass in Custom Styles

    For quick and "dirty" styling, you can always just use the style prop on any of the mantine*Props options. It depends on your codebase and your team's preferences whether or not you want to use this method. Technically, Inline Styles are less performant than CSS or CSS modules, as discussed in the official Mantine Docs. But for some quick styling, especially conditional styling, it can be very useful.

    const table = useMantineReactTable({
      columns,
      data,
      mantineTableBodyCell: ({ row }) => ({
        style: { //you could also easily conditionally use a className here instead.
          fontWeight: row.getIsSelected() ? 'bold' : 'normal', //conditional styling
        },
      }),
    });