Installation

Drop a single CSS file into your project. No build step, no JavaScript, no dependencies. grit.css weighs in under 10KB gzipped and has zero external dependencies — just download grit.css and link it in your <head>.

Usage

Link the stylesheet and start writing semantic HTML. Headings, paragraphs, links, inputs, and buttons all look polished out of the box — no classes needed. When you want more control, layer on utility classes like .btn-primary, .card, or .row gap-md. Everything composes: you can mix and match without conflicts.

Dark Mode

grit.css supports dark mode in two ways. By default, it reads your system preference via prefers-color-scheme: dark — no extra work required. If you want manual control (e.g., a toggle button), add a .dark class to <html>. You can also force light mode with .light to override a dark system preference. All components, colors, shadows, and borders adapt automatically.

Themes

Themes restyle everything inside a container by overriding grit's CSS custom properties. Apply the built-in .theme-midnight to any element and all child components — buttons, badges, cards, alerts — pick up the new colors automatically. Create your own themes by overriding properties like --grit-primary, --grit-bg, and --grit-surface. You can nest themes, scope them to a single card, or apply them to the whole page.

Buttons

Start with the base .btn class, then add a color variant (.btn-primary, .btn-error, etc.) and optional style modifiers. Use .btn-outline for bordered buttons, .btn-ghost for minimal text-only buttons, and .btn-pill for fully rounded edges. Size modifiers .btn-sm and .btn-lg adjust padding and font size. Add .btn-block for full-width. All buttons support disabled natively.

Cards

Cards are flexible content containers with a subtle border, rounded corners, and an optional shadow on hover. Wrap content in .card-body for padding. Use .card-title for headings and .card-actions for a button row at the bottom. Cards can also hold a top image — just place an <img> before the body and it will fill the card width with rounded top corners.

Badges

Small inline status indicators. Apply a color variant (.badge-primary, .badge-success, .badge-error, etc.) for filled badges, or add .badge-outline for a bordered style. Use .badge-lg for a slightly larger size. Badges work great inside headings, table cells, or next to avatars.

Alerts

Contextual feedback messages with a tinted background and colored left border. Use .alert-info for informational, .alert-success for confirmations, .alert-warning for cautions, and .alert-error for failures. Alerts are block-level and take the full width of their container — perfect for form validation messages, system notifications, or status banners.

Tabs

A horizontal tab bar built with .tabs as the container and .tab on each item. Mark the current tab with .tab-active — it gets an underline and bolder color. Tabs are styled buttons by default, so they work with onclick handlers or as part of a router. The active indicator is a 2px bottom border that transitions smoothly.

Toggles

iOS-style toggle switches built on native <input type="checkbox"> elements — just add the .toggle class. No JavaScript required; the switch state is backed by the real checkbox. The knob slides with a smooth transition and the track changes color when checked. Pair with a <label> for an accessible, clickable label.

Progress

Lightweight progress bars with a track-and-fill pattern. The outer .progress div provides the gray track, and the inner .progress-bar fills to whatever width you set inline. Color variants — .progress-bar-success, .progress-bar-warning, .progress-bar-error — change the fill color. Great for upload indicators, storage meters, or step-completion visuals.

Avatars

Circular image thumbnails in four sizes. The base .avatar class gives you a 2.5rem circle. Add .avatar-sm (2rem), .avatar-lg (3.5rem), or .avatar-xl (5rem) for different scales. Images are object-fit: cover, so they crop gracefully. Stack avatars in a .row gap-sm for a team member bar.

Tooltips

Pure-CSS tooltips — add a data-tooltip="Your text" attribute to any element and a tooltip appears on hover. No JavaScript, no initialization. The tooltip fades in above the element with a subtle arrow. Works on buttons, links, spans, or any inline/block element. Keep tooltip text short (one line) for best results.

Accordion

Expandable content sections built on native <details>/<summary> — zero JavaScript. Wrap multiple <details> elements in an .accordion container. Each item gets a clickable header with a rotating chevron indicator. Use the open attribute to expand an item by default. Content goes inside .accordion-body.

Tables

Clean, readable data tables. The base .table class adds consistent padding and borders. Add .table-striped for alternating row backgrounds, .table-hover for hover highlights, and .table-bordered for cell borders. Wrap in .table-responsive for horizontal scrolling on narrow screens.

Pagination

Page navigation for multi-page content. Use a .pagination <nav> with links or spans inside. Mark the current page with .active and unavailable pages with .disabled. The active page gets a filled primary-color background.

List Group

A vertical list of items with borders, perfect for settings menus, notifications, or simple navigation. Use a <ul> or <div> with the .list-group class. Items can be plain <li> elements or <a> links (which get hover highlights). Mark the current item with .active.

Chips

Compact pill-shaped labels for tags, filters, or selections. Apply the .chip class to a <span>. Chips are smaller and more rounded than badges — use them when you need inline tag-like elements that feel tappable.

Divider

A horizontal rule with an optional centered text label. Use a <div class="divider"> with text content, or leave it empty for a plain line. The text appears centered between two lines — great for "or" separators in forms or section breaks.

Skeleton

Loading placeholder shapes that shimmer while content loads. Use .skeleton-text for text lines, .skeleton-title for headings, and .skeleton-avatar for circular placeholders. The shimmer animation runs automatically. Combine multiple skeleton elements to approximate your content layout.

Spinner

Animated loading indicators. The base .spinner class creates a spinning circle. Size variants .spinner-sm and .spinner-lg scale it up or down. The spinner uses currentColor so it inherits whatever text color its parent has.

Toast

Brief notification messages that appear in the corner of the screen. Place a .toast-container (fixed to the viewport corner), then add .toast elements inside it. Color variants — .toast-success, .toast-error, .toast-warning, .toast-info — add a colored left border. Add .toast-out to animate dismissal. Requires a small JS snippet to manage show/hide timing.

Prose

Typographic styling for long-form content like blog posts, articles, or documentation. Wrap your content in a .prose container and headings, paragraphs, lists, blockquotes, code blocks, and links all get comfortable reading styles with proper spacing and line heights. No extra classes needed on the inner elements.

Inputs

Text inputs, selects, and textareas are styled globally — no classes needed. Every input gets consistent padding, border radius, and a colored focus ring that matches --grit-primary. Pair each input with a <label> for accessibility and wrap the pair in a .col gap-xs for standard form spacing. Inputs stretch to fill their container width by default.

Input Groups

Visually attach a prefix or suffix to an input. Wrap an <input> and a .input-group-text span inside .input-group — the addon and input merge into a single bordered row. Use this for currency symbols, "@" username prefixes, search icons, or domain suffixes. The addon inherits the surface background so it's visually distinct from the input area.

Fieldset

Group related form controls with a labeled border. The native <fieldset> element gets clean styling with a subtle border and rounded corners. Use a <legend> for the group title. The .fieldset class is optional — grit styles the native elements directly.

Container

The .container class centers content and caps it at a max-width of 1200px with horizontal padding on each side. Use it as the outermost wrapper for your page content. It works at every viewport width — on mobile it's full-width with padding, on desktop it creates comfortable reading margins. Nest grids, rows, and sections inside it.

Grid

CSS Grid utilities for common column layouts. Start with .grid, then add .grid-2, .grid-3, or .grid-4 for fixed-column layouts. Use .grid-auto for a responsive auto-fit grid that wraps items into rows at 250px minimum width. All grid layouts collapse to a single column on mobile. Use .span-2, .span-3, or .span-full on children to span multiple columns.

Stack

A vertical layout helper that adds consistent spacing between child elements using the lobotomized owl selector (* + *). Apply .stack to a container and every direct child after the first gets a top margin. On mobile, the spacing tightens automatically. Great for article layouts, form sections, or any vertical flow where you want uniform spacing without gap utilities.

Flex Utilities

Flexbox helpers for common layout patterns. .row creates a horizontal flex container (items centered vertically); .col creates a vertical stack. Both accept gap utilities. Use .between for space-between, .center for centering both axes, .end for flex-end, and .wrap for wrapping. .grow makes a child fill available space. Combine freely: .row between wrap gap-md is a common pattern.

Spacing

Control the space between and inside elements with gap and padding utilities. Gap classes set the --gap custom property, which is picked up by .row, .col, and .grid containers. Padding classes add uniform padding on all sides. Both use a consistent size scale so your layouts feel cohesive.

Gap (space between children)

Add a gap class to any flex or grid container. Gap only affects the space between children — it doesn't add space on the outer edges. If no gap class is set, .row, .col, and .grid default to 0.75rem.

ClassValuePixels (at 16px base)Visual
.gap-xs0.25rem4px
.gap-sm0.5rem8px
.gap-md1rem16px
.gap-lg1.5rem24px
.gap-xl2rem32px

Padding (space inside an element)

Padding utilities add equal padding on all four sides. Use them on cards, sections, containers, or any element that needs internal breathing room.

ClassValuePixels (at 16px base)Visual
.pad-sm0.5rem8px
.pad1rem16px
.pad-lg2rem32px
.pad-xl3rem48px

Margin

.m-auto sets margin: auto — handy for centering a fixed-width element horizontally.

Common patterns

Here are the spacing combos you'll reach for most often: