Components

The Grid

Structural backbone: a .columns parent with only direct .column children. Put shared rhythm (counts, gaps, padding, surfaces) on the parent; keep cells for content. Add a single wckd-* root on that same parent when you opt into carousel, tabs, accordion, or filtering so wckd-ui.js sees a stable DOM.

Download & setup

Start with the package download and setup steps in Get Started, then use the style guide for utility and token references while implementing this component.

Default implementation

The grid contract

Minimum viable grid: .columns sets the track model (count-*), .column elements are the only direct grid children, and parent utilities (gap, padded, filled, rounded) apply shared chrome in one place.

Column

Direct child of .columns.

Column

Same contract everywhere.

Column

Change count-* on the parent only.

Markup

<div class="columns count-3 gap padded filled rounded">
  <div class="column">…</div>
  <div class="column">…</div>
  <div class="column">…</div>
</div>

Configuration options

Each block below is a standalone recipe. Pick the knobs that match your intent (density, gutters, height, spanning, surfaces), then add a wckd-* root on the same .columns element when interactivity is required.

Track density (count-*)

Use count-2count-6 (and related utilities from the style guide) on .columns to change how many tracks you get at a given breakpoint. Children stay .column; never insert anonymous wrappers between the parent and columns if a wckd-* module expects column children.

count-2

A
B

count-6

1
2
3
4
5
6

Markup

<div class="columns count-2 gap padded-s filled rounded text-center">…</div>
<div class="columns count-6 gap-s padded-s filled-light rounded text-center text-xs">…</div>

Gutters (gap, gap-*)

gap and gap-xs / gap-s / gap-m / gap-l control rhythm between columns. Tighten for dense dashboards; loosen for editorial hero rows.

Tight (gap-xs)

a
b
c

Comfortable (gap-l)

A
B
C

Markup

<div class="columns count-3 gap-xs padded filled-fade rounded">…</div>
<div class="columns count-3 gap-l padded-s filled-fade rounded text-center">…</div>

Equal-height columns (match-height)

Add match-height on .columns when cards or columns should stretch to the tallest sibling, common for pricing rows, feature tiles, or any row where uneven copy would break the visual baseline.

Short

Taller

Extra lines make this column taller without breaking the row rhythm when match-height is on the parent.

Medium

Still stretches.

Markup

<div class="columns count-3 gap match-height padded-s filled-light rounded">…</div>

Spanning tracks (span-*)

Use span-2 (and responsive variants like desktop-span-2 where documented) on a .column to widen one cell across multiple tracks, hero + sidebar, wide chart + meta column, etc.

Wide cell

span-2 across two tracks in a count-3 row.

Sidebar

Single track.

Full row item
Full row item
Full row item

Markup

<div class="columns count-3 gap padded-s filled rounded">
  <div class="column span-2">…</div>
  <div class="column">…</div>
</div>

Parent-level vs child-level utilities

Preferred: put padded-*, filled-*, rounded*, borders*, shadows on .columns when every child should share the same card chrome. Exception: use pad-*, fill-*, round* on individual .column cells when you deliberately need mixed surfaces (status lanes, contrast tiles, callouts).

Parent-level (preferred)

Same surface A
Same surface B
Same surface C

Child-level (intentional mix)

Light
Fade
Dark

Markup

<!-- Parent-level: chrome on .columns -->
<div class="columns count-3 gap padded filled-fade rounded">
  <div class="column">Same surface A</div>
  <div class="column">Same surface B</div>
  <div class="column">Same surface C</div>
</div>

<!-- Child-level (intentional mix): chrome on each .column -->
<div class="columns count-3 gap-s rounded">
  <div class="column pad-s fill-light border">Light</div>
  <div class="column pad-s fill-fade">Fade</div>
  <div class="column pad-s fill-dark">Dark</div>
</div>

Page rhythm (margin-* on wrappers)

Keep .columns focused on internal grid logic. Use outer wrappers (section, div) with margin-bottom-* / margin-top-* for vertical rhythm between sections so spacing stays predictable when grids stack on small viewports.

Section A (wrapper carries margin)

1
2
3

Section B

Left
Right

Markup

<section class="margin-bottom-xl">
  <div class="columns count-3 gap padded-s filled rounded">…</div>
</section>

Static grid → interactive carousel

Same markup shape as the carousel page: .wckd-carousel on the .columns parent; each slide is a .column. Needs wckd-ui.js (see Get Started). You can leave the class off while you check layout, then add it when you want arrows and dots. Arrows and dots are on by default; add hide-arrows / hide-dots, or hide-nav for both.

Static

A
B
C

Interactive (wckd-carousel)

Markup

<!-- static -->
<div class="columns count-1 gap padded-s filled-fade rounded">…</div>

<!-- interactive: add wckd-carousel on the same parent -->
<div class="wckd-carousel columns count-1 gap padded-s filled-fade rounded">…</div>

Accordion shell (wckd-accordion)

Each .column is one accordion row: button.accordion-toggle plus .accordion-content. Optional data-show-filter / data-show-expand-all on the parent add toolbar behaviour. Requires wckd-ui.js.

A .columns parent with direct .column children, shared utilities on the parent, semantics inside each cell.

Interactive modules query column children; changing wrappers breaks initialisers and keyboard flows.

Markup

<div class="wckd-accordion columns count-1 gap-s">
  <div class="column">
    <button type="button" class="accordion-toggle">Question</button>
    <div class="accordion-content">…</div>
  </div>
</div>

Tabs on the grid (wckd-tabs)

Each .column holds one tab: .tabs-toggle + .tabs-content. Mark the default panel with .column.active. The grid classes (columns, count-*, spacing) stay on the same element as .wckd-tabs. Requires wckd-ui.js.

High-level summary for this tab.

Copy the structure from each variation block.

Pair with Get Started for package + bootstrap wiring.

Markup

<div class="wckd-tabs columns count-1 accordion background-color">
  <div class="column active">
    <button type="button" class="tabs-toggle">Overview</button>
    <div class="tabs-content pad">…</div>
  </div>
  <div class="column">…</div>
</div>

Filterable list shell (wckd-list-filter)

Wrap .columns (or a ul.columns list) in .wckd-list-filter, add input.wckd-filter, and mark the list with .filterable. Each filterable item remains a .column (or li.column). Requires wckd-ui.js.

  • Billing
  • Identity
  • Analytics
  • Security
  • Support
  • Integrations

Markup

<div class="wckd-list-filter">
  <input class="wckd-filter" type="search" placeholder="Filter…" />
  <ul class="columns count-3 gap no-bullets filterable">
    <li class="column">…</li>
  </ul>
</div>

When to use

  • Every page section: marketing bands, app settings rows, docs layouts, and dashboard tiles.
  • Progressive handoff: ship static HTML first for layout sign-off, then add a single wckd-* class for behaviour without restructuring the Grid.
  • Cross-team alignment: design and engineering share one vocabulary: count-*, gap-*, parent surfaces, optional wckd-* roots.

Implementation notes

  • Treat .columns plus direct .column children as a DOM contract: many wckd-* initialisers walk immediate column children; extra wrapper divs between parent and .column can break measurements and focus management.
  • Put shared chrome on the parent (padded-*, filled-*, rounded*, borders*) so you do not repeat the same utility stack on every child.
  • When something does not carousel, tab, or accordion, validate root class and column shape before debugging JavaScript, most issues are markup drift.
  • For carousels and sliders, avoid arbitrary margin on direct .column children; keep width math predictable for scroll-snap and track sizing.
  • Use semantic elements inside cells (article, section, headings) freely, only the columns-to-column edge is constrained.

Developer checklist

  • Parent is always .columns; direct children are always .column (or li.column when the columns container is a ul or ol).
  • Load wckd-ui.css for grid utilities; load wckd-ui-components.css and wckd-ui.js when any variation uses wckd-* roots.
  • After adding a wckd-* class, re-test keyboard focus, reduced motion (if applicable), and a narrow viewport where columns stack.
  • Keep one interactive wckd-* root per .columns element; compose multiple Grids as siblings rather than nesting conflicting wckd-* parents unless a component explicitly documents nesting.

← All components