Skip to content

Instantly share code, notes, and snippets.

@TheLazron
Created June 7, 2023 12:45
Show Gist options
  • Save TheLazron/97fe5d9938b8cf8a81a118f8426d3f49 to your computer and use it in GitHub Desktop.
Save TheLazron/97fe5d9938b8cf8a81a118f8426d3f49 to your computer and use it in GitHub Desktop.
Setting up Mantine with Tailwind CSS using emotion cache

Working with Mantine and Tailwind CSS

If you have tried setting up Mantine and Tailwind in your project, you would have faced this issue where mantine and tailwind styles end up conflicting with each other. As a result it introduces several unwanted behaviours like your buttons disappearing and only showing when hovered over.

Cause

The reason this issue arises is mantine's styles getting overridden by tailwinds. Specifically, tailwinds preflight styles. These preflight styles are applied by default by tailwind in order to normalize styles across across different browsers. As a result mantine's style aren't applied correctly

Solution

In order to resolve this issue, one solution would be to disable these preflight styles completely.

Here is how you would implement in your Next.js app:

import "../styles/globals.css";
import { MantineProvider } from "@mantine/core";
import type { AppProps } from "next/app";

function MyApp({ Component, pageProps }: AppProps) {
 return (
   <MantineProvider
     withGlobalStyles
     withNormalizeCSS //Instructing mantine to apply necessary CSS reset or noramlization styles in your application
     theme={{
       colorScheme: "light",
     }}
   >
     <Component {...pageProps} />
   </MantineProvider>
 );
}

export default MyApp;

And modify your tailwind config as follows:

/** @type {import('tailwindcss').Config} */
module.exports = {
 corePlugins: {
   preflight: false, //disabling preflight
 },
 content: ["./src/**/*.{js,ts,jsx,tsx,mdx}"],
 theme: {
   extend: {},
 },
 plugins: [],
};

This will disable preflight styles applied by tailwind to solve your issue.

You can follow this approach in your react projects as well.

But it might not be the solution you require as it has it's own caveats like

  1. Tailwind CSS's preflight styles include a CSS reset or normalization that establishes a consistent baseline across browsers. Disabling preflight will impact the baseline styles implemented by tailwind CSS.
  2. It may result in a divergence from the default styling provided by CSS. If you have a high dependency on default styles provided by CSS, disabling preflight will sure shot hit your design consistency

Using Emotion Cache

Emotion.js is a CSS-in-JS library for styling your react/next components. Both Mantine and Tailwind use emotion under the hood. Emotion cache is a caching system provided by Emotion Library. It caches your styles in memory which is used in subsequent renders for your app. We will use this emotion cache in order to prepend Mantine's style so that they are applied after the tailwind's preflight styles

Lets see how to implement this approach:

Assuming you have a Next.js/React Project setup with tailwind and mantine.

You can follow the steps for each of them here:

Tailwind Next.js: https://tailwindcss.com/docs/guides/nextjs React.js: https://tailwindcss.com/docs/guides/create-react-app

Mantine Next.js: https://mantine.dev/guides/next/ React.js: https://mantine.dev/guides/cra/

To implement emotion cache, we need to get dependencies:

npm install @emotion/react @emotion/cache

OR

yarn add @emotion/react @emotion/cache

Now, In your _app.jsx/tsx import the CacheProvider and createCache respectively. In react you can perform these steps in your App.js

import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';

Then create an emotion cache

function MyApp({ Component, pageProps }: AppProps) {
 const cache = createCache({ key: "mantine", prepend: false });
  return (
    <MantineProvider
      withGlobalStyles
      withNormalizeCSS
      theme={{
        colorScheme: "light",
      }}
    >
      <Component {...pageProps} />
    </MantineProvider>
  );

When creating the cache we pass in two things, key and a boolean option called prepend. The key is used by emotion to identify the cache. And prepend option plays an important role of The prepend option lets us control the order in which the styles are injected in the page. This would help in resolving the issue by fixing the order in which the styles are applied between mantine and tailwind. if you want Mantine styles to take precedence over Tailwind CSS styles, you can set the prepend option to true for Mantine and false for Tailwind CSS.

After that wrap your components with the CacheProvider passing the cache as a prop to the provider, like so:

function MyApp({ Component, pageProps }: AppProps) {
  const cache = createCache({ key: "mantine", prepend: false });
  return (
    <CacheProvider value={cache}>
      <MantineProvider
        withGlobalStyles
        theme={{
          /** Put your mantine theme override here */
          colorScheme: "light",
        }}
      >
        <Component {...pageProps} />
      </MantineProvider>
    </CacheProvider>
  );
}

Instead of using CacheProvider, you can pass the cache object to the MantineProvider as well by with the prop called "emotionCache"

function MyApp({ Component, pageProps }: AppProps) {
  const cache = createCache({ key: "mantine", prepend: false });
  return (
    <MantineProvider
      withGlobalStyles
      emotionCache={cache}
      theme={{
        /** Put your mantine theme override here */
        colorScheme: "light",
      }}
    >
      <Component {...pageProps} />
    </MantineProvider>
  );
}

And you are ready to go as your styles you apps with Mantine and Tailwind. Here is the repository with the mentioned implementation: https://github.com/TheLazron/mantine-tailwind


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment