gui.css
The CSS style engine of the native UI runtime: selectors, the cascade, inheritance, media queries, shorthands, var() and computed values that match Chromium.
import gui.css
This package is the style engine of the native UI runtime. For each element of a page it takes what the web generator writes for it today (its own declarations, the extra ones for hover, focus and active, its element key, classes and id) together with the page's global and media rules, and computes the final value of every property exactly as a browser would. The native window then looks like the web page.
A Sheet starts with the user agent style sheet, the browser defaults that give a heading its size and a paragraph its margins, written after Chromium's own and compared with Chromium property by property. You add rules with AddRule, AddMediaRule or a whole style sheet with AddCss, describe the elements as a vector of Element in document order, and call Compute. Style then gives each element a ComputedStyle: lengths in pixels (percentages stay relative until layout), colours as straight RGBA, keywords as enums, and lists for backgrounds, shadows, transforms and transitions. ToBox turns it into a gui.cssbox style for layout.
Supported: type, class, id and attribute selectors, descendant, child and sibling combinators, :hover, :focus, :focus-visible, :active, the child and type position pseudo-classes, :not(), :is() and :where(); specificity and !important; inheritance with inherit, initial and unset; media queries on size, orientation, colour scheme, reduced motion, hover and pointer; every length unit, calc(), min(), max() and clamp(); colours in every common syntax; gradients, shadows, transforms, transitions, fonts, logical properties for right to left pages, and var() with fallbacks. Grid and table properties are parsed, cascaded and checked: track lists, areas, placements and their shorthands (grid, grid-template, grid-area, grid-row, grid-column), border-collapse, border-spacing, table-layout and caption-side; ToBox hands them to the layout engine. Pseudo-elements, subgrid, animations and container queries are not done.
Things to know
- An element's own declarations act like a class rule written after the global rules, which is what the web generator emits. Its hover, focus and active declarations act like the same class with that pseudo-class.
- Elements must come in document order, each after its parent. The page itself has parent -1; an implicit
htmlroot above it matches:root. - Elements with the same inputs share one computed style. Each distinct declaration string is parsed once.
- After a pointer move, call
HoverChainand pass its result toRestyle: only the elements whose state changed, and their descendants when an inherited value changed, are computed again. - Strings returned by the text helpers belong to the caller. The vectors inside a
ComputedStylebelong to the sheet. border-imageand its longhands, gradient colour hints andcalc()stop positions are supported. Gradient stops are resolved when painting withGradientStops, which expands hints and non-sRGB segments in the interpolation colour space the way Chromium does. Colour transitions between non-legacy colours mix in Oklab.- Values are applied by keyword id, not by comparing strings, and the cascade passes its large structures by reference: computing all styles of a 202-element page shaped like
tools/bench/gui_ui.salamwent from about 282 us to about 113 us (minimum of 500 runs, one core, C backend).
Styling a page
A card with a heading and a paragraph. The global rule sets the heading's margins, the user agent sheet gives it its size and weight, and the card's own declarations are converted to a layout style and placed with gui.cssbox.
import gui.css
import gui.cssbox
func add(els &: Vector<css.Element>, kind: str, parent: int, classes: str, base: str): int:
mut e := css.NewElement(kind, parent)
e.classes = classes
e.base = base
els.push(e)
ret els.len() - 1
end
func main:
mut sheet := css.NewSheet()
defer sheet.Free()
_g := sheet.AddRule("*", "box-sizing: border-box")
_c := sheet.AddRule(".card h2", "margin: 0 0 8px")
mut els := Vector {} as Vector<css.Element>
body := add(els, "page", -1, "", "font-family: Vazirmatn, sans-serif; background: #f8fafc")
card := add(els, "box", body, "card", "padding: 1em; border: 1px solid #e2e8f0; border-radius: 12px; max-width: 30rem")
title := add(els, "h2", card, "", "color: #0f172a")
text := add(els, "paragraph", card, "", "line-height: 1.5")
_n := sheet.Compute(els, css.Env { width = 800.0, height = 600.0 })
each i in [body, card, title, text]:
cs := sheet.Style(i)
println els[i].tag, css.ValueText(cs, "display"), css.ValueText(cs, "font-size"), css.ValueText(cs, "margin-top"), css.ValueText(cs, "padding-top"), css.ValueText(cs, "color")
end
mut tree := cssbox.Tree {}
defer tree.Free()
mut ids := Vector {} as Vector<int>
defer ids.free()
repeat els.len() in i:
ids.push(tree.AddNode(css.ToBox(sheet.Style(i))))
if els[i].parent >= 0:
tree.AddChild(ids[els[i].parent], ids[i])
end
end
tree.Compute(ids[0], cssbox.Definite(800.0), cssbox.Definite(600.0))
l := tree.Layout(ids[card])
println "card box", l.x, l.y, l.width, l.height
repeat els.len() in i:
mut x := els.ref(i)
x.Free()
end
els.free()
endHover, pressed and media
The button's hover background applies once the pointer is over it, and only the elements on the hover path are computed again. A media condition changes the navigation into a column when the window is narrow. Computing styles for 5,000 elements with 11 distinct styles takes about 10 ms on one desktop core; a hover change restyles four elements in about 0.1 ms. With 5,000 different styles it takes about 100 ms the first time and about 50 ms once the declarations are parsed.
import gui.css
func main:
mut sheet := css.NewSheet()
defer sheet.Free()
_r := sheet.AddRule("nav a:hover", "text-decoration: none")
mut els := Vector {} as Vector<css.Element>
els.push(css.NewElement("page", -1))
mut nav := css.NewElement("nav", 0)
nav.base = "display: flex; gap: 8px; padding: 16px"
nav.AddMedia("(max-width: 600px)", "flex-direction: column; padding: 8px")
els.push(nav)
mut button := css.NewElement("button", 1)
button.base = "background: #2563eb; color: white; border: none; transition: background 200ms ease-in-out"
button.hover = "background: #1d4ed8"
button.active = "transform: scale(0.98)"
els.push(button)
mut link := css.NewElement("link", 1)
link.AddAttr("href", "/help")
els.push(link)
_n := sheet.Compute(els, css.Env { width = 900.0, height = 700.0 })
println "wide", css.ValueText(sheet.Style(1), "flex-direction"), css.ValueText(sheet.Style(1), "padding-top")
println "button", css.ValueText(sheet.Style(2), "background-color"), css.ValueText(sheet.Style(2), "transition-duration")
top := css.HoverChain(els, 2)
println "hover touches", sheet.Restyle(els, top), "elements:", css.ValueText(sheet.Style(2), "background-color")
mut b := els.ref(2)
b.pressed = true
_p := sheet.Restyle(els, 2)
println "pressed", css.ValueText(sheet.Style(2), "transform")
top2 := css.HoverChain(els, 3)
_q := sheet.Restyle(els, top2)
println "link", css.ValueText(sheet.Style(3), "text-decoration-line"), css.ValueText(sheet.Style(3), "cursor")
_m := sheet.Compute(els, css.Env { width = 500.0, height = 700.0, dark = true })
println "narrow", css.ValueText(sheet.Style(1), "flex-direction"), css.ValueText(sheet.Style(1), "padding-top")
repeat els.len() in i:
mut x := els.ref(i)
x.Free()
end
els.free()
endCompiled style programs
A page built with --ui=native does not parse CSS when it runs. At compile time the compiler fills a Program with CompileDecls (one id per distinct declaration list), CompileRule and CompileCss: shorthands are expanded, values are tokenized and validated, selectors and media conditions are compiled, and anything invalid is reported through ProgramErrors. ProgramSource then writes a Salam function that rebuilds the same program from literals, one call per declaration, and the program turns it into a sheet with SheetFromProgram. Elements point at declaration lists through decl_base, decl_hover, decl_focus and decl_active, so computing styles never touches CSS text. Only a style value that is a runtime expression goes through DynDecl, which parses that one value once and caches it. The user agent sheet is itself a generated program, so NewSheet no longer parses CSS either.
import gui.css
import mem
func styles(): css.Program:
mut p := css.NewProgram()
p.AddSimple(3, "card", "", 0, 0, 0, false)
p.AddCompound(0, 1, 0)
p.AddSelector(0, 1, 1000, false, false)
p.AddMedia(-1, [css.Fn(""), css.Kw("max-width"), css.Delim(58, false), css.Dim(600.0, "px"), css.Close()])
p.AddDecl("padding-top", false, [css.Dim(12.0, "px")])
p.AddDecl("color", true, [css.Hash("334155")])
p.AddDecl("font-family", false, [css.KwAs("vazirmatn", "Vazirmatn"), css.Comma(), css.Kw("sans-serif")])
p.AddDecl("line-height", false, [css.Num(1.5)])
p.AddDecl("order", false, [css.Int(2.0)])
p.AddDecl("width", false, [css.Pct(50.0)])
p.AddDecl("background-image", false, [css.Url("bg.png")])
p.AddVarDecl("--label", "\"hi\"", false)
p.EndList(8)
p.AddDecl("margin-top", false, [css.Str("x")])
p.EndList(1)
p.AddRule(0, 0, 0)
ret p
end
func main:
mut p := css.NewProgram()
card := css.CompileDecls(p, "padding: 16px; border-radius: 8px")
println "list", card, "same text", css.CompileDecls(p, "padding: 16px; border-radius: 8px"), "empty", css.CompileDecls(p, "")
println "rule", css.CompileRule(p, ".card:hover", "background: #eef", ""), css.CompileRule(p, ".card", "padding: 8px", "(max-width: 600px)")
println "css rules", css.CompileCss(p, "h1 { margin: 0 } @media (prefers-color-scheme: dark) { body { color: #eee } }")
_bad := css.CompileDecls(p, "colr: red")
println "errors", css.ProgramErrors(p)
e := css.ProgramError(p, 0)
println e
mem.Free(e as void*)
src := css.ProgramSource(p, "page_styles", "css")
println src.starts_with("func page_styles(): css.Program:")
mem.Free(src as void*)
wide := css.DynDecl(p, "width", "240px")
mut sheet := css.SheetFromProgram(p)
mut els := Vector {} as Vector<css.Element>
els.push(css.NewElement("page", -1))
mut box := css.NewElement("box", 0)
box.classes = "card"
box.decl_base = card
box.decl_hover = -1
box.decl_focus = -1
box.decl_active = -1
box.decl_dyn.push(wide)
els.push(box)
_n := sheet.Compute(els, css.Env { width = 500.0 })
cs := sheet.Style(1)
println "padding", css.LenText(cs.padding_top), "width", css.LenText(cs.width)
println "added again", sheet.AddProgram(p)
mut q := styles()
piece := css.Kw("auto")
println "piece", piece.kind, piece.text, piece.raw, piece.num, piece.code, piece.space, "program", q.id >= 0
repeat els.len() in i:
mut x := els.ref(i)
x.Free()
end
els.free()
sheet.Free()
q.Free()
p.Free()
endTyped values and colours
The program that ProgramSource writes carries values decided at compile time. A declaration is AddTyped with the integer property id from PropertyId; keywords, units and function names are indexes into one name table (KeywordId); lengths keep their number and unit, with absolute units already in pixels and angles in degrees; a calc() that needs nothing from the page is folded to one value; and every colour that does not depend on currentColor is resolved to straight RGBA for the light and the dark scheme. Loading such a program compares no strings and parses nothing.
Colours follow CSS Color 4 and 5: hex, the 148 named colours, transparent, currentColor, rgb(), hsl() and hwb() in the modern and the comma syntax, lab(), lch(), oklab(), oklch(), color() in srgb, srgb-linear, display-p3, a98-rgb, prophoto-rgb, rec2020, xyz, xyz-d50 and xyz-d65, color-mix() in any of those spaces with the four hue interpolation methods, relative colours such as rgb(from red r g calc(b * 2)), light-dark() and the system colours with Chromium's values for each scheme. Every colour inside sRGB matches Chromium; colours outside it are gamut mapped with the CSS Color 4 algorithm, where Chromium clips. Gradients interpolate in the space given with in, and in Oklab when a stop uses one of the newer syntaxes. When the operating system switches between light and dark, SetColorScheme restyles only the elements that depend on the scheme.
import gui.css
import mem
func styles(): css.Program:
mut p := css.NewProgram()
p.AddTyped(css.PropertyId("display"), 0, [css.KwId(css.KeywordId("flex"))])
p.AddTyped(css.PropertyId("margin-top"), 0, [css.DimId(1.5, css.KeywordId("em"))])
p.AddTyped(css.PropertyId("width"), 0, [css.FnId(css.KeywordId("calc")), css.Pct(100.0), css.Delim(45, true), css.DimId(20.0, css.KeywordId("px")), css.Close()])
p.AddTyped(css.PropertyId("color-scheme"), 2, [css.KwId(css.KeywordId("light")), css.KwId(css.KeywordId("dark"))])
p.AddTyped(css.PropertyId("color"), 2, [css.ColorValue(0x111111ff, 0xeeeeeeff, 1)])
p.EndList(5)
ret p
end
func main:
name := css.PropertyName(css.PropertyId("color"))
kw := css.KeywordName(css.KeywordId("flex"))
println "ids", css.PropertyId("color"), name, css.KeywordId("flex"), kw
mem.Free(name as void*)
mem.Free(kw as void*)
piece := css.ColorValue(0x3366aaff, 0x99bbffff, 1)
println "piece", piece.id, piece.color, piece.dark, css.KwId(5).id
mut c := css.Color {}
_ok := css.ParseColor("oklch(0.7 0.1 30)", c)
println "oklch", c.r, c.g, c.b
mixed := css.ColorText(css.MixColors(css.Color { r = 255 }, css.Color { b = 255, a = 0 }, 0.5))
println "mix", mixed
mem.Free(mixed as void*)
mut p := styles()
mut sheet := css.SheetFromProgram(p)
mut els := Vector {} as Vector<css.Element>
els.push(css.NewElement("page", -1))
mut box := css.NewElement("box", 0)
box.decl_base = 0
els.push(box)
_n := sheet.Compute(els, css.Env { width = 400.0 })
println "light", css.ValueText(sheet.Style(1), "color"), css.ValueText(sheet.Style(1), "width")
println "restyled", sheet.SetColorScheme(els, true)
println "dark", css.ValueText(sheet.Style(1), "color")
repeat els.len() in i:
mut x := els.ref(i)
x.Free()
end
els.free()
sheet.Free()
p.Free()
endTypes
Piece
struct PieceProgramSource. Build it with Kw, Num, Dim and the other constructors rather than by hand.| Name | Type | Description |
|---|---|---|
kind | int = 0 | The token kind. |
num | f64 = 0 | The number of a number, dimension or percentage. |
text | str = "" | The keyword, unit, function name, string, URL or hash text. |
raw | str = "" | The keyword as written, when it differs from the lower case text (font family names keep their case). |
code | int = 0 | The character of a delimiter, or 1 for a number written as an integer. |
space | bool = false | Whether white space came before a delimiter. |
id | int = -1 | The index of a keyword, unit or function name in the name table, or -1 when the piece carries its text instead. |
color | i64 = 0 | A resolved colour as straight RGBA in one integer, 0xRRGGBBAA, for the light scheme. |
dark | i64 = 0 | The same colour for the dark scheme; equal to color unless the value used light-dark() or a system colour. |
import gui.css
import mem
func styles(): css.Program:
mut p := css.NewProgram()
p.AddSimple(3, "card", "", 0, 0, 0, false)
p.AddCompound(0, 1, 0)
p.AddSelector(0, 1, 1000, false, false)
p.AddMedia(-1, [css.Fn(""), css.Kw("max-width"), css.Delim(58, false), css.Dim(600.0, "px"), css.Close()])
p.AddDecl("padding-top", false, [css.Dim(12.0, "px")])
p.AddDecl("color", true, [css.Hash("334155")])
p.AddDecl("font-family", false, [css.KwAs("vazirmatn", "Vazirmatn"), css.Comma(), css.Kw("sans-serif")])
p.AddDecl("line-height", false, [css.Num(1.5)])
p.AddDecl("order", false, [css.Int(2.0)])
p.AddDecl("width", false, [css.Pct(50.0)])
p.AddDecl("background-image", false, [css.Url("bg.png")])
p.AddVarDecl("--label", "\"hi\"", false)
p.EndList(8)
p.AddDecl("margin-top", false, [css.Str("x")])
p.EndList(1)
p.AddRule(0, 0, 0)
ret p
end
func main:
mut p := css.NewProgram()
card := css.CompileDecls(p, "padding: 16px; border-radius: 8px")
println "list", card, "same text", css.CompileDecls(p, "padding: 16px; border-radius: 8px"), "empty", css.CompileDecls(p, "")
println "rule", css.CompileRule(p, ".card:hover", "background: #eef", ""), css.CompileRule(p, ".card", "padding: 8px", "(max-width: 600px)")
println "css rules", css.CompileCss(p, "h1 { margin: 0 } @media (prefers-color-scheme: dark) { body { color: #eee } }")
_bad := css.CompileDecls(p, "colr: red")
println "errors", css.ProgramErrors(p)
e := css.ProgramError(p, 0)
println e
mem.Free(e as void*)
src := css.ProgramSource(p, "page_styles", "css")
println src.starts_with("func page_styles(): css.Program:")
mem.Free(src as void*)
wide := css.DynDecl(p, "width", "240px")
mut sheet := css.SheetFromProgram(p)
mut els := Vector {} as Vector<css.Element>
els.push(css.NewElement("page", -1))
mut box := css.NewElement("box", 0)
box.classes = "card"
box.decl_base = card
box.decl_hover = -1
box.decl_focus = -1
box.decl_active = -1
box.decl_dyn.push(wide)
els.push(box)
_n := sheet.Compute(els, css.Env { width = 500.0 })
cs := sheet.Style(1)
println "padding", css.LenText(cs.padding_top), "width", css.LenText(cs.width)
println "added again", sheet.AddProgram(p)
mut q := styles()
piece := css.Kw("auto")
println "piece", piece.kind, piece.text, piece.raw, piece.num, piece.code, piece.space, "program", q.id >= 0
repeat els.len() in i:
mut x := els.ref(i)
x.Free()
end
els.free()
sheet.Free()
q.Free()
p.Free()
endProgram
struct Program| Name | Type | Description |
|---|---|---|
id | int = -1 | The handle number, -1 for a program that was not created with NewProgram yet. |
The example for this item is shown with the ones above: gui-css-Program.salam
AddDecl
func AddDecl(prop: str, important: bool, value: Piece)ProgramSource now writes AddTyped.The example for this item is shown with the ones above: gui-css-Program.salam
AddTyped
func AddTyped(prop: int, flags: int, value: Piece)!important, 2 when the value depends on the colour scheme) and the value as pieces. This is what ProgramSource writes; loading it compares no strings and parses nothing.import gui.css
import mem
func styles(): css.Program:
mut p := css.NewProgram()
p.AddTyped(css.PropertyId("display"), 0, [css.KwId(css.KeywordId("flex"))])
p.AddTyped(css.PropertyId("margin-top"), 0, [css.DimId(1.5, css.KeywordId("em"))])
p.AddTyped(css.PropertyId("width"), 0, [css.FnId(css.KeywordId("calc")), css.Pct(100.0), css.Delim(45, true), css.DimId(20.0, css.KeywordId("px")), css.Close()])
p.AddTyped(css.PropertyId("color-scheme"), 2, [css.KwId(css.KeywordId("light")), css.KwId(css.KeywordId("dark"))])
p.AddTyped(css.PropertyId("color"), 2, [css.ColorValue(0x111111ff, 0xeeeeeeff, 1)])
p.EndList(5)
ret p
end
func main:
name := css.PropertyName(css.PropertyId("color"))
kw := css.KeywordName(css.KeywordId("flex"))
println "ids", css.PropertyId("color"), name, css.KeywordId("flex"), kw
mem.Free(name as void*)
mem.Free(kw as void*)
piece := css.ColorValue(0x3366aaff, 0x99bbffff, 1)
println "piece", piece.id, piece.color, piece.dark, css.KwId(5).id
mut c := css.Color {}
_ok := css.ParseColor("oklch(0.7 0.1 30)", c)
println "oklch", c.r, c.g, c.b
mixed := css.ColorText(css.MixColors(css.Color { r = 255 }, css.Color { b = 255, a = 0 }, 0.5))
println "mix", mixed
mem.Free(mixed as void*)
mut p := styles()
mut sheet := css.SheetFromProgram(p)
mut els := Vector {} as Vector<css.Element>
els.push(css.NewElement("page", -1))
mut box := css.NewElement("box", 0)
box.decl_base = 0
els.push(box)
_n := sheet.Compute(els, css.Env { width = 400.0 })
println "light", css.ValueText(sheet.Style(1), "color"), css.ValueText(sheet.Style(1), "width")
println "restyled", sheet.SetColorScheme(els, true)
println "dark", css.ValueText(sheet.Style(1), "color")
repeat els.len() in i:
mut x := els.ref(i)
x.Free()
end
els.free()
sheet.Free()
p.Free()
endAddVarDecl
func AddVarDecl(prop: str, value: str, important: bool)var() and is resolved when styles are computed.The example for this item is shown with the ones above: gui-css-Program.salam
EndList
func EndList(count: int)The example for this item is shown with the ones above: gui-css-Program.salam
AddMedia
func AddMedia(parent: int, condition: Piece)The example for this item is shown with the ones above: gui-css-Program.salam
AddSimple
func AddSimple(kind: int, name: str, value: str, op: int, a: int, b: int, icase: bool)The example for this item is shown with the ones above: gui-css-Program.salam
AddCompound
func AddCompound(first: int, count: int, combinator: int)The example for this item is shown with the ones above: gui-css-Program.salam
AddSelector
func AddSelector(first: int, count: int, specificity: int, state_left: bool, sibling: bool)The example for this item is shown with the ones above: gui-css-Program.salam
AddRule
func AddRule(selector: int, list: int, media: int)The example for this item is shown with the ones above: gui-css-Program.salam
Free
func Free()The example for this item is shown with the ones above: gui-css-Program.salam
ComputedStyle
struct ComputedStyle| Name | Type | Description |
|---|---|---|
display | Display | Computed display. |
position | cssbox.Position | Computed position. |
top | Len | Computed top. |
right | Len | Computed right. |
bottom | Len | Computed bottom. |
left | Len | Computed left. |
box_sizing | cssbox.BoxSizing | Computed box-sizing. |
width | Len | Computed width. |
height | Len | Computed height. |
min_width | Len | Computed min-width. |
min_height | Len | Computed min-height. |
max_width | Len | Computed max-width. |
max_height | Len | Computed max-height. |
aspect_ratio | f64 = 0 | Computed aspect-ratio. |
margin_top | Len | Computed margin-top. |
margin_right | Len | Computed margin-right. |
margin_bottom | Len | Computed margin-bottom. |
margin_left | Len | Computed margin-left. |
padding_top | Len | Computed padding-top. |
padding_right | Len | Computed padding-right. |
padding_bottom | Len | Computed padding-bottom. |
padding_left | Len | Computed padding-left. |
border_top | BorderSide | Computed border-top. |
border_right | BorderSide | Computed border-right. |
border_bottom | BorderSide | Computed border-bottom. |
border_left | BorderSide | Computed border-left. |
radius_top_left | Corner | Computed border-top-left-radius. |
radius_top_right | Corner | Computed border-top-right-radius. |
radius_bottom_right | Corner | Computed border-bottom-right-radius. |
radius_bottom_left | Corner | Computed border-bottom-left-radius. |
overflow_x | cssbox.Overflow | Computed overflow-x. |
overflow_y | cssbox.Overflow | Computed overflow-y. |
direction | cssbox.Direction | Computed direction. |
flex_direction | cssbox.FlexDirection | Computed flex-direction. |
flex_wrap | cssbox.FlexWrap | Computed flex-wrap. |
flex_grow | f64 = 0 | Computed flex-grow. |
flex_shrink | f64 = 1 | Computed flex-shrink. |
flex_basis | Len | Computed flex-basis. |
justify_content | cssbox.Align | Computed justify-content. |
align_items | cssbox.Align | Computed align-items. |
align_self | cssbox.Align | Computed align-self. |
align_content | cssbox.Align | Computed align-content. |
justify_items | cssbox.Align | Computed justify-items. |
justify_self | cssbox.Align | Computed justify-self. |
row_gap | Len | Computed row-gap. |
column_gap | Len | Computed column-gap. |
order | int = 0 | Computed order. |
z_index | int = 0 | Computed z-index. |
z_auto | bool = true | Whether z-index is auto. |
float_mode | Float | Computed float. |
clear | Clear | Computed clear. |
vertical_align | VerticalAlign | Computed vertical-align. |
vertical_align_len | Len | The length when vertical_align is Length. |
color | Color | Computed color. |
background_color | Color | Computed background-color. |
backgrounds | Vector | Background layers, first on top, combining background-image and the per-layer background properties. |
box_shadows | Vector | Computed box-shadow. |
outline | BorderSide | outline width, style and colour. |
outline_offset | f64 = 0 | Computed outline-offset. |
opacity | f64 = 1 | Computed opacity. |
transforms | Vector | Computed transform. |
filters | Vector | Computed filter, one entry per filter function. |
border_image | BorderImage | Computed border-image and its longhands. The border shorthand resets it. |
backdrop_filters | Vector | Computed backdrop-filter. |
transform_origin_x | Len | transform-origin, x. |
transform_origin_y | Len | transform-origin, y. |
translate_x | Len | The translate property, x. |
translate_y | Len | The translate property, y. |
rotate | f64 = 0 | The rotate property in degrees. |
scale_x | f64 = 1 | The scale property, x. |
scale_y | f64 = 1 | The scale property, y. |
visibility | Visibility | Computed visibility. |
cursor | str = "auto" | cursor keyword; url() cursors keep only their fallback keyword. |
pointer_events | bool = true | False when pointer-events is none. |
user_select | UserSelect | Computed user-select. |
font_family | str = "Times New Roman" | font-family as a list separated by ", "; see FontFamilies. The initial value is Times New Roman, as in Chromium. |
font_size | f64 = 16 | Computed font-size. |
font_size_keyword | f64 = 1 | The font size as a multiple of medium while it derives from a keyword, used to size monospace text like Chromium; zero otherwise. |
font_weight | int = 400 | Computed font-weight. |
font_style | FontStyle | Computed font-style. |
small_caps | bool = false | Computed font-variant-caps. |
font_stretch | f64 = 100 | Computed font-stretch. |
line_height | f64 = 19.2 | line-height in pixels. |
line_height_factor | f64 = 0 | The number when line-height is a plain number (it is inherited as a number); otherwise zero. |
line_height_normal | bool = true | Whether line-height is normal; line_height then holds 1.2 times the font size until the text package measures the font. |
letter_spacing | f64 = 0 | Computed letter-spacing. |
word_spacing | f64 = 0 | Computed word-spacing. |
text_align | TextAlign | Computed text-align. |
text_indent | Len | Computed text-indent. |
text_transform | TextTransform | Computed text-transform. |
white_space | WhiteSpace | Computed white-space. |
underline | bool = false | text-decoration-line has underline. |
overline | bool = false | text-decoration-line has overline. |
line_through | bool = false | text-decoration-line has line-through. |
decoration_style | DecorationStyle | Computed text-decoration-style. |
decoration_color | Color | Computed text-decoration-color. |
decoration_thickness | Len | Computed text-decoration-thickness. |
text_shadows | Vector | Computed text-shadow. |
text_overflow | TextOverflow | Computed text-overflow. |
word_break | WordBreak | Computed word-break. |
overflow_wrap | OverflowWrap | Computed overflow-wrap. |
tab_size | f64 = 8 | tab-size as a number of spaces, zero when given as a length. |
tab_size_px | f64 = 0 | tab-size in pixels when given as a length. |
list_style_type | str = "disc" | Computed list-style-type. |
list_style_position | ListPosition | Computed list-style-position. |
list_style_image | str = "" | Computed list-style-image. |
border_collapse | BorderCollapse | Computed border-collapse. |
border_spacing_x | f64 = 0 | Horizontal border-spacing. |
border_spacing_y | f64 = 0 | Vertical border-spacing. |
table_layout | TableLayout | Computed table-layout. |
caption_side | cssbox.CaptionSide | Computed caption-side of a table caption. |
grid_template_columns | str = "" | Computed grid-template-columns as CSS text with lengths in pixels, or empty for none. |
grid_template_rows | str = "" | Computed grid-template-rows, or empty for none. |
grid_template_areas | str = "" | Computed grid-template-areas as quoted rows, or empty for none. |
grid_auto_columns | str = "" | Computed grid-auto-columns, or empty for auto. |
grid_auto_rows | str = "" | Computed grid-auto-rows, or empty for auto. |
grid_auto_flow | cssbox.GridAutoFlow | Computed grid-auto-flow. |
grid_row_start | str = "" | Computed grid-row-start, or empty for auto. |
grid_row_end | str = "" | Computed grid-row-end, or empty for auto. |
grid_column_start | str = "" | Computed grid-column-start, or empty for auto. |
grid_column_end | str = "" | Computed grid-column-end, or empty for auto. |
transitions | Vector | Transitions, combining the four transition-* lists. |
caret_color | Color | Computed caret-color. |
accent_color | Color | Computed accent-color. |
accent_auto | bool = true | Whether accent-color is auto; accent_color then holds the system accent. |
appearance | str = "none" | appearance; form controls with auto are painted in the native look. |
color_scheme | ColorScheme | Computed color-scheme. |
used_dark | bool = false | Whether system colours resolve to their dark variants for this element (from color-scheme and the environment). |
object_fit | ObjectFit | Computed object-fit. |
object_position_x | Len | object-position, x. |
object_position_y | Len | object-position, y. |
import gui.css
func main:
mut sheet := css.NewSheet()
defer sheet.Free()
mut els := Vector {} as Vector<css.Element>
mut root := css.NewElement("page", -1)
root.base = "color: #222; font: 16px/1.5 Vazirmatn, sans-serif"
els.push(root)
mut card := css.NewElement("box", 0)
card.base = `display: flex; position: relative; top: 4px; flex-flow: row wrap; gap: 8px 2%; padding: 12px 16px; margin: 0 auto; border: 2px solid #ccc; border-radius: 12px; background: linear-gradient(to right, #fff 0%, #eee 100%), url(bg.png) center / cover no-repeat, #fafafa; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2); outline: 1px dashed red; outline-offset: 2px; opacity: 0.9; transform: rotate(5deg) scale(1.1); transform-origin: left top; translate: 4px 2px; rotate: 10deg; scale: 2; transition: opacity 300ms ease-out 100ms; cursor: pointer; z-index: 3; text-align: center; text-shadow: 1px 1px 2px black; letter-spacing: 1px; word-spacing: 2px; text-decoration: underline overline line-through wavy red 2px; list-style: square inside; caret-color: blue; accent-color: green; color-scheme: light dark; aspect-ratio: 4 / 3; overflow: hidden auto; white-space: nowrap; text-overflow: ellipsis; word-break: break-all; overflow-wrap: anywhere; tab-size: 4; vertical-align: middle; float: left; clear: both; user-select: none; pointer-events: none; visibility: visible; object-fit: cover; object-position: right bottom; border-collapse: collapse; border-spacing: 2px 4px; table-layout: fixed; appearance: none; font-style: italic; font-variant-caps: small-caps; font-stretch: condensed; text-transform: uppercase; text-indent: 1em; order: 2; flex-grow: 1; flex-shrink: 0; flex-basis: 50%; justify-content: center; align-items: stretch; align-self: flex-start; align-content: space-around; justify-items: start; justify-self: end; box-sizing: border-box; direction: ltr; min-width: 100px; max-width: 800px; min-height: 2em; max-height: none; width: 50%; height: auto; right: auto; bottom: auto; left: 0`
els.push(card)
_n := sheet.Compute(els, css.Env {})
cs := sheet.Style(1)
println cs.display, cs.position, css.LenText(cs.top), css.LenText(cs.right), css.LenText(cs.bottom), css.LenText(cs.left)
println cs.box_sizing, css.LenText(cs.width), css.LenText(cs.height), css.LenText(cs.min_width), css.LenText(cs.min_height), css.LenText(cs.max_width)
println css.LenText(cs.max_height), cs.aspect_ratio, css.LenText(cs.margin_top), css.LenText(cs.margin_right), css.LenText(cs.margin_bottom), css.LenText(cs.margin_left)
println css.LenText(cs.padding_top), css.LenText(cs.padding_right), css.LenText(cs.padding_bottom), css.LenText(cs.padding_left), cs.border_top.width, cs.border_top.style
println css.ColorText(cs.border_top.color), cs.border_right.width, cs.border_right.style, css.ColorText(cs.border_right.color), cs.border_bottom.width, cs.border_bottom.style
println css.ColorText(cs.border_bottom.color), cs.border_left.width, cs.border_left.style, css.ColorText(cs.border_left.color), css.LenText(cs.radius_top_left.h), css.LenText(cs.radius_top_left.v)
println css.LenText(cs.radius_top_right.h), css.LenText(cs.radius_top_right.v), css.LenText(cs.radius_bottom_right.h), css.LenText(cs.radius_bottom_right.v), css.LenText(cs.radius_bottom_left.h), css.LenText(cs.radius_bottom_left.v)
println cs.overflow_x, cs.overflow_y, cs.direction, cs.flex_direction, cs.flex_wrap, cs.flex_grow
println cs.flex_shrink, css.LenText(cs.flex_basis), cs.justify_content, cs.align_items, cs.align_self, cs.align_content
println cs.justify_items, cs.justify_self, css.LenText(cs.row_gap), css.LenText(cs.column_gap), cs.order, cs.z_index
println cs.z_auto, cs.float_mode, cs.clear, cs.vertical_align, css.LenText(cs.vertical_align_len), css.ColorText(cs.color)
println css.ColorText(cs.background_color), cs.backgrounds.len(), cs.box_shadows.len(), cs.outline.width, cs.outline.style, css.ColorText(cs.outline.color)
println cs.outline_offset, cs.opacity, cs.transforms.len(), css.LenText(cs.transform_origin_x), css.LenText(cs.transform_origin_y), css.LenText(cs.translate_x)
println css.LenText(cs.translate_y), cs.rotate, cs.scale_x, cs.scale_y, cs.visibility, "[" + cs.cursor + "]"
println cs.pointer_events, cs.user_select, "[" + cs.font_family + "]", cs.font_size, cs.font_size_keyword, cs.font_weight
println cs.font_style, cs.small_caps, cs.font_stretch, cs.line_height, cs.line_height_factor, cs.line_height_normal
println cs.letter_spacing, cs.word_spacing, cs.text_align, css.LenText(cs.text_indent), cs.text_transform, cs.white_space
println cs.underline, cs.overline, cs.line_through, cs.decoration_style, css.ColorText(cs.decoration_color), css.LenText(cs.decoration_thickness)
println cs.text_shadows.len(), cs.text_overflow, cs.word_break, cs.overflow_wrap, cs.tab_size, cs.tab_size_px
println "[" + cs.list_style_type + "]", cs.list_style_position, "[" + cs.list_style_image + "]", cs.border_collapse, cs.border_spacing_x, cs.border_spacing_y
println cs.table_layout, cs.transitions.len(), css.ColorText(cs.caret_color), css.ColorText(cs.accent_color), cs.accent_auto, "[" + cs.appearance + "]"
println cs.color_scheme, cs.used_dark, cs.object_fit, css.LenText(cs.object_position_x), css.LenText(cs.object_position_y)
l := cs.backgrounds[0]
println l.image, l.url.len(), l.repeating, l.angle, l.to_x, l.to_y, l.shape, l.extent, css.LenText(l.radius_x), css.LenText(l.radius_y), css.LenText(l.center_x), css.LenText(l.center_y)
println l.stops.len(), css.LenText(l.position_x), css.LenText(l.position_y), l.size_kind, css.LenText(l.size_w), css.LenText(l.size_h), l.repeat_x, l.repeat_y, l.clip, l.origin, l.fixed
st := l.stops[1]
println css.ColorText(st.color), css.LenText(st.pos), st.has_pos, st.hint
u := cs.backgrounds[1]
println u.image, u.url, u.size_kind, u.repeat_x
s := cs.box_shadows[0]
println s.x, s.y, s.blur, s.spread, css.ColorText(s.color), s.inset
f := cs.transforms[1]
println f.kind, css.LenText(f.x), css.LenText(f.y), f.a, f.b, f.c, f.d, f.e, f.f
t := cs.transitions[0]
println t.property, t.duration, t.delay, t.timing.kind
repeat els.len() in i:
mut x := els.ref(i)
x.Free()
end
els.free()
endDisplay
enum Displaydisplay, after blockification of flex items, floats, absolutely positioned boxes and the root.| Name | Type | Description |
|---|---|---|
Block | | The block value. |
Inline | | The inline value. |
InlineBlock | | The inline-block value. |
FlowRoot | | The flow-root value. |
Flex | | The flex value. |
InlineFlex | | The inline-flex value. |
Grid | | The grid value. |
InlineGrid | | The inline-grid value. |
ListItem | | The list-item value. |
Table | | The table value. |
InlineTable | | The inline-table value. |
TableRowGroup | | The table-row-group value. |
TableHeaderGroup | | The table-header-group value. |
TableFooterGroup | | The table-footer-group value. |
TableRow | | The table-row value. |
TableCell | | The table-cell value. |
TableColumn | | The table-column value. |
TableColumnGroup | | The table-column-group value. |
TableCaption | | The table-caption value. |
Contents | | contents: the children take the box's place. |
None | | none: no box. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
LenKind
enum LenKindLen holds.| Name | Type | Description |
|---|---|---|
Auto | | The auto value. |
Length | | A length or percentage. |
None | | The none value. |
Normal | | The normal value. |
MinContent | | The min-content value. |
MaxContent | | The max-content value. |
FitContent | | The fit-content value. |
Content | | The content value. |
Number | | A plain number, used by border-image widths, outsets and slices: px holds the number. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
BorderStyle
enum BorderStyle| Name | Type | Description |
|---|---|---|
None | | The none value. |
Hidden | | The hidden value. |
Solid | | The solid value. |
Dashed | | The dashed value. |
Dotted | | The dotted value. |
Double | | The double value. |
Groove | | The groove value. |
Ridge | | The ridge value. |
Inset | | The inset value. |
Outset | | The outset value. |
Auto | | The outline-only auto style, drawn as a focus ring. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
Visibility
enum Visibilityvisibility.| Name | Type | Description |
|---|---|---|
Visible | | The visible value. |
Hidden | | The hidden value. |
Collapse | | The collapse value. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
TextAlign
enum TextAligntext-align; start and end follow the direction.| Name | Type | Description |
|---|---|---|
Start | | The start value. |
End | | The end value. |
Left | | The left value. |
Right | | The right value. |
Center | | The center value. |
Justify | | The justify value. |
MatchParent | | The match-parent value. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
TextTransform
enum TextTransformtext-transform.| Name | Type | Description |
|---|---|---|
None | | The none value. |
Capitalize | | The capitalize value. |
Uppercase | | The uppercase value. |
Lowercase | | The lowercase value. |
FullWidth | | The full-width value. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
WhiteSpace
enum WhiteSpacewhite-space.| Name | Type | Description |
|---|---|---|
Normal | | The normal value. |
Pre | | The pre value. |
NoWrap | | The nowrap value. |
PreWrap | | The pre-wrap value. |
PreLine | | The pre-line value. |
BreakSpaces | | The break-spaces value. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
FontStyle
enum FontStylefont-style.| Name | Type | Description |
|---|---|---|
Normal | | The normal value. |
Italic | | The italic value. |
Oblique | | The oblique value. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
ImageKind
enum ImageKind| Name | Type | Description |
|---|---|---|
None | | No image. |
Url | | A url() image. |
Linear | | A linear gradient. |
Radial | | A radial gradient. |
Conic | | A conic gradient. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
RadialShape
enum RadialShape| Name | Type | Description |
|---|---|---|
Ellipse | | The ellipse value. |
Circle | | The circle value. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
RadialExtent
enum RadialExtent| Name | Type | Description |
|---|---|---|
FarthestCorner | | The farthest-corner value. |
FarthestSide | | The farthest-side value. |
ClosestCorner | | The closest-corner value. |
ClosestSide | | The closest-side value. |
Explicit | | Radii given as lengths. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
SizeKind
enum SizeKindbackground-size mode.| Name | Type | Description |
|---|---|---|
Explicit | | Width and height given (each may be auto). |
Cover | | The cover value. |
Contain | | The contain value. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
Repeat
enum Repeatbackground-repeat per axis.| Name | Type | Description |
|---|---|---|
Repeat | | The repeat value. |
NoRepeat | | The no-repeat value. |
Space | | The space value. |
Round | | The round value. |
Stretch | | The stretch value of border-image-repeat. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
BoxArea
enum BoxAreabackground-clip and background-origin.| Name | Type | Description |
|---|---|---|
BorderBox | | The border-box value. |
PaddingBox | | The padding-box value. |
ContentBox | | The content-box value. |
Text | | The text value. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
TransformKind
enum TransformKind| Name | Type | Description |
|---|---|---|
Translate | | translate() and its axis forms. |
Scale | | scale(); 3D rotations and perspective are kept as an identity scale. |
Rotate | | rotate(). |
Skew | | skew(), skewX(), skewY(). |
Matrix | | matrix(), or the 2D part of matrix3d(). |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
TimingKind
enum TimingKind| Name | Type | Description |
|---|---|---|
Linear | | The linear value. |
CubicBezier | | A cubic Bezier curve. |
Steps | | steps(). |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
StepPosition
enum StepPositionsteps() jumps.| Name | Type | Description |
|---|---|---|
JumpEnd | | The jump-end value. |
JumpStart | | The jump-start value. |
JumpNone | | The jump-none value. |
JumpBoth | | The jump-both value. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
DecorationStyle
enum DecorationStyletext-decoration-style.| Name | Type | Description |
|---|---|---|
Solid | | The solid value. |
Double | | The double value. |
Dotted | | The dotted value. |
Dashed | | The dashed value. |
Wavy | | The wavy value. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
ListPosition
enum ListPositionlist-style-position.| Name | Type | Description |
|---|---|---|
Outside | | The outside value. |
Inside | | The inside value. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
Float
enum Floatfloat, with logical values resolved.| Name | Type | Description |
|---|---|---|
None | | The none value. |
Left | | The left value. |
Right | | The right value. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
Clear
enum Clearclear.| Name | Type | Description |
|---|---|---|
None | | The none value. |
Left | | The left value. |
Right | | The right value. |
Both | | The both value. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
VerticalAlign
enum VerticalAlignvertical-align.| Name | Type | Description |
|---|---|---|
Baseline | | The baseline value. |
Sub | | The sub value. |
Super | | The super value. |
Top | | The top value. |
TextTop | | The text-top value. |
Middle | | The middle value. |
Bottom | | The bottom value. |
TextBottom | | The text-bottom value. |
Length | | A length or percentage in vertical_align_len. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
WordBreak
enum WordBreakword-break.| Name | Type | Description |
|---|---|---|
Normal | | The normal value. |
BreakAll | | The break-all value. |
KeepAll | | The keep-all value. |
BreakWord | | The break-word value. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
OverflowWrap
enum OverflowWrapoverflow-wrap.| Name | Type | Description |
|---|---|---|
Normal | | The normal value. |
Anywhere | | The anywhere value. |
BreakWord | | The break-word value. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
TextOverflow
enum TextOverflowtext-overflow.| Name | Type | Description |
|---|---|---|
Clip | | The clip value. |
Ellipsis | | The ellipsis value. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
BorderCollapse
enum BorderCollapseborder-collapse.| Name | Type | Description |
|---|---|---|
Separate | | The separate value. |
Collapse | | The collapse value. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
TableLayout
enum TableLayouttable-layout.| Name | Type | Description |
|---|---|---|
Auto | | The auto value. |
Fixed | | The fixed value. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
UserSelect
enum UserSelectuser-select.| Name | Type | Description |
|---|---|---|
Auto | | The auto value. |
None | | The none value. |
Text | | The text value. |
All | | The all value. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
ColorScheme
enum ColorSchemecolor-scheme.| Name | Type | Description |
|---|---|---|
Normal | | The normal value. |
Light | | The light value. |
Dark | | The dark value. |
LightDark | | light dark: follows the system scheme. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
ObjectFit
enum ObjectFitobject-fit.| Name | Type | Description |
|---|---|---|
Fill | | The fill value. |
Contain | | The contain value. |
Cover | | The cover value. |
None | | The none value. |
ScaleDown | | The scale-down value. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
Color
struct Color| Name | Type | Description |
|---|---|---|
r | int = 0 | Red, 0 to 255. |
g | int = 0 | Green, 0 to 255. |
b | int = 0 | Blue, 0 to 255. |
a | int = 255 | Alpha, 0 (transparent) to 255 (opaque). |
legacy | bool = true | Whether the colour was written as hex, a name, rgb(), hsl() or hwb(). Transitions and gradients between legacy colours stay in sRGB; any other colour makes them use Oklab. |
import gui.css
import mem
func main:
mut c := css.Color {}
ok := css.ParseColor("hsl(210 80% 50% / 0.5)", c)
t := css.ColorText(c)
println ok, c.r, c.g, c.b, c.a, t
mem.Free(t as void*)
mut ds := css.ParseDeclarations("margin: 4px 8px; color: red !important; --x: 1")
repeat ds.len() in i:
d := ds[i]
println d.name, d.value, d.important
end
css.FreeDeclarations(ds)
sp := css.SelectorSpecificity("#nav .item:hover > a")
println "specificity", sp.ids, sp.classes, sp.types
env := css.Env { width = 500.0, height = 800.0 }
println "media", css.MediaMatches("(max-width: 600px) and (orientation: portrait)", env)
ease := css.Timing {}
println "ease", ease.kind, ease.x1, ease.y1, ease.x2, ease.y2, ease.steps, ease.step_position, css.EasingAt(ease, 0.5) > 0.8
steps := css.Timing { kind = css.TimingKind.Steps, steps = 4, step_position = css.StepPosition.JumpEnd }
println "steps", css.EasingAt(steps, 0.6)
mut sheet := css.NewSheet()
defer sheet.Free()
mut els := Vector {} as Vector<css.Element>
els.push(css.NewElement("page", -1))
mut box := css.NewElement("box", 0)
box.base = "width: calc(100% - 2em); height: min(50vh, 300px); border-radius: 20px / 10px; transform: translate(10px, 0) rotate(90deg); font-family: Vazirmatn, Tahoma, sans-serif; display: flex; padding: 1em"
els.push(box)
_n := sheet.Compute(els, env)
cs := sheet.Style(1)
w := cs.width
wtext := css.LenText(w)
println "width", wtext, w.kind, w.px, w.pct, w.has_pct, w.calc.len() == 0, css.Resolve(w, 300.0)
mem.Free(wtext as void*)
println "needs basis", css.NeedsBasis(cs)
b := css.ToBox(cs)
bi := css.ToBoxIn(cs, 300.0, 200.0)
println "box", b.display, b.width.kind, bi.width.value, bi.height.value
m := css.TransformMatrix(cs, 100.0, 40.0)
println "matrix", m.a, m.b, m.c, m.d, m.e, m.f
r := css.UsedRadii(cs, 30.0, 40.0)
println "radii", r.top_left_x, r.top_left_y, r.top_right_x, r.top_right_y, r.bottom_right_x, r.bottom_right_y, r.bottom_left_x, r.bottom_left_y
mut fams := css.FontFamilies(cs)
println "families", fams.len(), fams[0], fams[2]
fams.free()
v := css.ValueText(cs, "border-top-left-radius")
println "value text", v
mem.Free(v as void*)
repeat els.len() in i:
mut x := els.ref(i)
x.Free()
end
els.free()
endLen
struct Lencalc() expression that mixes them non-linearly, or a keyword such as auto.| Name | Type | Description |
|---|---|---|
kind | LenKind | Whether this is a length or a keyword. |
px | f64 = 0 | The pixel part. |
pct | f64 = 0 | The percentage part, 50 for 50%. |
has_pct | bool = false | Whether a percentage part is present. |
calc | str = "" | A min(), max() or calc() expression in pixels and percentages when the value is not linear; resolve it with Resolve. |
The example for this item is shown with the ones above: gui-css-values.salam
Corner
struct Corner| Name | Type | Description |
|---|---|---|
h | Len | Horizontal radius. |
v | Len | Vertical radius. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
BorderSide
struct BorderSide| Name | Type | Description |
|---|---|---|
width | f64 = 0 | Width in pixels, zero when the style is none or hidden, and snapped to whole pixels like Chromium. |
style | BorderStyle | The line style. |
color | Color | The colour, currentColor already resolved. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
Shadow
struct Shadow| Name | Type | Description |
|---|---|---|
x | f64 = 0 | Horizontal offset in pixels. |
y | f64 = 0 | Vertical offset in pixels. |
blur | f64 = 0 | Blur radius in pixels. |
spread | f64 = 0 | Spread in pixels; always zero for text shadows. |
color | Color | The colour. |
inset | bool = false | Whether this is an inner shadow. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
ColorStop
struct ColorStop| Name | Type | Description |
|---|---|---|
color | Color | The colour. |
pos | Len | The position; for conic gradients the pixel part holds degrees. |
has_pos | bool = false | Whether a position was given. |
hint | bool = false | Whether this is a bare position that moves the midpoint between two colours. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
BgLayer
struct BgLayer| Name | Type | Description |
|---|---|---|
image | ImageKind | What the image is. |
url | str = "" | The address of a url() image. |
repeating | bool = false | Whether the gradient is a repeating one. |
angle | f64 = 180 | Linear gradient angle in degrees, or the from angle of a conic gradient. |
to_x | int = 0 | For to a corner: -1 left, 1 right; zero when the angle is used. |
to_y | int = 0 | For to a corner: -1 top, 1 bottom. |
shape | RadialShape | Radial gradient shape. |
extent | RadialExtent | Radial gradient size keyword, or explicit radii. |
radius_x | Len | Explicit horizontal radius. |
radius_y | Len | Explicit vertical radius. |
center_x | Len | Centre of a radial or conic gradient. |
center_y | Len | Vertical centre. |
stops | Vector | The colour stops. |
position_x | Len | background-position-x. |
position_y | Len | background-position-y. |
size_kind | SizeKind | cover, contain or explicit sizes. |
size_w | Len | Explicit width, or auto. |
size_h | Len | Explicit height, or auto. |
repeat_x | Repeat | Horizontal repeat. |
repeat_y | Repeat | Vertical repeat. |
clip | BoxArea | background-clip. |
origin | BoxArea | background-origin. |
interpolation | int = 0 | The colour space the gradient interpolates in, as a number: 0 srgb, 1 srgb-linear, 2 display-p3, 3 a98-rgb, 4 prophoto-rgb, 5 rec2020, 6 xyz-d50, 7 xyz-d65, 8 lab, 9 lch, 10 oklab, 11 oklch, 12 hsl, 13 hwb. Without in it is srgb when every stop is a legacy colour and oklab otherwise. |
hue_interpolation | int = 0 | The hue method for the polar spaces: 0 shorter, 1 longer, 2 increasing, 3 decreasing. |
interpolation_set | bool = false | Whether the gradient named its space with in. |
fixed | bool = false | Whether background-attachment is fixed. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
BorderImage
struct BorderImageborder-image: the image, how it is cut, how wide the parts are drawn, how far they reach outside the border box and how the edges repeat.| Name | Type | Description |
|---|---|---|
source | BgLayer | border-image-source: a gradient or url() layer, or an image of kind none. |
slice_top | Len | The top slice: a LenKind.Number in image pixels or a percentage of the image height. |
slice_right | Len | The right slice. |
slice_bottom | Len | The bottom slice. |
slice_left | Len | The left slice. |
fill | bool = false | Whether border-image-slice has fill, which draws the middle of the image too. |
width_top | Len | The top border-image-width: a number times the border width, a length, a percentage of the border image area, or auto. |
width_right | Len | The right width. |
width_bottom | Len | The bottom width. |
width_left | Len | The left width. |
outset_top | Len | The top border-image-outset: a number times the border width, or a length. |
outset_right | Len | The right outset. |
outset_bottom | Len | The bottom outset. |
outset_left | Len | The left outset. |
repeat_x | Repeat | How the top and bottom edges repeat: stretch, repeat, round or space. |
repeat_y | Repeat | How the left and right edges repeat. |
import gui.css
func main:
mut sheet := css.NewSheet()
defer sheet.Free()
mut els := Vector {} as Vector<css.Element>
mut card := css.NewElement("box", -1)
card.base = "border: 8px solid; border-image: linear-gradient(45deg, red, blue) 30% fill / 2 / 4px round stretch; background: linear-gradient(90deg in oklch, oklch(70% 0.15 30), 25%, oklch(60% 0.12 250))"
els.push(card)
_n := sheet.Compute(els, css.Env {})
cs := sheet.Style(0)
bi := cs.border_image
println "source:", css.ValueText(cs, "border-image-source")
println "slice:", css.LenText(bi.slice_top), css.LenText(bi.slice_right), css.LenText(bi.slice_bottom), css.LenText(bi.slice_left), "fill", bi.fill
println "width:", bi.width_top.kind == css.LenKind.Number, bi.width_top.px, bi.width_right.px, bi.width_bottom.px, bi.width_left.px
println "outset:", css.LenText(bi.outset_top), css.LenText(bi.outset_right), css.LenText(bi.outset_bottom), css.LenText(bi.outset_left)
println "repeat:", bi.repeat_x == css.Repeat.Round, bi.repeat_y == css.Repeat.Stretch, bi.source.image == css.ImageKind.Linear
bg := cs.backgrounds[0]
println "gradient space:", bg.interpolation, "hue:", bg.hue_interpolation, "written:", bg.interpolation_set
mut stops := css.GradientStops(bg, 200.0)
first := stops[0]
last := stops[stops.len() - 1]
println "stops at paint time:", stops.len(), css.ColorText(first.color), "at", first.pos.px, "to", css.ColorText(last.color), "at", last.pos.px
stops.free()
mut a := css.Color {}
mut b := css.Color {}
_x := css.ParseColor("oklch(70% 0.15 30)", a)
_y := css.ParseColor("oklch(60% 0.12 250)", b)
m := css.MixColors(a, b, 0.5)
println "legacy:", a.legacy, "transition midpoint:", css.ColorText(m)
els[0].Free()
els.free()
endTransformFn
struct TransformFntransform list.| Name | Type | Description |
|---|---|---|
kind | TransformKind | Which function. |
x | Len | Translate x. |
y | Len | Translate y. |
a | f64 = 1 | Scale x, rotation in degrees, skew x in degrees, or matrix a. |
b | f64 = 0 | Skew y in degrees, or matrix b. |
c | f64 = 0 | Matrix c. |
d | f64 = 1 | Scale y, or matrix d. |
e | f64 = 0 | Matrix e. |
f | f64 = 0 | Matrix f. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
FilterFn
struct FilterFnfilter or backdrop-filter list.| Name | Type | Description |
|---|---|---|
name | str = "" | The function name: blur, brightness, contrast, grayscale, sepia, saturate, hue-rotate, invert, opacity or drop-shadow. |
amount | f64 = 0 | The amount: pixels for blur, degrees for hue-rotate, a factor for the rest (percentages become fractions). |
shadow | Shadow | The shadow of drop-shadow. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
Matrix
struct Matrix[a c e; b d f], as in CSS matrix().| Name | Type | Description |
|---|---|---|
a | f64 = 1 | Row 1, column 1. |
b | f64 = 0 | Row 2, column 1. |
c | f64 = 0 | Row 1, column 2. |
d | f64 = 1 | Row 2, column 2. |
e | f64 = 0 | Horizontal translation. |
f | f64 = 0 | Vertical translation. |
The example for this item is shown with the ones above: gui-css-values.salam
Timing
struct Timingease become one), linear or steps(). The default is ease.| Name | Type | Description |
|---|---|---|
kind | TimingKind | Which kind of function. |
x1 | f64 = 0.25 | First control point x. |
y1 | f64 = 0.1 | First control point y. |
x2 | f64 = 0.25 | Second control point x. |
y2 | f64 = 1 | Second control point y. |
steps | int = 1 | Number of steps. |
step_position | StepPosition | Where the jumps happen. |
The example for this item is shown with the ones above: gui-css-values.salam
Transition
struct Transition| Name | Type | Description |
|---|---|---|
property | str = "all" | The property name, or all. |
duration | f64 = 0 | Duration in milliseconds. |
delay | f64 = 0 | Delay in milliseconds. |
timing | Timing | The timing function. |
The example for this item is shown with the ones above: gui-css-ComputedStyle.salam
Radii
struct RadiiUsedRadii.| Name | Type | Description |
|---|---|---|
top_left_x | f64 = 0 | The horizontal radius of the top left corner. |
top_left_y | f64 = 0 | The vertical radius of the top left corner. |
top_right_x | f64 = 0 | The horizontal radius of the top right corner. |
top_right_y | f64 = 0 | The vertical radius of the top right corner. |
bottom_right_x | f64 = 0 | The horizontal radius of the bottom right corner. |
bottom_right_y | f64 = 0 | The vertical radius of the bottom right corner. |
bottom_left_x | f64 = 0 | The horizontal radius of the bottom left corner. |
bottom_left_y | f64 = 0 | The vertical radius of the bottom left corner. |
The example for this item is shown with the ones above: gui-css-values.salam
Specificity
struct Specificity| Name | Type | Description |
|---|---|---|
ids | int = 0 | Number of id selectors. |
classes | int = 0 | Number of class, attribute and pseudo-class selectors. |
types | int = 0 | Number of type selectors. |
The example for this item is shown with the ones above: gui-css-values.salam
Declaration
struct Declaration| Name | Type | Description |
|---|---|---|
name | str = "" | Property name, a longhand after expansion. |
value | str = "" | The value text. |
important | bool = false | Whether it was marked !important. |
The example for this item is shown with the ones above: gui-css-values.salam
Env
struct Env| Name | Type | Description |
|---|---|---|
width | f64 = 1024 | Viewport width in pixels. |
height | f64 = 768 | Viewport height in pixels. |
dark | bool = false | Whether the system uses a dark colour scheme. |
reduced_motion | bool = false | Whether the user asked for less motion. |
hover | bool = true | Whether the main pointer can hover. |
fine_pointer | bool = true | Whether the main pointer is precise, like a mouse. |
dir | str = "ltr" | The page direction on the root, ltr or rtl. |
lang | str = "en" | The page language on the root. |
import gui.css
import mem
func main:
mut sheet := css.NewSheet()
defer sheet.Free()
println "rules", sheet.RuleCount() > 100
_a := sheet.AddRule(".card > p:first-child", "color: #334155; margin: 0 0 8px")
_b := sheet.AddMediaRule("(max-width: 600px)", ".card", "padding: 8px")
println "css rules", sheet.AddCss("@media (prefers-color-scheme: dark) { body { background: #111 } } a:hover { color: red }")
mut els := Vector {} as Vector<css.Element>
mut body := css.NewElement("page", -1)
body.base = "font-family: Vazirmatn, sans-serif; --gap: 12px"
els.push(body)
mut card := css.NewElement("box", 0)
card.id = "main"
card.classes = "card"
card.base = "display: flex; gap: var(--gap); padding: 16px"
card.AddMedia("(min-width: 1200px)", "padding: 32px")
els.push(card)
mut p := css.NewElement("paragraph", 1)
p.AddAttr("lang", "en")
els.push(p)
mut link := css.NewElement("link", 1)
link.AddAttr("href", "/next")
link.hover = "text-decoration: none"
link.focus = "outline: 2px solid blue"
link.active = "color: purple"
els.push(link)
println "tag", link.tag, link.kind, link.parent, link.HasAttr("href")
env := css.Env { width = 800.0, height = 600.0, dark = false, reduced_motion = false, hover = true, fine_pointer = true, dir = "ltr", lang = "en" }
println "distinct", sheet.Compute(els, env), "elements", sheet.Count()
cs := sheet.Style(2)
println "p", css.ValueText(cs, "color"), css.ValueText(cs, "margin-top"), css.ValueText(cs, "margin-bottom")
println "card", css.ValueText(sheet.Style(1), "column-gap"), css.ValueText(sheet.Style(1), "padding-top")
println "root", css.ValueText(sheet.RootStyle(), "display"), "same style", sheet.StyleId(2) == sheet.StyleId(2)
g := sheet.Var(2, "--gap")
println "var", g
mem.Free(g as void*)
println "matches", sheet.Matches("#main > a[href]", els, 3)
top := css.HoverChain(els, 3)
println "hovered", els[3].hovered, els[1].hovered, "restyled", sheet.Restyle(els, top)
println "after hover", css.ValueText(sheet.Style(3), "text-decoration-line"), "cascades", sheet.CascadeCount(), "distinct", sheet.DistinctStyles()
mut l2 := els.ref(3)
l2.focused = true
l2.focus_visible = true
l2.pressed = true
_r := sheet.Restyle(els, 3)
println "focus", css.ValueText(sheet.Style(3), "outline-style"), css.ValueText(sheet.Style(3), "color")
mut bare := css.EmptySheet()
defer bare.Free()
println "empty", bare.RuleCount(), "defaults added", bare.AddDefaults() > 0
ua := css.DefaultCss()
println "default css bytes", ua.len() > 1000, css.TagOf("ordered list")
mem.Free(ua as void*)
println "media", env.width, env.height, env.dark, env.reduced_motion, env.hover, env.fine_pointer, env.dir, env.lang, "[" + link.id + "]", "[" + link.classes + "]", "[" + link.base + "]"
repeat els.len() in i:
mut x := els.ref(i)
println i, x.attr_names.len(), x.attr_values.len(), x.media_conditions.len(), x.media_declarations.len()
x.Free()
end
els.free()
endElement
struct Element| Name | Type | Description |
|---|---|---|
kind | str = "box" | The page element key, such as paragraph. |
tag | str = "div" | The HTML tag that type selectors match. |
id | str = "" | The id. |
classes | str = "" | Class names separated by spaces. |
parent | int = -1 | Index of the parent, or -1 for the page. |
base | str = "" | The element's own declarations; they take part in the cascade like a class rule written after the global rules. |
inline_style | str = "" | The element's style attribute. It wins over every author rule whatever its specificity, like an inline style in a browser; only !important author rules beat it. |
hover | str = "" | Declarations for :hover. |
focus | str = "" | Declarations for :focus. |
active | str = "" | Declarations for :active. |
hovered | bool = false | Whether the element matches :hover. |
focused | bool = false | Whether it has focus. |
focus_visible | bool = false | Whether the focus should show a ring (keyboard focus); also counts as focused. |
pressed | bool = false | Whether it matches :active. |
attr_names | Vector | Attribute names, for attribute selectors and pseudo-classes such as :checked. |
attr_values | Vector | Attribute values, in the same order. |
media_conditions | Vector | Media conditions of the element's media children. |
media_declarations | Vector | Declarations for each media condition, in the same order. |
decl_base | int = -1 | Id of the element's own declaration list in the sheet's compiled program, or -1 to use base. |
decl_hover | int = -1 | Id of the compiled declaration list for :hover, or -1. |
decl_focus | int = -1 | Id of the compiled declaration list for :focus, or -1. |
decl_active | int = -1 | Id of the compiled declaration list for :active, or -1. |
decl_dyn | Vector | Ids of declaration lists made by DynDecl for style values known only at runtime; they apply after the element's own declarations. |
The example for this item is shown with the ones above: gui-css-Sheet.salam
AddAttr
func AddAttr(name: str, value: str)The example for this item is shown with the ones above: gui-css-Sheet.salam
AddMedia
func AddMedia(condition: str, declarations: str)The example for this item is shown with the ones above: gui-css-Sheet.salam
HasAttr
func HasAttr(name: str): boolThe example for this item is shown with the ones above: gui-css-Sheet.salam
Free
func Free()The example for this item is shown with the ones above: gui-css-Sheet.salam
Sheet
struct SheetCompute.The example for this item is shown with the ones above: gui-css-Sheet.salam
AddRule
func AddRule(selector: str, declarations: str): bool"color: red; margin: 0". Returns false when the selector is not supported, and the rule is then dropped as a browser would drop it.The example for this item is shown with the ones above: gui-css-Sheet.salam
AddMediaRule
func AddMediaRule(condition: str, selector: str, declarations: str): bool(max-width: 600px) holds for the Env given to Compute.The example for this item is shown with the ones above: gui-css-Sheet.salam
AddCss
func AddCss(text: str): int@media blocks, and returns the number of rules added. @supports and @layer blocks are read as if they apply; other at-rules are skipped.The example for this item is shown with the ones above: gui-css-Sheet.salam
RuleCount
func RuleCount(): intThe example for this item is shown with the ones above: gui-css-Sheet.salam
Compute
func Compute(elements &: Vector<Element>, env: Env): intThe example for this item is shown with the ones above: gui-css-Sheet.salam
Restyle
func Restyle(elements &: Vector<Element>, index: int): intThe example for this item is shown with the ones above: gui-css-Sheet.salam
SetColorScheme
func SetColorScheme(elements &: Vector<Element>, dark: bool): intlight-dark(), a system colour, color-scheme or var(), elements matched by a prefers-color-scheme rule whose result changed, and the descendants of every element whose style changed. Returns how many elements were computed again, 0 when the scheme did not change.The example for this item is shown with the ones above: gui-css-typed.salam
Count
func Count(): intCompute.The example for this item is shown with the ones above: gui-css-Sheet.salam
Style
func Style(index: int): ComputedStyleCompute.The example for this item is shown with the ones above: gui-css-Sheet.salam
RootStyle
func RootStyle(): ComputedStylehtml root that holds the page; :root rules and custom properties set there reach every element.The example for this item is shown with the ones above: gui-css-Sheet.salam
StyleId
func StyleId(index: int): intCompute.The example for this item is shown with the ones above: gui-css-Sheet.salam
DistinctStyles
func DistinctStyles(): intThe example for this item is shown with the ones above: gui-css-Sheet.salam
CascadeCount
func CascadeCount(): intCompute; shared styles and cache hits do not count.The example for this item is shown with the ones above: gui-css-Sheet.salam
Var
func Var(index: int, name: str): str--gap on an element, with nested var() resolved, or an empty string. The caller frees the result.The example for this item is shown with the ones above: gui-css-Sheet.salam
Matches
func Matches(selector: str, elements &: Vector<Element>, index: int): boolThe example for this item is shown with the ones above: gui-css-Sheet.salam
Free
func Free()The example for this item is shown with the ones above: gui-css-Sheet.salam
AddDefaults
func AddDefaults(): intNewSheet already does this.The example for this item is shown with the ones above: gui-css-Sheet.salam
AddProgram
func AddProgram(p: Program): intProgram. The first program added is the one that element decl_* ids refer to. Calling it again with the same program adds only what the program gained since, such as lists made by DynDecl, and returns how many rules and lists were added.The example for this item is shown with the ones above: gui-css-Program.salam
Functions
Kw
func Kw(text: str): Pieceauto or solid.The example for this item is shown with the ones above: gui-css-Program.salam
KwAs
func KwAs(text: str, raw: str): PieceThe example for this item is shown with the ones above: gui-css-Program.salam
Num
func Num(value: f64): Piece1.5.The example for this item is shown with the ones above: gui-css-Program.salam
Int
func Int(value: f64): Piece2; some properties accept only integers.The example for this item is shown with the ones above: gui-css-Program.salam
Dim
func Dim(value: f64, unit: str): Piece12px or 1.5em.The example for this item is shown with the ones above: gui-css-Program.salam
Pct
func Pct(value: f64): PieceThe example for this item is shown with the ones above: gui-css-Program.salam
Hash
func Hash(text: str): Piece#.The example for this item is shown with the ones above: gui-css-Program.salam
Str
func Str(text: str): PieceThe example for this item is shown with the ones above: gui-css-Program.salam
Url
func Url(text: str): Pieceurl() piece with its address.The example for this item is shown with the ones above: gui-css-Program.salam
Fn
func Fn(name: str): Piececalc or rgba; an empty name opens plain parentheses. Close it with Close.The example for this item is shown with the ones above: gui-css-Program.salam
Close
func Close(): PieceThe example for this item is shown with the ones above: gui-css-Program.salam
Comma
func Comma(): PieceThe example for this item is shown with the ones above: gui-css-Program.salam
Delim
func Delim(code: int, space: bool): Piece/, + or :, and whether white space came before it.The example for this item is shown with the ones above: gui-css-Program.salam
NewProgram
func NewProgram(): ProgramThe example for this item is shown with the ones above: gui-css-Program.salam
CompileDecls
func CompileDecls(p &: Program, text: str): int"padding: 20px; border-radius: 8px" and returns its id, or -1 when nothing in it is valid. The same text always gives the same id.The example for this item is shown with the ones above: gui-css-Program.salam
CompileRule
func CompileRule(p &: Program, selector: str, decls: str, media: str): boolThe example for this item is shown with the ones above: gui-css-Program.salam
CompileCss
func CompileCss(p &: Program, text: str): int@media blocks included, and returns the number of rules read.The example for this item is shown with the ones above: gui-css-Program.salam
ProgramErrors
func ProgramErrors(p: Program): intThe example for this item is shown with the ones above: gui-css-Program.salam
ProgramError
func ProgramError(p: Program, index: int): strThe example for this item is shown with the ones above: gui-css-Program.salam
ProgramSource
func ProgramSource(p: Program, fn_name: str, css_pkg: str): strcss, an empty string inside this package, or the Persian package name, which also switches the names to Persian). Keywords are English. The caller frees it.The example for this item is shown with the ones above: gui-css-Program.salam
SheetFromProgram
func SheetFromProgram(p: Program): Sheetdecl_* ids.The example for this item is shown with the ones above: gui-css-Program.salam
DynDecl
func DynDecl(p &: Program, prop: str, value: str): intdecl_dyn, or -1 when the value is invalid. Each distinct value is parsed once. Call Sheet.AddProgram before computing so the sheet sees the new list.The example for this item is shown with the ones above: gui-css-Program.salam
NewSheet
func NewSheet(): SheetThe example for this item is shown with the ones above: gui-css-Sheet.salam
EmptySheet
func EmptySheet(): SheetThe example for this item is shown with the ones above: gui-css-Sheet.salam
DefaultCss
func DefaultCss(): strThe example for this item is shown with the ones above: gui-css-Sheet.salam
TagOf
func TagOf(kind: str): strp for paragraph and div for box. Type selectors match these tags. The caller frees the result.The example for this item is shown with the ones above: gui-css-Sheet.salam
NewElement
func NewElement(kind: str, parent: int): ElementThe example for this item is shown with the ones above: gui-css-Sheet.salam
HoverChain
func HoverChain(elements &: Vector<Element>, target: int): intRestyle, or -1.The example for this item is shown with the ones above: gui-css-Sheet.salam
ToBox
func ToBox(cs: ComputedStyle): cssbox.Stylegui.cssbox style. A length that mixes a percentage with pixels, such as calc(100% - 2em), cannot be expressed there; use ToBoxIn when NeedsBasis says so.The example for this item is shown with the ones above: gui-css-values.salam
NeedsBasis
func NeedsBasis(cs: ComputedStyle): boolThe example for this item is shown with the ones above: gui-css-values.salam
ToBoxIn
func ToBoxIn(cs: ComputedStyle, cb_width: f64, cb_height: f64): cssbox.StyleToBox, but resolves mixed lengths against a containing block of the given width and height, the way layout would.The example for this item is shown with the ones above: gui-css-values.salam
Resolve
func Resolve(l: Len, basis: f64): f64calc(), min(), max() and clamp() evaluated.The example for this item is shown with the ones above: gui-css-values.salam
ParseColor
func ParseColor(text: str, out &: Color): boolrgb(), rgba(), hsl(), hsla(), hwb() in comma or space syntax, light-dark(), named and system colours and transparent. Returns false when the text is not a colour.The example for this item is shown with the ones above: gui-css-values.salam
ColorText
func ColorText(c: Color): strrgb(r, g, b) or rgba(r, g, b, a), the way a browser reports computed colours. The caller frees it.The example for this item is shown with the ones above: gui-css-values.salam
LenText
func LenText(l: Len): str16px, 50%, calc(50% - 10px), auto and so on. The caller frees it.The example for this item is shown with the ones above: gui-css-values.salam
ParseDeclarations
func ParseDeclarations(text: str): Vector<Declaration>FreeDeclarations.The example for this item is shown with the ones above: gui-css-values.salam
FreeDeclarations
func FreeDeclarations(list &: Vector<Declaration>)ParseDeclarations.The example for this item is shown with the ones above: gui-css-values.salam
SelectorSpecificity
func SelectorSpecificity(selector: str): SpecificityThe example for this item is shown with the ones above: gui-css-values.salam
MediaMatches
func MediaMatches(condition: str, env: Env): booland, or, not and commas.The example for this item is shown with the ones above: gui-css-values.salam
EasingAt
func EasingAt(t: Timing, x: f64): f64The example for this item is shown with the ones above: gui-css-values.salam
TransformMatrix
func TransformMatrix(cs: ComputedStyle, width: f64, height: f64): Matrixtranslate, rotate, scale and transform for a border box of the given size, around its transform-origin.The example for this item is shown with the ones above: gui-css-values.salam
ValueText
func ValueText(cs: ComputedStyle, property: str): strgetComputedStyle gives, for a property name such as margin-top; empty for properties the package does not keep. The caller frees it.The example for this item is shown with the ones above: gui-css-values.salam
UsedRadii
func UsedRadii(cs: ComputedStyle, width: f64, height: f64): RadiiThe example for this item is shown with the ones above: gui-css-values.salam
FontFamilies
func FontFamilies(cs: ComputedStyle): Vector<str>The example for this item is shown with the ones above: gui-css-values.salam
KeywordId
func KeywordId(name: str): intflex, px, calc) in the name table, or -1 for a name that is not in it. Names are only ever added at the end.The example for this item is shown with the ones above: gui-css-typed.salam
KeywordName
func KeywordName(id: int): strThe example for this item is shown with the ones above: gui-css-typed.salam
PropertyId
func PropertyId(name: str): intmargin-top, as used by AddTyped, or -1. Longhands are 0 to 121, shorthands start at 200 and logical properties at 300; new properties are only ever added at the end.The example for this item is shown with the ones above: gui-css-typed.salam
PropertyName
func PropertyName(id: int): strThe example for this item is shown with the ones above: gui-css-typed.salam
KwId
func KwId(id: int): PieceThe example for this item is shown with the ones above: gui-css-typed.salam
DimId
func DimId(value: f64, unit: int): Pieceem.The example for this item is shown with the ones above: gui-css-typed.salam
FnId
func FnId(id: int): Piececalc or linear-gradient. Close it with Close.The example for this item is shown with the ones above: gui-css-typed.salam
ColorValue
func ColorValue(light: i64, dark: i64, flags: int): Piece0xRRGGBBAA for the light and the dark scheme and flags (1 when the two differ, 2 when it was written in a syntax newer than hex, named, rgb(), hsl() and hwb(), which makes gradients interpolate in Oklab).The example for this item is shown with the ones above: gui-css-typed.salam
GradientStops
func GradientStops(l: BgLayer, length: f64): Vector<ColorStop>length pixels (360 for a conic gradient): positions in calc(), missing positions and out of order positions are fixed up as CSS says, colour hints are replaced by nine stops the way Chromium does, and segments in a space other than sRGB are split into short pieces mixed in that space. Each returned stop has pos.px set; free the vector.The example for this item is shown with the ones above: gui-css-BorderImage.salam
MixColors
func MixColors(start: Color, finish: Color, amount: f64): ColorThe example for this item is shown with the ones above: gui-css-typed.salam