I stumbled upon Anthony Fu's Reimagine Atomic CSS post the other day, and his fine work on unocss.

The basic idea simply scan the HTML/whatever files for all of the classes that are used, and then generate the css based on that. This results in a much faster build time, and also smaller CSS files. And you can use the same classes that you are used to with Tailwind.

1
wc -c site/main.css
1
    3371 site/main.css

That's only 3K!

There's also a couple of other cool features. One that I think is very useful is the web fonts preset, which does some boilerplate lifting that's a bit awkward in Tailwind.

1
2
3
4
5
6
7
8
  import presetWebFonts from '@unocss/preset-web-fonts';

  const fonts = presetWebFonts({
    provider: 'google', // default provider
    fonts: {
      header: "Averia Serif Libre",
    }
  })

Lets get started on how to use it without any fancy frameworks.

live-server

First we can start up a live server with

1
2
  mkdir site
  npx live-server site

Basic page with unocss runtime

site/basic.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  <html>
    <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />

      <title>Base Template</title>

      <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@unocss/reset/tailwind.min.css">
      <script src="https://cdn.jsdelivr.net/npm/@unocss/runtime/attributify.global.js"></script>
    </head>

    <body p-2 md:p-0 h-full>
      <header max-w-screen-lg mx-auto md:flex justify-between py-4>
        <h1 font-bold text-4xl md:inline-block>
          Basic template
        </h1>

        <ul pt-2>
          <li md:inline-block ml-4><a href="/basic.html">basic</a></li>
          <li md:inline-block ml-4><a href="/inline.html">inline</a></li>
        </ul>
      </header>

      <h2 max-w-screen-lg mx-auto font-bold text-2xl py-4>This is a page</h2>

      <p max-w-screen-lg mx-auto>I really really like it</p>

    </body>
  </html>

Generating css using watch

That's nice any easy, but lets setup our own config file, and we can add a couple of other plugins to make things easier.

uno.config.ts:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
  // uno.config.ts
  import { defineConfig, presetAttributify, presetUno, presetTypography } from 'unocss'
  import presetWebFonts from '@unocss/preset-web-fonts';

  const fonts = presetWebFonts({
    provider: 'google', // default provider
    fonts: {
      header: "Averia Serif Libre",
    }
  })

  export default defineConfig({
    presets: [
      presetAttributify({ /* preset options */}),
      presetUno(),
      fonts,
      presetTypography()
      // ...custom presets
    ],
  })

Then create package.json as

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
  {
    "scripts": {
      "dev": "unocss \"site/**/*.html\" -o site/main.css --watch & live-server site",
      "build": "unocss \"site/**/*.html\" -o site/main.css"
    },
    "devDependencies": {
      "live-server": "^1.2.2",
      "unocss": "^0.53.4"
    }
  }

And set it up and run

1
2
3
  curl -o site/reset.css https://cdn.jsdelivr.net/npm/@unocss/reset/tailwind.min.css
  npm i
  npm run dev

Now we can replace

1
2
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@unocss/reset/tailwind.min.css">
  <script src="https://cdn.jsdelivr.net/npm/@unocss/runtime/attributify.global.js"></script>

with:

1
2
  <link rel="stylesheet" href="reset.css" />
  <link rel="stylesheet" href="main.css" />

That will give us:

site/inline.html:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  <html>
    <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />

      <title>Base Template</title>

      <link rel="stylesheet" href="reset.css" />
      <link rel="stylesheet" href="main.css" />
    </head>

    <body p-2 md:p-0 h-full>
      <header max-w-screen-lg mx-auto md:flex justify-between py-4 font-header>
        <h1 text-4xl md:inline-block>
          Basic template
        </h1>

        <ul pt-2>
          <li md:inline-block ml-4><a href="/basic.html">basic</a></li>
          <li md:inline-block ml-4><a href="/inline.html">inline</a></li>
        </ul>
      </header>

      <h2 max-w-screen-lg mx-auto font-bold text-2xl py-4>This is a page</h2>

      <p max-w-screen-lg mx-auto>I really really like it</p>

    </body>
  </html>

References

Previously

Updating date in org file simple and fun

2023-07-10

Next

Using ruby netssh Connect to a server

2023-07-10

labnotes

Previously

Updating date in org file simple and fun

2023-07-10

Next

Using ruby netssh Connect to a server

2023-07-10