--- navigation.icon: uil:palette --- # Styling Nuxt is highly flexible when it comes to styling. Write your own styles, or reference local and external stylesheets. You can use CSS preprocessors, CSS frameworks, UI libraries and Nuxt modules to style your application. ## Local Stylesheets If you're writing local stylesheets, the natural place to put them is the `assets/` directory. ### Importing Within Components You can import stylesheets in your pages, layouts and components directly. You can use a javascript import, or a css [`@import` statement](https://developer.mozilla.org/en-US/docs/Web/CSS/@import). ```vue [pages/index.vue] ``` ::alert{type=info} The stylesheets will be inlined in the HTML rendered by Nuxt. :: ### The CSS Property You can also use the `css` property in the Nuxt configuration. The natural place for your stylesheets is the `assets/` directory. You can then reference its path and Nuxt will include it to all the pages of your application. ```ts [nuxt.config.ts] export default defineNuxtConfig({ css: ['~/assets/css/main.css'] }) ``` ::alert{type=info} The stylesheets will be inlined in the HTML rendered by Nuxt, injected globally and present in all pages. :: ### Working With Fonts Place your local fonts files in your `~/public/` directory, for example in `~/public/fonts`. You can then reference them in your stylesheets using `url()`. ```css [assets/css/main.css] @font-face { font-family: 'FarAwayGalaxy'; src: url('/fonts/FarAwayGalaxy.woff') format('woff'); font-weight: normal; font-style: normal; font-display: swap; } ``` Then reference your fonts by name in your stylesheets, pages or components: ```vue ``` ### Stylesheets Distributed Through NPM You can also reference stylesheets that are distributed through npm. Let's use the popular `animate.css` library as an example. ```bash npm install animate.css ``` Then you can reference it directly in your pages, layouts and components: ```vue [app.vue] ``` The package can also be referenced as a string in the css property of your Nuxt configuration. ```ts [nuxt.config.ts] export default defineNuxtConfig({ css: ['animate.css'] }) ``` ## External Stylesheets You can include external stylesheets in your application by adding a link element in the head section of your nuxt.config file. You can achieve this result using different methods. Note that local stylesheets can also be included like this. You can manipulate the head with the `app.head` property of your Nuxt configuration: ```ts [nuxt.config.ts] export default defineNuxtConfig({ app: { head: { link: [{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css' }] } }}) ``` ### Dynamically Adding Stylesheets You can use the useHead composable to dynamically set a value in your head in your code. ::ReadMore{link="/docs/api/composables/use-head"} :: ```ts useHead({ link: [{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css' }] }) ``` Nuxt uses `unhead` under the hood, and you can refer to its full documentation [here](https://unhead.harlanzw.com/). ### Modifying The Rendered Head With A Nitro Plugin If you need more advanced control, you can intercept the rendered html with a hook and modify the head programmatically. Create a plugin in `~/server/plugins/my-plugin.ts` like this: ```ts [server/plugins/my-plugin.ts] export default defineNitroPlugin((nitro) => { nitro.hooks.hook('render:html', (html) => { html.head.push('') }) }) ``` External stylesheets are render-blocking resources: they must be loaded and processed before the browser renders the page. Web pages that contain unnecessarily large styles take longer to render. You can read more about it on [web.dev](https://web.dev/defer-non-critical-css/). ## Using Preprocessors To use a preprocessor like SCSS, Sass, Less or Stylus, install it first. ::code-group ```bash [Sass & SCSS] npm install sass ``` ```bash [Less] npm install less ``` ```bash [Stylus] npm install stylus ``` :: The natural place to write your stylesheets is the `assets` directory. You can then import your source files in your `app.vue` (or layouts files) using your preprocessor's syntax. ```vue [pages/app.vue] ``` Alternatively, you can use the `css` property of your Nuxt configuration. ```ts [nuxt.config.ts] export default defineNuxtConfig({ css: ['~/assets/scss/main.scss'] }) ``` ::alert{type=info} In both cases, the compiled stylesheets will be inlined in the HTML rendered by Nuxt. :: If you need to inject code in pre-processed files, like a [sass partial](https://sass-lang.com/documentation/at-rules/use#partials) with color variables, you can do so with the vite [preprocessors options](https://vitejs.dev/config/shared-options.html#css-preprocessoroptions). Create some partials in your `assets` directory: ::code-group ```scss [assets/_colors.scss] $primary: #49240F; $secondary: #E4A79D; ``` ```sass [assets/_colors.sass] $primary: #49240F $secondary: #E4A79D ``` :: Then in your `nuxt.config` : ::code-group ```ts [SCSS] export default defineNuxtConfig({ vite: { css: { preprocessorOptions: { scss: { additionalData: '@use "@/assets/_colors.scss" as *;' } } } } }) ``` ```ts [SASS] export default defineNuxtConfig({ vite: { css: { preprocessorOptions: { sass: { additionalData: '@use "@/assets/_colors.sass" as *\n' } } } } }) ``` :: Nuxt uses Vite by default. If you wish to use webpack instead, refer to each preprocessor loader [documentation](https://webpack.js.org/loaders/sass-loader/). ## Single File Components (SFC) Styling One of the best thing about Vue and SFC is how great it is at naturally dealing with styling. You can directly write CSS or preprocessor code in the style block of your components file, therefore you will have fantastic developer experience without having to use something like CSS-in-JS. However if you wish to use CSS-in-JS, you can find 3rd party libraries and modules that support it, such as [pinceau](https://pinceau.dev/). You can refer to the [Vue docs](https://vuejs.org/api/sfc-css-features.html) for a comprehensive reference about styling components in SFC. ### Class And Style Bindings You can leverage Vue SFC features to style your components with class and style attributes. ::code-group ```vue [Ref and Reactive]
``` ```vue [Computed] ``` ```vue [Array] ``` ```vue [Style] ``` :: Refer to the [Vue docs](https://vuejs.org/guide/essentials/class-and-style.html) for more information. ### Dynamic Styles With `v-bind` You can reference JavaScript variable and expression within your style blocks with the v-bind function. The binding will be dynamic, meaning that if the variable value changes, the style will be updated. ```vueThis should be red
``` ### Preprocessors Support SFC style blocks support preprocessors syntax. Vite come with built-in support for .scss, .sass, .less, .styl and .stylus files without configuration. You just need to install them first, and they will be available directly in SFC with the lang attribute. ::code-group ```vue [SCSS] ``` ```vue [Sass] ``` ```vue [LESS] ``` ```vue [Stylus] ``` :: You can refer to the [Vite CSS docs](https://vitejs.dev/guide/features.html#css) and the [@vitejs/plugin-vue docs](https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue). For webpack users, refer to the [vue loader docs](https://vue-loader.vuejs.org/). ## Using PostCSS Nuxt comes with postcss built-in. You can configure it in your `nuxt.config` file. ```ts [nuxt.config.ts] export default defineNuxtConfig({ postcss: { plugins: { 'postcss-nested': {} "postcss-custom-media": {} } } }) ``` For proper syntax highlighting in SFC, you can use the postcss lang attribute. ```vue ``` By default, Nuxt comes with the following plugins already pre-configured: - [postcss-import](https://github.com/postcss/postcss-import): Improves the `@import` rule - [postcss-url](https://github.com/postcss/postcss-url): Transforms `url()` statements - [autoprefixer](https://github.com/postcss/autoprefixer): Automatically adds vendor prefixes - [cssnano](https://cssnano.co/): Minification and purge ## Leveraging Layouts For Multiple Styles If you need to style different parts of your application completely differently, you can use layouts. Use different styles for different layouts. ```vue