Shine CSS reference
Every class and data attribute in Shine, with live examples. This page is generated from the CSS source, so it always matches the code. Try the playground.
Getting started
Shine is a pure-CSS utility framework. Add one stylesheet and use class names. There is no JavaScript to load and no build step to run.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/asticore/shine@v1.0.0/dist/shine.min.css">
How classes combine
A component class gives you the base look. Modifier classes change it. Tone classes recolor it. Utilities adjust it locally.
<button class="btn btn-outline tone-danger mt-4 md:mt-0">Delete</button>
<!-- base style tone utilities -->
Knobs first, utilities second
Start by setting a few master knobs on <html>: theme, corner radius, shadow, density and brand colors. The whole site follows. Reach for utility classes only when one element needs to differ. Your own CSS always wins over Shine, so you never need !important.
<html data-theme="auto" data-radius="3" data-shadow="2" style="--sh-primary:#0ea5e9">
Master knobs
Knobs are data attributes and CSS variables. Set them on <html> for the whole site, or on any element to restyle just that subtree.
Data attributes
| Attribute | Values | What it changes |
|---|---|---|
data-theme | light · dark · auto | Page background, surfaces, text, borders and shadows. A themed element paints its own background, so a dark section can sit inside a light page. Set on: html or any section. |
data-radius | 0 · 1 · 2 · 3 · 4 · 5 | Corner level for every rounded thing: buttons, cards, inputs, modals and the rounded-* utilities. Set on: html or any element. |
data-btn-radius | 0 · 1 · 2 · 3 · 4 · 5 | Corner level for buttons only (and pagination, tabs pills, close buttons). 5 makes pills. Set on: any element. |
data-card-radius | 0 · 1 · 2 · 3 · 4 · 5 | Corner level for cards, modals, menus and accordions. Set on: any element. |
data-input-radius | 0 · 1 · 2 · 3 · 4 · 5 | Corner level for text inputs, selects and textareas. 5 makes pills. Set on: any element. |
data-shadow | 0 · 1 · 2 · 3 · 4 · 5 | Elevation of cards, from none (0) to very high (5). Also drives the shadow-elevation utility. Set on: html or any element. |
data-density | compact · comfortable | Component padding multiplier: compact = .75, comfortable = 1.25, default = 1. Set on: html or any element. |
data-theme
data-radius
data-btn-radius
data-input-radius
data-card-radius
data-shadow
data-density
CSS variables (tokens)
Every --sh-* variable defined on :root. Override any of them on any element: style="--sh-primary:#e11d48" re-brands that subtree.
| Variable | Default | Preview | Note |
|---|---|---|---|
--sh-primary | #4f46e5 | Brand | |
--sh-secondary | #64748b | Brand | |
--sh-accent | #db2777 | Brand | |
--sh-success | #15803d | Brand | |
--sh-warning | #b45309 | Brand | |
--sh-danger | #dc2626 | Brand | |
--sh-info | #0369a1 | Brand | |
--sh-on-primary | #fff | Brand | |
--sh-on-secondary | #fff | Brand | |
--sh-on-accent | #fff | Brand | |
--sh-on-success | #fff | Brand | |
--sh-on-warning | #fff | Brand | |
--sh-on-danger | #fff | Brand | |
--sh-on-info | #fff | Brand | |
--sh-bg | #fff | page | |
--sh-surface | #f8fafc | cards, panels | |
--sh-surface-2 | #f1f5f9 | inputs, wells, hover | |
--sh-text | #0f172a | Surfaces (light) | |
--sh-text-muted | #5f6e84 | Surfaces (light) | |
--sh-border | #e2e8f0 | Surfaces (light) | |
--sh-radius | .5rem | global corner level (see data-radius) | |
--sh-border-width | 1px | Shape | |
--sh-space | .25rem | spacing unit: p-4 = 4 x this | |
--sh-density | 1 | component padding multiplier | |
--sh-shadow-1 | 0 1px 2px rgb(0 0 0 / .06), 0 1px 3px rgb(0 0 0 / .08) | Elevation | |
--sh-shadow-2 | 0 2px 4px rgb(0 0 0 / .06), 0 4px 8px rgb(0 0 0 / .08) | Elevation | |
--sh-shadow-3 | 0 4px 8px rgb(0 0 0 / .06), 0 10px 20px rgb(0 0 0 / .10) | Elevation | |
--sh-shadow-4 | 0 8px 16px rgb(0 0 0 / .08), 0 20px 40px rgb(0 0 0 / .12) | Elevation | |
--sh-shadow-5 | 0 12px 24px rgb(0 0 0 / .10), 0 32px 64px rgb(0 0 0 / .18) | Elevation | |
--sh-font-sans | ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif | Typography | |
--sh-font-serif | ui-serif, Georgia, Cambria, "Times New Roman", serif | Typography | |
--sh-font-mono | ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace | Typography | |
--sh-leading | 1.5 | Typography | |
--sh-duration | 150ms | Motion | |
--sh-ease | cubic-bezier(.4, 0, .2, 1) | Motion |
Components also read optional variables that are not set by default. Set them to override one component: --sh-stack-gap --sh-center-max --sh-section-gap --sh-tone --sh-on-tone --sh-btn-radius --sh-card-radius --sh-input-radius --sh-badge-radius --sh-card-shadow --sh-elevation --sh-ring.
Tones
Tone classes recolor any component: buttons, badges, alerts, tabs, progress bars, switches. Without a tone, components use --sh-primary.
| Class | Preview |
|---|---|
tone-primary | Badge |
tone-secondary | Badge |
tone-accent | Badge |
tone-success | Badge |
tone-warning | Badge |
tone-danger | Badge |
tone-info | Badge |
tone-neutral | Badge |
<button class="btn tone-danger">Delete</button>
<span class="badge tone-success">Live</span>
<div class="alert tone-warning">Heads up</div>
Components
Eight small files. Each example below is live, followed by its exact HTML and a table of every class in the source file.
Layout primitives
Easy-to-use building blocks for spacing and page width. Gap, width and section padding follow --sh-stack-gap, --sh-center-max and --sh-section-gap; utilities such as gap-2 or py-4 override them.
Children are spaced evenly.
<div class="stack">
<strong>Stack</strong>
<p class="m-0">Children are spaced evenly.</p>
<div class="cluster">
<span class="badge">Cluster</span><span class="badge">of</span><span class="badge">items</span><button class="btn btn-sm">Action</button>
</div>
</div>
Eyebrow, display, banner, segmented, hairline grid, full-bleed
Layout
Fluid headings
- One
- Two
- Three
<div class="banner tone-accent"><span>Shine 1.1 is out.</span><a href="#c-layout">See what is new</a></div>
<div class="stack gap-2">
<p class="eyebrow m-0">Layout</p>
<h3 class="display-3 m-0">Fluid headings</h3>
</div>
<div class="segmented" role="radiogroup" aria-label="Billing period">
<label><input type="radio" name="ex-billing" checked> Monthly</label>
<label><input type="radio" name="ex-billing"> Yearly</label>
</div>
<ul class="grid grid-cols-1 sm:grid-cols-3 grid-hairline list-none p-0 m-0">
<li class="p-4">One</li><li class="p-4">Two</li><li class="p-4">Three</li>
</ul>
<div class="full-bleed bg-surface-2 py-6 text-center">Full-bleed band</div>
| Class | What it does |
|---|---|
.stack | Vertical flex column with a consistent gap. |
.cluster | Wrapping horizontal row, vertically centered, with a gap. |
.center | Centered container with a max width and side padding. |
.section | Large vertical padding for a page section (scales with density, or set --sh-section-gap). |
.full-bleed | Edge-to-edge band (100vw) inside a centered page. The body clips horizontal overflow. |
.grid-hairline | Items separated by 1px lines instead of gaps. Use with grid or flex; direct children get the page background. |
.eyebrow | Small uppercase label above a heading, colored by the tone. |
.display-1 | Largest fluid hero heading (2.5rem to 4.5rem). |
.display-2 | Large fluid hero heading (2rem to 3.5rem). |
.display-3 | Medium fluid hero heading (1.75rem to 2.75rem). |
.banner | Thin announcement strip filled with the tone color; links inside are underlined. |
.segmented | Segmented switch: radio labels, or buttons with aria-pressed, aria-selected or .active. |
.active | Marks the selected button inside a .segmented switch (aria-pressed="true" does the same). |
Card
A bordered surface. Radius follows data-card-radius, elevation follows data-shadow.
<article class="card">
<div class="card-header"><h3 class="card-title">Title</h3></div>
<div class="card-body">Body text. Radius and shadow follow the knobs.</div>
<div class="card-footer"><button class="btn btn-sm">Save</button></div>
</article>
| Class | What it does |
|---|---|
.card | Bordered surface with radius and shadow. |
.card-flat | Removes the shadow. |
.card-header | Padded top area with a bottom border. |
.card-body | Padded main area. |
.card-footer | Padded bottom area with a top border. |
.card-title | Heading style for a card. |
.card-media | Full-width image at the top, rounded to match the card. |
Form
Native controls, styled. Wrap a label, control and hint in field for even spacing. Mark errors with is-invalid or aria-invalid="true".
<div class="field">
<label class="label" for="ex-name">Name</label>
<input class="input" id="ex-name" placeholder="Ada Lovelace">
<span class="hint">Helper text</span>
</div>
<div class="field">
<label class="label" for="ex-mail">Email</label>
<input class="input is-invalid" id="ex-mail" value="nope" aria-invalid="true">
<span class="hint">Enter a valid email</span>
</div>
<div class="field">
<label class="label" for="ex-plan">Plan</label>
<select class="select" id="ex-plan"><option>Free</option><option>Pro</option></select>
</div>
<div class="field">
<label class="label" for="ex-msg">Message</label>
<textarea class="textarea" id="ex-msg"></textarea>
</div>
<label class="flex items-center gap-2"><input type="checkbox" class="checkbox" checked> Checkbox</label>
<label class="flex items-center gap-2"><input type="radio" class="radio" name="ex-r" checked> Radio</label>
<label class="flex items-center gap-2"><input type="checkbox" class="switch" checked> Switch</label>
<div class="input-group">
<span class="input-addon">https://</span>
<input class="input" aria-label="Domain" placeholder="example.com">
<button class="btn">Go</button>
</div>
<input type="range" class="range" aria-label="Volume" value="40">
<input type="file" class="file" aria-label="Upload file">
| Class | What it does |
|---|---|
.input | Text input. |
.select | Dropdown select with a custom arrow. |
.textarea | Multi-line text input. |
.is-invalid | Red error state (aria-invalid="true" does the same). Turns the next hint red. |
.input-sm | Smaller input. |
.input-lg | Larger input. |
.checkbox | Checkbox tinted with the tone. |
.radio | Radio button tinted with the tone. |
.switch | Toggle switch (use on a checkbox input). |
.label | Form label. |
.field | Groups label, control and hint in a tidy grid. |
.hint | Small helper text under a control. |
.input-group | Joins inputs, buttons and addons into one bar with shared borders. Items must be direct children. |
.input-addon | Muted text cell (a prefix, suffix or unit) inside an input-group. |
.range | Slider (use on input type=range), tinted with the tone. |
.file | File picker (use on input type=file) with a soft-button style. |
Badge, avatar, divider
Small status chips, round avatars and separators. Badges take tone classes.
<span class="badge">Default</span>
<span class="badge tone-success">Success</span>
<span class="badge badge-solid tone-danger">Solid</span>
<span class="badge badge-outline tone-info">Outline</span>
<span class="avatar">AB</span>
<div class="avatar-group"><span class="avatar">AB</span><span class="avatar">CD</span><span class="avatar">EF</span></div>
<hr class="divider">
<div class="divider">or</div>
| Class | What it does |
|---|---|
.badge | Small tinted pill. |
.badge-solid | Solid tone fill. |
.badge-outline | Outlined, no fill. |
.avatar | Round box for initials or an image. |
.avatar-group | Overlapping row of avatars, each ringed in the page background. On a card, set style="--sh-avatar-ring:var(--sh-surface)". |
.divider | Horizontal rule; put text inside for a labelled divider. |
Alert and kbd
Inline messages and keyboard keys. Alerts take tone classes.
Press Ctrl + K
<div class="alert tone-info"><span class="alert-title">Heads up</span> Soft alert.</div>
<div class="alert alert-solid tone-danger"><span class="alert-title">Failed</span> Solid alert.</div>
<p>Press <kbd class="kbd">Ctrl</kbd> + <kbd class="kbd">K</kbd></p>
| Class | What it does |
|---|---|
.alert | Tinted message box. |
.alert-solid | Solid tone fill. |
.alert-title | Bold first line. |
.kbd | Keyboard key cap. |
Overlays: modal, offcanvas, dropdown, tooltip
No JavaScript. Modals use <dialog> with command / commandfor (Invoker Commands). Offcanvas uses the Popover API. Dropdowns use <details>. Tooltips use a data attribute.
Toast
<button class="btn" popovertarget="demo-toast">Show toast</button>
<div id="demo-toast" popover="manual" class="toast tone-success" role="status">
<strong>Saved.</strong> Your changes are live.
<button class="btn-close" popovertarget="demo-toast" popovertargetaction="hide" aria-label="Dismiss"></button>
</div>
<div class="toast tone-info">A static toast is just a card notice.</div>
Modal
<button class="btn" command="show-modal" commandfor="demo-modal">Open modal</button>
<dialog id="demo-modal" class="modal" aria-labelledby="demo-modal-title">
<div class="modal-header">
<h3 class="card-title" id="demo-modal-title">Modal title</h3>
<button class="btn-close" command="close" commandfor="demo-modal" aria-label="Close"></button>
</div>
<div class="modal-body">Esc or the backdrop closes it. Focus is trapped natively.</div>
<div class="modal-footer">
<button class="btn btn-ghost" command="close" commandfor="demo-modal">Cancel</button>
<button class="btn" command="close" commandfor="demo-modal">OK</button>
</div>
</dialog>
Offcanvas
<button class="btn" popovertarget="demo-oc">Open panel</button>
<aside id="demo-oc" popover class="offcanvas" aria-label="Demo panel">
<div class="offcanvas-header">
<strong>Panel</strong>
<button class="btn-close" popovertarget="demo-oc" popovertargetaction="hide" aria-label="Close"></button>
</div>
<div class="offcanvas-body">Slides in from the left. Add offcanvas-right, -top or -bottom to change the side.</div>
</aside>
Dropdown
Menu
<details class="dropdown">
<summary class="btn btn-outline">Menu</summary>
<ul class="menu">
<li><a href="#overlay" class="active">Profile</a></li>
<li><a href="#overlay">Settings</a></li>
<li><hr class="menu-divider"></li>
<li><button type="button">Sign out</button></li>
</ul>
</details>
Tooltip
<button class="btn btn-outline" data-tooltip="Saved to your account">Hover me</button>
<button class="btn btn-outline" data-tooltip="Below" data-tooltip-pos="bottom">Bottom</button>
<button class="btn btn-outline" data-tooltip="Right" data-tooltip-pos="right">Right</button>
| Class | What it does |
|---|---|
.modal | Centered dialog. Put it on a <dialog>. |
.offcanvas | Side panel that slides in. Put it on an element with the popover attribute. |
.modal-sm | Narrower modal. |
.modal-lg | Wider modal. |
.modal-full | Nearly full-screen modal. |
.modal-header | Top bar of a modal. |
.modal-body | Padded content of a modal. |
.modal-footer | Bottom bar for action buttons. |
.offcanvas-header | Top bar of an offcanvas. |
.offcanvas-body | Padded content of an offcanvas. |
.offcanvas-right | Slides in from the right. |
.offcanvas-top | Slides in from the top. |
.offcanvas-bottom | Slides in from the bottom. |
.btn-close | Round close button with a multiplication sign. |
.dropdown | Wrapper for a details/summary dropdown. |
.menu | Vertical list of links or buttons. |
.dropdown-menu | Popover menu: put on an element with popover, open with a popovertarget button. Closes on outside click and Esc. |
.dropdown-end | Aligns the menu to the right edge. |
.dropdown-menu-end | Aligns a popover menu to the end edge of its button. |
.active | Highlights the current menu or tab item. |
.menu-divider | Thin separator line between menu items. |
data-tooltip | Attribute: text shown on hover or focus. |
.toast | Notification box. On an element with popover="manual" it floats bottom-right; without popover it is a static notice. Tone sets the left border. Show one floating toast at a time; they share the same corner. |
.toast-top | Positions the toast at the top. |
.toast-left | Positions the toast at the left. |
.toast-center | Centers the toast horizontally. |
Content: accordion, table, progress, meter, stat, prose
Building blocks for documents. The accordion is plain <details>; the progress bar is a native <progress>; prose styles long-form HTML such as articles.
First item
Opens and closes natively.
Second item
More content.
| Name | Role | Commits |
|---|---|---|
| Ada | Engineer | 1,204 |
| Grace | Admiral | 982 |
| Alan | Researcher | 640 |
| Total | 2,826 |
| Plan | Price |
|---|---|
| Free | $0 |
| Legacy | Ends soon |
<div class="accordion">
<details open><summary>First item</summary><p>Opens and closes natively.</p></details>
<details><summary>Second item</summary><p>More content.</p></details>
</div>
<div class="table-wrap max-h-full">
<table class="table table-striped table-hover table-stack">
<caption>Team (sort arrows come from aria-sort; stacks into cards on phones)</caption>
<thead><tr><th aria-sort="ascending">Name</th><th aria-sort="none">Role</th><th class="text-right">Commits</th></tr></thead>
<tbody>
<tr><td data-label="Name">Ada</td><td data-label="Role">Engineer</td><td data-label="Commits" class="text-right">1,204</td></tr>
<tr class="tone-success"><td data-label="Name">Grace</td><td data-label="Role">Admiral</td><td data-label="Commits" class="text-right">982</td></tr>
<tr aria-selected="true"><td data-label="Name">Alan</td><td data-label="Role">Researcher</td><td data-label="Commits" class="text-right">640</td></tr>
</tbody>
<tfoot><tr><td>Total</td><td></td><td class="text-right">2,826</td></tr></tfoot>
</table>
</div>
<table class="table table-bordered table-compact">
<thead><tr><th>Plan</th><th>Price</th></tr></thead>
<tbody><tr><td>Free</td><td>$0</td></tr><tr class="tone-danger"><td>Legacy</td><td>Ends soon</td></tr></tbody>
</table>
<progress class="progress" value="60" max="100" aria-label="Upload"></progress>
<progress class="progress tone-success" value="30" max="100" aria-label="Done"></progress>
<meter class="meter" value="80" min="0" max="100" low="30" high="70" optimum="100" aria-label="Good"></meter>
<meter class="meter" value="50" min="0" max="100" low="30" high="70" optimum="100" aria-label="Fair"></meter>
<meter class="meter" value="15" min="0" max="100" low="30" high="70" optimum="100" aria-label="Poor"></meter>
<div class="card"><div class="card-body stat">
<span class="stat-label">Revenue</span><span class="stat-value">$12,480</span><span class="stat-desc">+8% from last month</span>
</div></div>
<a class="skip-link" href="#main">Skip to content</a>
| Class | What it does |
|---|---|
.accordion | Bordered stack of <details> items with a chevron. |
.table | Full-width table with row borders. |
.table-striped | Zebra rows. |
.table-hover | Highlights the row under the pointer. |
.table-compact | Tighter cell padding. |
.table-bordered | Borders on every cell. |
.table-borderless | No cell borders. |
.active | Highlights a row or cell (also aria-selected="true" or any tone-* class). |
.table-wrap | Scroll container for a table. Give it max-h-* and the header row sticks. |
.table-sticky-col | Pins the first column while the table scrolls sideways (inside .table-wrap). |
.table-stack | On phones, each row becomes a card. Put data-label="Column" on every td. |
data-label | Attribute on a td: the column name shown in .table-stack mode. |
.progress | Rounded progress bar (use on <progress>). |
.meter | Gauge bar (use on <meter>); green, amber or red from low/high/optimum. |
.stat | Metric block: label, big value, description. Works inside a card. |
.stat-label | Small muted label above the value. |
.stat-desc | Small muted note under the value. |
.stat-value | Large bold number. |
.prose | Styles plain h1-h4, p, lists, code, tables and quotes inside it. |
.skip-link | Hidden link that appears on keyboard focus; place first in body. |
Extras: list group, button group, floating label, carousel
Small add-ons. The carousel is plain scroll-snap (link to item ids, no JS); the floating label needs placeholder=" " on the input.
<div class="btn-group">
<button class="btn">Save</button>
<button class="btn btn-caret" popovertarget="split-menu" aria-label="More save options"></button>
</div>
<div id="split-menu" popover class="menu dropdown-menu dropdown-menu-end">
<a href="#extras">Save as…</a><a href="#extras">Export PDF</a>
</div>
<div class="card glass p-6">Frosted glass card</div>
<ul class="list-group">
<li>Plain item</li>
<li><a href="#extras" aria-current="true">Current link</a></li>
<li><a href="#extras">Link item</a></li>
</ul>
<div class="btn-group"><button class="btn btn-outline">Left</button><button class="btn btn-outline">Middle</button><button class="btn btn-outline">Right</button></div>
<div class="floating"><input class="input" placeholder=" " id="fl-email"><label for="fl-email">Email</label></div>
<div class="carousel carousel-peek carousel-hide-bar">
<div id="s1" class="card card-body">Slide 1 <a href="#s2">Next</a></div>
<div id="s2" class="card card-body">Slide 2 <a href="#s1">Prev</a></div>
</div>
<div class="card card-body"><a class="stretched-link" href="#extras">Whole card is a link</a></div>
<div class="cluster"><span class="indicator"><span class="indicator-item badge badge-solid tone-danger">3</span><button class="btn">Inbox</button></span><span class="dot tone-success"></span> Online <span class="vr"></span> <mark>marked</mark></div>
<p class="lead">A lead paragraph.</p>
| Class | What it does |
|---|---|
.list-group | Bordered stacked list; a/button items get hover, [aria-current] or .active is solid. |
.active | With .list-group items: marks the current item. |
.btn-group | Joins adjacent .btn elements into one segmented control. |
.btn-group-vertical | Button group stacked vertically. |
.btn | Used inside .btn-group. |
.floating | Wrapper whose label floats above the input when focused or filled. |
.input | Used inside .floating. |
.textarea | Used inside .floating. |
.carousel | Scroll-snap slider; each child fills the width. |
.carousel-peek | Items are 85% wide so the next one peeks in. |
.carousel-hide-bar | Hides the carousel scrollbar. |
.stretched-link | Makes a link cover its whole positioned parent, such as a card. |
.card | Cards containing a .stretched-link become positioned. |
.indicator | Wrapper that pins an .indicator-item to its top-right corner. |
.indicator-item | Badge or dot placed on the corner of an .indicator. |
.dot | Small status dot colored by tone. |
.vr | Vertical rule for flex rows. |
.lead | Larger intro paragraph. |
.mark | Highlighted text (also styles the mark element). |
.btn-caret | Adds a down chevron; pair with popovertarget for a split button menu. |
.glass | Frosted-glass surface (blurred, translucent). Tune with --sh-glass-blur and --sh-glass-opacity. |
.modal-blur | Blurs the page behind an open modal. |
Utilities
819 utility rules, generated from src/utilities/*.css when this page is built. Class names follow familiar utility conventions (inspired by Tailwind CSS). The last column lists the prefixed versions that the build creates, such as md:p-4 or hover:bg-primary.
layout
Layout: display, position, overflow, container, misc (66 rules)
| Class | CSS | Variants |
|---|---|---|
.block | display:block | sm md lg xl print |
.inline-block | display:inline-block | sm md lg xl print |
.inline | display:inline | sm md lg xl print |
.flex | display:flex | sm md lg xl print |
.inline-flex | display:inline-flex | sm md lg xl print |
.grid | display:grid | sm md lg xl print |
.inline-grid | display:inline-grid | sm md lg xl print |
.contents | display:contents | sm md lg xl print |
.hidden | display:none | sm md lg xl print |
.container | width:100%; margin-inline:auto; padding-inline:calc(var(--sh-space)*4) | - |
.static | position:static | - |
.relative | position:relative | - |
.absolute | position:absolute | - |
.fixed | position:fixed | - |
.sticky | position:sticky | - |
.inset-0 | inset:0 | - |
.inset-x-0 | inset-inline:0 | - |
.inset-y-0 | inset-block:0 | - |
.top-0 | top:0 | - |
.top-auto | top:auto | - |
.right-0 | right:0 | - |
.right-auto | right:auto | - |
.bottom-0 | bottom:0 | - |
.bottom-auto | bottom:auto | - |
.left-0 | left:0 | - |
.left-auto | left:auto | - |
.z-0 | z-index:0 | - |
.z-10 | z-index:10 | - |
.z-20 | z-index:20 | - |
.z-30 | z-index:30 | - |
.z-40 | z-index:40 | - |
.z-50 | z-index:50 | - |
.z-auto | z-index:auto | - |
.overflow-auto | overflow:auto | - |
.overflow-hidden | overflow:hidden | - |
.overflow-visible | overflow:visible | - |
.overflow-scroll | overflow:scroll | - |
.overflow-x-auto | overflow-x:auto | - |
.overflow-x-hidden | overflow-x:hidden | - |
.overflow-y-auto | overflow-y:auto | - |
.overflow-y-hidden | overflow-y:hidden | - |
.box-border | box-sizing:border-box | - |
.box-content | box-sizing:content-box | - |
.visible | visibility:visible | - |
.invisible | visibility:hidden | - |
.isolate | isolation:isolate | - |
.object-cover | object-fit:cover | - |
.object-contain | object-fit:contain | - |
.aspect-square | aspect-ratio:1/1 | - |
.aspect-video | aspect-ratio:16/9 | - |
.aspect-auto | aspect-ratio:auto | - |
.aspect-4/3 | aspect-ratio:4/3 | - |
.columns-1 | columns:1 | - |
.columns-2 | columns:2 | - |
.columns-3 | columns:3 | - |
.align-baseline | vertical-align:baseline | - |
.align-top | vertical-align:top | - |
.align-middle | vertical-align:middle | - |
.align-bottom | vertical-align:bottom | - |
.align-text-top | vertical-align:text-top | - |
.scroll-mt-4 | scroll-margin-top:calc(var(--sh-space)*4) | - |
.scroll-mt-16 | scroll-margin-top:calc(var(--sh-space)*16) | - |
.scroll-mt-20 | scroll-margin-top:calc(var(--sh-space)*20) | - |
.scroll-mt-24 | scroll-margin-top:calc(var(--sh-space)*24) | - |
.sr-only | position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border-width:0 | sm md lg xl |
.not-sr-only | position:static; width:auto; height:auto; padding:0; margin:0; overflow:visible; clip:auto; white-space:normal | sm md lg xl |
flex-grid
Flex & grid (123 rules)
| Class | CSS | Variants |
|---|---|---|
.flex-row | flex-direction:row | sm md lg xl |
.flex-col | flex-direction:column | sm md lg xl |
.flex-wrap | flex-wrap:wrap | sm md lg xl |
.flex-nowrap | flex-wrap:nowrap | sm md lg xl |
.flex-row-reverse | flex-direction:row-reverse | - |
.flex-col-reverse | flex-direction:column-reverse | - |
.flex-wrap-reverse | flex-wrap:wrap-reverse | - |
.flex-1 | flex:1 1 0% | - |
.flex-auto | flex:1 1 auto | - |
.flex-initial | flex:0 1 auto | - |
.flex-none | flex:none | - |
.grow | flex-grow:1 | - |
.grow-0 | flex-grow:0 | - |
.shrink | flex-shrink:1 | - |
.shrink-0 | flex-shrink:0 | - |
.basis-0 | flex-basis:0 | - |
.basis-auto | flex-basis:auto | - |
.basis-full | flex-basis:100% | - |
.basis-1/2 | flex-basis:50% | - |
.basis-1/3 | flex-basis:33.333333% | - |
.basis-2/3 | flex-basis:66.666667% | - |
.basis-1/4 | flex-basis:25% | - |
.basis-3/4 | flex-basis:75% | - |
.items-start | align-items:flex-start | sm md lg xl |
.items-center | align-items:center | sm md lg xl |
.items-end | align-items:flex-end | sm md lg xl |
.items-baseline | align-items:baseline | sm md lg xl |
.items-stretch | align-items:stretch | sm md lg xl |
.justify-start | justify-content:flex-start | sm md lg xl |
.justify-center | justify-content:center | sm md lg xl |
.justify-end | justify-content:flex-end | sm md lg xl |
.justify-between | justify-content:space-between | sm md lg xl |
.justify-around | justify-content:space-around | sm md lg xl |
.justify-evenly | justify-content:space-evenly | sm md lg xl |
.self-auto | align-self:auto | - |
.self-start | align-self:flex-start | - |
.self-center | align-self:center | - |
.self-end | align-self:flex-end | - |
.self-baseline | align-self:baseline | - |
.self-stretch | align-self:stretch | - |
.content-start | align-content:flex-start | - |
.content-center | align-content:center | - |
.content-end | align-content:flex-end | - |
.content-between | align-content:space-between | - |
.place-items-center | place-items:center | - |
.place-content-center | place-content:center | - |
.justify-items-center | justify-items:center | - |
.justify-self-start | justify-self:start | - |
.justify-self-center | justify-self:center | - |
.justify-self-end | justify-self:end | - |
.place-self-center | place-self:center | - |
.grid-cols-1 | grid-template-columns:repeat(1,minmax(0,1fr)) | sm md lg xl |
.grid-cols-2 | grid-template-columns:repeat(2,minmax(0,1fr)) | sm md lg xl |
.grid-cols-3 | grid-template-columns:repeat(3,minmax(0,1fr)) | sm md lg xl |
.grid-cols-4 | grid-template-columns:repeat(4,minmax(0,1fr)) | sm md lg xl |
.grid-cols-5 | grid-template-columns:repeat(5,minmax(0,1fr)) | sm md lg xl |
.grid-cols-6 | grid-template-columns:repeat(6,minmax(0,1fr)) | sm md lg xl |
.grid-cols-12 | grid-template-columns:repeat(12,minmax(0,1fr)) | sm md lg xl |
.grid-cols-none | grid-template-columns:none | - |
.col-span-1 | grid-column:span 1 | sm md lg xl |
.col-span-2 | grid-column:span 2 | sm md lg xl |
.col-span-3 | grid-column:span 3 | sm md lg xl |
.col-span-4 | grid-column:span 4 | sm md lg xl |
.col-span-5 | grid-column:span 5 | sm md lg xl |
.col-span-6 | grid-column:span 6 | sm md lg xl |
.col-span-8 | grid-column:span 8 | sm md lg xl |
.col-span-9 | grid-column:span 9 | sm md lg xl |
.col-span-12 | grid-column:span 12 | sm md lg xl |
.col-span-full | grid-column:1/-1 | sm md lg xl |
.col-span-7 | grid-column:span 7 | - |
.col-span-10 | grid-column:span 10 | - |
.col-span-11 | grid-column:span 11 | - |
.col-start-1 | grid-column-start:1 | sm md lg xl |
.col-start-2 | grid-column-start:2 | sm md lg xl |
.col-start-3 | grid-column-start:3 | sm md lg xl |
.col-start-4 | grid-column-start:4 | sm md lg xl |
.col-start-auto | grid-column-start:auto | - |
.grid-rows-1 | grid-template-rows:repeat(1,minmax(0,1fr)) | - |
.grid-rows-2 | grid-template-rows:repeat(2,minmax(0,1fr)) | - |
.grid-rows-3 | grid-template-rows:repeat(3,minmax(0,1fr)) | - |
.row-span-1 | grid-row:span 1 | - |
.row-span-2 | grid-row:span 2 | - |
.row-span-3 | grid-row:span 3 | - |
.row-span-full | grid-row:1/-1 | - |
.row-start-1 | grid-row-start:1 | - |
.grid-flow-row | grid-auto-flow:row | - |
.grid-flow-col | grid-auto-flow:column | - |
.grid-flow-dense | grid-auto-flow:dense | - |
.gap-0 | gap:0 | sm md lg xl |
.gap-2 | gap:calc(var(--sh-space)*2) | sm md lg xl |
.gap-4 | gap:calc(var(--sh-space)*4) | sm md lg xl |
.gap-6 | gap:calc(var(--sh-space)*6) | sm md lg xl |
.gap-8 | gap:calc(var(--sh-space)*8) | sm md lg xl |
.gap-px | gap:1px | - |
.gap-0.5 | gap:calc(var(--sh-space)*0.5) | - |
.gap-1 | gap:calc(var(--sh-space)*1) | - |
.gap-1.5 | gap:calc(var(--sh-space)*1.5) | - |
.gap-2.5 | gap:calc(var(--sh-space)*2.5) | - |
.gap-3 | gap:calc(var(--sh-space)*3) | - |
.gap-5 | gap:calc(var(--sh-space)*5) | - |
.gap-10 | gap:calc(var(--sh-space)*10) | - |
.gap-12 | gap:calc(var(--sh-space)*12) | - |
.gap-16 | gap:calc(var(--sh-space)*16) | - |
.gap-x-0 | column-gap:0 | - |
.gap-y-0 | row-gap:0 | - |
.gap-x-1 | column-gap:calc(var(--sh-space)*1) | - |
.gap-y-1 | row-gap:calc(var(--sh-space)*1) | - |
.gap-x-2 | column-gap:calc(var(--sh-space)*2) | - |
.gap-y-2 | row-gap:calc(var(--sh-space)*2) | - |
.gap-x-3 | column-gap:calc(var(--sh-space)*3) | - |
.gap-y-3 | row-gap:calc(var(--sh-space)*3) | - |
.gap-x-4 | column-gap:calc(var(--sh-space)*4) | - |
.gap-y-4 | row-gap:calc(var(--sh-space)*4) | - |
.gap-x-6 | column-gap:calc(var(--sh-space)*6) | - |
.gap-y-6 | row-gap:calc(var(--sh-space)*6) | - |
.gap-x-8 | column-gap:calc(var(--sh-space)*8) | - |
.gap-y-8 | row-gap:calc(var(--sh-space)*8) | - |
.order-first | order:-9999 | sm md lg xl |
.order-last | order:9999 | sm md lg xl |
.order-none | order:0 | - |
.order-1 | order:1 | - |
.order-2 | order:2 | - |
.order-3 | order:3 | - |
spacing
Spacing: padding, margin, space-x/y (scale via --sh-space) (181 rules)
| Class | CSS | Variants |
|---|---|---|
.p-0 | padding:0 | sm md lg xl |
.p-2 | padding:calc(var(--sh-space)*2) | sm md lg xl |
.p-4 | padding:calc(var(--sh-space)*4) | sm md lg xl |
.p-6 | padding:calc(var(--sh-space)*6) | sm md lg xl |
.p-8 | padding:calc(var(--sh-space)*8) | sm md lg xl |
.p-12 | padding:calc(var(--sh-space)*12) | sm md lg xl |
.p-16 | padding:calc(var(--sh-space)*16) | sm md lg xl |
.p-px | padding:1px | - |
.p-0.5 | padding:calc(var(--sh-space)*0.5) | - |
.p-1 | padding:calc(var(--sh-space)*1) | - |
.p-1.5 | padding:calc(var(--sh-space)*1.5) | - |
.p-2.5 | padding:calc(var(--sh-space)*2.5) | - |
.p-3 | padding:calc(var(--sh-space)*3) | - |
.p-5 | padding:calc(var(--sh-space)*5) | - |
.p-10 | padding:calc(var(--sh-space)*10) | - |
.px-0 | padding-inline:0 | sm md lg xl |
.px-2 | padding-inline:calc(var(--sh-space)*2) | sm md lg xl |
.px-4 | padding-inline:calc(var(--sh-space)*4) | sm md lg xl |
.px-6 | padding-inline:calc(var(--sh-space)*6) | sm md lg xl |
.px-8 | padding-inline:calc(var(--sh-space)*8) | sm md lg xl |
.px-px | padding-inline:1px | - |
.px-0.5 | padding-inline:calc(var(--sh-space)*0.5) | - |
.px-1 | padding-inline:calc(var(--sh-space)*1) | - |
.px-1.5 | padding-inline:calc(var(--sh-space)*1.5) | - |
.px-2.5 | padding-inline:calc(var(--sh-space)*2.5) | - |
.px-3 | padding-inline:calc(var(--sh-space)*3) | - |
.px-5 | padding-inline:calc(var(--sh-space)*5) | - |
.px-10 | padding-inline:calc(var(--sh-space)*10) | - |
.px-12 | padding-inline:calc(var(--sh-space)*12) | - |
.py-0 | padding-block:0 | sm md lg xl |
.py-2 | padding-block:calc(var(--sh-space)*2) | sm md lg xl |
.py-4 | padding-block:calc(var(--sh-space)*4) | sm md lg xl |
.py-8 | padding-block:calc(var(--sh-space)*8) | sm md lg xl |
.py-12 | padding-block:calc(var(--sh-space)*12) | sm md lg xl |
.py-16 | padding-block:calc(var(--sh-space)*16) | sm md lg xl |
.py-20 | padding-block:calc(var(--sh-space)*20) | sm md lg xl |
.py-24 | padding-block:calc(var(--sh-space)*24) | sm md lg xl |
.py-px | padding-block:1px | - |
.py-0.5 | padding-block:calc(var(--sh-space)*0.5) | - |
.py-1 | padding-block:calc(var(--sh-space)*1) | - |
.py-1.5 | padding-block:calc(var(--sh-space)*1.5) | - |
.py-2.5 | padding-block:calc(var(--sh-space)*2.5) | - |
.py-3 | padding-block:calc(var(--sh-space)*3) | - |
.py-5 | padding-block:calc(var(--sh-space)*5) | - |
.py-6 | padding-block:calc(var(--sh-space)*6) | - |
.py-10 | padding-block:calc(var(--sh-space)*10) | - |
.pt-0 | padding-top:0 | - |
.pt-1 | padding-top:calc(var(--sh-space)*1) | - |
.pt-2 | padding-top:calc(var(--sh-space)*2) | - |
.pt-3 | padding-top:calc(var(--sh-space)*3) | - |
.pt-4 | padding-top:calc(var(--sh-space)*4) | - |
.pt-6 | padding-top:calc(var(--sh-space)*6) | - |
.pt-8 | padding-top:calc(var(--sh-space)*8) | - |
.pt-12 | padding-top:calc(var(--sh-space)*12) | - |
.pt-16 | padding-top:calc(var(--sh-space)*16) | - |
.pt-24 | padding-top:calc(var(--sh-space)*24) | - |
.pr-0 | padding-right:0 | - |
.pr-1 | padding-right:calc(var(--sh-space)*1) | - |
.pr-2 | padding-right:calc(var(--sh-space)*2) | - |
.pr-3 | padding-right:calc(var(--sh-space)*3) | - |
.pr-4 | padding-right:calc(var(--sh-space)*4) | - |
.pr-6 | padding-right:calc(var(--sh-space)*6) | - |
.pr-8 | padding-right:calc(var(--sh-space)*8) | - |
.pb-0 | padding-bottom:0 | - |
.pb-1 | padding-bottom:calc(var(--sh-space)*1) | - |
.pb-2 | padding-bottom:calc(var(--sh-space)*2) | - |
.pb-3 | padding-bottom:calc(var(--sh-space)*3) | - |
.pb-4 | padding-bottom:calc(var(--sh-space)*4) | - |
.pb-6 | padding-bottom:calc(var(--sh-space)*6) | - |
.pb-8 | padding-bottom:calc(var(--sh-space)*8) | - |
.pb-12 | padding-bottom:calc(var(--sh-space)*12) | - |
.pb-16 | padding-bottom:calc(var(--sh-space)*16) | - |
.pb-24 | padding-bottom:calc(var(--sh-space)*24) | - |
.pl-0 | padding-left:0 | - |
.pl-1 | padding-left:calc(var(--sh-space)*1) | - |
.pl-2 | padding-left:calc(var(--sh-space)*2) | - |
.pl-3 | padding-left:calc(var(--sh-space)*3) | - |
.pl-4 | padding-left:calc(var(--sh-space)*4) | - |
.pl-6 | padding-left:calc(var(--sh-space)*6) | - |
.pl-8 | padding-left:calc(var(--sh-space)*8) | - |
.m-auto | margin:auto | sm md lg xl |
.m-0 | margin:0 | sm md lg xl |
.m-px | margin:1px | - |
.m-1 | margin:calc(var(--sh-space)*1) | - |
.m-2 | margin:calc(var(--sh-space)*2) | - |
.m-3 | margin:calc(var(--sh-space)*3) | - |
.m-4 | margin:calc(var(--sh-space)*4) | - |
.m-5 | margin:calc(var(--sh-space)*5) | - |
.m-6 | margin:calc(var(--sh-space)*6) | - |
.m-8 | margin:calc(var(--sh-space)*8) | - |
.mx-auto | margin-inline:auto | sm md lg xl |
.mx-0 | margin-inline:0 | - |
.mx-px | margin-inline:1px | - |
.mx-1 | margin-inline:calc(var(--sh-space)*1) | - |
.mx-2 | margin-inline:calc(var(--sh-space)*2) | - |
.mx-3 | margin-inline:calc(var(--sh-space)*3) | - |
.mx-4 | margin-inline:calc(var(--sh-space)*4) | - |
.mx-5 | margin-inline:calc(var(--sh-space)*5) | - |
.mx-6 | margin-inline:calc(var(--sh-space)*6) | - |
.mx-8 | margin-inline:calc(var(--sh-space)*8) | - |
.my-auto | margin-block:auto | sm md lg xl |
.my-0 | margin-block:0 | - |
.my-px | margin-block:1px | - |
.my-1 | margin-block:calc(var(--sh-space)*1) | - |
.my-2 | margin-block:calc(var(--sh-space)*2) | - |
.my-3 | margin-block:calc(var(--sh-space)*3) | - |
.my-4 | margin-block:calc(var(--sh-space)*4) | - |
.my-5 | margin-block:calc(var(--sh-space)*5) | - |
.my-6 | margin-block:calc(var(--sh-space)*6) | - |
.my-8 | margin-block:calc(var(--sh-space)*8) | - |
.my-10 | margin-block:calc(var(--sh-space)*10) | - |
.my-12 | margin-block:calc(var(--sh-space)*12) | - |
.my-16 | margin-block:calc(var(--sh-space)*16) | - |
.my-24 | margin-block:calc(var(--sh-space)*24) | - |
.mt-0 | margin-top:0 | sm md lg xl |
.mt-4 | margin-top:calc(var(--sh-space)*4) | sm md lg xl |
.mt-8 | margin-top:calc(var(--sh-space)*8) | sm md lg xl |
.mt-auto | margin-top:auto | - |
.mt-1 | margin-top:calc(var(--sh-space)*1) | - |
.mt-2 | margin-top:calc(var(--sh-space)*2) | - |
.mt-3 | margin-top:calc(var(--sh-space)*3) | - |
.mt-6 | margin-top:calc(var(--sh-space)*6) | - |
.mt-12 | margin-top:calc(var(--sh-space)*12) | - |
.mt-16 | margin-top:calc(var(--sh-space)*16) | - |
.mt-24 | margin-top:calc(var(--sh-space)*24) | - |
.mr-auto | margin-right:auto | - |
.mr-0 | margin-right:0 | - |
.mr-1 | margin-right:calc(var(--sh-space)*1) | - |
.mr-2 | margin-right:calc(var(--sh-space)*2) | - |
.mr-3 | margin-right:calc(var(--sh-space)*3) | - |
.mr-4 | margin-right:calc(var(--sh-space)*4) | - |
.mr-6 | margin-right:calc(var(--sh-space)*6) | - |
.mr-8 | margin-right:calc(var(--sh-space)*8) | - |
.mb-0 | margin-bottom:0 | sm md lg xl |
.mb-4 | margin-bottom:calc(var(--sh-space)*4) | sm md lg xl |
.mb-8 | margin-bottom:calc(var(--sh-space)*8) | sm md lg xl |
.mb-auto | margin-bottom:auto | - |
.mb-1 | margin-bottom:calc(var(--sh-space)*1) | - |
.mb-2 | margin-bottom:calc(var(--sh-space)*2) | - |
.mb-3 | margin-bottom:calc(var(--sh-space)*3) | - |
.mb-6 | margin-bottom:calc(var(--sh-space)*6) | - |
.mb-12 | margin-bottom:calc(var(--sh-space)*12) | - |
.mb-16 | margin-bottom:calc(var(--sh-space)*16) | - |
.mb-24 | margin-bottom:calc(var(--sh-space)*24) | - |
.ml-auto | margin-left:auto | - |
.ml-0 | margin-left:0 | - |
.ml-1 | margin-left:calc(var(--sh-space)*1) | - |
.ml-2 | margin-left:calc(var(--sh-space)*2) | - |
.ml-3 | margin-left:calc(var(--sh-space)*3) | - |
.ml-4 | margin-left:calc(var(--sh-space)*4) | - |
.ml-6 | margin-left:calc(var(--sh-space)*6) | - |
.ml-8 | margin-left:calc(var(--sh-space)*8) | - |
.-mx-1 | margin-inline:calc(var(--sh-space)*-1) | - |
.-mx-2 | margin-inline:calc(var(--sh-space)*-2) | - |
.-mx-4 | margin-inline:calc(var(--sh-space)*-4) | - |
.-mx-8 | margin-inline:calc(var(--sh-space)*-8) | - |
.-my-1 | margin-block:calc(var(--sh-space)*-1) | - |
.-my-2 | margin-block:calc(var(--sh-space)*-2) | - |
.-my-4 | margin-block:calc(var(--sh-space)*-4) | - |
.-my-8 | margin-block:calc(var(--sh-space)*-8) | - |
.-mt-1 | margin-top:calc(var(--sh-space)*-1) | - |
.-mt-2 | margin-top:calc(var(--sh-space)*-2) | - |
.-mt-4 | margin-top:calc(var(--sh-space)*-4) | - |
.-mt-8 | margin-top:calc(var(--sh-space)*-8) | - |
.space-x-0>:not(:last-child) | margin-inline-end:0 | - |
.space-y-0>:not(:last-child) | margin-block-end:0 | - |
.space-x-1>:not(:last-child) | margin-inline-end:calc(var(--sh-space)*1) | - |
.space-y-1>:not(:last-child) | margin-block-end:calc(var(--sh-space)*1) | - |
.space-x-2>:not(:last-child) | margin-inline-end:calc(var(--sh-space)*2) | - |
.space-y-2>:not(:last-child) | margin-block-end:calc(var(--sh-space)*2) | - |
.space-x-3>:not(:last-child) | margin-inline-end:calc(var(--sh-space)*3) | - |
.space-y-3>:not(:last-child) | margin-block-end:calc(var(--sh-space)*3) | - |
.space-x-4>:not(:last-child) | margin-inline-end:calc(var(--sh-space)*4) | - |
.space-y-4>:not(:last-child) | margin-block-end:calc(var(--sh-space)*4) | - |
.space-x-6>:not(:last-child) | margin-inline-end:calc(var(--sh-space)*6) | - |
.space-y-6>:not(:last-child) | margin-block-end:calc(var(--sh-space)*6) | - |
.space-x-8>:not(:last-child) | margin-inline-end:calc(var(--sh-space)*8) | - |
.space-y-8>:not(:last-child) | margin-block-end:calc(var(--sh-space)*8) | - |
.space-y-10>:not(:last-child) | margin-block-end:calc(var(--sh-space)*10) | - |
.space-y-12>:not(:last-child) | margin-block-end:calc(var(--sh-space)*12) | - |
.space-y-16>:not(:last-child) | margin-block-end:calc(var(--sh-space)*16) | - |
sizing
Sizing: width, height, min/max, size (84 rules)
| Class | CSS | Variants |
|---|---|---|
.w-full | width:100% | sm md lg xl |
.w-auto | width:auto | sm md lg xl |
.w-1/2 | width:50% | sm md lg xl |
.w-1/3 | width:33.333333% | sm md lg xl |
.w-2/3 | width:66.666667% | sm md lg xl |
.w-1/4 | width:25% | sm md lg xl |
.w-3/4 | width:75% | sm md lg xl |
.w-0 | width:0 | - |
.w-px | width:1px | - |
.w-1 | width:calc(var(--sh-space)*1) | - |
.w-2 | width:calc(var(--sh-space)*2) | - |
.w-3 | width:calc(var(--sh-space)*3) | - |
.w-4 | width:calc(var(--sh-space)*4) | - |
.w-5 | width:calc(var(--sh-space)*5) | - |
.w-6 | width:calc(var(--sh-space)*6) | - |
.w-8 | width:calc(var(--sh-space)*8) | - |
.w-10 | width:calc(var(--sh-space)*10) | - |
.w-12 | width:calc(var(--sh-space)*12) | - |
.w-16 | width:calc(var(--sh-space)*16) | - |
.w-20 | width:calc(var(--sh-space)*20) | - |
.w-24 | width:calc(var(--sh-space)*24) | - |
.w-32 | width:calc(var(--sh-space)*32) | - |
.w-40 | width:calc(var(--sh-space)*40) | - |
.w-48 | width:calc(var(--sh-space)*48) | - |
.w-64 | width:calc(var(--sh-space)*64) | - |
.w-80 | width:calc(var(--sh-space)*80) | - |
.w-screen | width:100vw | - |
.w-min | width:min-content | - |
.w-max | width:max-content | - |
.w-fit | width:fit-content | - |
.h-auto | height:auto | sm md lg xl |
.h-full | height:100% | sm md lg xl |
.h-0 | height:0 | - |
.h-px | height:1px | - |
.h-1 | height:calc(var(--sh-space)*1) | - |
.h-2 | height:calc(var(--sh-space)*2) | - |
.h-3 | height:calc(var(--sh-space)*3) | - |
.h-4 | height:calc(var(--sh-space)*4) | - |
.h-5 | height:calc(var(--sh-space)*5) | - |
.h-6 | height:calc(var(--sh-space)*6) | - |
.h-8 | height:calc(var(--sh-space)*8) | - |
.h-10 | height:calc(var(--sh-space)*10) | - |
.h-12 | height:calc(var(--sh-space)*12) | - |
.h-16 | height:calc(var(--sh-space)*16) | - |
.h-20 | height:calc(var(--sh-space)*20) | - |
.h-24 | height:calc(var(--sh-space)*24) | - |
.h-32 | height:calc(var(--sh-space)*32) | - |
.h-40 | height:calc(var(--sh-space)*40) | - |
.h-48 | height:calc(var(--sh-space)*48) | - |
.h-64 | height:calc(var(--sh-space)*64) | - |
.h-80 | height:calc(var(--sh-space)*80) | - |
.h-screen | height:100vh; height:100dvh | - |
.h-min | height:min-content | - |
.h-max | height:max-content | - |
.h-fit | height:fit-content | - |
.min-h-0 | min-height:0 | - |
.min-h-full | min-height:100% | - |
.min-h-screen | min-height:100vh; min-height:100dvh | - |
.min-h-dvh | min-height:100dvh | - |
.min-w-0 | min-width:0 | - |
.min-w-full | min-width:100% | - |
.max-w-md | max-width:28rem | sm md lg xl |
.max-w-lg | max-width:32rem | sm md lg xl |
.max-w-xl | max-width:36rem | sm md lg xl |
.max-w-2xl | max-width:42rem | sm md lg xl |
.max-w-4xl | max-width:56rem | sm md lg xl |
.max-w-full | max-width:100% | sm md lg xl |
.max-w-none | max-width:none | sm md lg xl |
.max-w-xs | max-width:20rem | - |
.max-w-sm | max-width:24rem | - |
.max-w-3xl | max-width:48rem | - |
.max-w-5xl | max-width:64rem | - |
.max-w-6xl | max-width:72rem | - |
.max-w-7xl | max-width:80rem | - |
.max-w-prose | max-width:65ch | - |
.max-h-full | max-height:100% | - |
.max-h-screen | max-height:100vh; max-height:100dvh | - |
.size-4 | width:calc(var(--sh-space)*4); height:calc(var(--sh-space)*4) | - |
.size-5 | width:calc(var(--sh-space)*5); height:calc(var(--sh-space)*5) | - |
.size-6 | width:calc(var(--sh-space)*6); height:calc(var(--sh-space)*6) | - |
.size-8 | width:calc(var(--sh-space)*8); height:calc(var(--sh-space)*8) | - |
.size-10 | width:calc(var(--sh-space)*10); height:calc(var(--sh-space)*10) | - |
.size-12 | width:calc(var(--sh-space)*12); height:calc(var(--sh-space)*12) | - |
.size-full | width:100%; height:100% | - |
typography
Shine — typography utilities (66 rules)
| Class | CSS | Variants |
|---|---|---|
.font-sans | font-family: var(--sh-font-sans) | - |
.font-serif | font-family: var(--sh-font-serif) | - |
.font-mono | font-family: var(--sh-font-mono) | - |
.font-heading | font-family: var(--sh-font-heading, var(--sh-font-sans)) | - |
.text-xs | font-size: .75rem; line-height: 1rem | sm md lg xl |
.text-sm | font-size: .875rem; line-height: 1.25rem | sm md lg xl |
.text-base | font-size: 1rem; line-height: 1.5rem | sm md lg xl |
.text-lg | font-size: 1.125rem; line-height: 1.75rem | sm md lg xl |
.text-xl | font-size: 1.25rem; line-height: 1.75rem | sm md lg xl |
.text-2xl | font-size: 1.5rem; line-height: 2rem | sm md lg xl |
.text-3xl | font-size: 1.875rem; line-height: 2.25rem | sm md lg xl |
.text-4xl | font-size: 2.25rem; line-height: 2.5rem | sm md lg xl |
.text-5xl | font-size: 3rem; line-height: 1 | sm md lg xl |
.text-6xl | font-size: 3.75rem; line-height: 1 | - |
.font-thin | font-weight: 100 | - |
.font-light | font-weight: 300 | - |
.font-normal | font-weight: 400 | - |
.font-medium | font-weight: 500 | - |
.font-semibold | font-weight: 600 | - |
.font-bold | font-weight: 700 | - |
.font-extrabold | font-weight: 800 | - |
.font-black | font-weight: 900 | - |
.italic | font-style: italic | - |
.not-italic | font-style: normal | - |
.text-left | text-align: left | sm md lg xl |
.text-center | text-align: center | sm md lg xl |
.text-right | text-align: right | sm md lg xl |
.text-justify | text-align: justify | - |
.leading-none | line-height: 1 | - |
.leading-tight | line-height: 1.25 | - |
.leading-snug | line-height: 1.375 | - |
.leading-normal | line-height: 1.5 | - |
.leading-relaxed | line-height: 1.625 | - |
.leading-loose | line-height: 2 | - |
.tracking-tight | letter-spacing: -.025em | - |
.tracking-normal | letter-spacing: 0 | - |
.tracking-wide | letter-spacing: .025em | - |
.tracking-wider | letter-spacing: .05em | - |
.uppercase | text-transform: uppercase | - |
.lowercase | text-transform: lowercase | - |
.capitalize | text-transform: capitalize | - |
.normal-case | text-transform: none | - |
.underline | text-decoration-line: underline | hover |
.no-underline | text-decoration-line: none | hover |
.line-through | text-decoration-line: line-through | - |
.underline-offset-2 | text-underline-offset: 2px | - |
.underline-offset-4 | text-underline-offset: 4px | - |
.truncate | overflow: hidden; text-overflow: ellipsis; white-space: nowrap | - |
.line-clamp-1 | display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1; line-clamp: 1; overflow: hidden | - |
.line-clamp-2 | display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden | - |
.line-clamp-3 | display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3; overflow: hidden | - |
.whitespace-nowrap | white-space: nowrap | - |
.whitespace-normal | white-space: normal | - |
.whitespace-pre | white-space: pre | - |
.whitespace-pre-wrap | white-space: pre-wrap | - |
.break-words | overflow-wrap: break-word | - |
.break-all | word-break: break-all | - |
.text-balance | text-wrap: balance | - |
.text-pretty | text-wrap: pretty | - |
.text-wrap | text-wrap: wrap | - |
.text-nowrap | text-wrap: nowrap | - |
.tabular-nums | font-variant-numeric: tabular-nums | - |
.list-disc | list-style-type: disc | - |
.list-decimal | list-style-type: decimal | - |
.list-none | list-style-type: none | - |
.list-inside | list-style-position: inside | - |
color
Shine — color utilities (semantic + gray). Opacity: .bg-o-50 etc. set --sh-*-o (112 rules)
| Class | CSS | Variants |
|---|---|---|
.bg-primary | background-color: color-mix(in oklab, var(--sh-primary) var(--sh-bg-o), transparent) | hover |
.bg-secondary | background-color: color-mix(in oklab, var(--sh-secondary) var(--sh-bg-o), transparent) | hover |
.bg-accent | background-color: color-mix(in oklab, var(--sh-accent) var(--sh-bg-o), transparent) | hover |
.bg-success | background-color: color-mix(in oklab, var(--sh-success) var(--sh-bg-o), transparent) | hover |
.bg-warning | background-color: color-mix(in oklab, var(--sh-warning) var(--sh-bg-o), transparent) | hover |
.bg-danger | background-color: color-mix(in oklab, var(--sh-danger) var(--sh-bg-o), transparent) | hover |
.bg-info | background-color: color-mix(in oklab, var(--sh-info) var(--sh-bg-o), transparent) | hover |
.bg-surface-2 | background-color: color-mix(in oklab, var(--sh-surface-2) var(--sh-bg-o), transparent) | hover |
.bg-base | background-color: color-mix(in oklab, var(--sh-bg) var(--sh-bg-o), transparent) | - |
.bg-surface | background-color: color-mix(in oklab, var(--sh-surface) var(--sh-bg-o), transparent) | - |
.bg-white | background-color: color-mix(in oklab, #fff var(--sh-bg-o), transparent) | - |
.bg-black | background-color: color-mix(in oklab, #000 var(--sh-bg-o), transparent) | - |
.bg-gray-50 | background-color: color-mix(in oklab, #f8fafc var(--sh-bg-o), transparent) | - |
.bg-gray-100 | background-color: color-mix(in oklab, #f1f5f9 var(--sh-bg-o), transparent) | - |
.bg-gray-200 | background-color: color-mix(in oklab, #e2e8f0 var(--sh-bg-o), transparent) | - |
.bg-gray-300 | background-color: color-mix(in oklab, #cbd5e1 var(--sh-bg-o), transparent) | - |
.bg-gray-400 | background-color: color-mix(in oklab, #94a3b8 var(--sh-bg-o), transparent) | - |
.bg-gray-500 | background-color: color-mix(in oklab, #64748b var(--sh-bg-o), transparent) | - |
.bg-gray-600 | background-color: color-mix(in oklab, #475569 var(--sh-bg-o), transparent) | - |
.bg-gray-700 | background-color: color-mix(in oklab, #334155 var(--sh-bg-o), transparent) | - |
.bg-gray-800 | background-color: color-mix(in oklab, #1e293b var(--sh-bg-o), transparent) | - |
.bg-gray-900 | background-color: color-mix(in oklab, #0f172a var(--sh-bg-o), transparent) | - |
.bg-gray-950 | background-color: color-mix(in oklab, #020617 var(--sh-bg-o), transparent) | - |
.bg-transparent | background-color: transparent | - |
.bg-current | background-color: currentColor | - |
.bg-primary-soft | background-color: color-mix(in oklab, var(--sh-primary) 15%, transparent) | - |
.bg-secondary-soft | background-color: color-mix(in oklab, var(--sh-secondary) 15%, transparent) | - |
.bg-accent-soft | background-color: color-mix(in oklab, var(--sh-accent) 15%, transparent) | - |
.bg-success-soft | background-color: color-mix(in oklab, var(--sh-success) 15%, transparent) | - |
.bg-warning-soft | background-color: color-mix(in oklab, var(--sh-warning) 15%, transparent) | - |
.bg-danger-soft | background-color: color-mix(in oklab, var(--sh-danger) 15%, transparent) | - |
.bg-info-soft | background-color: color-mix(in oklab, var(--sh-info) 15%, transparent) | - |
.text-primary | color: color-mix(in oklab, color-mix(in oklab, var(--sh-primary) var(--sh-brand-text, 100%), var(--sh-text)) var(--sh-text-o), transparent) | hover |
.text-secondary | color: color-mix(in oklab, color-mix(in oklab, var(--sh-secondary) var(--sh-brand-text, 100%), var(--sh-text)) var(--sh-text-o), transparent) | hover |
.text-accent | color: color-mix(in oklab, color-mix(in oklab, var(--sh-accent) var(--sh-brand-text, 100%), var(--sh-text)) var(--sh-text-o), transparent) | hover |
.text-success | color: color-mix(in oklab, color-mix(in oklab, var(--sh-success) var(--sh-brand-text, 100%), var(--sh-text)) var(--sh-text-o), transparent) | hover |
.text-warning | color: color-mix(in oklab, color-mix(in oklab, var(--sh-warning) var(--sh-brand-text, 100%), var(--sh-text)) var(--sh-text-o), transparent) | hover |
.text-danger | color: color-mix(in oklab, color-mix(in oklab, var(--sh-danger) var(--sh-brand-text, 100%), var(--sh-text)) var(--sh-text-o), transparent) | hover |
.text-info | color: color-mix(in oklab, color-mix(in oklab, var(--sh-info) var(--sh-brand-text, 100%), var(--sh-text)) var(--sh-text-o), transparent) | hover |
.text-default | color: color-mix(in oklab, var(--sh-text) var(--sh-text-o), transparent) | - |
.text-muted | color: color-mix(in oklab, var(--sh-text-muted) var(--sh-text-o), transparent) | - |
.text-white | color: color-mix(in oklab, #fff var(--sh-text-o), transparent) | - |
.text-black | color: color-mix(in oklab, #000 var(--sh-text-o), transparent) | - |
.text-gray-50 | color: color-mix(in oklab, #f8fafc var(--sh-text-o), transparent) | - |
.text-gray-100 | color: color-mix(in oklab, #f1f5f9 var(--sh-text-o), transparent) | - |
.text-gray-200 | color: color-mix(in oklab, #e2e8f0 var(--sh-text-o), transparent) | - |
.text-gray-300 | color: color-mix(in oklab, #cbd5e1 var(--sh-text-o), transparent) | - |
.text-gray-400 | color: color-mix(in oklab, #94a3b8 var(--sh-text-o), transparent) | - |
.text-gray-500 | color: color-mix(in oklab, #64748b var(--sh-text-o), transparent) | - |
.text-gray-600 | color: color-mix(in oklab, #475569 var(--sh-text-o), transparent) | - |
.text-gray-700 | color: color-mix(in oklab, #334155 var(--sh-text-o), transparent) | - |
.text-gray-800 | color: color-mix(in oklab, #1e293b var(--sh-text-o), transparent) | - |
.text-gray-900 | color: color-mix(in oklab, #0f172a var(--sh-text-o), transparent) | - |
.text-gray-950 | color: color-mix(in oklab, #020617 var(--sh-text-o), transparent) | - |
.text-transparent | color: transparent | - |
.text-current | color: currentColor | - |
.text-on-primary | color: var(--sh-on-primary) | - |
.text-on-secondary | color: var(--sh-on-secondary) | - |
.text-on-accent | color: var(--sh-on-accent) | - |
.text-on-success | color: var(--sh-on-success) | - |
.text-on-warning | color: var(--sh-on-warning) | - |
.text-on-danger | color: var(--sh-on-danger) | - |
.text-on-info | color: var(--sh-on-info) | - |
.bg-o-0 | --sh-bg-o: 0% | - |
.bg-o-5 | --sh-bg-o: 5% | - |
.bg-o-10 | --sh-bg-o: 10% | - |
.bg-o-20 | --sh-bg-o: 20% | - |
.bg-o-25 | --sh-bg-o: 25% | - |
.bg-o-30 | --sh-bg-o: 30% | - |
.bg-o-40 | --sh-bg-o: 40% | - |
.bg-o-50 | --sh-bg-o: 50% | - |
.bg-o-60 | --sh-bg-o: 60% | - |
.bg-o-70 | --sh-bg-o: 70% | - |
.bg-o-75 | --sh-bg-o: 75% | - |
.bg-o-80 | --sh-bg-o: 80% | - |
.bg-o-90 | --sh-bg-o: 90% | - |
.bg-o-95 | --sh-bg-o: 95% | - |
.bg-o-100 | --sh-bg-o: 100% | - |
.text-o-50 | --sh-text-o: 50% | - |
.text-o-60 | --sh-text-o: 60% | - |
.text-o-70 | --sh-text-o: 70% | - |
.text-o-75 | --sh-text-o: 75% | - |
.text-o-80 | --sh-text-o: 80% | - |
.text-o-90 | --sh-text-o: 90% | - |
| border colors | ||
.border-primary | border-color: color-mix(in oklab, var(--sh-primary) var(--sh-border-o), transparent) | - |
.border-secondary | border-color: color-mix(in oklab, var(--sh-secondary) var(--sh-border-o), transparent) | - |
.border-accent | border-color: color-mix(in oklab, var(--sh-accent) var(--sh-border-o), transparent) | - |
.border-success | border-color: color-mix(in oklab, var(--sh-success) var(--sh-border-o), transparent) | - |
.border-warning | border-color: color-mix(in oklab, var(--sh-warning) var(--sh-border-o), transparent) | - |
.border-danger | border-color: color-mix(in oklab, var(--sh-danger) var(--sh-border-o), transparent) | - |
.border-info | border-color: color-mix(in oklab, var(--sh-info) var(--sh-border-o), transparent) | - |
.border-default | border-color: color-mix(in oklab, var(--sh-border) var(--sh-border-o), transparent) | - |
.border-gray-100 | border-color: color-mix(in oklab, #f1f5f9 var(--sh-border-o), transparent) | - |
.border-gray-200 | border-color: color-mix(in oklab, #e2e8f0 var(--sh-border-o), transparent) | - |
.border-gray-300 | border-color: color-mix(in oklab, #cbd5e1 var(--sh-border-o), transparent) | - |
.border-gray-400 | border-color: color-mix(in oklab, #94a3b8 var(--sh-border-o), transparent) | - |
.border-gray-500 | border-color: color-mix(in oklab, #64748b var(--sh-border-o), transparent) | - |
.border-gray-600 | border-color: color-mix(in oklab, #475569 var(--sh-border-o), transparent) | - |
.border-gray-700 | border-color: color-mix(in oklab, #334155 var(--sh-border-o), transparent) | - |
.border-gray-800 | border-color: color-mix(in oklab, #1e293b var(--sh-border-o), transparent) | - |
.border-white | border-color: #fff | - |
.border-black | border-color: #000 | - |
.border-transparent | border-color: transparent | - |
.border-current | border-color: currentColor | - |
.border-o-50 | --sh-border-o: 50% | - |
.border-o-60 | --sh-border-o: 60% | - |
.border-o-70 | --sh-border-o: 70% | - |
.border-o-75 | --sh-border-o: 75% | - |
.border-o-80 | --sh-border-o: 80% | - |
.border-o-90 | --sh-border-o: 90% | - |
.fill-current | fill: currentColor | - |
.stroke-current | stroke: currentColor | - |
borders
Shine — borders, radius, rings. Loads after color.css: default border-color uses :where() (0 specificity) so .border-{color} always wins. (57 rules)
| Class | CSS | Variants |
|---|---|---|
.border | border-width: var(--sh-border-width); border-style: solid | sm md lg xl |
.border-0 | border-width: 0 | sm md lg xl |
.border-2 | border-width: 2px; border-style: solid | - |
.border-4 | border-width: 4px; border-style: solid | - |
.border-x | border-left-width: var(--sh-border-width); border-right-width: var(--sh-border-width); border-style: solid | - |
.border-x-0 | border-left-width: 0; border-right-width: 0 | - |
.border-y | border-top-width: var(--sh-border-width); border-bottom-width: var(--sh-border-width); border-style: solid | - |
.border-y-0 | border-top-width: 0; border-bottom-width: 0 | - |
.border-t | border-top-width: var(--sh-border-width); border-style: solid | - |
.border-t-0 | border-top-width: 0 | - |
.border-r | border-right-width: var(--sh-border-width); border-style: solid | - |
.border-r-0 | border-right-width: 0 | - |
.border-b | border-bottom-width: var(--sh-border-width); border-style: solid | - |
.border-b-0 | border-bottom-width: 0 | - |
.border-l | border-left-width: var(--sh-border-width); border-style: solid | - |
.border-l-0 | border-left-width: 0 | - |
.border-solid | border-style: solid | - |
.border-dashed | border-style: dashed | - |
.border-dotted | border-style: dotted | - |
.border-none | border-style: none | - |
.rounded-none | border-radius: 0 | - |
.rounded-sm | border-radius: calc(var(--sh-radius) * .5) | - |
.rounded | border-radius: var(--sh-radius) | - |
.rounded-md | border-radius: calc(var(--sh-radius) * 1.25) | - |
.rounded-lg | border-radius: calc(var(--sh-radius) * 1.5) | - |
.rounded-xl | border-radius: calc(var(--sh-radius) * 2) | - |
.rounded-2xl | border-radius: calc(var(--sh-radius) * 3) | - |
.rounded-full | border-radius: 9999px | - |
.rounded-t | border-top-left-radius: var(--sh-radius); border-top-right-radius: var(--sh-radius) | - |
.rounded-t-lg | border-top-left-radius: calc(var(--sh-radius) * 1.5); border-top-right-radius: calc(var(--sh-radius) * 1.5) | - |
.rounded-t-none | border-top-left-radius: 0; border-top-right-radius: 0 | - |
.rounded-r | border-top-right-radius: var(--sh-radius); border-bottom-right-radius: var(--sh-radius) | - |
.rounded-r-lg | border-top-right-radius: calc(var(--sh-radius) * 1.5); border-bottom-right-radius: calc(var(--sh-radius) * 1.5) | - |
.rounded-r-none | border-top-right-radius: 0; border-bottom-right-radius: 0 | - |
.rounded-b | border-bottom-left-radius: var(--sh-radius); border-bottom-right-radius: var(--sh-radius) | - |
.rounded-b-lg | border-bottom-left-radius: calc(var(--sh-radius) * 1.5); border-bottom-right-radius: calc(var(--sh-radius) * 1.5) | - |
.rounded-b-none | border-bottom-left-radius: 0; border-bottom-right-radius: 0 | - |
.rounded-l | border-top-left-radius: var(--sh-radius); border-bottom-left-radius: var(--sh-radius) | - |
.rounded-l-lg | border-top-left-radius: calc(var(--sh-radius) * 1.5); border-bottom-left-radius: calc(var(--sh-radius) * 1.5) | - |
.rounded-l-none | border-top-left-radius: 0; border-bottom-left-radius: 0 | - |
.divide-x > :not(:last-child) | border-right-width: var(--sh-border-width); border-style: solid | - |
.divide-y > :not(:last-child) | border-bottom-width: var(--sh-border-width); border-style: solid | - |
.divide-x-0 > :not(:last-child) | border-right-width: 0 | - |
.divide-y-0 > :not(:last-child) | border-bottom-width: 0 | - |
.ring-0 | box-shadow: 0 0 0 0 var(--sh-ring-color, color-mix(in oklab, var(--sh-tone, var(--sh-primary)) 50%, transparent)) | - |
.ring-1 | box-shadow: 0 0 0 1px var(--sh-ring-color, color-mix(in oklab, var(--sh-tone, var(--sh-primary)) 50%, transparent)) | - |
.ring | box-shadow: 0 0 0 3px var(--sh-ring-color, color-mix(in oklab, var(--sh-tone, var(--sh-primary)) 50%, transparent)) | - |
.ring-2 | box-shadow: 0 0 0 2px var(--sh-ring-color, color-mix(in oklab, var(--sh-tone, var(--sh-primary)) 50%, transparent)) | - |
.ring-4 | box-shadow: 0 0 0 4px var(--sh-ring-color, color-mix(in oklab, var(--sh-tone, var(--sh-primary)) 50%, transparent)) | - |
.ring-primary | --sh-ring-color: color-mix(in oklab, var(--sh-primary) 50%, transparent) | - |
.ring-secondary | --sh-ring-color: color-mix(in oklab, var(--sh-secondary) 50%, transparent) | - |
.ring-accent | --sh-ring-color: color-mix(in oklab, var(--sh-accent) 50%, transparent) | - |
.ring-success | --sh-ring-color: color-mix(in oklab, var(--sh-success) 50%, transparent) | - |
.ring-warning | --sh-ring-color: color-mix(in oklab, var(--sh-warning) 50%, transparent) | - |
.ring-danger | --sh-ring-color: color-mix(in oklab, var(--sh-danger) 50%, transparent) | - |
.ring-info | --sh-ring-color: color-mix(in oklab, var(--sh-info) 50%, transparent) | - |
.outline-none | outline: 2px solid transparent; outline-offset: 2px | - |
effects
Shine — minimal effects (shadows, opacity, backdrop blur) (28 rules)
| Class | CSS | Variants |
|---|---|---|
.shadow-none | box-shadow: none | hover |
.shadow-sm | box-shadow: var(--sh-shadow-1) | hover |
.shadow | box-shadow: var(--sh-shadow-2) | hover |
.shadow-md | box-shadow: var(--sh-shadow-3) | hover |
.shadow-lg | box-shadow: var(--sh-shadow-4) | hover |
.shadow-xl, .shadow-2xl | box-shadow: var(--sh-shadow-5) | hover |
.shadow-tone | box-shadow: 0 8px 24px -6px color-mix(in oklab, var(--sh-tone, var(--sh-primary)) 50%, transparent) | hover |
.shadow-inner | box-shadow: inset 0 2px 4px rgb(0 0 0 / .08) | - |
.shadow-elevation | box-shadow: var(--sh-elevation, var(--sh-shadow-1)) | - |
.opacity-0 | opacity: 0 | hover |
.opacity-50 | opacity: .5 | hover |
.opacity-75 | opacity: .75 | hover |
.opacity-100 | opacity: 1 | hover |
.opacity-5 | opacity: .05 | - |
.opacity-10 | opacity: .1 | - |
.opacity-20 | opacity: .2 | - |
.opacity-25 | opacity: .25 | - |
.opacity-80 | opacity: .8 | - |
.opacity-90 | opacity: .9 | - |
.opacity-95 | opacity: .95 | - |
| Backdrop filters: blur and saturate combine (frosted glass) | ||
:where(.backdrop-blur-none, .backdrop-blur-sm, .backdrop-blur, .backdrop-blur-md, .backdrop-blur-lg, .backdrop-blur-xl, .backdrop-saturate-150) | backdrop-filter: blur(var(--sh-bd-blur, 0)) saturate(var(--sh-bd-sat, 1)) | - |
.backdrop-blur-none | --sh-bd-blur: 0 | - |
.backdrop-blur-sm | --sh-bd-blur: 4px | - |
.backdrop-blur | --sh-bd-blur: 8px | - |
.backdrop-blur-md | --sh-bd-blur: 12px | - |
.backdrop-blur-lg | --sh-bd-blur: 16px | - |
.backdrop-blur-xl | --sh-bd-blur: 24px | - |
.backdrop-saturate-150 | --sh-bd-sat: 1.5 | - |
interactivity
Shine — interactivity & transitions (38 rules)
| Class | CSS | Variants |
|---|---|---|
.cursor-pointer | cursor: pointer | - |
.cursor-default | cursor: default | - |
.cursor-not-allowed | cursor: not-allowed | - |
.cursor-wait | cursor: wait | - |
.cursor-text | cursor: text | - |
.cursor-move | cursor: move | - |
.cursor-grab | cursor: grab | - |
.pointer-events-none | pointer-events: none | - |
.pointer-events-auto | pointer-events: auto | - |
.select-none | user-select: none | - |
.select-text | user-select: text | - |
.select-all | user-select: all | - |
.select-auto | user-select: auto | - |
.resize | resize: both | - |
.resize-none | resize: none | - |
.resize-x | resize: horizontal | - |
.resize-y | resize: vertical | - |
.scroll-smooth | scroll-behavior: smooth | - |
.snap-x | scroll-snap-type: x mandatory | - |
.snap-y | scroll-snap-type: y mandatory | - |
.snap-start | scroll-snap-align: start | - |
.snap-center | scroll-snap-align: center | - |
.appearance-none | appearance: none | - |
.touch-none | touch-action: none | - |
.touch-manipulation | touch-action: manipulation | - |
.transition | transition-property: color, background-color, border-color, opacity, box-shadow, transform; transition-timing-function: var(--sh-ease); transition-duration: var(--sh-duration) | - |
.transition-colors | transition-property: color, background-color, border-color; transition-timing-function: var(--sh-ease); transition-duration: var(--sh-duration) | - |
.transition-opacity | transition-property: opacity; transition-timing-function: var(--sh-ease); transition-duration: var(--sh-duration) | - |
.transition-none | transition-property: none | - |
.duration-75 | transition-duration: 75ms | - |
.duration-150 | transition-duration: 150ms | - |
.duration-200 | transition-duration: 200ms | - |
.duration-300 | transition-duration: 300ms | - |
.duration-500 | transition-duration: 500ms | - |
.ease-linear | transition-timing-function: linear | - |
.ease-in | transition-timing-function: cubic-bezier(.4, 0, 1, 1) | - |
.ease-out | transition-timing-function: cubic-bezier(0, 0, .2, 1) | - |
.ease-in-out | transition-timing-function: cubic-bezier(.4, 0, .2, 1) | - |
extras
Extras: centering/position helpers, translate, object/overflow/overscroll, container queries (64 rules)
| Class | CSS | Variants |
|---|---|---|
.top-1/2 | top:50% | - |
.left-1/2 | left:50% | - |
.right-1/2 | right:50% | - |
.bottom-1/2 | bottom:50% | - |
.top-full | top:100% | - |
.left-full | left:100% | - |
.right-full | right:100% | - |
.bottom-full | bottom:100% | - |
.inset-2 | inset:calc(var(--sh-space)*2) | - |
.inset-4 | inset:calc(var(--sh-space)*4) | - |
.-translate-x-1/2 | translate:-50% 0 | - |
.-translate-y-1/2 | translate:0 -50% | - |
.-translate-1/2 | translate:-50% -50% | - |
.object-center | object-position:center | - |
.object-top | object-position:top | - |
.overflow-clip | overflow:clip | - |
.overscroll-contain | overscroll-behavior:contain | - |
.cq | container-type:inline-size | - |
| Tables | ||
.table-auto | table-layout:auto | - |
.table-fixed | table-layout:fixed | - |
.border-collapse | border-collapse:collapse | - |
.border-separate | border-collapse:separate | - |
.caption-top | caption-side:top | - |
.caption-bottom | caption-side:bottom | - |
| Logical / RTL-aware spacing and edges | ||
.ps-0 | padding-inline-start:0 | - |
.ps-2 | padding-inline-start:calc(var(--sh-space)*2) | - |
.ps-4 | padding-inline-start:calc(var(--sh-space)*4) | - |
.pe-0 | padding-inline-end:0 | - |
.pe-2 | padding-inline-end:calc(var(--sh-space)*2) | - |
.pe-4 | padding-inline-end:calc(var(--sh-space)*4) | - |
.ms-auto | margin-inline-start:auto | - |
.ms-2 | margin-inline-start:calc(var(--sh-space)*2) | - |
.ms-4 | margin-inline-start:calc(var(--sh-space)*4) | - |
.me-auto | margin-inline-end:auto | - |
.me-2 | margin-inline-end:calc(var(--sh-space)*2) | - |
.me-4 | margin-inline-end:calc(var(--sh-space)*4) | - |
.start-0 | inset-inline-start:0 | - |
.end-0 | inset-inline-end:0 | - |
.text-start | text-align:start | - |
.text-end | text-align:end | - |
.border-s | border-inline-start-width:var(--sh-border-width) | - |
.border-e | border-inline-end-width:var(--sh-border-width) | - |
.rounded-s | border-start-start-radius:var(--sh-radius); border-end-start-radius:var(--sh-radius) | - |
.rounded-e | border-start-end-radius:var(--sh-radius); border-end-end-radius:var(--sh-radius) | - |
| Background images | ||
.bg-cover | background-size:cover | - |
.bg-contain | background-size:contain | - |
.bg-center | background-position:center | - |
.bg-top | background-position:top | - |
.bg-bottom | background-position:bottom | - |
.bg-no-repeat | background-repeat:no-repeat | - |
.bg-fixed | background-attachment:fixed | - |
| Floats | ||
.float-left | float:left | - |
.float-right | float:right | - |
.float-none | float:none | - |
.clear-both | clear:both | - |
| Text and flow | ||
.antialiased | -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale | - |
.hyphens-auto | hyphens:auto | - |
.text-ellipsis | text-overflow:ellipsis | - |
.break-inside-avoid | break-inside:avoid | - |
| Grid tracks, sizing, forms | ||
.auto-rows-fr | grid-auto-rows:minmax(0,1fr) | - |
.auto-cols-fr | grid-auto-columns:minmax(0,1fr) | - |
.min-w-max | min-width:max-content | - |
.min-h-svh | min-height:100svh | - |
.field-sizing-content | field-sizing:content | - |
Variants and cascade
Responsive prefixes
Mobile first. An unprefixed class applies everywhere; a prefixed class applies at that width and up. Only layout-critical utilities have them (see the Variants column above).
| Prefix | Min width | Example |
|---|---|---|
sm: | 640px and up | sm:grid-cols-3 |
md: | 768px and up | md:grid-cols-3 |
lg: | 1024px and up | lg:grid-cols-3 |
xl: | 1280px and up | xl:grid-cols-3 |
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">…</div>
Hover and focus
hover: applies on pointer hover. focus: applies on :focus-visible, so it only shows for keyboard focus. They exist on colors, opacity, shadow and underline.
<a class="text-muted hover:text-primary focus:underline" href="#">Link</a>
There is no dark: variant. Themes switch dark mode through tokens, so the same classes work in both.
Cascade layers
Shine is built with CSS @layer. Utilities beat components, components beat base, and your own unlayered CSS beats everything, with no specificity fights.
@layer shine.tokens, shine.reset, shine.base, shine.components, shine.utilities;
Opacity modifiers
Opacity is a second class, not a slash. Add bg-o-50 next to a background color (also text-o-* and border-o-*).
<div class="bg-primary bg-o-50 p-4">Half-transparent primary</div>
Differences from Tailwind
- Semantic colors.
bg-primary,text-danger,bg-primary-soft,text-muted,bg-surface, plus onegray-50togray-950scale. Add brand colors as tokens. - Opacity modifier classes (
bg-o-50) instead ofbg-primary/50. - Radius scales with
data-radius:rounded-lgis 1.5 times the global radius. - Spacing scales with
--sh-space(default .25rem):p-4is 4 units. - No arbitrary values like
w-[13px]; use inline styles or your own CSS. - No
dark:variant. Usedata-theme. - Fewer variants. Only responsive on layout, hover and focus on colors and effects.