Quick Start

npm version

Add the single bundle:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/pico-ink/css/pico.min.css">

Minimal page:

<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/pico-ink/css/pico.min.css"> </head> <body> <main class="container"> <h1>Hello world</h1> </main> </body> </html>

Theming

Set two variables on :root to customize everything:

:root { --pico-primary: #0172ad; --pico-secondary: #646e82; }

All colors (hover states, backgrounds, borders) derive automatically via color-mix().

Available Variables

VariablePurpose
--pico-primaryBrand/accent color
--pico-secondaryNeutral (text, borders)
--pico-border-radiusCorner rounding (default: 0.25rem)
--pico-shadowBox shadow (set to none to disable)

Buttons

<button>Primary</button> <button class="secondary">Secondary</button> <button class="contrast">Contrast</button> <button class="outline">Outline</button> <button class="secondary outline">Secondary</button> <button class="contrast outline">Contrast</button>

Forms

Checkboxes
Switches
Radios

Cards

Card Title

Card content goes here.

<article> <header>Card Title</header> <p>Card content goes here.</p> <footer> <button>Save</button> <button class="secondary">Cancel</button> </footer> </article>

Tables

NameEmailStatus
Alicealice@example.comActive
Bobbob@example.comInactive

Tags & Badges

Default Primary Secondary Contrast
Success Warning Error

Progress

70% Indeterminate

Accordion

Open section

Visible content here.

Closed section

Hidden content revealed on click.

Light/Dark Mode

Automatic: Colors switch based on system preference. Works out of the box.

Force globally:

:root { color-scheme: light; } /* or dark */

Invert sections:

<nav class="pico-dark">...</nav> <article class="pico-light">...</article>

Accessibility

Pico Ink provides built-in accessibility utilities and patterns.

Skip Link

Allow keyboard users to skip navigation:

<a href="#main" class="skip-link">Skip to content</a> <nav>...</nav> <main id="main">...</main>

Screen Reader Only

Hide content visually but keep it accessible to screen readers:

<button> <span class="icon icon-search" aria-hidden="true"></span> <span class="sr-only">Search</span> </button>

Reduced Motion

Animations are automatically disabled for users who prefer reduced motion.

High Contrast Mode

Colors adapt for users who need higher contrast.

Icons

Icons inherit text color and size (1em). Add aria-hidden="true" for decorative icons:

<button><span class="icon icon-plus" aria-hidden="true"></span> Add</button> <a href="#">Continue <span class="icon icon-arrow-right" aria-hidden="true"></span></a>

Available Icons

Navigation: arrow-right, arrow-left, arrow-up, arrow-down, chevron-right, chevron-left, chevron-up, chevron-down

Actions: plus, minus, x, check, edit, trash

UI: menu, more, search, filter

Status: info, warning, error, success

Common: user, settings, home, external, sun, moon, system

Layout

Use inline CSS for grids (no utility classes):

<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem"> <div>1</div> <div>2</div> <div>3</div> </div>

Responsive:

<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem"> ... </div>

MapLibre GL

Isolate third-party widgets with data-no-pico:

<div id="map" data-no-pico style="color-scheme: light; background: white"></div>

Apache ECharts

Charts also use data-no-pico for isolation:

<div id="chart" data-no-pico style="color-scheme: light; background: white"></div>

Escape Hatch

For any third-party widget, isolate from Pico styles:

<div data-no-pico style="color-scheme: light; background: white"> <!-- Your widget here --> </div>

Browser Support

FeatureChromeFirefoxSafari
light-dark()123+120+17.2+
CSS nesting120+117+17.2+
Cascade layers99+97+15.4+