Framework-agnostic CSS component implementations.
29 components and 1 utility, written as plain CSS, reading their values from @uncinq/component-tokens and adding none of their own.
@uncinq/design-tokens primitive + semantic values
@uncinq/component-tokens component-scoped values
@uncinq/css-base reset, native elements, layouts
@uncinq/css-components ← this package
All four packages are required. @uncinq/css-base is a genuine prerequisite but is not declared in peerDependencies, so install it explicitly.
npm install @uncinq/design-tokens @uncinq/component-tokens @uncinq/css-base @uncinq/css-componentsDeclare the cascade layer order once at the top of your entry stylesheet, before any import:
@layer reset, tokens, libs, base, vendors, layouts, components, pages, utilities;
@import '@uncinq/design-tokens'; /* @layer tokens */
@import '@uncinq/css-base'; /* @layer reset, base, layouts */
@import '@uncinq/component-tokens'; /* @layer tokens */
@import '@uncinq/css-components'; /* @layer components, utilities */Per component:
@import '@uncinq/css-components/css/components/button.css';
@import '@uncinq/css-components/css/utilities/scrollsnap.css';@uncinq/design-tokens and @uncinq/component-tokens can be linked straight from a CDN, because they emit nothing but custom properties. This package cannot, and neither can @uncinq/css-base.
Both ship @media (--sm) queries that rely on the @custom-media rules declared in css-base/css/mediaqueries.css, and no browser implements @custom-media. Loaded without postcss-custom-media, 13 responsive blocks in this package are dropped: .panel-inline-*, .panel-trigger-* and every .scrollsnap-* variant.
The failure is silent. No error is raised, the page simply stays at its mobile values on every screen. A build step is required.
| Group | Components |
|---|---|
| Buttons | .btn with colour, size and style variants, plus btn-close, btn-menu, btn-search, btn-filter, btn-share, btn-toc, btn-toggle-video |
| Overlays | modal, drawer, dropdown, and the shared panel skeleton |
| Content | alert, badge, banner, card, items, list, media, surtitle |
| Navigation | nav, nav-title, nav-accessibility, breadcrumb, pagination |
| Embeds | embed, video, map |
| Forms | form, form-check and the layout helpers |
| Utilities | scrollsnap |
components/panel.css must come after modal.css and drawer.css: its .panel-inline-* variants beat them on source order, because most of the file is :where()-wrapped and carries no specificity. Alphabetical order already gives that in css/index.css.
utilities/scrollsnap.css comes after everything, in @layer utilities, because it has to win over the grid a component declares for itself.
If you import file by file rather than using the barrel, preserve both positions.
- No JavaScript.
modal,draweranddropdownexpect a script; each documents the classes and attributes it must toggle. - No
.item. This package ships.card, a complete implementation..itemlives in the Hugolify design system theme. - No
.iconglyphs. Buttons andpaginationmask their own from icon tokens, but an.iconelement you place inside analertor a video toggle is the theme's to render.
Full documentation: socle.uncinq.dev/docs/css-components/
It is also versioned with the code in docs/, one page per component, and ships inside the npm package, so it is readable offline and from node_modules:
- Cascade layers — the two layers, and the
:where()convention - Buttons —
.btnand the seven specialised buttons - Overlays — the panel skeleton,
.modal,.drawer,.dropdown - Content —
.alert,.badge,.banner,.card,.items,.list,.media,.surtitle - Navigation —
.nav,.nav-title, skip links, breadcrumb, pagination - Embeds —
.embed,.video,.map - Forms —
.form,.form-check - Utilities —
.scrollsnapand the bleed contract
@uncinq/component-tokens— the values these components read@uncinq/css-base— the foundation underneath- MDN: CSS cascade layers
MIT © Un Cinq