@cssints/layout

Layout primitives for cssints, after Every Layout and smolcss: stack(), cluster(), sidebar(), switcher(), cover() and autoGrid(). Each one is a chain member of cssints/plugin scope(): a call gives the primitive's kernel classes, and each method sets one custom property. No runtime, no media queries: the layouts respond to the space they have.

import { cn, p } from "cssints" with { type: "cssints" };
import {
  autoGrid,
  cluster,
  sidebar,
  stack,
  switcher,
} from "@cssints/layout" with { type: "cssints" };

export const page = cn(stack().gap(6), p(4));
export const toolbar = cluster().gap(2).justify("space-between");
export const layout = sidebar().width("20rem").content("50%").gap(4);
export const buttons = switcher().threshold("30rem");
export const cards = autoGrid().min("16rem").gap(4);
@layer _.k {
  ._layout-stack-core {
    gap: var(--layout-stack-gap);
    --layout-stack-gap: 1rem;
    display: flex;
    flex-direction: column;
  }
  ._layout-sidebar-core {
    gap: var(--layout-sidebar-gap);
    --layout-sidebar-gap: 1rem;
    --layout-sidebar-width: auto;
    --layout-sidebar-content: 50%;
    --layout-sidebar-ff: 1 1 var(--layout-sidebar-width);
    --layout-sidebar-fm: auto;
    --layout-sidebar-lf: 999 1 0;
    --layout-sidebar-lm: var(--layout-sidebar-content);
    display: flex;
    flex-wrap: wrap;
  }
  ._layout-sidebar-core > :first-child {
    flex: var(--layout-sidebar-ff);
    min-inline-size: var(--layout-sidebar-fm);
  }
  ._layout-sidebar-core > :last-child {
    flex: var(--layout-sidebar-lf);
    min-inline-size: var(--layout-sidebar-lm);
  }
  ._layout-switcher-core > * {
    flex-grow: 1;
    flex-basis: calc((var(--layout-switcher-threshold) - 100%) * 999);
  }
  ._layout-grid-core {
    gap: var(--layout-grid-gap);
    --layout-grid-min: 16rem;
    --layout-grid-gap: 1rem;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(var(--layout-grid-min), 100%), 1fr));
  }
  /* ... the other kernels */
}
@layer _.a {
  ._x {
    --layout-stack-gap: 1.5rem;
  }
  ._y {
    --layout-sidebar-width: 20rem;
  }
  /* ... one class per method and value */
}

The primitives

Primitive Methods (each once, in any order) What it is
stack() gap (1rem) a flex column with a gap
cluster() gap (1rem), justify (flex-start), align (center) a wrapping row: tags, buttons, a toolbar
sidebar() side (left), width (auto, its content), content (50%), gap (1rem) two children side by side; they stack when the content child would be narrower than content of the container
switcher() threshold (30rem), gap (1rem) its children in one row while the container is wider than threshold, else one column (Heydon Pickering's Flexbox Holy Albatross)
cover() minHeight (100vh), gap (1rem) a flex column of a min height with its content centred vertically
autoGrid() min (16rem), gap (1rem) as many columns of at least min as fit, repeat(auto-fit, minmax(min(min, 100%), 1fr)), which never overflows

Rules

Limits

cd packages/layout && bun run test   # fixtures through the engine (output, conflicts, build errors), and the type test via bun run typecheck

Credits

The primitives are those of Every Layout (Heydon Pickering and Andy Bell) and smolcss (Stephanie Eckles); the switcher is Heydon Pickering's Flexbox Holy Albatross. The CSS is written here as styles of scope(); no code is copied.