If you like Tailwind CSS then you will love UnoCSS, due to its incredible performance, easy customizability, pre-packaged icon sets and its extensive devtools inspector.
To me, the best ideally atomic CSS should be invisible. Once learned, it should be intuitive and analogous to know the others. It’s invisible when it works as you expect and could become frustrating when it doesn’t.
– Anthony Fu, creator of UnoCSS
Just as Anthony wishes for such an invisible framework, he and his team actually builds one.
UnoCSS is an on-demand atomic css engine. It generates the classes on demand when it detects them in your source.
One of the distinctive features that differentiates UnoCSS from other utility frameworks such as Tailwind CSS and Windi CSS is its ability to generate necessary classes without using a parser. For example: Tailwind CSS uses Postcss AST ( Abstract Syntax Tree ) under the hood.
And Tachyons packages the entire css file. Hmm…
Instead UnoCSS has its own engine which uses regex to detect patterns in the source code. Classes are generated only for matched patterns, making development faster and HMR seamless since the code goes through a single pass. Furthermore in production unused classes are stripped away automatically. ( In Tailwind CSS, PurgeCSS can be used for this procedure. )
UnoCSS is more like a framework creator than a framework. At the core of UnoCSS, different presets are used for working with different features, i.e. you can make your own presets by defining your own regex rules. By default, utility classes from Tailwind CSS, Tachyons, Bootstrap and Windi CSS are included in the default preset.
You know the drill. Making a new SvelteKit project is easy as copying the following command, pasting it in the terminal and pressing Enter.
npm create svelte@latest app-name && cd app-name && npm i
<div>
<p>Hey</p>
</div>
The main juice of this article is here. Once you have initialised the project with the above command, you can install UnoCSS and configure it.
npm i -D unocss
Paste this code in vite.config.ts
. It essentially installs UnoCSS into your Vite server.
// vite.config.ts
import type { UserConfig } from 'vite';
import { sveltekit } from '@sveltejs/kit/vite';
import UnoCSS from 'unocss/vite';
const config = {
plugins: [UnoCSS(), sveltekit()]
};
This is the part where we configure UnoCSS to meet our needs.
For this purpose, create a new file named uno.config.ts
in the root directory of your project.
And paste the following code there.
// uno.config.ts
import {
defineConfig,
// presets
presetAttributify,
presetUno,
presetWind,
presetWebFonts,
presetTypography,
presetIcons,
// transformers
transformerAttributifyJsx,
} from 'unocss';
export default defineConfig({
// ...UnoCSS options
presets: [
presetUno(),
presetAttributify(),
presetWind(),
presetWebFonts({
provider: 'bunny',
fonts: {
base: 'Inter:400,500,600,700,800,900',
},
}),
presetTypography(),
presetIcons(
],
transformers: [
transformerAttributifyJsx()
],
theme: {
colors: {
'primary': '#6259E3',
'text': '#050505',
'bg': '#F7F7F7',
},
},
preflights: [
{
getCSS: ({ theme }) => {
const t = theme as any;
return `
body {
--c-primary: ${t.colors.primary};
--c-text: ${t.colors.text};
--c-bg: ${t.colors.bg};
}
html {
scroll-behavior: smooth;
height: 100%;
}
`;
},
}
],
});
It contains the necessary options to get you started such as
<html>
Inter
font from bunny
font provider is loadedFinally, import UnoCSS into your website’s entry point.
<!-- src/routes/+layout.svelte -->
<script lang="ts">
import 'uno.css';
import '@unocss/reset/tailwind.css';
</script>
<!-- ... other stuff -->
And that’s it. Now, you can use UnoCSS in your project.
The default mode of the UnoCSS Vite plugin ( the one we are using ) is called global
. In this mode, all the styles are put into one single css file. This doesn’t make much difference if you are making a small project, but as it scales with many different pages with their own styles… The bundle size will get quite large.
Inorder to mitigate this performance issue, another mode called svelte-scoped
can be used. By using this mode, we tell UnoCSS that we want component and route specific styles to be included in the component/route <style>
itself.
npm i -D @unocss/svelte-scoped
Paste it in your vite.config.ts
// vite.config.ts
import { defineConfig } from 'vite';
import { sveltekit } from '@sveltejs/kit/vite';
import UnoCSS from '@unocss/svelte-scoped/vite';
export default defineConfig({
plugins: [
UnoCSS({
// style reset here
injectReset: '@unocss/reset/tailwind.css'
// ...other Svelte Scoped options
}),
sveltekit()
]
});
Eventhough the component/route-specific styles are placed within them itself, few of the styles must still be placed in the global context. For this purpose, add the %unocss-svelte-scoped.global%
placeholder before %sveltekit.head%
in src/app.html
.
<head> %unocss-svelte-scoped.global% %sveltekit.head% </head>
Finally, the html has to be transformed in a SvelteKit hook. Therefore, place this in your src/hooks.server.ts
.
import type { Handle } from '@sveltejs/kit';
export const handle: Handle = async ({ event, resolve }) => {
const response = await resolve(event, {
transformPageChunk: ({ html }) =>
html.replace('%unocss-svelte-scoped.global%', 'unocss_svelte_scoped_global_styles')
});
return response;
};
If you have been using SvelteKit with Tailwind CSS, you can do something like class:foo={bar}
, where class foo
is applied when bar
evaluates to true.
By default this won’t work with what we have done. So you will have to install an extractor for svelte.
npm i -D @unocss/extractor-svelte
// uno.config.js
import { defineConfig } from 'unocss';
import extractorSvelte from '@unocss/extractor-svelte';
export default defineConfig({
extractors: [extractorSvelte()]
});
Now you can use UnoCSS like this too!
Classes from class:
directive are extracted into the final stylesheet.
<div class:text-2xl={foo} />
Generated style:
.text-2xl {
font-size: 1.5rem; /* 24px */
line-height: 2rem; /* 32px */
}
Refer to the Config reference in the documentation for more.
Setting all this up is not a daunting task. But what if you need a starting point for your new UnoCSS website? Don’t worry we’ve got your back. Focus on your website’s purpose instead of wasting time fixing some random style issue because we have done it for you. Checkout some of these easily customizable and beautiful UnoCSS templates and SvelteKit templates.
Or are you looking for something more custom? Contact us with your requirements.
Until then, 👋!