-
-
Notifications
You must be signed in to change notification settings - Fork 32.6k
[docs] Add Tailwind CSS v4 integration guide #45906
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
fb1e11f
a6ffe17
09e4f63
bf65db5
3de9351
876c85c
03d4475
41d2dbb
b5690a1
91925a1
c4e8d3e
b54e6c1
fd0e4f1
a24c96e
0da9a81
b2644c2
60f0aab
cfade20
3fac47d
aa07fe7
8a13a4f
6784999
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import * as React from 'react'; | ||
import FormControl from '@mui/material/FormControl'; | ||
import InputLabel from '@mui/material/InputLabel'; | ||
import Input from '@mui/material/Input'; | ||
import FormHelperText from '@mui/material/FormHelperText'; | ||
|
||
export default function TextFieldTailwind() { | ||
return ( | ||
<FormControl> | ||
<InputLabel | ||
shrink | ||
htmlFor="component-outlined" | ||
className="relative top-0 left-0 transform-none text-sm font-medium text-neutral-800 dark:text-neutral-200 pointer-events-auto mb-0.5" | ||
> | ||
Name | ||
</InputLabel> | ||
<Input | ||
id="component-outlined" | ||
placeholder="Type your name" | ||
slotProps={{ | ||
root: { | ||
className: | ||
'mt-0 -ml-0.5 px-2 h-10 border-1 border-neutral-300 dark:border-neutral-700 rounded-md has-[input:focus-visible]:outline-2 has-[input:focus-visible]:outline-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm before:hidden after:hidden', | ||
}, | ||
input: { | ||
className: | ||
'placeholder:opacity-100 placeholder:text-neutral-400 dark:placeholder:text-neutral-500', | ||
}, | ||
}} | ||
/> | ||
<FormHelperText className="ml-0">Some important helper text</FormHelperText> | ||
</FormControl> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import * as React from 'react'; | ||
import FormControl from '@mui/material/FormControl'; | ||
import InputLabel from '@mui/material/InputLabel'; | ||
import Input from '@mui/material/Input'; | ||
import FormHelperText from '@mui/material/FormHelperText'; | ||
|
||
export default function TextFieldTailwind() { | ||
return ( | ||
<FormControl> | ||
<InputLabel | ||
shrink | ||
htmlFor="component-outlined" | ||
className="relative top-0 left-0 transform-none text-sm font-medium text-neutral-800 dark:text-neutral-200 pointer-events-auto mb-0.5" | ||
> | ||
Name | ||
</InputLabel> | ||
<Input | ||
id="component-outlined" | ||
placeholder="Type your name" | ||
slotProps={{ | ||
root: { | ||
className: | ||
'mt-0 -ml-0.5 px-2 h-10 border-1 border-neutral-300 dark:border-neutral-700 rounded-md has-[input:focus-visible]:outline-2 has-[input:focus-visible]:outline-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm before:hidden after:hidden', | ||
}, | ||
input: { | ||
className: | ||
'placeholder:opacity-100 placeholder:text-neutral-400 dark:placeholder:text-neutral-500', | ||
}, | ||
}} | ||
/> | ||
<FormHelperText className="ml-0">Some important helper text</FormHelperText> | ||
</FormControl> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
# Tailwind CSS v4 integration | ||
|
||
<p class="description">Learn how to use Material UI with Tailwind CSS v4.</p> | ||
|
||
## Overview | ||
|
||
There are two steps to integrate Tailwind CSS v4 with Material UI: | ||
|
||
1. Configure the styles to generate with the `@layer` directive. | ||
2. Set up the layer order so that `mui` comes before the `utilities` layer, allowing Tailwind CSS classes to override Material UI styles. | ||
|
||
The instructions below detail how to achieve this using common React frameworks. | ||
|
||
### Next.js App Router | ||
|
||
To integrate Tailwind CSS v4 with Material UI in a Next.js App Router project, start by configuring Material UI with Next.js in the [App Router integration guide](/material-ui/integrations/nextjs/#app-router). | ||
Then follow these steps: | ||
|
||
1. Enable the [CSS layer feature](/material-ui/integrations/nextjs/#using-other-styling-solutions) in the root layout: | ||
|
||
```tsx title="src/app/layout.tsx" | ||
import { AppRouterCacheProvider } from '@mui/material-nextjs/v15-appRouter'; | ||
|
||
export default function RootLayout() { | ||
return ( | ||
<html lang="en" suppressHydrationWarning> | ||
<body> | ||
<AppRouterCacheProvider options={{ enableCssLayer: true }}> | ||
{/* Your app */} | ||
</AppRouterCacheProvider> | ||
</body> | ||
</html> | ||
); | ||
} | ||
``` | ||
|
||
2. Configure the layer order in the Tailwind CSS file: | ||
|
||
```css title="src/app/globals.css" | ||
@layer theme, base, mui, components, utilities; | ||
@import 'tailwindcss'; | ||
``` | ||
|
||
### Next.js Pages Router | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I couldn't make this work, I tried to follow the steps from the Next.js guide and this one, but Tailwind classes were not overriding the MUI styles. It would be great if we can have an example to link (together with the guides), as combining the two guides it's kind of hard to follow. Also, I've created #45922 with bunch of issues I found on the Next.js guide. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is expected because we haven't release #45596. Updated the PR description to make it clear what build to use. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, ok, I will update my testing app to use the build from that PR. |
||
|
||
To integrate Tailwind CSS v4 with Material UI in a Next.js Pages Router project, start by configuring Material UI with Next.js in the [Pages Router integration guide](/material-ui/integrations/nextjs/#pages-router). | ||
Then follow these steps: | ||
|
||
1. Enable the [CSS layer feature](/material-ui/integrations/nextjs/#configuration-2) in a custom `_document`: | ||
|
||
```tsx title="pages/_document.tsx" | ||
import { | ||
createCache, | ||
documentGetInitialProps, | ||
} from '@mui/material-nextjs/v15-pagesRouter'; | ||
|
||
// ... | ||
|
||
MyDocument.getInitialProps = async (ctx: DocumentContext) => { | ||
const finalProps = await documentGetInitialProps(ctx, { | ||
emotionCache: createCache({ enableCssLayer: true }), | ||
}); | ||
return finalProps; | ||
}; | ||
``` | ||
|
||
2. Configure the layer order with the `GlobalStyles` component—it must be the first child of the `AppCacheProvider`: | ||
|
||
```tsx title="pages/_app.tsx" | ||
import { AppCacheProvider } from '@mui/material-nextjs/v15-pagesRouter'; | ||
import GlobalStyles from '@mui/material/GlobalStyles'; | ||
|
||
export default function MyApp(props: AppProps) { | ||
const { Component, pageProps } = props; | ||
return ( | ||
<AppCacheProvider {...props}> | ||
<GlobalStyles styles="@layer theme, base, mui, components, utilities;" /> | ||
{/* Your app */} | ||
</AppCacheProvider> | ||
); | ||
} | ||
``` | ||
|
||
### Vite.js or any other SPA | ||
|
||
To integrate Tailwind CSS v4 with Material UI in a Vite-based app, make the following changes in `src/main.tsx`: | ||
|
||
1. Pass the `enableCssLayer` prop to the `StyledEngineProvider` component. | ||
2. Configure the layer order with the `GlobalStyles` component. | ||
|
||
```tsx title="main.tsx" | ||
import { StyledEngineProvider } from '@mui/material/styles'; | ||
import GlobalStyles from '@mui/material/GlobalStyles'; | ||
|
||
ReactDOM.createRoot(document.getElementById('root')!).render( | ||
<React.StrictMode> | ||
<StyledEngineProvider enableCssLayer> | ||
<GlobalStyles styles="@layer theme, base, mui, components, utilities;" /> | ||
{/* Your app */} | ||
</StyledEngineProvider> | ||
</React.StrictMode>, | ||
); | ||
``` | ||
|
||
## Tailwind CSS IntelliSense for VS Code | ||
|
||
The official [Tailwind CSS IntelliSense](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) extension requires extra configuration to work properly when customizing the interior slots of Material UI components. | ||
After installing the extension, add the following line to your [VS Code `settings.json`](https://code.visualstudio.com/docs/editor/settings#_settings-json-file) file: | ||
|
||
```json | ||
{ | ||
// ...config | ||
"tailwindCSS.experimental.classRegex": [["className\\s*:\\s*['\"]([^'\"]*)['\"]"]] | ||
} | ||
``` | ||
|
||
Now you should see the autocomplete and syntax highlighting features when using the `slotProps` prop, as shown in the screenshot below: | ||
|
||
 | ||
|
||
## Usage | ||
|
||
- Use the `className` prop to apply Tailwind CSS classes to the root element of the component. | ||
- Use `slotProps.{slotName}.className` to apply Tailwind CSS classes to a component's [interior slots](/material-ui/customization/overriding-component-structure/#interior-slots). | ||
mapache-salvaje marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
{{"demo": "TextFieldTailwind.js"}} | ||
|
||
## Troubleshooting | ||
|
||
If the Tailwind CSS classes are not overriding Material UI components, make sure that: | ||
|
||
- You are using Tailwind CSS >= v4. | ||
- You have configured the layer order correctly by checking the [DevTools styles tab](https://developer.chrome.com/docs/devtools/css/reference#cascade-layers). The `mui` layer should come before the `utilities` layer. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import * as React from 'react'; | ||
import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; | ||
import * as pageProps from 'docs/data/material/integrations/tailwindcss/tailwindcss-v4.md?muiMarkdown'; | ||
|
||
export default function Page() { | ||
return <MarkdownDocs {...pageProps} />; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,7 @@ export const replaceMaterialLinks = (url: string) => { | |
return url; | ||
} | ||
return url.replace( | ||
/(guides|customization|getting-started|discover-more|experimental-api|migration)/, | ||
/(guides|customization|getting-started|discover-more|experimental-api|migration|integrations)/, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
'material-ui/$1', | ||
); | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doc as a whole is very outdated and needs some serious reworking, possibly to split it up into multiple docs. As a start, what do you think about moving the Tailwind v3 info into the new v4 doc and making that the single source of truth for all Tailwind integrations? (That could also be a separate PR so we don't block this one.)
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Totally agree, that's what I think.
However, I lean toward splitting v4 from v3 because the setup is quite different.
Also, I want to leave v3 integration as a separate page because the integration is such painful (we can't do anything about it because of the technical limitation), so in v3 page there should be an info to recommend Tailwind CSS v4 instead.