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/v4/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 ¶
- Variables
- func Class(parts ...any) html.PropOption
- func CriticalCSS() string
- func DeclareLayers(parseNames ...string)
- func DefineVariant(selectorTemplate string) func(...Rule) []Rule
- func EmitThemeTokens(parseTheme Theme)
- func Global(parseSelector string, parseRules ...Rule)
- func Harvest() string
- func HarvestedClasses() []string
- func Inject(parseID string, parseCSS string)
- func LayerGlobal(parseName string, parseSelector string, parseRules ...Rule)
- func Preflight()
- func PreflightInLayer(parseLayer string)
- func Reset()
- func Root(parseRules ...Rule)
- func Seed(parseClasses ...string)
- func StyleBlock() string
- func UseTheme(parseTheme Theme)
- type Angle
- type Color
- type Duration
- type Dynamic
- type Easing
- type Frame
- type Length
- func BreakpointValue(parseName string) (Length, bool)
- func Ems(n float64) Length
- func FontSizeValue(parseName string) (Length, bool)
- func Percent(n float64) Length
- func Px(n int) Length
- func RadiusValue(parseName string) (Length, bool)
- func RawLength(parseValue string) Length
- func Rem(n float64) Length
- func SpacingValue(parseIndex int) Length
- func VarLength(parseName string) Length
- func Vh(n float64) Length
- func Vw(n float64) Length
- type MediaQuery
- type NthArg
- type Number
- type Rule
- func Active(rules ...Rule) []Rule
- func Adjacent(target Selector, rules ...Rule) []Rule
- func After(rules ...Rule) []Rule
- func Animation(duration Duration, timing Easing) Rule
- func Before(rules ...Rule) []Rule
- func Bg(c Color) Rule
- func Border(width Length, c Color) Rule
- func Child(target Selector, rules ...Rule) []Rule
- func DataTheme(parseName string, parseRules ...Rule) []Rule
- func DefineUtility(parseName string, rules ...Rule) []Rule
- func Descendant(target Selector, rules ...Rule) []Rule
- func Disabled(rules ...Rule) []Rule
- func FirstChild(rules ...Rule) []Rule
- func Focus(rules ...Rule) []Rule
- func FocusVisible(rules ...Rule) []Rule
- func FontSize(v Length) Rule
- func Gap(v Length) Rule
- func H(v Length) Rule
- func Has(target Selector, rules ...Rule) []Rule
- func Hover(rules ...Rule) []Rule
- func Is(targets []Selector, rules ...Rule) []Rule
- func Keyframes(parseName string, frames ...Frame) Rule
- func LastChild(rules ...Rule) []Rule
- func LineHeight(n Number) Rule
- func LineHeightLen(v Length) Rule
- func Margin(v Length) Rule
- func MarginX(v Length) Rule
- func MarginY(v Length) Rule
- func MarkImportant(parseRule Rule) Rule
- func MaxHeight(v Length) Rule
- func MaxWidth(v Length) Rule
- func Media(query MediaQuery, rules ...Rule) []Rule
- func MinHeight(v Length) Rule
- func MinWidth(v Length) Rule
- func Not(target Selector, rules ...Rule) []Rule
- func NthChild(arg NthArg, rules ...Rule) []Rule
- func NthOfType(arg NthArg, rules ...Rule) []Rule
- func Opacity(n float64) Ruledeprecated
- func OpacityNum(n Number) Rule
- func Outline(width Length, c Color) Rule
- func OutlineOffset(v Length) Rule
- func Padding(v Length) Rule
- func PaddingX(v Length) Rule
- func PaddingY(v Length) Rule
- func Property(parseName, parseValue string) Ruledeprecated
- func Raw(parseProperty, parseValue string) Rule
- func Rounded(v Length) Rule
- func Rules(parts ...any) []Rule
- func Shadow(token ShadowToken) Rule
- func Sibling(target Selector, rules ...Rule) []Rule
- func TextColor(c Color) Rule
- func Tracking(v Length) Rule
- func Transform(fns ...TransformFn) Rule
- func Transition(property TransitionProperty, duration Duration, easing Easing) Rule
- func Utility(parseName string) (rules []Rule, ok bool)
- func W(v Length) Rule
- func WhenDisabled(rules ...Rule) []Ruledeprecated
- func Within(parseAncestor string, parseRules ...Rule) []Rule
- type Selector
- type ShadowToken
- type Sheet
- type Sink
- type Theme
- type TransformFn
- type TransitionProperty
Constants ¶
This section is empty.
Variables ¶
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.
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, …
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.
var FontVariantNumeric = fontVariantNumericProp{
Normal: decl("font-variant-numeric", "normal"),
TabularNums: decl("font-variant-numeric", "tabular-nums"),
}
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.
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"),
}
Items is the typed namespace for align-items.
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.
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.
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.
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.
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 ¶
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 ¶
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 ¶
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 ¶
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.Raw("--accent", "#4f46e5"), css.Raw("--radius", "12px"))
It is shorthand for Global(":root", rules...). Author custom properties with the existing css.Raw(property, value) escape hatch. 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 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.
Types ¶
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 ColorValue ¶
ColorValue resolves a color token name against the active theme; ok reports whether the token exists.
func Hex ¶
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".
type Duration ¶
type Duration string
Duration is a CSS time value (transition/animation timing). Build with Ms or S.
func VarDuration ¶
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 ¶
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 ¶
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 ¶
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.
func CubicBezier ¶
CubicBezier builds a typed cubic-bezier easing.
type Frame ¶
Frame is a single keyframe step: an offset (e.g. "0%", "from", "100%") and the rules applied at that offset.
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 ¶
BreakpointValue resolves a responsive breakpoint name to its min-width.
func FontSizeValue ¶
FontSizeValue resolves a type-scale name against the active theme.
func RadiusValue ¶
RadiusValue resolves a rounding name against the active theme.
func RawLength ¶
RawLength is the escape hatch for any length string not covered by a unit constructor (e.g. "calc(100% - 8px)", "min(10px, 1rem)").
func SpacingValue ¶
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 ¶
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.
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)"
Dark is the prefers-color-scheme:dark 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).
type Number ¶
type Number string
Number is a unitless CSS number (line-height, flex-grow, opacity factors, scale factors). Build with Num.
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 Animation ¶
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 ¶
Before / After scope to the ::before / ::after pseudo-elements. A content declaration defaults to "" when absent so the pseudo-element renders.
func DataTheme ¶
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 ¶
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 ¶
Descendant scopes rules to any descendant: & target.
func Disabled ¶
Disabled scopes rules to the :disabled pseudo-class. It uses the bare pseudo-class name like the other variants (Hover, Focus, Active, …).
func FirstChild ¶
FirstChild scopes rules to the :first-child structural pseudo-class.
func FocusVisible ¶
FocusVisible scopes rules to :focus-visible.
func Keyframes ¶
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 LineHeight ¶
LineHeight sets line-height from a typed Number (unitless) or Length.
func LineHeightLen ¶
LineHeightLen sets line-height from a typed Length.
func MarkImportant ¶
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 Media ¶
func Media(query MediaQuery, rules ...Rule) []Rule
Media scopes rules inside an @media at-rule.
func OutlineOffset ¶
OutlineOffset sets outline-offset from a typed Length.
func Raw ¶
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 Rules ¶
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 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.
func WhenDisabled
deprecated
func Within ¶
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 { … }`.
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 ¶
AttrEq targets an attribute-equals selector: css.AttrEq("type","submit") -> `[type="submit"]`.
func AttrSel ¶
AttrSel targets an attribute-presence selector: css.AttrSel("data-open") -> "[data-open]".
func ClassSel ¶
ClassSel targets a literal class name (interop with existing string classes): css.ClassSel("title") -> ".title".
func Sel ¶
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.
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 (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 ¶
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 ¶
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.
type Sink ¶
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.
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 ¶
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 TransformFn ¶
type TransformFn string
TransformFn is a single typed transform function (Scale, Rotate, …). Compose several in one Transform call.
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 a property for Transition. The All/Colors/Transform/ Opacity presets cover the common cases; Prop wraps an arbitrary property name.
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).