css

package
v5.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 28, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package css is GoWebComponents' typed, type-safe CSS layer. The raw-CSS layer (Rule/value/prop/variant) is the foundation; the Tailwind-shaped utility engine (subpackage css/u) is a typed convenience built on top. Emission v1 is runtime <style> injection on wasm and an in-memory buffer (read back by SSR and tests) on native.

The two public entry points cross into the html package without any edits to it: New returns a Sheet (a fmt.Stringer that flows through html.ClassNames, ClassMap keys, SSR, and attribute strings) and Class returns an html.PropOption that delegates to the existing html.Class setter.

// today
Div(html.Class("flex gap-2 hover:bg-slate-900"), …)
// typed, same shape
Div(css.Class(css.Display.Flex, css.Gap(css.Px(8)), css.Hover(css.Bg(css.Slate900))), …)

Package css authoring guide.

Layers

Layer 1 — typed raw CSS (the foundation). Typed properties and values fold into a hashed class:

class := css.New(
    css.Display.Flex,
    css.Gap(css.Px(8)),
    css.Bg(css.Slate900),
    css.Hover(css.Bg(css.Slate800)),          // pseudo variant
    css.Media(css.MinW(768), css.FlexDir.Row), // at-rule variant
)
// class is "c-…"; the compiled CSS is emitted once through the active Sink.

Layer 2 — Tailwind-shaped utilities (subpackage css/u), built on Layer 1. Every utility resolves against the active css.Theme and returns Layer-1 rules:

import "github.com/monstercameron/GoWebComponents/v5/css/u"
css.New(u.Flex, u.Gap(3), u.Bg(u.Slate900), u.Md(u.Hover(u.FlexRow)...)...)

Crossing into html

Two entry points cross into the html package with zero edits to it:

// css.Class is an html.PropOption — drop it into any shorthand call site.
shorthand.Div(css.Class(css.Display.Flex, css.Gap(css.Px(8))), …)

// css.New returns a Sheet (fmt.Stringer) that flows through html.ClassNames,
// ClassMap keys, SSR, and attribute strings.
sheet := css.New(css.Display.Grid)

Dynamic values

Runtime values would mint a new class per distinct value. Use Dynamic to keep a stable class that references a custom property and set the live value inline:

d := css.DynamicLength("--gap", "gap", state.Gap())
shorthand.Div(d.Class(), d.Style(), …)

SSR & hydration

On native (SSR) the buffer sink collects every emitted rule. Serialize it into the head with css.StyleBlock(), which renders <style data-gwc-css="…">. On wasm hydration, css.SeedFromDocument() pre-seeds the registry from that block so already-present rules are recognized as hits and not re-injected.

Extension points

  • css.DefineUtility(name, rules…) — named reusable bundles (the plugin path).
  • css.UseTheme(theme) — swap/extend the token scales the utility engine reads.
  • css.DefineVariant(selectorTemplate) — new variant selectors via an "&" template.
  • css.SetSink(sink) — custom emission targets without touching authoring.

Index

Constants

This section is empty.

Variables

View Source
var (
	Overflow  = overflowNamespace("overflow")
	OverflowX = overflowNamespace("overflow-x")
	OverflowY = overflowNamespace("overflow-y")
)

Overflow / OverflowX / OverflowY are the typed namespaces for the overflow properties: css.OverflowY.Auto.

Accessibility note: a box with Overflow.Auto or .Scroll is a scroll container, and a scroll container that is not focusable cannot be scrolled by keyboard. Pair it with html.Props{TabIndex: html.TabIndexZero} (see that field's comment).

View Source
var (
	OverscrollBehavior  = overscrollNamespace("overscroll-behavior")
	OverscrollBehaviorX = overscrollNamespace("overscroll-behavior-x")
	OverscrollBehaviorY = overscrollNamespace("overscroll-behavior-y")
)

OverscrollBehavior / -X / -Y are the typed namespaces for overscroll-behavior. Contain stops a scroll that reaches the end of this box from chaining to the page behind it (and suppresses pull-to-refresh) — the fix for a horizontally scrolling table that drags the whole document sideways.

View Source
var (
	AlignSelf   = selfAlignNamespace("align-self")
	JustifySelf = selfAlignNamespace("justify-self")
)

AlignSelf / JustifySelf override the container's alignment for one item — how a grid child stops stretching to its row's full height (AlignSelf.Start) without the container losing stretch for everything else.

These use the CSS-Align `start`/`end` keywords rather than the flexbox-era `flex-start`/`flex-end` used by the older Items/Justify namespaces, because `flex-start` is not valid in a grid context while `start` works in both.

View Source
var AlignContent = contentAlignProp{
	Normal:   decl("align-content", "normal"),
	Start:    decl("align-content", "start"),
	Center:   decl("align-content", "center"),
	End:      decl("align-content", "end"),
	Between:  decl("align-content", "space-between"),
	Around:   decl("align-content", "space-around"),
	Evenly:   decl("align-content", "space-evenly"),
	Stretch:  decl("align-content", "stretch"),
	Baseline: decl("align-content", "baseline"),
}

AlignContent distributes a multi-line flex container's lines, or a grid's rows, within the container's own height.

It gets its own namespace rather than reusing selfAlignNamespace because the value grammars genuinely differ: align-content accepts the space-* distributions but NOT `auto`, while align-self/justify-self accept `auto` and no distributions. Sharing one struct would have put a silently-invalid `AlignContent.Auto` in autocomplete, which is precisely the class of mistake a typed CSS layer exists to prevent.

View Source
var Appearance = appearanceProp{
	Auto: decl("appearance", "auto"),
	None: decl("appearance", "none"),
}

Appearance is the typed namespace for appearance. None strips the platform widget look from a control (the native <select> arrow, the iOS <input> inner shadow) so a design system can style one box primitive and share it across input and select. It is emitted unprefixed; every current browser supports the unprefixed property.

View Source
var BgClip = bgClipProp{
	BorderBox:  decl("background-clip", "border-box"),
	PaddingBox: decl("background-clip", "padding-box"),
	ContentBox: decl("background-clip", "content-box"),
	Text: Rule{
		// contains filtered or unexported fields
	},
}

BgClip is the typed namespace for background-clip.

View Source
var BgOrigin = bgOriginProp{
	BorderBox:  decl("background-origin", "border-box"),
	PaddingBox: decl("background-origin", "padding-box"),
	ContentBox: decl("background-origin", "content-box"),
}
View Source
var BgRepeat = bgRepeatProp{
	Repeat:   decl("background-repeat", "repeat"),
	NoRepeat: decl("background-repeat", "no-repeat"),
	RepeatX:  decl("background-repeat", "repeat-x"),
	RepeatY:  decl("background-repeat", "repeat-y"),
	Round:    decl("background-repeat", "round"),
	Space:    decl("background-repeat", "space"),
}

BgRepeat is the typed namespace for background-repeat: css.BgRepeat.RepeatX.

View Source
var BorderCollapse = borderCollapseProp{
	Collapse: decl("border-collapse", "collapse"),
	Separate: decl("border-collapse", "separate"),
}

BorderCollapse is the typed namespace for border-collapse. `collapse` is what makes a table's hairlines share a single line rather than doubling at every cell boundary — the difference between a printed manifest and a spreadsheet.

View Source
var ColorScheme = colorSchemeProp{
	Normal:    decl("color-scheme", "normal"),
	Light:     decl("color-scheme", "light"),
	Dark:      decl("color-scheme", "dark"),
	LightDark: decl("color-scheme", "light dark"),
}

ColorScheme is the typed namespace for the color-scheme property.

View Source
var Cursor = cursorProp{
	Auto:       decl("cursor", "auto"),
	Pointer:    decl("cursor", "pointer"),
	Default:    decl("cursor", "default"),
	Text:       decl("cursor", "text"),
	Move:       decl("cursor", "move"),
	NotAllowed: decl("cursor", "not-allowed"),
	Wait:       decl("cursor", "wait"),
	Grab:       decl("cursor", "grab"),
	Grabbing:   decl("cursor", "grabbing"),
}

Cursor is the typed namespace for the cursor property: css.Cursor.Pointer.

View Source
var Display = displayProp{
	Block:       decl("display", "block"),
	InlineBlock: decl("display", "inline-block"),
	Inline:      decl("display", "inline"),
	Flex:        decl("display", "flex"),
	InlineFlex:  decl("display", "inline-flex"),
	Grid:        decl("display", "grid"),
	None:        decl("display", "none"),
}

Display is the typed namespace for the CSS display property: css.Display.Flex, css.Display.Grid, css.Display.None, …

View Source
var FlexDir = flexDirProp{
	Row:    decl("flex-direction", "row"),
	RowRev: decl("flex-direction", "row-reverse"),
	Col:    decl("flex-direction", "column"),
	ColRev: decl("flex-direction", "column-reverse"),
}

FlexDir is the typed namespace for flex-direction.

View Source
var FlexWrap = flexWrapProp{
	Wrap:        decl("flex-wrap", "wrap"),
	NoWrap:      decl("flex-wrap", "nowrap"),
	WrapReverse: decl("flex-wrap", "wrap-reverse"),
}

FlexWrap is the typed namespace for flex-wrap.

View Source
var FontStyle = fontStyleProp{
	Normal:  decl("font-style", "normal"),
	Italic:  decl("font-style", "italic"),
	Oblique: decl("font-style", "oblique"),
}

FontStyle is the typed namespace for font-style.

View Source
var FontVariantLigatures = fontVariantLigaturesProp{
	Normal:        decl("font-variant-ligatures", "normal"),
	None:          decl("font-variant-ligatures", "none"),
	NoCommon:      decl("font-variant-ligatures", "no-common-ligatures"),
	Contextual:    decl("font-variant-ligatures", "contextual"),
	NoContextual:  decl("font-variant-ligatures", "no-contextual"),
	Discretionary: decl("font-variant-ligatures", "discretionary-ligatures"),
}

FontVariantLigatures is the typed namespace for font-variant-ligatures.

View Source
var FontVariantNumeric = fontVariantNumericProp{
	Normal:      decl("font-variant-numeric", "normal"),
	TabularNums: decl("font-variant-numeric", "tabular-nums"),
}
View Source
var FontWeight = fontWeightProp{
	Normal:   decl("font-weight", "400"),
	Medium:   decl("font-weight", "500"),
	Semibold: decl("font-weight", "600"),
	Bold:     decl("font-weight", "700"),
}

FontWeight is the typed namespace for font-weight.

View Source
var Items = alignProp{
	Start:    decl("align-items", "flex-start"),
	Center:   decl("align-items", "center"),
	End:      decl("align-items", "flex-end"),
	Stretch:  decl("align-items", "stretch"),
	Baseline: decl("align-items", "baseline"),
}

Items is the typed namespace for align-items.

View Source
var Justify = justifyProp{
	Start:   decl("justify-content", "flex-start"),
	Center:  decl("justify-content", "center"),
	End:     decl("justify-content", "flex-end"),
	Between: decl("justify-content", "space-between"),
	Around:  decl("justify-content", "space-around"),
}

Justify is the typed namespace for justify-content.

View Source
var JustifyItems = itemsAlignProp{
	Normal:   decl("justify-items", "normal"),
	Start:    decl("justify-items", "start"),
	Center:   decl("justify-items", "center"),
	End:      decl("justify-items", "end"),
	Stretch:  decl("justify-items", "stretch"),
	Baseline: decl("justify-items", "baseline"),
}

JustifyItems is the container-side default for every item's justify-self.

View Source
var MaskRepeat = maskRepeatProp{
	Repeat:   maskRepeatRule("repeat"),
	NoRepeat: maskRepeatRule("no-repeat"),
	RepeatX:  maskRepeatRule("repeat-x"),
	RepeatY:  maskRepeatRule("repeat-y"),
}

MaskRepeat is the typed namespace for mask-repeat.

View Source
var OverflowWrap = overflowWrapProp{
	Normal:    decl("overflow-wrap", "normal"),
	Anywhere:  decl("overflow-wrap", "anywhere"),
	BreakWord: decl("overflow-wrap", "break-word"),
}

OverflowWrap is the typed namespace for overflow-wrap — the escape valve for an unbreakable token (a URL, a hash) that would otherwise overflow its container.

View Source
var PointerEvents = pointerEventsProp{
	Auto: decl("pointer-events", "auto"),
	None: decl("pointer-events", "none"),
}

PointerEvents is the typed namespace for pointer-events. None makes a box invisible to the mouse so clicks fall through to what is underneath — required for decorative overlays (a gradient scrim, a perforation strip) that must not eat the clicks of the content they sit over.

View Source
var Position = positionProp{
	Static:   decl("position", "static"),
	Relative: decl("position", "relative"),
	Absolute: decl("position", "absolute"),
	Fixed:    decl("position", "fixed"),
	Sticky:   decl("position", "sticky"),
}

Position is the typed namespace for the CSS position property.

View Source
var TableLayout = tableLayoutProp{
	Auto:  decl("table-layout", "auto"),
	Fixed: decl("table-layout", "fixed"),
}

TableLayout is the typed namespace for table-layout. `fixed` sizes columns from the first row only (fast, predictable); `auto` measures all content.

View Source
var TextAlign = textAlignProp{
	Left:    decl("text-align", "left"),
	Center:  decl("text-align", "center"),
	Right:   decl("text-align", "right"),
	Justify: decl("text-align", "justify"),
	Start:   decl("text-align", "start"),
	End:     decl("text-align", "end"),
}

TextAlign is the typed namespace for text-align: css.TextAlign.Right.

View Source
var TextDecoration = textDecorationProp{
	None:        decl("text-decoration-line", "none"),
	Underline:   decl("text-decoration-line", "underline"),
	Overline:    decl("text-decoration-line", "overline"),
	LineThrough: decl("text-decoration-line", "line-through"),
}

TextDecoration is the typed namespace for text-decoration-line. It sets the LONGHAND, not the shorthand: the shorthand resets thickness and offset, so TextDecoration.Underline composed with TextDecorationThickness would have raced against declaration ordering. As longhands they compose unconditionally.

View Source
var TextDecorationStyle = textDecorationStyleProp{
	Solid:  decl("text-decoration-style", "solid"),
	Double: decl("text-decoration-style", "double"),
	Dotted: decl("text-decoration-style", "dotted"),
	Dashed: decl("text-decoration-style", "dashed"),
	Wavy:   decl("text-decoration-style", "wavy"),
}

TextDecorationStyle is the typed namespace for text-decoration-style.

View Source
var TextTransform = textTransformProp{
	None:       decl("text-transform", "none"),
	Uppercase:  decl("text-transform", "uppercase"),
	Lowercase:  decl("text-transform", "lowercase"),
	Capitalize: decl("text-transform", "capitalize"),
}

TextTransform is the typed namespace for text-transform.

View Source
var TextWrap = textWrapProp{
	Wrap:    decl("text-wrap", "wrap"),
	NoWrap:  decl("text-wrap", "nowrap"),
	Balance: decl("text-wrap", "balance"),
	Pretty:  decl("text-wrap", "pretty"),
	Stable:  decl("text-wrap", "stable"),
}

TextWrap is the typed namespace for text-wrap. Unsupported values are ignored by older browsers, so these are safe progressive enhancement.

View Source
var UserSelect = selectProp{
	None: decl("user-select", "none"),
	Text: decl("user-select", "text"),
	All:  decl("user-select", "all"),
	Auto: decl("user-select", "auto"),
}

Select is the typed namespace for user-select: css.UserSelect.None.

View Source
var VerticalAlign = verticalAlignProp{
	Baseline:   decl("vertical-align", "baseline"),
	Top:        decl("vertical-align", "top"),
	Middle:     decl("vertical-align", "middle"),
	Bottom:     decl("vertical-align", "bottom"),
	TextTop:    decl("vertical-align", "text-top"),
	TextBottom: decl("vertical-align", "text-bottom"),
	Sub:        decl("vertical-align", "sub"),
	Super:      decl("vertical-align", "super"),
}

VerticalAlign is the typed namespace for vertical-align — the property that controls where a table cell's content sits when rows have unequal heights.

View Source
var WhiteSpace = whiteSpaceProp{
	Normal:      decl("white-space", "normal"),
	NoWrap:      decl("white-space", "nowrap"),
	Pre:         decl("white-space", "pre"),
	PreWrap:     decl("white-space", "pre-wrap"),
	PreLine:     decl("white-space", "pre-line"),
	BreakSpaces: decl("white-space", "break-spaces"),
}

WhiteSpace is the typed namespace for white-space.

Functions

func Class

func Class(parts ...any) html.PropOption

Class is the unified PropOption entry point for Div(...)/shorthand argument lists — the typed analog of JSX's className/clsx. It accepts a mixed list of:

  • string — a literal class name (migration / third-party / utility strings)
  • Rule — a single typed rule
  • []Rule — the slice returned by variants (Hover, Media, Child, …)
  • Sheet — a pre-folded class from New
  • []Sheet — several pre-folded classes

Typed rules are folded together into one hashed class via New; strings and Sheets pass through as class names. Everything is joined into the class attribute. Mixing is the whole point:

Div(Class("legacy-util", Display.Flex, Gap(Px(8)), Hover(Bg(Slate900)), someSheet))

Type-safety note: the compile-checked guarantees live in the rule builders (Display.Flex, Gap(Px(8)), …); the argument list is `...any` because the class attribute is an inherently stringy boundary (exactly like clsx). Unrecognized argument types are ignored.

func CriticalCSS

func CriticalCSS() string

CriticalCSS returns the critical-CSS <style> block to inline into an SSR document head (CSS6). It is the extraction half of the author-in-Go / ship- inline pipeline: render the app under the native sink (which collects every emitted rule), call CriticalCSS to serialize it into the page, and on the client call SeedFromDocument so the same rules are recognized as already present and never re-injected. CriticalCSS is an alias of StyleBlock with the pipeline-oriented name; both return "" when nothing has been emitted.

func DeclareLayers

func DeclareLayers(parseNames ...string)

DeclareLayers emits an `@layer a, b, c;` statement establishing layer order (earlier = lower precedence). Call it once at startup before other emissions so the order statement leads the stylesheet. Identical declarations dedupe.

css.DeclareLayers("base", "components", "overrides")

func DefineVariant

func DefineVariant(selectorTemplate string) func(...Rule) []Rule

DefineVariant returns a reusable variant function from a selector template containing a single "&" placeholder (e.g. ".group:hover &" for group-hover, or "&[data-open]" for a data-attribute state). It is the open extension point for new pseudo/combinator variants beyond the built-ins.

func EmitThemeTokens

func EmitThemeTokens(parseTheme Theme)

EmitThemeTokens emits the theme's RootRules into :root in one call — the convenience form of css.Root(theme.RootRules()...).

func Global

func Global(parseSelector string, parseRules ...Rule)

Global emits CSS rules under a literal, top-level selector — an element (`body`, `h3`), the universal selector (`*`), a `:root` token block, or a stable semantic class (`.nav-link`, `.bento`) that other markup or a runtime theme engine targets by name. Unlike New, the rules are NOT scoped under a generated hashed class: the selector you pass is emitted verbatim.

css.Global("body", css.Margin(css.Px(0)), css.Font(css.SansStack))
css.Global(".nav-link", css.Display.Flex, css.Hover(css.Bg(css.Slate800)))

Variants compose against the selector exactly as they do against `&` in New: the `&` placeholder is replaced by the literal selector, so css.Hover(...) under Global(".btn", ...) emits `.btn:hover { … }` and css.Descendant(h3, ...) emits `.btn h3 { … }`.

Emission is deduped process-wide on the (selector + rules) content, flows through the same Sink as New (so SSR StyleBlock/Harvest include it and the wasm DOM sink injects it), and is hardened against <style> breakout. Calling Global repeatedly with the same selector and rules is cheap and emits once.

func Harvest

func Harvest() string

Harvest returns all CSS emitted into the native buffer sink so far, concatenated in emission order. SSR serializes this into a <style> block; tests assert on it.

Harvest reads the active sink only when it is the default buffer sink. If a test installed a custom sink via SetSink, harvest its own state instead.

func HarvestedClasses

func HarvestedClasses() []string

HarvestedClasses returns the class names emitted into the native buffer sink, in emission order. Used to seed the client registry for hydration.

func Inject

func Inject(parseID string, parseCSS string)

Inject installs an arbitrary CSS string as a managed <style> element, keyed by id and idempotent (the first call for an id wins; later calls for the same id are no-ops). It is the runtime counterpart to Global for CSS that must be a raw string rather than typed rules — `@font-face` blocks for user-uploaded fonts, a third-party widget's stylesheet, etc.

css.Inject("app-fonts", `@font-face{font-family:"My Font";src:url(...)}`)

On wasm it creates (once) a <style id="..."> in <head>; on native it records the CSS into the buffer sink so SSR/tests can read it back. The CSS is hardened against <style> breakout. To replace injected CSS, use a new id.

func LayerGlobal

func LayerGlobal(parseName string, parseSelector string, parseRules ...Rule)

LayerGlobal emits global rules (element/:root/semantic-class selectors) inside a named cascade layer — the typed home for a light-theme override layer that must beat base rules by layer order rather than specificity hacks (CSS4).

css.LayerGlobal("overrides", `[data-theme="light"] .card`, css.Bg(css.White))

func Preflight

func Preflight()

Preflight emits a small, modern CSS reset (a Tailwind-preflight-equivalent) as global rules (CSS5). It is opt-in — call it once at startup if you want the base layer managed by the framework instead of hand-maintained inline. Rules are deduped, hardened, and flow through the same sink as the rest of css, so they appear in SSR output and inject on wasm.

func main() { css.Preflight(); /* … */ }

To place the reset in a cascade layer (so app styles reliably win), see PreflightInLayer.

func PreflightInLayer

func PreflightInLayer(parseLayer string)

PreflightInLayer emits the reset inside a named cascade layer (e.g. "base"), so it sits below component/override layers regardless of source order (CSS4+CSS5).

css.DeclareLayers("base", "components", "overrides")
css.PreflightInLayer("base")

func Reset

func Reset()

Reset clears the registry and resets the active sink to the build default. For tests — it gives each test a clean process-wide registry.

func Root

func Root(parseRules ...Rule)

Root emits a `:root { … }` block — the canonical home for a custom-property (design-token) palette authored in typed Go:

css.Root(
    css.CustomColor("accent", css.Hex("4f46e5")),  // --accent: #4f46e5
    css.CustomLength("radius", css.Px(12)),        // --radius: 12px
)

It is shorthand for Global(":root", rules...). Author custom properties with the Custom* constructors in custom.go: they normalize the name through the same helper Var uses, so a declaration and its css.Var("accent") reference cannot drift apart, and a missing "--" prefix is impossible rather than a silently dead declaration. (css.Raw("--accent", "#4f46e5") still works and is what these replace.)

A runtime theme engine can then override individual tokens with element.style.setProperty without regenerating any classes.

func Seed

func Seed(parseClasses ...string)

Seed marks a class as already-present without emitting it. Client hydration uses it to pre-seed the registry from server-rendered class names so existing rules are recognized as hits and not re-injected.

func SeedFromDocument

func SeedFromDocument()

SeedFromDocument is a no-op on native builds: there is no DOM/document to read a server-rendered <style data-gwc-css> block from. It exists for cross-target API parity so code that hydrates the client registry compiles on both targets (the wasm build does the real seeding).

func StyleBlock

func StyleBlock() string

StyleBlock returns the harvested CSS wrapped in a <style data-gwc-css> element carrying the emitted class names in a data attribute. The SSR head includes this so styles are present on first paint and the client can pre-seed its registry to suppress re-injection. Returns "" when nothing has been emitted.

func UseTheme

func UseTheme(parseTheme Theme)

UseTheme swaps the active theme that the utility engine resolves against.

Types

type Angle

type Angle string

Angle is a CSS angle value. Build with Deg or Turn.

func Deg

func Deg(n float64) Angle

Deg is a degree angle: Deg(45) -> "45deg".

func Turn

func Turn(n float64) Angle

Turn is a turn angle: Turn(0.5) -> "0.5turn".

func VarAngle

func VarAngle(parseName string) Angle

func (Angle) String

func (a Angle) String() string

type BgSizeValue

type BgSizeValue string

BgSizeValue is one background-size layer value.

const (
	// BgCover scales the image to cover the box, cropping the overflow;
	// BgContain fits it entirely, leaving gaps.
	BgCover   BgSizeValue = "cover"
	BgContain BgSizeValue = "contain"
	BgAuto    BgSizeValue = "auto"
)

func BgSizeXY

func BgSizeXY(w, h Length) BgSizeValue

BgSizeXY is an explicit width/height tile size: BgSizeXY(Px(11), Px(7)) -> "11px 7px".

func (BgSizeValue) String

func (v BgSizeValue) String() string

type Color

type Color string

Color is a CSS color value. Use the curated token constants, Hex, or RGB/RGBA.

const (
	Transparent Color = "transparent"
	CurrentCo   Color = "currentColor"
	White       Color = "#ffffff"
	Black       Color = "#000000"

	Slate50  Color = "#f8fafc"
	Slate100 Color = "#f1f5f9"
	Slate200 Color = "#e2e8f0"
	Slate300 Color = "#cbd5e1"
	Slate400 Color = "#94a3b8"
	Slate500 Color = "#64748b"
	Slate600 Color = "#475569"
	Slate700 Color = "#334155"
	Slate800 Color = "#1e293b"
	Slate900 Color = "#0f172a"

	Sky400 Color = "#38bdf8"
	Sky500 Color = "#0ea5e9"
	Sky600 Color = "#0284c7"

	Red500   Color = "#ef4444"
	Red600   Color = "#dc2626"
	Green500 Color = "#22c55e"
	Amber500 Color = "#f59e0b"
)

Curated v1 color tokens (a Tailwind-shaped slice of the default palette).

func ColorMix

func ColorMix(a, b Color, pct float64) Color

ColorMix blends two colors: ColorMix(Sky500, White, 20) is "20% Sky500, the rest White". pct is the share of the FIRST color and is clamped to [0,100].

Mixing happens in oklab, not sRGB, because sRGB interpolation runs through a muddy desaturated midpoint (the classic grey band halfway between blue and yellow) while oklab keeps perceived lightness and chroma steady. This is how a design system derives a hover tint or a disabled tone from ONE token instead of shipping a whole second palette — and because the mix resolves at paint time, it composes with var() tokens a runtime theme engine rewrites.

func ColorValue

func ColorValue(parseName string) (Color, bool)

ColorValue resolves a color token name against the active theme; ok reports whether the token exists.

func Hex

func Hex(parseValue string) Color

Hex builds a color from a hex string, tolerating a missing leading '#': Hex("0af") and Hex("#0af") both -> "#0af". As a typed constructor it is safe-by-construction: any non-hex characters are dropped, so an untrusted string can never inject CSS or break out (e.g. Hex("</style>") -> "#e"). An empty/all- invalid input falls back to "#000000".

func RGB

func RGB(r, g, b int) Color

RGB builds an rgb() color; channels are clamped to [0,255] (matching how RGBA clamps alpha) so the formatter emits canonical, in-range output.

func RGBA

func RGBA(r, g, b int, a float64) Color

RGBA builds an rgba() color; alpha is clamped to [0,1].

func Var

func Var(parseName string) Color

Var references a CSS custom property, the bridge for runtime/dynamic values: Var("--accent") -> "var(--accent)". As a typed constructor it sanitizes the name to CSS identifier characters (letters, digits, '-', '_'), so an untrusted name can never close the var() call or inject CSS.

func (Color) String

func (c Color) String() string

type ColorStop

type ColorStop string

ColorStop is one entry in a gradient's stop list. Build one with Stop, StopAt, StopSpan, or ColorHint.

func ColorHint

func ColorHint(pos Length) ColorStop

ColorHint is a bare position between two stops that shifts the midpoint of the blend without introducing a third color.

func Stop

func Stop(c Color) ColorStop

Stop is a color with no explicit position — the gradient distributes it evenly.

func StopAt

func StopAt(c Color, pos Length) ColorStop

StopAt pins a color to a position along the gradient line: StopAt(White, Percent(40)).

func StopSpan

func StopSpan(c Color, from, to Length) ColorStop

StopSpan gives a color a start AND end position, so it holds flat between them and then changes abruptly. This is how hard-edged devices (stripes, dot grids, perforations) are drawn without an image asset:

StopSpan(paper, Zero, RawLength("3.5px"))  -> "<paper> 0 3.5px"

func (ColorStop) String

func (s ColorStop) String() string

type Duration

type Duration string

Duration is a CSS time value (transition/animation timing). Build with Ms or S.

func Ms

func Ms(n int) Duration

Ms is a millisecond duration: Ms(120) -> "120ms".

func RawDuration

func RawDuration(parseValue string) Duration

RawDuration is the escape hatch for a time value the unit constructors cannot express — notably the sub-millisecond "0.01ms" used to neutralize a transition under prefers-reduced-motion. 0.01ms rather than 0ms is deliberate there: it still fires transitionend, so code awaiting that event does not hang for exactly the users who asked for less motion.

func S

func S(n float64) Duration

S is a second duration: S(0.2) -> "0.2s".

func VarDuration

func VarDuration(parseName string) Duration

func (Duration) String

func (d Duration) String() string

type Dynamic

type Dynamic struct {
	// contains filtered or unexported fields
}

Dynamic pairs a static, hashed class that references a CSS custom property with the inline StyleVar PropOption that carries the live value. This is the static/runtime boundary: a rule built from a runtime value would mint a new class per distinct value and grow the registry unboundedly, so instead the class references var(--name) (one stable hashed class) and the per-element value is set inline.

d := css.Dynamic("--gap", "gap", state.Gap())   // state.Gap() is a css.Length
Div(d.Class(), d.Style(), …)                     // class is stable; value is live

Construct one with DynamicLength (typed Length value) or DynamicVar (any string value); there is no NewDynamic — the type-specific factories are the intended constructors.

func DynamicLength

func DynamicLength(parseName, parseProperty string, parseValue Length) Dynamic

DynamicLength declares a class that sets parseProperty to var(--parseName), plus the live Length value to bind inline. parseName is normalized to a "--" custom property.

func DynamicVar

func DynamicVar(parseName, parseProperty, parseValue string) Dynamic

DynamicVar builds a Dynamic for any property/value pair.

func (Dynamic) Class

func (d Dynamic) Class() html.PropOption

Class returns the PropOption that applies the var-referencing class.

func (Dynamic) Rule

func (d Dynamic) Rule() Rule

Rule returns the static Layer-1 rule that references the custom property. Fold it into New alongside other rules, or use Class for a one-shot PropOption.

func (Dynamic) Style

func (d Dynamic) Style() html.PropOption

Style returns the PropOption that sets the live custom-property value inline, keeping the class and value in sync per element.

type Easing

type Easing string

Easing is a typed timing-function. Use the presets or CubicBezier.

const (
	Linear    Easing = "linear"
	Ease      Easing = "ease"
	EaseIn    Easing = "ease-in"
	EaseOut   Easing = "ease-out"
	EaseInOut Easing = "ease-in-out"
)

func CubicBezier

func CubicBezier(p1, p2, p3, p4 float64) Easing

CubicBezier builds a typed cubic-bezier easing.

type FontStack

type FontStack string

FontStack is a typed font-family value: an ordered fallback list, a var() reference to a token, or one of the built-in system stacks.

const (
	SansStack  FontStack = "ui-sans-serif,system-ui,-apple-system,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif"
	SerifStack FontStack = "ui-serif,Georgia,Cambria,'Times New Roman',Times,serif"
	MonoStack  FontStack = "ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace"
)

The built-in stacks. font-family IS a comma-separated fallback list — that is its entire grammar, and unlike the transition shorthand nothing is appended after the list, so a plain comma join is correct. `ui-*` leads each stack so the browser can pick the platform UI face before falling back to named families.

func FontStackOf

func FontStackOf(parseFamilies ...string) FontStack

FontStackOf builds a fallback list from family names, quoting any name that needs it and dropping characters that could close the quote or end the declaration — so a family name from a user profile cannot inject CSS:

FontStackOf("Atlas Grotesk", "system-ui", "sans-serif")
  -> "'Atlas Grotesk',system-ui,sans-serif"

func RawFontStack

func RawFontStack(parseValue string) FontStack

RawFontStack is the escape hatch for a family list the constructors do not cover.

func VarFontStack

func VarFontStack(parseName string) FontStack

VarFontStack references a custom property holding a font stack — the typed sibling of Var/VarLength for the font-family position, so a design token flows into Font without dropping to Raw. Same name sanitizing as Var.

func (FontStack) String

func (s FontStack) String() string

type Frame

type Frame struct {
	Offset string
	Rules  []Rule
}

Frame is a single keyframe step: an offset (e.g. "0%", "from", "100%") and the rules applied at that offset.

func At

func At(offset string, rules ...Rule) Frame

At builds a keyframe Frame at the given offset.

type GradientDirection

type GradientDirection string

GradientDirection is a typed `to <side>` gradient direction.

const (
	ToTop         GradientDirection = "to top"
	ToBottom      GradientDirection = "to bottom"
	ToLeft        GradientDirection = "to left"
	ToRight       GradientDirection = "to right"
	ToTopLeft     GradientDirection = "to top left"
	ToTopRight    GradientDirection = "to top right"
	ToBottomLeft  GradientDirection = "to bottom left"
	ToBottomRight GradientDirection = "to bottom right"
)

type GradientShape

type GradientShape string

GradientShape is the typed shape/position prefix of a radial gradient.

const (
	Circle  GradientShape = "circle"
	Ellipse GradientShape = "ellipse"
)

func CircleAt

func CircleAt(x, y Length) GradientShape

CircleAt / EllipseAt position the gradient's center: CircleAt(Percent(50), Percent(100)) -> "circle at 50% 100%".

func CircleSizedAt

func CircleSizedAt(radius Length, x, y Length) GradientShape

CircleSizedAt gives the circle an explicit radius as well as a center.

func EllipseAt

func EllipseAt(x, y Length) GradientShape

type GridPlacement

type GridPlacement string

GridPlacement is a typed grid-column / grid-row value. Build one with GridLineAt, GridSpan, GridLineName, GridRange, or GridAuto.

const GridAuto GridPlacement = "auto"

GridAuto lets the auto-placement algorithm pick the track.

func GridLineAt

func GridLineAt(parseN int) GridPlacement

GridLineAt names a numbered grid line. Negative indices count back from the end, so GridLineAt(-1) is the last line — the typed way to say "to the far edge" without knowing the column count.

func GridLineName

func GridLineName(parseName string) GridPlacement

GridLineName references a named grid line (from a [name] entry in a track list).

func GridRange

func GridRange(start, end GridPlacement) GridPlacement

GridRange combines a start and an end placement: GridRange(GridLineAt(1), GridLineAt(-1)) -> "1 / -1". The separator is a slash, not a comma; grid-column takes exactly one start/end pair, so there is no list to get wrong.

func GridSpan

func GridSpan(parseN int) GridPlacement

GridSpan spans a number of tracks from wherever the item lands: GridSpan(2).

func (GridPlacement) String

func (p GridPlacement) String() string

type Image

type Image string

Image is a CSS <image> value: a gradient, a url(), or the none keyword. Build one with the gradient constructors or URLImage.

const NoImage Image = "none"

NoImage is the `none` keyword — the typed way to clear an inherited background-image.

func ConicGradient

func ConicGradient(from Angle, x, y Length, stops ...ColorStop) Image

ConicGradient builds conic-gradient(from <angle> at <x> <y>, stops…) — pie/donut meters without SVG.

func LinearGradient

func LinearGradient(a Angle, stops ...ColorStop) Image

LinearGradient builds linear-gradient(<angle>, stops…). The angle is the direction the gradient travels TOWARD, measured clockwise from "up": Deg(180) points down.

func LinearGradientTo

func LinearGradientTo(dir GradientDirection, stops ...ColorStop) Image

LinearGradientTo builds linear-gradient(to <side>, stops…) — the keyword form, which unlike an angle stays correct when the box is not square.

func RadialGradient

func RadialGradient(shape GradientShape, stops ...ColorStop) Image

RadialGradient builds radial-gradient(<shape>, stops…).

func RawImage

func RawImage(parseValue string) Image

RawImage is the escape hatch for an <image> value the constructors do not cover (image-set(), cross-fade(), a paint() worklet).

func RepeatingLinearGradient

func RepeatingLinearGradient(dir GradientDirection, stops ...ColorStop) Image

RepeatingLinearGradient tiles a linear gradient's stop list — stripes, rules, ruled-paper backdrops.

func RepeatingRadialGradient

func RepeatingRadialGradient(shape GradientShape, stops ...ColorStop) Image

RepeatingRadialGradient tiles a radial gradient — dot grids, and the half-circle perforation of a torn stub:

RepeatingRadialGradient(CircleAt(Percent(50), Percent(100)),
    StopSpan(paper, Zero, RawLength("3.5px")),
    StopAt(Transparent, RawLength("3.5px")))

func URLImage

func URLImage(parsePath string) Image

URLImage builds url("…") from a path. The path is emitted inside a quoted CSS string with '"' and '\' escaped, so it cannot close the url() and inject declarations; it is NOT scheme-checked, so treat the path as author-trusted.

func (Image) String

func (i Image) String() string

type Length

type Length string

Length is a CSS length/size value that carries its unit in the value text, not the type. Build one with Px, Rem, Em, Percent, or the Raw escape hatch.

const Auto Length = "auto"

Auto is the keyword length "auto".

const Full Length = "100%"

Full is "100%".

const Zero Length = "0"

Zero is "0".

func BreakpointValue

func BreakpointValue(parseName string) (Length, bool)

BreakpointValue resolves a responsive breakpoint name to its min-width.

func Ch

func Ch(n float64) Length

Ch is a character-width length: Ch(68) -> "68ch". One ch is the advance width of the "0" glyph in the element's own font, so a ch max-width tracks the measure of the text (the ~45-75 character line that reads comfortably) instead of a pixel guess that drifts every time the font size changes.

func Clamp

func Clamp(min, preferred, max Length) Length

Clamp builds clamp(min, preferred, max) — one fluid value instead of a media-query staircase. The preferred term is normally viewport-relative (Vw) so it scales, with min/max as the hard stops:

Clamp(Rem(1), Vw(2.5), Rem(1.5)) -> clamp(1rem,2.5vw,1.5rem)

Keep min <= max: an inverted pair is legal CSS but resolves to min, silently ignoring the preferred value.

func Ems

func Ems(n float64) Length

Ems is an em length: Ems(1.5) -> "1.5em".

func FontSizeValue

func FontSizeValue(parseName string) (Length, bool)

FontSizeValue resolves a type-scale name against the active theme.

func MaxLen

func MaxLen(values ...Length) Length

func MinLen

func MinLen(values ...Length) Length

MinLen / MaxLen build min()/max() over a list of lengths. The commas are function arguments, not a declaration-level list, so they are safe wherever a Length goes.

func Percent

func Percent(n float64) Length

Percent is a percentage length: Percent(50) -> "50%".

func Px

func Px(n int) Length

Px is an integer pixel length: Px(8) -> "8px".

func RadiusValue

func RadiusValue(parseName string) (Length, bool)

RadiusValue resolves a rounding name against the active theme.

func RawLength

func RawLength(parseValue string) Length

RawLength is the escape hatch for any length string not covered by a unit constructor (e.g. "calc(100% - 8px)", "min(10px, 1rem)").

func Rem

func Rem(n float64) Length

Rem is a rem length: Rem(0.5) -> "0.5rem".

func SpacingValue

func SpacingValue(parseIndex int) Length

SpacingValue resolves a spacing-scale index against the active theme, falling back to Tailwind's n*0.25rem formula for indices outside the curated map.

func VarLength

func VarLength(parseName string) Length

VarLength / VarDuration / VarAngle / VarNumber are the typed siblings of Var for custom properties used in non-color positions, so a CSS variable flows into W/FontSize/Gap (Length), Transition/Animation (Duration), Rotate (Angle), or LineHeight/Opacity (Number) with full type safety instead of falling through to Raw(...). Same sanitizing as Var.

func Vh

func Vh(n float64) Length

Vh / Vw are viewport-relative lengths.

func Vw

func Vw(n float64) Length

func (Length) String

func (l Length) String() string

type LineStyle

type LineStyle string

LineStyle is a typed border/outline line style.

const (
	LineSolid  LineStyle = "solid"
	LineDashed LineStyle = "dashed"
	LineDotted LineStyle = "dotted"
	LineDouble LineStyle = "double"
	LineGroove LineStyle = "groove"
	LineRidge  LineStyle = "ridge"
	// LineNone removes the border and collapses its width to 0; LineHidden does the
	// same except in a collapsed table border conflict, where it wins outright.
	LineNone   LineStyle = "none"
	LineHidden LineStyle = "hidden"
)

func (LineStyle) String

func (s LineStyle) String() string

type MediaQuery

type MediaQuery string

Media is a media-query at-rule wrapper. Build the query with MinW/MaxW or pass a raw query string via RawMedia.

const (
	Dark  MediaQuery = "(prefers-color-scheme:dark)"
	Light MediaQuery = "(prefers-color-scheme:light)"
)

Dark / Light are the prefers-color-scheme media queries.

const (
	// ReducedMotion matches when the user has asked the OS to reduce animation
	// (Windows "Show animations", macOS "Reduce motion", GNOME/Android equivalents).
	// Motion under this query should be neutralized, not merely shortened.
	ReducedMotion MediaQuery = "(prefers-reduced-motion:reduce)"
	// MotionOK is the inverse — the explicit "no preference" state. Prefer gating
	// motion ON with MotionOK over gating it OFF with ReducedMotion when the
	// animation is decorative: the default then costs nothing for a user whose
	// preference is unknown.
	MotionOK MediaQuery = "(prefers-reduced-motion:no-preference)"

	// ContrastMore / ContrastLess match prefers-contrast. Under ContrastMore, raise
	// border and text contrast rather than adding decoration.
	ContrastMore MediaQuery = "(prefers-contrast:more)"
	ContrastLess MediaQuery = "(prefers-contrast:less)"

	// ForcedColors matches when the platform has substituted its own palette
	// (Windows High Contrast / forced-colors mode). Inside it, colors are overridden
	// by the UA, so the useful work is restoring structure the forced palette
	// erases — borders on elements that were distinguished only by background color,
	// and forced-color-adjust:none on the few places a brand color must survive.
	ForcedColors MediaQuery = "(forced-colors:active)"

	// ReducedTransparency and ReducedData round out the preference set.
	ReducedTransparency MediaQuery = "(prefers-reduced-transparency:reduce)"
	ReducedData         MediaQuery = "(prefers-reduced-data:reduce)"
)

The accessibility preference queries. These are typed constants rather than RawMedia strings for a specific reason: a media query is not validated by anything. A typo in RawMedia("(prefers-reduced-motion: reduse)") does not fail to compile, does not fail to emit, and does not warn — it produces a syntactically valid @media block that simply never matches, so the accessibility accommodation silently does not exist. These three (plus MotionOK) are the a11y floor, so they are the ones that must be unmisspellable.

const (
	HoverCapable MediaQuery = "(hover:hover)"
	NoHover      MediaQuery = "(hover:none)"
)

Hover / NoHover match the hover media feature — the correct test for "does this pointer have a hover state", as opposed to inferring it from viewport width. (Named HoverCapable/NoHover to avoid colliding with the Hover pseudo-class variant.)

const Print MediaQuery = "print"

Print matches paged output.

func MaxW

func MaxW(px int) MediaQuery

MaxW is a max-width media query.

func MediaAll

func MediaAll(queries ...MediaQuery) MediaQuery

MediaAll combines features with `and`, so every one must match:

MediaAll(MinW(768), Dark) -> "(min-width:768px) and (prefers-color-scheme:dark)"

Note this is `and`, not the comma that @media uses for `or`. A comma-joined query list would match if ANY feature matched, which is almost never what a caller nesting two conditions means — hence only the `and` form is provided typed.

func MinW

func MinW(px int) MediaQuery

MinW is a min-width media query.

func RawMedia

func RawMedia(parseQuery string) MediaQuery

RawMedia is the escape hatch for an arbitrary media feature query.

type NthArg

type NthArg string

NthArg is a typed argument to NthChild/NthOfType: Odd, Even, or AnB(a,b).

const (
	Odd  NthArg = "odd"
	Even NthArg = "even"
)

func AnB

func AnB(a, b int) NthArg

AnB builds an An+B nth-child argument: AnB(3,1) -> "3n+1".

func Nth

func Nth(n int) NthArg

Nth builds a literal nth argument from an index: Nth(2) -> "2".

type Number

type Number string

Number is a unitless CSS number (line-height, flex-grow, opacity factors, scale factors). Build with Num.

func Num

func Num(n float64) Number

Num is a unitless number: Num(1.5) -> "1.5".

func VarNumber

func VarNumber(parseName string) Number

func (Number) String

func (n Number) String() string

type Rule

type Rule struct {
	// contains filtered or unexported fields
}

Rule is one typed CSS declaration (or a small group of declarations) optionally wrapped in a variant scope (a pseudo-selector and/or one or more at-rules).

Rules are opaque values: build them with the typed property constructors (css.Gap, css.Bg, the css.Display namespace, …), wrap them with variants (css.Hover, css.Media, …), and fold a set of them into a single hashed class with css.New. A Rule carries no class identity of its own — identity is minted at New time from the canonical serialization of the folded rule-set.

func Active

func Active(rules ...Rule) []Rule

Active scopes rules to :active.

func Adjacent

func Adjacent(target Selector, rules ...Rule) []Rule

Adjacent scopes rules to the next sibling: & + target.

func After

func After(rules ...Rule) []Rule

func Animation

func Animation(duration Duration, timing Easing) Rule

Animation sets the animation shorthand timing for a Keyframes rule. Compose it alongside the Keyframes rule in the same New(...) call. It takes a typed Duration and Easing (matching Transition), so a unit-less or mistyped value is a compile error: Animation(Ms(200), Linear).

func Before

func Before(rules ...Rule) []Rule

Before / After scope to the ::before / ::after pseudo-elements. A content declaration defaults to "" when absent so the pseudo-element renders.

func Bg

func Bg(c Color) Rule

Bg sets background-color.

func BgImage

func BgImage(images ...Image) Rule

BgImage sets background-image from one or more layers. background-image IS a comma-separated list of layers, first layer on top, and nothing is appended after it — so joining with commas is the correct grammar (contrast Transition, where the comma separates whole transitions and a bare property list is silently wrong).

There is deliberately NO Background() shorthand constructor in this package. The `background` shorthand is comma-separated per LAYER and each layer packs color/image/position/size/repeat/attachment/origin/clip in one slot; building it by concatenating a caller's image value with more tokens is exactly the defect class that made the old Transition emit dead CSS. Set background-color with Bg and the image/size/repeat/position longhands from here instead — as a bonus, a later rule can then override just the size without restating the image.

func BgPosition

func BgPosition(x, y Length) Rule

BgPosition sets background-position from typed offsets.

func BgSize

func BgSize(sizes ...BgSizeValue) Rule

BgSize sets background-size, one value per BgImage layer (comma-separated list, same grammar note as BgImage).

func Border

func Border(width Length, c Color) Rule

Border sets a solid border of the given width and color on all four sides. For a single edge use BorderTop/Right/Bottom/Left; for a non-solid line pair it with BorderStyle.

func BorderBottom

func BorderBottom(width Length, c Color) Rule

func BorderBottomStyle

func BorderBottomStyle(s LineStyle) Rule

func BorderColor

func BorderColor(c Color) Rule

BorderColor / BorderWidth set the color / width of all four sides without restating the whole shorthand.

func BorderLeft

func BorderLeft(width Length, c Color) Rule

func BorderLeftStyle

func BorderLeftStyle(s LineStyle) Rule

func BorderRight

func BorderRight(width Length, c Color) Rule

func BorderRightStyle

func BorderRightStyle(s LineStyle) Rule

func BorderSpacing

func BorderSpacing(v Length) Rule

BorderSpacing sets border-spacing (only meaningful under BorderCollapse.Separate).

func BorderStyle

func BorderStyle(s LineStyle) Rule

BorderStyle sets border-style for all four sides from a typed LineStyle.

func BorderTop

func BorderTop(width Length, c Color) Rule

BorderTop / BorderRight / BorderBottom / BorderLeft set one side's border to a solid line of the given width and color, matching Border's solid default:

BorderBottom(Px(1), Slate200) -> border-bottom: 1px solid #e2e8f0

For a non-solid line, pair a side constructor with BorderStyle (or the side-specific style namespaces): canonicalize sorts declarations by property name within a block, and "border-bottom" sorts before "border-bottom-style", so the longhand reliably overrides the shorthand it follows.

func BorderTopStyle

func BorderTopStyle(s LineStyle) Rule

BorderTopStyle / BorderRightStyle / BorderBottomStyle / BorderLeftStyle set one side's line style.

func BorderWidth

func BorderWidth(v Length) Rule

func BorderX

func BorderX(width Length, c Color) Rule

BorderX / BorderY set the horizontal / vertical border pairs as longhands, the same shape as PaddingX / MarginY.

func BorderY

func BorderY(width Length, c Color) Rule

func Bottom

func Bottom(v Length) Rule

func Child

func Child(target Selector, rules ...Rule) []Rule

Child scopes rules to a direct child: & > target.

func ColumnGap

func ColumnGap(v Length) Rule

func Custom

func Custom(parseName string, parseValue string) Rule

Custom declares a custom property from a raw value string — the escape hatch for token values with no typed constructor (a font stack fragment, a `1px solid` line, a whole gradient). Only the VALUE is author-trusted; the NAME is still sanitized, so this is strictly safer than Raw("--"+name, value) and stays greppable.

func CustomAngle

func CustomAngle(parseName string, parseValue Angle) Rule

func CustomColor

func CustomColor(parseName string, parseValue Color) Rule

CustomColor / CustomLength / CustomNumber / CustomDuration / CustomAngle declare a custom property from a typed value. The name may be written with or without the leading "--" (both "accent" and "--accent" produce `--accent`).

func CustomDuration

func CustomDuration(parseName string, parseValue Duration) Rule

func CustomFontStack

func CustomFontStack(parseName string, parseValue FontStack) Rule

func CustomLength

func CustomLength(parseName string, parseValue Length) Rule

func CustomNumber

func CustomNumber(parseName string, parseValue Number) Rule

func CustomShadow

func CustomShadow(parseName string, parseValue ShadowToken) Rule

func DataTheme

func DataTheme(parseName string, parseRules ...Rule) []Rule

DataTheme is a convenience for Within(`[data-theme="<name>"]`, rules...) — the common ancestor-attribute theming case. (Named DataTheme to avoid colliding with the Theme token-config type.)

css.New(css.Bg(css.Slate900), css.DataTheme("light", css.Bg(css.White)))

func DefineUtility

func DefineUtility(parseName string, rules ...Rule) []Rule

DefineUtility registers a named, reusable bundle of rules — the plugin path for user-defined utilities that compose with the built-ins. It returns the bundle so it can be used inline immediately, and stores it under name for later lookup via Utility.

card := css.DefineUtility("card",
    css.Padding(css.Px(16)), css.Rounded(css.Px(8)), css.Bg(css.White))
Div(css.Class(card...), …)

func Descendant

func Descendant(target Selector, rules ...Rule) []Rule

Descendant scopes rules to any descendant: & target.

func Disabled

func Disabled(rules ...Rule) []Rule

Disabled scopes rules to the :disabled pseudo-class. It uses the bare pseudo-class name like the other variants (Hover, Focus, Active, …).

func FirstChild

func FirstChild(rules ...Rule) []Rule

FirstChild scopes rules to the :first-child structural pseudo-class.

func Flex

func Flex(grow, shrink Number, basis Length) Rule

Flex sets the flex shorthand from its three typed parts: grow, shrink, basis. The three-value form is spelled out on purpose — the one-value form (`flex: 1`) resets basis to 0%, which is a different layout from `flex: 1 1 auto`, and the difference is the single most common flexbox surprise.

Flex(Num(0), Num(0), Auto) -> flex: 0 0 auto   // size to content, never flex
Flex(Num(1), Num(1), Zero) -> flex: 1 1 0      // share space equally

func FlexBasis

func FlexBasis(v Length) Rule

func FlexGrow

func FlexGrow(n Number) Rule

FlexGrow / FlexShrink / FlexBasis set the individual longhands.

func FlexShrink

func FlexShrink(n Number) Rule

func Focus

func Focus(rules ...Rule) []Rule

Focus scopes rules to the :focus state.

func FocusVisible

func FocusVisible(rules ...Rule) []Rule

FocusVisible scopes rules to :focus-visible.

func Font

func Font(stack FontStack) Rule

Font sets font-family from a typed stack: css.Font(css.SansStack).

There is deliberately NO `font` shorthand constructor. The `font` shorthand RESETS every font longhand it omits (line-height included) and ends in a comma-separated family list, which makes it both destructive and the same comma hazard the Transition grammar note describes. Use Font + FontSize + FontWeight + LineHeight.

func FontSize

func FontSize(v Length) Rule

FontSize sets font-size.

func Gap

func Gap(v Length) Rule

Gap sets the flex/grid gap.

func GridArea

func GridArea(parseName string) Rule

GridArea places an item into a named area from GridAreas: GridArea("rail").

func GridAreas

func GridAreas(parseRows ...string) Rule

GridAreas sets grid-template-areas from one quoted string per row:

GridAreas("rail head", "rail body") ->
  grid-template-areas: "rail head" "rail body"

The rows are whitespace-separated quoted strings, not a comma list. Each row is sanitized to area-name characters (letters, digits, '-', '_', '.', and spaces) so a quote in a row string cannot terminate the string and inject a declaration; '.' survives because it is grid's own "empty cell" token. Rows are NOT padded or validated for equal cell counts — a ragged template is invalid CSS and the browser drops the whole declaration, which is the loud failure you want.

func GridAutoColumns

func GridAutoColumns(tracks ...Track) Rule

func GridAutoRows

func GridAutoRows(tracks ...Track) Rule

GridAutoRows / GridAutoColumns size the implicit tracks the grid creates for items beyond the explicit template.

func GridCols

func GridCols(tracks ...Track) Rule

GridCols / GridRows set grid-template-columns / grid-template-rows from a typed track list:

GridCols(TrackLen(Rem(14)), MinMax(TrackLen(Zero), Fr(1)))
  -> grid-template-columns: 14rem minmax(0,1fr)

func GridColumn

func GridColumn(p GridPlacement) Rule

GridColumn / GridRow place an item on the column / row axis.

GridColumn(GridRange(GridLineAt(1), GridLineAt(-1)))  // full-bleed row
GridRow(GridSpan(2))                                  // two rows tall

func GridRow

func GridRow(p GridPlacement) Rule

func GridRows

func GridRows(tracks ...Track) Rule

func H

func H(v Length) Rule

func Has

func Has(target Selector, rules ...Rule) []Rule

Has scopes rules to :has(selector).

func Hover

func Hover(rules ...Rule) []Rule

Hover scopes rules to the :hover state.

func Inset

func Inset(v Length) Rule

Inset sets all four offsets at once (`inset: 0` is the "fill the positioned ancestor" idiom).

func InsetX

func InsetX(v Length) Rule

InsetX / InsetY set the horizontal / vertical offset pairs as longhands, the same shape as PaddingX / MarginY. They are emitted as physical longhands rather than `inset-inline`/`inset-block` so they do not flip under a right-to-left writing mode — matching PaddingX/MarginX, which are physical too.

func InsetY

func InsetY(v Length) Rule

func Is

func Is(targets []Selector, rules ...Rule) []Rule

Is scopes rules to :is(a, b, …).

func Keyframes

func Keyframes(parseName string, frames ...Frame) Rule

Keyframes registers an @keyframes animation built from frames and returns a Rule that both carries the (deduped, content-named) @keyframes block and sets animation-name to it, so applying the rule animates the element. duration and timing are applied via the returned rule's shorthand.

func LastChild

func LastChild(rules ...Rule) []Rule

LastChild scopes rules to the :last-child structural pseudo-class.

func Left

func Left(v Length) Rule

func LineHeight

func LineHeight(n Number) Rule

LineHeight sets line-height from a typed Number (unitless) or Length.

func LineHeightLen

func LineHeightLen(v Length) Rule

LineHeightLen sets line-height from a typed Length.

func Margin

func Margin(v Length) Rule

Margin sets uniform margin; MarginX/Y set the axis pairs.

func MarginX

func MarginX(v Length) Rule

func MarginY

func MarginY(v Length) Rule

func MarkImportant

func MarkImportant(parseRule Rule) Rule

MarkImportant returns a copy of the rule with "!important" appended to every declaration value (idempotent). It is the typed analog of Tailwind's "!" modifier.

func MaskImage

func MaskImage(images ...Image) Rule

MaskImage sets mask-image from the same typed Image values the gradients produce — the other half of the signature-device toolkit, where a gradient decides not what is painted but what survives. A fade-out edge on a scroll container, a torn paper edge, an icon tinted by currentColor: all of them are "paint a solid, mask it with a gradient", which needs no image asset and inverts with the theme for free.

MaskImage(LinearGradientTo(ToBottom, Stop(Black), Stop(Transparent)))

Both the -webkit- longhand and the standard property are emitted: Safari still requires the prefix, and canonicalize sorts "-webkit-mask-image" before "mask-image", so the standard property always wins where it is supported.

func MaskSize

func MaskSize(sizes ...BgSizeValue) Rule

MaskSize / MaskRepeat mirror BgSize / BgRepeat for the mask layer.

func MaxHeight

func MaxHeight(v Length) Rule

func MaxWidth

func MaxWidth(v Length) Rule

func Media

func Media(query MediaQuery, rules ...Rule) []Rule

Media scopes rules inside an @media at-rule.

func MinHeight

func MinHeight(v Length) Rule

func MinWidth

func MinWidth(v Length) Rule

func Not

func Not(target Selector, rules ...Rule) []Rule

Not scopes rules to :not(selector).

func NthChild

func NthChild(arg NthArg, rules ...Rule) []Rule

NthChild scopes rules to :nth-child(arg).

func NthOfType

func NthOfType(arg NthArg, rules ...Rule) []Rule

NthOfType scopes rules to :nth-of-type(arg).

func Opacity deprecated

func Opacity(n float64) Rule

Opacity sets the opacity (0..1).

Deprecated: prefer the typed OpacityNum(Num(n)) — it matches the typed-value convention used by the rest of the prop constructors. Opacity(float64) remains for convenience.

func OpacityNum

func OpacityNum(n Number) Rule

OpacityNum sets opacity from a typed Number.

func Order

func Order(parseN int) Rule

Order overrides a flex/grid item's visual position. It is deliberately separate from the DOM order it overrides: reordering visually without reordering the DOM desynchronizes tab order from reading order, so use it only where both still agree.

func Outline

func Outline(width Length, c Color) Rule

Outline builds a solid outline of the given width and color.

func OutlineOffset

func OutlineOffset(v Length) Rule

OutlineOffset sets outline-offset from a typed Length.

func OutlineStyle

func OutlineStyle(s LineStyle) Rule

func Padding

func Padding(v Length) Rule

Padding sets uniform padding; PaddingX/Y set the axis pairs.

func PaddingX

func PaddingX(v Length) Rule

func PaddingY

func PaddingY(v Length) Rule

func Property deprecated

func Property(parseName, parseValue string) Rule

Property is the legacy string escape hatch.

Deprecated: use Raw instead — it is the single, intentionally-named declaration escape hatch so raw usage stays greppable / lint-gateable.

func Raw

func Raw(parseProperty, parseValue string) Rule

Raw is the explicit declaration escape hatch for any property/value not covered by a typed constructor: css.Raw("backdrop-filter", "blur(4px)"). Intentionally named so it is greppable / lint-gateable; prefer a typed constructor.

func Right(v Length) Rule

func Rounded

func Rounded(v Length) Rule

Rounded sets border-radius.

func RoundedBottom

func RoundedBottom(v Length) Rule

func RoundedLeft

func RoundedLeft(v Length) Rule

func RoundedRight

func RoundedRight(v Length) Rule

func RoundedTop

func RoundedTop(v Length) Rule

RoundedTop / RoundedBottom / RoundedLeft / RoundedRight round one edge's pair of corners — the "tab" and "card stub" shapes, which Rounded (all four) cannot express.

func RowGap

func RowGap(v Length) Rule

RowGap / ColumnGap set the axis gaps individually (Gap sets both).

func Rules

func Rules(parts ...any) []Rule

Rules flattens a mix of single Rules and rule slices (the []Rule returned by variant helpers) into a flat []Rule, so authoring can freely intermix them:

css.New(css.Rules(
    css.Display.Flex,
    css.Hover(css.Bg(css.Slate800)),   // []Rule
    css.Gap(css.Px(8)),
)...)

func ScrollPadding

func ScrollPadding(v Length) Rule

ScrollPadding / ScrollPaddingTop inset the scrollport for scroll-snapping and fragment/focus jumps — how a sticky header stops covering the element that a same-page anchor just scrolled to.

func ScrollPaddingTop

func ScrollPaddingTop(v Length) Rule

func Shadow

func Shadow(token ShadowToken) Rule

Shadow sets box-shadow from a typed token.

func Sibling

func Sibling(target Selector, rules ...Rule) []Rule

Sibling scopes rules to any following sibling: & ~ target.

func TextColor

func TextColor(c Color) Rule

TextColor sets the text color.

func TextDecorationColor

func TextDecorationColor(c Color) Rule

TextDecorationColor sets the line color independently of the text color.

func TextDecorationThickness

func TextDecorationThickness(v Length) Rule

TextDecorationThickness / TextUnderlineOffset tune an underline's weight and distance from the baseline — the difference between a link underline that reads as typography and one that reads as a browser default.

func TextIndent

func TextIndent(v Length) Rule

TextIndent sets text-indent.

func TextOverflowEllipsis

func TextOverflowEllipsis() Rule

TextOverflowEllipsis truncates overflowing text with an ellipsis. It only takes effect on a single-line, non-wrapping, overflow-hidden box, so all three declarations are emitted together — the property on its own is a silent no-op, and that is the most common reason "text-overflow: ellipsis doesn't work".

func TextUnderlineOffset

func TextUnderlineOffset(v Length) Rule

func Top

func Top(v Length) Rule

Top / Right / Bottom / Left set a single positioning offset. Negative values come from the Length constructors (Px(-1)), so nothing here has to parse a sign.

func Tracking

func Tracking(v Length) Rule

Tracking sets letter-spacing from a typed Length: css.Tracking(css.Ems(0.18)).

func Transform

func Transform(fns ...TransformFn) Rule

Transform builds the transform property from one or more typed transform fns.

func Transition

func Transition(property TransitionProperty, duration Duration, easing Easing) Rule

Transition builds a typed transition shorthand: property, duration, easing.

GRAMMAR — DO NOT "simplify" the expansion below back into a concatenation. The `transition` shorthand is a comma-separated list of *whole transitions*, not a property list followed by shared timing:

transition: <prop> <dur> <ease>, <prop> <dur> <ease>, …

So the naive `string(property)+" "+dur+" "+ease` is silently wrong the moment property holds more than one name. With PropColors it emitted

transition: color, background-color, border-color, fill, stroke 120ms ease

which the browser parses as FOUR transitions with the default 0s duration (`color`, `background-color`, `border-color`, `fill`) plus one 120ms transition on `stroke` — i.e. the preset animated nothing anybody could see. The comma belongs *between* transitions, so a property list has to be distributed over the duration/easing rather than pasted in front of them.

Emission therefore expands one transition per property:

Transition(PropOpacity, Ms(120), Ease) -> transition:opacity 120ms ease
Transition(PropColors, Ms(120), Ease)  -> transition:color 120ms ease,
                                          background-color 120ms ease, … (5 total)

The single-property case is byte-identical to the old output, so class hashes for single-property transitions are unchanged. (The longhand alternative — transition-property/-duration/-timing-function — is equally correct CSS but would have changed every single-property class hash, so the shorthand expansion wins.) Commas nested inside functional values (cubic-bezier(...), rgba(...)) are not list separators and are preserved; see splitCommaList.

func TransitionDuration

func TransitionDuration(duration Duration) Rule

TransitionDuration sets transition-duration on its own — the typed path for a reduced-motion override that neutralizes motion without restating the property list (pair it with TransitionLonghands).

func TransitionLonghands

func TransitionLonghands(property TransitionProperty, duration Duration, easing Easing) Rule

TransitionLonghands is the longhand form of Transition: transition-property / -duration / -timing-function as three declarations.

It exists for the case where a later rule (a reduced-motion override, say) wants to replace ONLY the duration: canonicalize folds declarations by property name within a scope, so an override of `transition-duration` beats the longhand but cannot reach inside the `transition` shorthand's single value. Prefer Transition unless you specifically need that.

func Utility

func Utility(parseName string) (rules []Rule, ok bool)

Utility looks up a previously defined utility bundle; ok reports existence.

func W

func W(v Length) Rule

W / H / MinWidth / MaxWidth size a box (W=width, H=height).

func WhenDisabled deprecated

func WhenDisabled(rules ...Rule) []Rule

WhenDisabled scopes rules to :disabled.

Deprecated: use Disabled, which matches the bare pseudo-class naming of the other variants.

func Within

func Within(parseAncestor string, parseRules ...Rule) []Rule

Within scopes rules to apply only when an ancestor matches selector — the `<ancestor> &` form that powers attribute-state theming (`[data-theme="light"] &`, `html[data-density="compact"] &`). It is the ancestor-state counterpart to the self-state variants (Hover/Focus/…):

css.New(css.Within(`[data-theme="light"]`, css.Bg(css.White), css.Color(css.Slate900)))

emits `[data-theme="light"] .c-xxx { … }`.

func WordSpacing

func WordSpacing(v Length) Rule

WordSpacing sets word-spacing (letter-spacing is Tracking).

func ZIndex

func ZIndex(n int) Rule

ZIndex sets the stacking order. It takes an int, not a Length, because z-index is an integer property: a "1px" z-index is simply dropped by the browser.

type Selector

type Selector string

Selector is a typed CSS selector fragment used as the target of a combinator (Child/Descendant/…) or a functional pseudo-class (Not/Has/Is). Build one with the typed constructors — never a free string — so composition stays checkable.

func AttrEq

func AttrEq(parseName, parseValue string) Selector

AttrEq targets an attribute-equals selector: css.AttrEq("type","submit") -> `[type="submit"]`. The name is sanitized and the value is string-escaped so a crafted value cannot break out of the quotes and inject a live global rule.

func AttrSel

func AttrSel(parseName string) Selector

AttrSel targets an attribute-presence selector: css.AttrSel("data-open") -> "[data-open]". The attribute name is sanitized to CSS-identifier-safe characters.

func ClassSel

func ClassSel(parseName string) Selector

ClassSel targets a literal class name (interop with existing string classes): css.ClassSel("title") -> ".title". The name is sanitized to CSS-identifier-safe characters so it cannot inject additional selector/rule text.

func El

func El(parseTag string) Selector

El targets an HTML element by tag name: css.El("h3") -> "h3".

func Sel

func Sel(parseFragment string) Selector

Sel is the explicit selector-template escape hatch for a fragment the typed builders don't cover. The fragment is appended after the class anchor; use "&" only via DefineVariant for parent-context selectors. Greppable on purpose.

func SheetRef

func SheetRef(parseSheet Sheet) Selector

SheetRef targets another generated class, composing one Sheet against another with full type-safety: css.SheetRef(titleSheet) -> ".c-abc".

func (Selector) String

func (s Selector) String() string

type ShadowToken

type ShadowToken string

ShadowToken is a typed box-shadow value. Use the preset tokens or RawShadow.

const (
	ShadowNone ShadowToken = "none"
	ShadowSm   ShadowToken = "0 1px 2px 0 rgba(0,0,0,0.05)"
	ShadowMd   ShadowToken = "0 4px 6px -1px rgba(0,0,0,0.1)"
	ShadowLg   ShadowToken = "0 10px 15px -3px rgba(0,0,0,0.1)"
	ShadowXl   ShadowToken = "0 20px 25px -5px rgba(0,0,0,0.1)"
	Shadow2xl  ShadowToken = "0 25px 50px -12px rgba(0,0,0,0.25)"
)

func RawShadow

func RawShadow(parseValue string) ShadowToken

RawShadow is the escape hatch for a box-shadow value no preset token or ShadowOf call covers (a `drop-shadow`-style stack copied from a design tool, a currentColor ring, …): RawShadow("0 0 0 3px currentColor").

Named like RawLength/RawMedia so raw usage stays greppable. The value is emitted verbatim, so it is author-trusted CSS — see hardenCSS for what is (and is not) guaranteed about untrusted input.

func ShadowInset

func ShadowInset(x, y, blur, spread Length, c Color) ShadowToken

ShadowInset is ShadowOf with the `inset` keyword (an inner shadow).

func ShadowOf

func ShadowOf(x, y, blur, spread Length, c Color) ShadowToken

ShadowOf builds one shadow from typed parts: offset, blur, spread, color.

ShadowOf(Zero, Px(1), Px(2), Zero, RGBA(0,0,0,0.05)) -> "0 1px 2px 0 rgba(0,0,0,0.05)"

func Shadows

func Shadows(tokens ...ShadowToken) ShadowToken

Shadows layers several shadows into one box-shadow value.

Unlike `transition`, box-shadow's comma-separated list IS a list of complete values with nothing appended after it, so joining tokens with a comma is the whole grammar — there is no per-item timing to distribute (contrast Transition). ShadowNone is not a list item; a "none" among several shadows makes the entire declaration invalid, so it is dropped here rather than emitted into the list.

func (ShadowToken) String

func (parseToken ShadowToken) String() string

String returns the box-shadow value, matching the other typed CSS value types.

type Sheet

type Sheet string

Sheet is a generated class name (or space-separated names). It satisfies fmt.Stringer, so it already flows through html.ClassNames(...), appendClassFragments, ClassMap keys, SSR, and attribute strings.

func Layer

func Layer(parseName string, parseRules ...Rule) Sheet

Layer folds rules into a hashed class emitted inside the named cascade layer (`@layer <name> { .c-xxx { … } }`), giving declared override precedence instead of registration-order accident (CSS4). Declare the layer order once with DeclareLayers so later layers reliably win.

css.DeclareLayers("base", "components", "overrides")
btn := css.Layer("components", css.Display.Flex, css.Padding(css.Px(8)))

func New

func New(rules ...Rule) Sheet

New folds a rule-set into a single content-hashed class, registers it (deduped process-wide), and emits its compiled CSS through the active Sink exactly once. It is safe and cheap to call inside render loops: N identical New(...) calls produce one registry entry and one injected rule.

Variant helpers (css.Hover, css.Media, …) return []Rule; spread them into New with the ... operator, or pass them through the rules... variadic directly — New accepts both single Rules and rule slices via the Rules helper.

func (Sheet) String

func (s Sheet) String() string

String implements fmt.Stringer.

type Sink

type Sink interface {
	Emit(parseClass string, parseCSS string)
}

Sink is the documented emission seam. New(...) calls Emit exactly once per newly-registered class (the dedup happens before the sink is touched), so a Sink never sees the same class twice within one process. The runtime wasm sink appends to a managed <style> element; the native sink buffers for SSR/tests; a build-time extraction pass would be a third implementation.

func SetSink

func SetSink(parseSink Sink) Sink

SetSink swaps the active emission sink and returns the previous one. Mainly for tests and for wiring a custom emission target. Passing nil restores the build's default sink.

type Theme

type Theme struct {
	// Spacing maps a scale index (Tailwind's 0,1,2,3,…) to a Length. The default
	// follows Tailwind: index n -> n*0.25rem.
	Spacing map[int]Length
	// Colors maps a token name ("slate-900") to a Color.
	Colors map[string]Color
	// FontSizes maps a type-scale name ("sm","base","lg") to a Length.
	FontSizes map[string]Length
	// Breakpoints maps a responsive name ("sm","md","lg","xl","2xl") to its
	// min-width Length and drives the responsive variants.
	Breakpoints map[string]Length
	// Radii maps a rounding name ("sm","md","lg","full") to a Length.
	Radii map[string]Length
}

Theme is the typed analog of tailwind.config.js: the named scales the Layer-2 utility engine resolves against. Swap or extend it with UseTheme; utilities and responsive variants read the active theme.

func ActiveTheme

func ActiveTheme() Theme

ActiveTheme returns a snapshot reference to the active theme.

func DefaultTheme

func DefaultTheme() Theme

DefaultTheme returns Tailwind's default scales (the curated v1 subset).

func (Theme) RootRules

func (parseTheme Theme) RootRules() []Rule

RootRules returns the theme's scales as typed custom-property declarations (CSS2): --color-<name>, --space-<index>, --text-<name>, --radius-<name>. It is the bridge between the typed Theme (which the utility engine resolves at class-generation time) and a live CSS-variable palette: emit these into :root and reference them with Var, then a runtime element.style.setProperty reskins every reference without regenerating classes.

css.Root(css.DefaultTheme().RootRules()...)               // :root palette
css.New(css.DataTheme("light", lightTheme.RootRules()...)) // a scoped theme

Breakpoints are intentionally omitted — they drive @media queries, where var() is not reliably supported.

type Track

type Track string

Track is one entry in a grid track list (a column width or a row height). Build one with Fr, TrackLen, MinMax, Repeat, FitContent, or the keyword constants.

const (
	// TrackAuto sizes the track to its content, then absorbs leftover space.
	TrackAuto Track = "auto"
	// TrackMinContent / TrackMaxContent size to the smallest / largest the content
	// can be without overflowing.
	TrackMinContent Track = "min-content"
	TrackMaxContent Track = "max-content"
)

func FitContent

func FitContent(limit Length) Track

FitContent builds fit-content(limit): size to content, but never past limit.

func Fr

func Fr(n float64) Track

Fr is a fractional track: Fr(1) -> "1fr". The fr unit only exists inside a grid track list, which is why it is a Track constructor and not a Length one.

func MinMax

func MinMax(min, max Track) Track

MinMax builds minmax(min, max). The commas here are *function arguments*, not a track-list separator, so they are safe inside a joined track list.

MinMax(TrackLen(Zero), Fr(1)) -> minmax(0,1fr)

minmax(0,1fr) rather than a bare 1fr is the fix for a grid column that refuses to shrink below its content: 1fr's implicit minimum is auto (i.e. min-content).

func Repeat

func Repeat(count int, tracks ...Track) Track

Repeat repeats a track pattern a fixed number of times: Repeat(3, Fr(1)).

func RepeatFill

func RepeatFill(tracks ...Track) Track

func RepeatFit

func RepeatFit(tracks ...Track) Track

RepeatFit / RepeatFill are repeat(auto-fit, …) / repeat(auto-fill, …): as many tracks as fit. auto-fit collapses the empty ones (so the filled tracks stretch), auto-fill keeps them (so the grid holds its rhythm). This is the whole no-media-query responsive-card-grid idiom:

GridCols(RepeatFit(MinMax(TrackLen(Rem(16)), Fr(1))))

func TrackLen

func TrackLen(v Length) Track

TrackLen makes a fixed-size track from a typed Length: TrackLen(Rem(16)).

func (Track) String

func (t Track) String() string

type TransformFn

type TransformFn string

TransformFn is a single typed transform function (Scale, Rotate, …). Compose several in one Transform call.

func Rotate

func Rotate(a Angle) TransformFn

Rotate builds rotate() from a typed Angle.

func Scale

func Scale(n float64) TransformFn

Scale builds a uniform scale(): css.Scale(0.94).

func ScaleXY

func ScaleXY(x, y float64) TransformFn

ScaleXY builds scale(x, y).

func TranslateX

func TranslateX(v Length) TransformFn

TranslateX / TranslateY build translate functions from typed Lengths.

func TranslateY

func TranslateY(v Length) TransformFn

type TransitionProperty

type TransitionProperty string

TransitionProperty names one property — or a comma-separated LIST of properties (see PropColors) — for Transition. The All/Colors/Transform/Opacity presets cover the common cases; Prop wraps an arbitrary property name and TransitionProps composes several into a list.

const (
	PropAll       TransitionProperty = "all"
	PropColors    TransitionProperty = "color, background-color, border-color, fill, stroke"
	PropOpacity   TransitionProperty = "opacity"
	PropTransform TransitionProperty = "transform"
	PropShadow    TransitionProperty = "box-shadow"
)

func Prop

func Prop(parseName string) TransitionProperty

Prop names an arbitrary transition property (typed wrapper, not a free arg).

func TransitionProps

func TransitionProps(parseProps ...TransitionProperty) TransitionProperty

TransitionProps composes several properties into one comma-separated TransitionProperty list, the same shape as the PropColors preset:

css.Transition(css.TransitionProps(css.PropOpacity, css.PropTransform), css.Ms(120), css.Ease)

Transition expands the list correctly (one transition per property) — see the grammar note on Transition.

Directories

Path Synopsis
u
Package u is the Tailwind-shaped typed utility engine layered over the css Layer-1 foundation.
Package u is the Tailwind-shaped typed utility engine layered over the css Layer-1 foundation.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL