erikt/ui
A CSS reset and a small UI library in one stylesheet.
erikt/ui is somewhere between a CSS reset and a classless CSS project. It styles native HTML elements directly, so plain semantic markup looks decent with no extra work. A small set of opt-in class names covers the things HTML can't express on its own.
The core idea is borrowed from Pico CSS. A stylesheet should improve the browser's defaults, not replace them. erikt/ui adds more components and a theming layer on top.
Installation
CDN
Link the stylesheet from the CDN:
<link rel="stylesheet" href="https://esm.sh/@erikt/ui" />
You can also download the CSS file and host it yourself:
Download ui.cssnpm
Install the package:
npm install @erikt/ui
With a bundler like Vite, import it by package name from your CSS:
@import "@erikt/ui";
Without a bundler, link the file in node_modules:
<link rel="stylesheet" href="node_modules/@erikt/ui/dist/ui.css" />
Or copy it into your public folder, if node_modules
isn't served.
Theme
Optionally change the overall theme:
:root {
--ui-primary: light-dark(#111, #fefefe);
}
Built in docs
When installing through npm, the package ships with a copy of these docs, built for the installed version. They work offline and always match the version in your project. Start the docs server and open http://localhost:3456:
npx @erikt/ui docs
Overview
erikt/ui styles native HTML elements directly, no class names required.
<fieldset role="group">
<input type="text" placeholder="Input" /> <button>Button</button>
</fieldset>
UI, not layout
erikt/ui styles interactive elements (buttons, inputs, popovers) and
leaves the page layout to you. flex and grid
are already short to write and easy to read. Wrapping them in classes
doesn't make them better.
There are a few exceptions. Some patterns show up so often that a short class saves real typing.
<style>
form {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 1rem;
input[type="email"] {
grid-column: 1 / -1;
}
button {
grid-column: 1 / -1;
justify-self: end;
}
}
</style>
<form>
<input type="text" placeholder="First name" />
<input type="text" placeholder="Last name" />
<input type="email" placeholder="Email" />
<button type="submit">Submit</button>
</form>
With Tailwind
erikt/ui and Tailwind get along. erikt/ui handles component styles,
Tailwind handles layout and one-off utilities. Nothing collides,
because erikt/ui wraps everything in @layer ui {} and any
Tailwind utility beats it without the ! prefix.
Declare the layer order before importing either library. That puts Tailwind's reset below erikt/ui and its utilities above:
/* main.css */
@layer theme, base, ui-reset, ui, components, utilities;
@import "https://esm.sh/@erikt/ui";
@import "tailwindcss";
Philosophy
erikt/ui is also where I try out new CSS. Anchor positioning,
@starting-style, the Popover API and :has()
all landed here first. The question I keep poking at is how far CSS
gets before JavaScript is needed.
So it leans on very new browser features and isn't meant for projects that need broad support. Treat it as an experiment rather than a production toolkit.