How to Use WindiCSS in a Vue Project
"3 years ago"Windi CSS is a next-generation utility-first CSS framework.
Installation
Create a Vue project and install the packages.
pnpm create vite vue-3-windi -- --template vue
cd vue-3-windi
pnpm i -D vite-plugin-windicss windicss
pnpm create vite vue-3-windi -- --template vue
cd vue-3-windi
pnpm i -D vite-plugin-windicss windicss
Configuration
- Register the plugin in
vite.config.js
.
import { defineConfig } from "vite"
import Vue from "@vitejs/plugin-vue"
import WindiCSS from "vite-plugin-windicss"
export default defineConfig({
plugins: [Vue(), WindiCSS()]
})
import { defineConfig } from "vite"
import Vue from "@vitejs/plugin-vue"
import WindiCSS from "vite-plugin-windicss"
export default defineConfig({
plugins: [Vue(), WindiCSS()]
})
- Create
windi.config.js
in the root. This is the config file for this site.
import { defineConfig } from "vite-plugin-windicss"
export default defineConfig({
preflight: false,
attributify: true,
transformCSS: "pre",
theme: {
fontFamily: {
sans: ["Fira Sans", "sans-serif"],
mono: ["Fira Code", "sans-serif"]
},
colors: {
blue: "#268bd2",
cyan: "#2aa198",
green: "#859900",
magenta: "#d33682",
orange: "#cb4b16",
red: "#dc322f",
violet: "#6c71c4",
yellow: "#b58900"
}
}
})
import { defineConfig } from "vite-plugin-windicss"
export default defineConfig({
preflight: false,
attributify: true,
transformCSS: "pre",
theme: {
fontFamily: {
sans: ["Fira Sans", "sans-serif"],
mono: ["Fira Code", "sans-serif"]
},
colors: {
blue: "#268bd2",
cyan: "#2aa198",
green: "#859900",
magenta: "#d33682",
orange: "#cb4b16",
red: "#dc322f",
violet: "#6c71c4",
yellow: "#b58900"
}
}
})
preflight
: false
is because I want to use sanitize.css for normalization. If you want to follow:
pnpm i sanitize.css
pnpm i sanitize.css
attributify
: true
is to help organize the classes better.transformCSS
: "pre"
is to get scoped style work.- I change the
fontFamily
to justsans
andmono
with fonts from Google Fonts. - I also change the
colors
to use the Solarized palette.
- Create
main.css
insrc
for the global style, including the fonts. Here is a snippet:
@import url("https://fonts.googleapis.com/css2?family=Fira+Code&family=Fira+Sans:wght@300;400;500&display=swap");
/* Variables */
html:not(.dark) {
--background: #fdf6e3;
--highlights: #eee8d5;
--primary: #657b83;
--secondary: #93a1a1;
--emphasis: #586e75;
}
html.dark {
--background: #002b36;
--highlights: #073642;
--primary: #839496;
--secondary: #586e75;
--emphasis: #93a1a1;
}
/* General */
::selection {
@apply bg-$highlights;
}
@import url("https://fonts.googleapis.com/css2?family=Fira+Code&family=Fira+Sans:wght@300;400;500&display=swap");
/* Variables */
html:not(.dark) {
--background: #fdf6e3;
--highlights: #eee8d5;
--primary: #657b83;
--secondary: #93a1a1;
--emphasis: #586e75;
}
html.dark {
--background: #002b36;
--highlights: #073642;
--primary: #839496;
--secondary: #586e75;
--emphasis: #93a1a1;
}
/* General */
::selection {
@apply bg-$highlights;
}
- Import everything in
src/main.js
. For sanitize.css’ available stylesheets, check the repo.
import { createApp } from "vue"
import App from "./App.vue"
import "sanitize.css"
import "sanitize.css/forms.css"
import "sanitize.css/assets.css"
import "virtual:windi.css"
import "./main.css"
const app = createApp(App)
app.mount("#app")
import { createApp } from "vue"
import App from "./App.vue"
import "sanitize.css"
import "sanitize.css/forms.css"
import "sanitize.css/assets.css"
import "virtual:windi.css"
import "./main.css"
const app = createApp(App)
app.mount("#app")
Usage
Look for the utilities and start putting the classes. You can also look for them in Tailwind’s documentation if you prefer their docs (like me).
Here is an example from this site (/index.html
).
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Yasmin ZY</title>
<link rel="icon" href="/favicon.ico" />
</head>
<body>
<div
id="app"
class="bg-$background font-sans min-h-screen text-$primary leading-relaxed w-full grid grid-rows-[auto,1fr,auto] overflow-hidden"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Yasmin ZY</title>
<link rel="icon" href="/favicon.ico" />
</head>
<body>
<div
id="app"
class="bg-$background font-sans min-h-screen text-$primary leading-relaxed w-full grid grid-rows-[auto,1fr,auto] overflow-hidden"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
$
inbg-
andtext-
tells Windi thatbackground
andprimary
are CSS variables.- Windi has several grid template rows classes, but there is not one for the values
auto 1fr auto
. Fortunately, Windi has a feature called auto-infer so I can just writegrid-rows-[auto,1fr,auto]
.
Another feature I use often is the @apply
directive. Here is another code snippet from this website.
.shiki-container {
@apply border-solid border-$highlights rounded-lg border-4 mb-4 leading-normal py-2 px-4;
}
.shiki-container {
@apply border-solid border-$highlights rounded-lg border-4 mb-4 leading-normal py-2 px-4;
}
Tips
This is for VSCode users:
- Install the WindiCSS IntelliSense extension. Ctrl+P and paste this:
ext install voorjaar.windicss-intellisense
ext install voorjaar.windicss-intellisense
- Turn on the
sortOnSave
setting.
"windicss.sortOnSave": true
"windicss.sortOnSave": true
Just be careful when you have autosave, it can move your class before you finish writing it.