Component Reference
Every component has a detailed markup comment directly in its .css file under components/ - this is just the quick reference. Live examples in the demo pages. Nothing here quite fits - tune individual properties or build a completely new piece in the same style: Tune individual components / Build Your Own Components.
Dialogs & Disclosure
modal.css | .ncss-modal, -header, -footer (+ --fullscreen, --dark, --3d, --3d-flip, --3d-swing, --slide-up, --slide-down, --slide-left, --slide-right, --zoom) | Centered dialog modal; --fullscreen+--dark yields a lightbox. --3d tilts in from depth on open, --3d-flip spins in around its own vertical axis like a card, --3d-swing swings in like a door on a hinge at its left edge. --slide-up/-down/-left/-right slide in from the respective direction (a slower, more pronounced decelerating --ncss-motion-easing-emphasized curve instead of the neutral default), --zoom grows in more noticeably than the default fade - all entrance variants are plain CSS, swappable via the class on the <dialog>. |
js/modal-router.js | Attributes data-modal-router, -trigger, -target, -content, -home, -redirect | Opt-in, requires JavaScript for the AJAX/modal behavior itself - trigger links keep a real href regardless: without JS (or before it loads), a click is a perfectly normal link, full navigation to the standalone target page, no modal (progressive-enhancement fallback - every target page must therefore also stand on its own). With JS, a click fetches the target into a shared .ncss-modal, the address bar follows along via history.pushState() so the open modal stays link-/shareable. <meta name="modal-router-redirect" content="..."> on the standalone target page bounces a genuinely fresh visit to its URL back to the listing page with the modal already open. No CSS of its own, uses .ncss-modal directly. |
lightbox.css + js/lightbox.js | .ncss-lightbox (-figure, -bar, -caption, -count, -prev, -next), attributes data-ncss-lightbox="group", data-caption | Opt-in - gallery navigation for the modal lightbox: all links with the same data-ncss-lightbox value form a group you can page through with arrow keys, prev/next buttons and swipe, with a counter and caption (data-caption, otherwise the thumbnail's alt). No separate dialog type: the script creates ONE <dialog class="ncss-modal ncss-modal--fullscreen ncss-modal--dark ncss-lightbox">; animation/backdrop/focus trap come from there. Without JS the link opens the large image. Texts follow <html lang> (de/en), overridable via data-lightbox-close/-prev/-next/-label/-of on <html>. |
theme-toggle.css + js/theme-toggle.js, js/theme-toggle-early.js | .ncss-theme-toggle, .ncss-theme-icon-dark/-light, attribute data-ncss-theme-toggle (="cycle") | Opt-in - light/dark toggle with a remembered choice and no flash on load, sets [data-theme]/[data-theme-resolved]. Details: Colors |
dialog-close.css | .ncss-dialog-close | Shared close button for modal/off-canvas/nav panel |
disclosure.css | .ncss-disclosure | FAQ-box look for <details>/<summary> |
<dialog id="d" class="ncss-modal">
<button type="button" class="ncss-dialog-close" command="close" commandfor="d" aria-label="Close">
<span class="ncss-icon ncss-icon-close" aria-hidden="true"></span>
</button>
<div class="ncss-modal-header"><h3>Title</h3></div>
<div class="ncss-modal-body">Content</div>
</dialog>
<button type="button" command="show-modal" commandfor="d">Open</button>
AJAX modal router live: standalone example (three cards, one shared modal, watch the address bar).
Lightbox gallery live: demo.
Cards & Content
card.css | .ncss-card-container, .ncss-card, -media, -header, -body, -footer (+ --flush, --transparent, --linked, --horizontal, --horizontal-end, color variants) | Card with no built-in border/corners/shadow (see Design Tokens). Color variants also double as a hint/callout box (tip/warning/error). |
split.css | .ncss-split-container, .ncss-split (+ --align-start/-end/-stretch), -media, -content | Text next to an image, see Landing Page Blocks |
tile.css | .ncss-tile (+ --muted/--brand/--brand-2) | Full-width color-block sections (UIkit tiles), see Landing Page Blocks |
accordion-split.css | .ncss-accordion-split-container, .ncss-accordion-split, -list, -item, -body, -media, -media-mobile | Transforming accordion (known from apple.com), fully native with no JS. For a smooth image swap (cross-fade/slide/3D flip instead of a hard cut), optionally include js/view-transitions.js (same-document View Transitions), see Landing Page Blocks |
marginnote.css | .ncss-marginnote-container, .ncss-marginnote-layout, .ncss-marginnote-start/-end | Margin notes (known from Tufte CSS) - image/text breaks out next to the running text instead of the screen edge, via CSS Grid auto-placement, see Landing Page Blocks |
badge.css | .ncss-badge (+ color variants), .ncss-badge-icon (+ --lg) | Status/category chips; -icon variant as a circle/square around an icon instead of a text pill |
lists.css | .ncss-list--dot/-dash/-icon/-divided/-plain/-steps, .ncss-dl/-dl--inline/-dl--stats | Ready-made ul/ol/dl variants, see Lists |
placeholder.css | .ncss-placeholder (+ --surface) | Gray placeholder for demo/prototype content |
hero.css | see Media | Image OR video background section with content on top, optional parallax |
<article class="ncss-card ncss-radius-lg ncss-border ncss-shadow-sm">
<img class="ncss-card-media ncss-ratio-video ncss-img-cover" src="image.jpg" alt="">
<div class="ncss-card-body">
<h3>Title</h3>
<p class="ncss-text-muted">Description</p>
</div>
</article>
Border, Radius & Shadow
helpers/elevation.css - standalone, component-independent utilities rather than baked into components (see Design Tokens), freely combinable with any element.
| Class | Purpose |
|---|---|
.ncss-border / --none | Border on/off |
.ncss-radius-sm/-md/-lg/-full/-none | Corner radius |
.ncss-shadow-sm/-md/-lg/-none | Shadow level |
.ncss-shadow-hover-sm/-md/-lg | Shadow grows on hover |
.ncss-blend-multiply/-screen/-overlay/-darken/-lighten/-color-dodge/-color-burn/-hard-light/-soft-light/-difference/-exclusion/-hue/-saturation/-color/-luminosity | mix-blend-mode utilities, 1:1 mapping to the matching CSS keywords (blends with whatever is BEHIND the element) |
<div class="ncss-card ncss-radius-lg ncss-border ncss-shadow-sm ncss-shadow-hover-md">...</div>
Forms & Search
select.css | .ncss-select-wrapper, .ncss-select | Styled native <select> including its own chevron. With appearance: base-select, additionally rich <option> content/custom popup styling - currently enabled ONLY in Chrome/Edge 135+, WebKit/Safari deliberately excluded (a known, not independently fixable duplicate-arrow rendering bug in Safari 26 - there AND in Firefox, js/combobox.js takes over automatically, see Forms) |
search.css | .ncss-search, .ncss-search-input | Search field that starts narrow and grows on focus via a pure width transition - no JS |
livesearch.css + js/livesearch.js | .ncss-livesearch, -results, -group, -option, attribute data-ncss-livesearch="URL" | Opt-in - suggestions from the server while typing, grouped, WAI-ARIA combobox (arrow keys, Enter, Esc), matches highlighted. A plain search form without JS. Details: Forms |
Scroll & Animation
slideshow.css | .ncss-slideshow, -track (+ --no-scrollbar), -item (+ --peek) | Scroll-snap carousel, no JS |
sparkline.css | .ncss-sparkline, -area, -dot | Small inline data line. Coordinates by hand OR computed by js/sparkline.js (opt-in) from data-values/data-src, including an accessible hidden table with the real values |
scroll-progress.css | .ncss-scroll-progress (+ --vertical, --end) | Reading progress bar, animation-timeline: scroll() |
scroll-stack.css | .ncss-stack-section, .ncss-stack-stage, .ncss-stack-card | Pinned stage, cards slide over one another into a fanned stack while scrolling ("pinned scrollytelling"). view-timeline-based, opt-in JS fallback for Firefox/older Safari: js/scroll-stack-fallback.js, see Web Awesome Bridge |
roadmap.css | .ncss-roadmap, -line, -list, -item, -dot, -card | Milestone list with a self-drawing progress line on scroll |
Effects
effects.css | .ncss-glow-border | Rotating gradient ring via ::before + mask-composite: exclude |
.ncss-glow-pulse | Pulsing box-shadow | |
.ncss-glass | Glassmorphism (backdrop-filter, @supports-guarded). Don't apply to an element with Floating UI descendants (<wa-dropdown> and similar) - backdrop-filter creates a new containing block for position:fixed | |
.ncss-stamped (+ --press) | Hairline-thin, two-tone "engraved" border, works on any surface | |
.ncss-grain | Fine SVG noise via ::after + mix-blend-mode | |
backdrop.css + js/backdrop.js | .ncss-backdrop, -item (+ --contained), attributes data-ncss-backdrop, data-interval | Background made of several images that slowly cross-fade and gently zoom out. Fixed page-wide by default (100lvh, no empty strip when the mobile address bar moves, no background-attachment:fixed, which iOS ignores); --contained only fills the nearest positioned ancestor. Without JS the first image stays; the script preloads, pauses in background tabs and does not switch at all under prefers-reduced-motion. Tokens --ncss-backdrop-fade, -zoom, -tint. No ancestor with transform/filter - otherwise the fixed background scrolls along. |
Purely decorative, deliberately optional - none of these classes are part of .ncss-card/-btn. Live: backdrop demo.