AceCSS component guidelines
One stylesheet, ace.css, with every AceCSS component: buttons, fields, dropdowns, date pickers and badges. It needs no framework or build step, so you can drop it into any project.
Originally designed for PRC.rent by Kosowwwa LLC. Credits
Get AceCSS v1.3.0
Link it from the CDN, or download the files and host them yourself. Both give you the same thing: one stylesheet, plus optional scripts for the date picker, the dropdown, the hero button and the navbars: one file each, or all of them in ace-all.js.
npm
npm i @acecss/core // Vite / Webpack / Next.js / Nuxt — load after any reset or Tailwind import '@acecss/core' // the stylesheet import '@acecss/core/datepicker' // optional import '@acecss/core/select' // optional import '@acecss/core/hero' // optional: hero button effects import '@acecss/core/navbar' // optional: navbar import '@acecss/core/navbar-liquid' // optional: liquid-glass navbar // …or every script at once instead of the lines above import '@acecss/core/all' /* Nuxt: css: ['@acecss/core'] in nuxt.config.ts */
Also on jsDelivr: https://cdn.jsdelivr.net/npm/@acecss/core@1/dist/ace.min.css
CDN, pinned to v1.3.0 (recommended)
The integrity hash makes the browser refuse the file if it ever changes, so this is safe for production.
<link rel="stylesheet" href="https://acecss.dev/v1.3.0/ace.min.css"
integrity="sha384-zHAwOqjifsc0D+iUvzD1a4W0R2g0BOK9AqQJZGakUEp/Tm5IUcP07R9xkY0q/stj" crossorigin="anonymous">
<!-- Optional: date picker -->
<script src="https://acecss.dev/v1.3.0/ace-datepicker.min.js" defer
integrity="sha384-al9SmJzBEkQvLjq3F7lSGkJUmv2DPLd+1HMRRktG/ms/mFfQTFLOG+WQIGCNufon" crossorigin="anonymous"></script>
<!-- Optional: dropdown for <select data-ace-select> -->
<script src="https://acecss.dev/v1.3.0/ace-select.min.js" defer
integrity="sha384-9tcWJ02N3Y9Q7gIqgr3CKRk+yH/lWuBSTDmUS6aAQLjUsSJkDcJrkErHCtfYOTkX" crossorigin="anonymous"></script>
<!-- Optional: hero button effects -->
<script src="https://acecss.dev/v1.3.0/ace-hero.min.js" defer
integrity="sha384-9GbyxTfs2krubP46OnEkVVYjds58yGjr3EF3P1CAujQqzY/qB9ccrF7YIQIaWif5" crossorigin="anonymous"></script>
<!-- Optional: navbar -->
<script src="https://acecss.dev/v1.3.0/ace-navbar.min.js" defer
integrity="sha384-mGzpk60jYDZT4XtoAEnKGnMuFh7nUewb/rMiOB82IYa3Lp2RBsDfTiAxl2uyF93S" crossorigin="anonymous"></script>
<!-- Optional: liquid-glass navbar -->
<script src="https://acecss.dev/v1.3.0/ace-navbar-liquid.min.js" defer
integrity="sha384-MPTj6aPtC7rgAi9qb4oqsdojHuP2ybdc1Rcz8S536m6iEbebzPF7bAAZkhr9EZx7" crossorigin="anonymous"></script>Want every component? Replace the scripts above with one file that has them all (15.3 KB gzipped):
<link rel="stylesheet" href="https://acecss.dev/v1.3.0/ace.min.css"
integrity="sha384-zHAwOqjifsc0D+iUvzD1a4W0R2g0BOK9AqQJZGakUEp/Tm5IUcP07R9xkY0q/stj" crossorigin="anonymous">
<script src="https://acecss.dev/v1.3.0/ace-all.min.js" defer
integrity="sha384-eVCvgsqmyfqUloRRGC3Z631/xDmItdReUNn1G6vY/zY4PFGp+pTrNGImikhyeMs5" crossorigin="anonymous"></script>CDN, always the latest 1.x
Picks up fixes automatically, with no breaking changes within 1.x.
Heads up: this URL serves different files after every release, so it can't carry an integrity hash, and what your visitors get can change without a deploy on your side. Use it for prototypes and demos; in production, pin a version (above).
<link rel="stylesheet" href="https://acecss.dev/v1/ace.min.css"> <script src="https://acecss.dev/v1/ace-datepicker.min.js" defer></script> <script src="https://acecss.dev/v1/ace-select.min.js" defer></script> <script src="https://acecss.dev/v1/ace-hero.min.js" defer></script> <script src="https://acecss.dev/v1/ace-navbar.min.js" defer></script> <script src="https://acecss.dev/v1/ace-navbar-liquid.min.js" defer></script> <!-- or every script in one file --> <script src="https://acecss.dev/v1/ace-all.min.js" defer></script>
Files
| File | What it's for | Minified | Gzipped |
|---|---|---|---|
ace.min.css · source | Every component. Required. | 56.0 KB | 9.4 KB |
ace-datepicker.min.js · source | Date picker and pick-up → return range. Optional. | 14.6 KB | 4.7 KB |
ace-select.min.js · source | Dropdown for <select>. Optional. | 7.0 KB | 2.7 KB |
ace-hero.min.js · source | Hero button effects. Optional. | 3.8 KB | 1.7 KB |
ace-navbar.min.js · source | Navbar highlight, mobile menu and glass. Optional. | 8.5 KB | 3.5 KB |
ace-navbar-liquid.min.js · source | Liquid-glass navbar (WebGL; loads modern-screenshot on demand). Optional. | 12.8 KB | 5.1 KB |
ace-all.min.js · source | All of the scripts above in one file. Use it instead of them, not with them. | 46.6 KB | 15.3 KB |
Self-hosted / bundlers
<!-- Plain HTML: unzip into your site --> <link rel="stylesheet" href="/css/ace.min.css"> <script src="/js/ace-datepicker.min.js" defer></script> /* Nuxt — nuxt.config.ts */ css: ['~/assets/css/main.css', '~/assets/css/ace.css'] /* Vite / React / Vue — main.ts */ import './styles/ace.css' /* Load AceCSS AFTER any reset or framework CSS (Tailwind, Bootstrap). Dark mode: put .dark (or data-theme="dark") on <html>. Follow the OS instead: <html class="ace-auto-dark"> */
Using it with Tailwind
- No name clashes. Every AceCSS class starts with
ace-and every variable with--ace-, so nothing collides with Tailwind's utilities. - Load order. Import AceCSS after Tailwind (and after
@tailwindcss/forms), so Preflight's resets don't flatten the components. - Utilities on AceCSS elements. Layout utilities just work (
class="ace-btn ace-btn--primary w-full mt-4"). For a utility to override a component style (sayrounded-noneon a button), put AceCSS in Tailwind's components layer: utilities always win over it there, whatever the order. - Re-colouring. Use the tokens through arbitrary properties:
class="ace-btn ace-btn--primary [--ace-tone:#7c3aed]".
/* app.css — Tailwind v4 */ @import "tailwindcss"; @import "@acecss/core" layer(components); /* utilities override AceCSS */ /* or, if AceCSS should win over utilities: */ @import "tailwindcss"; @import "@acecss/core";
Browser support
AceCSS needs a browser from 2023 or later: it relies on color-mix() for every hover, ring and tint.
| Browser | Supported from | Notes |
|---|---|---|
| Chrome, Edge, Opera, Samsung Internet | 111 | Everything, including the navbar's edge-bending lens. |
| Firefox | 113 | From 121, a choice card also highlights through its checked radio and disabled checkboxes dim their label (both use :has()); before that, use is-selected / aria-pressed. No edge-bending on ace-navbar (Chromium-only); it stays frosted glass. |
| Safari (macOS, iOS) | 16.2 | No edge-bending on ace-navbar; it stays frosted glass. ace-navbar-liquid works everywhere with WebGL. |
Every page of this site, the interactive components (date picker, dropdown, navbars, hero button) and an axe accessibility scan (WCAG 2.1 A and AA, light and dark) are tested in Chromium, Firefox and WebKit on every push.
Colours & tokens
Every colour is a CSS variable. To re-brand a project, override the tokens. You never need to edit the component rules.
/* Your project's CSS, loaded after ace.css */
:root {
--ace-primary: #05df72; /* e.g. the green landing-site brand */
--ace-radius: 12px; /* rounder corners */
--ace-font: 'Inter', system-ui, sans-serif;
}Pattern: form layout
Leave 16px between fields and 24px before the actions row. Put the primary action last. On mobile, make the main button full width.
<form style="display:flex;flex-direction:column;gap:16px;max-width:420px">
<div class="ace-field">
<label class="ace-label" for="email">Email</label>
<input id="email" type="email" class="ace-input" autocomplete="email">
</div>
<div class="ace-field">
<label class="ace-label" for="pw">Password</label>
<input id="pw" type="password" class="ace-input" autocomplete="current-password">
</div>
<label class="ace-check"><input type="checkbox"> Keep me signed in</label>
<button type="submit" class="ace-btn ace-btn--primary ace-btn--block">Sign in</button>
</form>Pattern: toolbar / filter bar
Every control in a toolbar is 36px tall. Use ace-btn--toolbar on buttons and ace-segmented--sm on segmented controls. Inputs and selects are already 36px.
<div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap"> <label class="ace-input-group" style="width:240px"><svg …/><input type="search" aria-label="Search"></label> <select class="ace-select" aria-label="Category" style="width:150px">…</select> <div class="ace-segmented ace-segmented--sm" role="group">…</div> <button class="ace-btn ace-btn--secondary ace-btn--toolbar">Export</button> <button class="ace-btn ace-btn--primary ace-btn--toolbar">Add car</button> </div>
Pattern: confirm dialog footer
Right-align the footer and put Cancel before the action. A normal confirmation uses --primary. Only an action that destroys something uses --danger, and its label should say what will happen.
<footer style="display:flex;gap:8px;justify-content:flex-end"> <button class="ace-btn ace-btn--secondary">Keep car</button> <button class="ace-btn ace-btn--danger">Delete car</button> </footer>
Class reference
| Component | Base class | Modifiers |
|---|---|---|
| Button | ace-btn | --primary --secondary --danger · colours --blue --green --purple --pink --black · any colour: style="--ace-tone:#…" (+ --ace-tone-fg) on primary · --attention (with primary) · --destructive (with secondary) · --sm --lg --icon --toolbar --block · aria-busy="true" · disabled |
| Hero button | ace-hero-btn | effects need ace-hero.js · data-no-icon · colour via --ace-tone · once per page |
| Navbar | ace-navbar | parts -bar -row -brand -logo -links -actions -link -secondary -cta -toggle · needs ace-navbar.js for the highlight, menu and canvas glass · data-no-glass · aria-current="page" |
| Liquid navbar | ace-navbar-liquid + data-glass-exclude | parts -bar -row -brand -logo -links -actions -signin -icon -cta -toggle · needs ace-navbar-liquid.js (WebGL + modern-screenshot) · data-no-glass · AceNavbarLiquid.refresh() |
| Segmented | ace-segmented | --xs --sm --block · children are ace-btn with aria-pressed |
| Field wrapper | ace-field | contains ace-label, control, ace-hint / ace-error; ace-required for the asterisk |
| Input | ace-input | --lg · is-invalid / aria-invalid="true" · disabled |
| Select | ace-select | --lg · is-invalid / aria-invalid="true" · data-ace-select (AceCSS dropdown, needs ace-select.js) · data-search · data-sublabel on options · <optgroup> |
| Textarea | ace-textarea | is-invalid / aria-invalid="true" |
| Input group | ace-input-group | children: <svg>, <input>, ace-addon · is-invalid is-disabled |
| Date picker | ace-datepicker + data-ace-datepicker | needs ace-datepicker.js · data-name data-id data-value data-min data-max data-locale data-invalid data-disabled |
| Date range | ace-datepicker + data-ace-daterange | data-start-name data-end-name data-start-time-name data-end-time-name data-time="false" · fires ace:change |
| Checkbox / radio | ace-check | label wrapping a native input |
| Switch | ace-switch | label wrapping <input type="checkbox" role="switch"> |
| Badge | ace-badge | --primary --success --warning --danger --info · --md |
| Choice card | ace-btn ace-btn--secondary ace-choice-card | is-selected / aria-pressed="true" / checked inner radio |
| Hover surface | ace-hover-surface | flat until hovered (nav links, list rows) |
Credits
AceCSS started as the component set of PRC.rent, the car rental platform built by Kosowwwa LLC. The buttons, inputs, dropdowns, date pickers and badges were designed for PRC.rent and are used there every day. AceCSS packages the same design so other projects can use it too.
Created by Kosowwwa LLC. Released under the MIT License: free to use in personal and commercial projects.