Density

Three density modes — compact, normal, and comfortable — let product teams tune information density to their context. A single data attribute on the root element rewires all spacing and height tokens simultaneously.

Modes

data-density="compact"

Compact

Data-dense UIs: admin dashboards, data grids, developer tools. Maximum information per screen with reduced padding and smaller controls.

data-density="normal"

Normal

The default. Balances readability and density for general-purpose product UIs. This is what all Sitka components render at out of the box.

data-density="comfortable"

Comfortable

Consumer apps, onboarding flows, marketing pages. More breathing room for non-expert audiences or touch-primary interfaces.

Token scale

All eight density tokens are CSS custom properties set on :root (normal defaults) and overridden by the data-density attribute.

TokenCompactNormalComfortableUse
--density-space-xs2px4px6pxIcon gaps, chip insets
--density-space-sm6px8px12pxInline element gaps
--density-space-md8px12px16pxComponent padding
--density-space-lg12px16px20pxRow padding, card insets
--density-space-xl16px24px32pxSection separation
--density-h-sm24px28px32pxSmall control height
--density-h-md30px36px40pxDefault control height
--density-h-lg36px44px48pxLarge control height

Component impact

ComponentCompactNormalComfortable
Button (md)30px height36px height40px height
Input30px height36px height40px height
Table row12px v-padding16px v-padding20px v-padding
List item6px v-padding8px v-padding12px v-padding
Card12px padding16px padding20px padding
Sidebar item6px v-padding8px v-padding12px v-padding

Usage

HTML — attribute
<!-- Apply to <html> to affect the whole app -->
<html data-density="compact">

<!-- Or scope to a subtree -->
<div data-density="comfortable">
  <YourDataTable />
</div>
React — DensityProvider
"use client";
import { createContext, useContext, useEffect } from "react";

type Density = "compact" | "normal" | "comfortable";

const DensityCtx = createContext<Density>("normal");

export function DensityProvider({
  density = "normal",
  children,
}: {
  density?: Density;
  children: React.ReactNode;
}) {
  useEffect(() => {
    document.documentElement.dataset.density =
      density === "normal" ? "" : density;
  }, [density]);

  return (
    <DensityCtx.Provider value={density}>
      {children}
    </DensityCtx.Provider>
  );
}

export const useDensity = () => useContext(DensityCtx);

Authoring density-aware components

CSS — referencing density tokens
.my-row {
  padding-block: var(--density-space-md);
  padding-inline: var(--density-space-lg);
  min-height: var(--density-h-md);
  gap: var(--density-space-sm);
}

Reference density tokens instead of hardcoded values. When the density attribute changes, every consuming component reflows automatically with no JavaScript required.

Guidelines

  • Choose one density mode per product surface — mixing modes within a single view creates visual inconsistency.
  • Compact mode is appropriate for power-user tooling (data grids, admin panels, developer dashboards).
  • Comfortable mode suits consumer onboarding, marketing microsites, and touch-primary mobile contexts.
  • Normal is the default for general-purpose SaaS product UI — most Sitka components are sized for this mode.
  • When in doubt, ship normal and add a user preference toggle later. Density changes are additive and non-breaking.