Skip to documentation
SLOP

tiny.css.value

Reference tiny.css value

Defined in tiny.css.

Typed CSS values and the sixteen byte declaration record they lower into.

API (31)

Actions

Public operations.

Types and contracts

Public types and contracts.

Namespaces

Public namespaces.

Values and defaults

Public values and defaults.

No direct callersNo direct callstiny.cssvalue
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Source: lib/css/src/value/parse.zig:14

zig
/// Which shapes a grammar admits, plus the keywords it names. One generic/// reader consumes this so a property table entry stays a single enum tag.pub const Accept = struct {    length: bool = false,    percent: bool = false,    number: bool = false,    integer: bool = false,    color: bool = false,    string: bool = false,    url: bool = false,    raw: bool = false,    keywords: []const Keyword = &.{},};

Source: lib/css/src/value/scalar.zig:355

zig
pub const Declaration = extern struct {    property: u32,    kind: u8,    unit: u8,    flags: u16,    a: u32,    b: u32,    /// The value this declaration carries. Importance is a cascade input    /// rather than part of the value, so it is dropped here.    pub fn value(self: Declaration) Value {        return .{            .kind = self.kind,            .unit = self.unit,            .flags = self.flags & ~flag_important,            .a = self.a,            .b = self.b,        };    }    pub fn important(self: Declaration) bool {        return self.flags & flag_important != 0;    }};

Source: lib/css/src/value/scalar.zig:210

zig
/// The value grammar a property accepts. `value.parse` switches on it, so a/// property table entry names a grammar rather than carrying a parser.pub const Grammar = enum(u8) {    length,    length_percentage,    length_percentage_auto,    size,    number,    integer,    opacity,    color,    string,    url,    display,    position,    overflow,    visibility,    box_sizing,    flex_direction,    flex_wrap,    justify,    @"align",    align_self,    text_align,    text_transform,    white_space,    font_style,    font_weight,    font_family,    line_height,    border_style,    text_decoration_line,    cursor,    list_style_type,    vertical_align,    content,    z_index,    gap,    flex_basis,    length_normal,    direction,    text_overflow,    word_break,    overflow_wrap,    object_fit,    pointer_events,    user_select,    list_style_position,    background_repeat,    background_size,    background_box,    background_attachment,};

Source: lib/css/src/value/scalar.zig:51

zig
/// Every keyword this engine understands, in one closed set so that a computed/// keyword is an integer rather than a byte slice.pub const Keyword = enum(u32) {    invalid = 0,    inherit,    initial,    unset,    revert,    auto,    none,    normal,    block,    @"inline",    inline_block,    flex,    inline_flex,    contents,    static,    relative,    absolute,    fixed,    sticky,    visible,    hidden,    scroll,    clip,    collapse,    content_box,    border_box,    row,    row_reverse,    column,    column_reverse,    nowrap,    wrap,    wrap_reverse,    flex_start,    flex_end,    center,    space_between,    space_around,    space_evenly,    start,    end,    stretch,    baseline,    left,    right,    justify,    capitalize,    uppercase,    lowercase,    pre,    pre_wrap,    pre_line,    break_spaces,    italic,    oblique,    bold,    bolder,    lighter,    solid,    dashed,    dotted,    double,    groove,    ridge,    inset,    outset,    underline,    overline,    line_through,    default,    pointer,    text,    move,    not_allowed,    grab,    grabbing,    crosshair,    wait,    help,    progress,    disc,    circle,    square,    decimal,    lower_alpha,    upper_alpha,    lower_roman,    upper_roman,    top,    middle,    bottom,    sub,    super,    text_top,    text_bottom,    min_content,    max_content,    fit_content,    content,    currentcolor,    transparent,    ltr,    rtl,    ellipsis,    break_all,    keep_all,    break_word,    anywhere,    fill,    contain,    cover,    scale_down,    all,    inside,    outside,    repeat,    repeat_x,    repeat_y,    no_repeat,    space,    round,    padding_box,    local,    /// Resolves a keyword by its CSS spelling, where an underscore in the tag    /// stands for a hyphen.    pub fn parse(word: []const u8) ?Keyword {        if (word.len == 0 or word.len > max_keyword_bytes) return null;        var buffer: [max_keyword_bytes]u8 = undefined;        for (word, 0..) |byte, index| {            buffer[index] = if (byte == '-') '_' else std.ascii.toLower(byte);        }        return std.meta.stringToEnum(Keyword, buffer[0..word.len]);    }    /// The CSS spelling of this keyword, with hyphens restored.    pub fn spelling(self: Keyword) []const u8 {        @setEvalBranchQuota(64_000);        return switch (self) {            inline else => |tag| comptime spell(@tagName(tag)),        };    }};

Source: lib/css/src/value/scalar.zig:7

zig
/// How the `a` and `b` words of a value are read.////// `asset` and `pair` are part of the published record layout and are produced/// by the tree publisher rather than by a stylesheet.pub const Kind = enum(u8) {    invalid = 0,    keyword = 1,    length = 2,    percent = 3,    number = 4,    color = 5,    string = 6,    asset = 7,    pair = 8,};

Source: lib/css/src/value/scalar.zig:20

zig
/// The unit a `length` carries. A percentage is a `Kind`, not a unit.pub const Unit = enum(u8) {    none = 0,    px = 1,    em = 2,    rem = 3,    ch = 4,    lh = 5,    ex = 6,    vw = 7,    vh = 8,    vmin = 9,    vmax = 10,    fr = 11,    deg = 12,    s = 13,    ms = 14,    /// Resolves a dimension unit by name, folded to ASCII lower case.    pub fn parse(spelling: []const u8) ?Unit {        const info = @typeInfo(Unit).@"enum";        inline for (info.field_names, info.field_values) |field_name, field_value| {            if (field_value != 0 and std.ascii.eqlIgnoreCase(spelling, field_name)) {                return @fromBackingInt(@intCast(field_value));            }        }        return null;    }};

Source: lib/css/src/value/scalar.zig:267

zig
/// One computed value. Twelve bytes, laid out as the published declaration/// record minus its property word.pub const Value = extern struct {    kind: u8 = @backingInt(Kind.invalid),    unit: u8 = @backingInt(Unit.none),    flags: u16 = 0,    a: u32 = 0,    b: u32 = 0,    pub fn keyword(word: Keyword) Value {        return .{ .kind = @backingInt(Kind.keyword), .a = @backingInt(word) };    }    pub fn length(amount: f32, unit: Unit) Value {        return .{            .kind = @backingInt(Kind.length),            .unit = @backingInt(unit),            .a = @bitCast(amount),        };    }    pub fn percent(amount: f32) Value {        return .{ .kind = @backingInt(Kind.percent), .a = @bitCast(amount) };    }    pub fn number(amount: f32) Value {        return .{ .kind = @backingInt(Kind.number), .a = @bitCast(amount) };    }    pub fn color(packed_rgba: u32) Value {        return .{ .kind = @backingInt(Kind.color), .a = packed_rgba };    }    pub fn string(offset: u32, length_bytes: u32) Value {        return .{ .kind = @backingInt(Kind.string), .a = offset, .b = length_bytes };    }    pub fn valueKind(self: Value) Kind {        return @fromBackingInt(@intCast(self.kind));    }    pub fn valueUnit(self: Value) Unit {        return @fromBackingInt(@intCast(self.unit));    }    /// The keyword behind a keyword value, or `invalid` for any other kind.    pub fn asKeyword(self: Value) Keyword {        if (self.valueKind() != .keyword) return .invalid;        return @fromBackingInt(@intCast(self.a));    }    /// The scalar behind a length, percentage, or number.    pub fn asNumber(self: Value) f32 {        std.debug.assert(numeric(self.valueKind()));        return @bitCast(self.a);    }    /// The source span behind a string value.    pub fn asString(self: Value, source: []const u8) []const u8 {        std.debug.assert(self.valueKind() == .string);        return source[self.a..][0..self.b];    }    pub fn present(self: Value) bool {        return self.valueKind() != .invalid;    }    /// Binds this value to a property, producing the published record.    pub fn declare(self: Value, property: u32, important: bool) Declaration {        return .{            .property = property,            .kind = self.kind,            .unit = self.unit,            .flags = self.flags | (if (important) flag_important else 0),            .a = self.a,            .b = self.b,        };    }};

Source: lib/css/src/value/parse.zig:72

zig
/// The admitted shapes of one grammar.pub fn accepted(grammar: Grammar) Accept {    return switch (grammar) {        .length => .{ .length = true },        .length_percentage => .{ .length = true, .percent = true },        .length_percentage_auto => .{ .length = true, .percent = true, .keywords = &.{.auto} },        .size => .{ .length = true, .percent = true, .keywords = &.{            .auto,        .none,        .min_content,            .max_content, .fit_content,        } },        .number => .{ .number = true },        .integer => .{ .integer = true },        .opacity => .{ .number = true, .percent = true },        .color => .{ .color = true },        .string => .{ .string = true },        .url => .{ .url = true, .keywords = &.{.none} },        .display => .{ .keywords = &.{            .block,       .@"inline", .inline_block, .flex,            .inline_flex, .none,      .contents,        } },        .position => .{ .keywords = &.{ .static, .relative, .absolute, .fixed, .sticky } },        .overflow => .{ .keywords = &.{ .visible, .hidden, .scroll, .auto, .clip } },        .visibility => .{ .keywords = &.{ .visible, .hidden, .collapse } },        .box_sizing => .{ .keywords = &.{ .content_box, .border_box } },        .flex_direction => .{ .keywords = &.{ .row, .row_reverse, .column, .column_reverse } },        .flex_wrap => .{ .keywords = &.{ .nowrap, .wrap, .wrap_reverse } },        .justify => .{ .keywords = &.{            .flex_start,   .flex_end, .center, .space_between, .space_around,            .space_evenly, .start,    .end,    .stretch,       .normal,            .left,         .right,        } },        .@"align" => .{ .keywords = &.{            .flex_start, .flex_end, .center, .baseline,            .stretch,    .start,    .end,    .normal,        } },        .align_self => .{ .keywords = &.{            .auto,     .flex_start, .flex_end, .center,            .baseline, .stretch,    .start,    .end,        } },        .text_align => .{ .keywords = &.{ .left, .right, .center, .justify, .start, .end } },        .text_transform => .{ .keywords = &.{ .none, .capitalize, .uppercase, .lowercase } },        .white_space => .{ .keywords = &.{            .normal, .nowrap, .pre, .pre_wrap, .pre_line, .break_spaces,        } },        .font_style => .{ .keywords = &.{ .normal, .italic, .oblique } },        .font_weight => .{ .number = true, .keywords = &.{ .normal, .bold, .bolder, .lighter } },        .font_family => .{ .raw = true },        .line_height => .{            .number = true,            .length = true,            .percent = true,            .keywords = &.{.normal},        },        .border_style => .{ .keywords = &.{            .none,   .hidden, .solid, .dashed, .dotted,            .double, .groove, .ridge, .inset,  .outset,        } },        .text_decoration_line => .{ .keywords = &.{            .none, .underline, .overline, .line_through,        } },        .cursor => .{ .keywords = &.{            .auto, .default,  .pointer,   .text, .move, .not_allowed,            .grab, .grabbing, .crosshair, .wait, .help, .progress,        } },        .list_style_type => .{ .keywords = &.{            .none,        .disc,        .circle,      .square,      .decimal,            .lower_alpha, .upper_alpha, .lower_roman, .upper_roman,        } },        .vertical_align => .{ .length = true, .percent = true, .keywords = &.{            .baseline, .top, .middle, .bottom, .sub, .super, .text_top, .text_bottom,        } },        .content => .{ .string = true, .keywords = &.{ .none, .normal } },        .z_index => .{ .integer = true, .keywords = &.{.auto} },        .gap => .{ .length = true, .percent = true, .keywords = &.{.normal} },        .flex_basis => .{ .length = true, .percent = true, .keywords = &.{ .auto, .content } },        .length_normal => .{ .length = true, .keywords = &.{.normal} },        .direction => .{ .keywords = &.{ .ltr, .rtl } },        .text_overflow => .{ .keywords = &.{ .clip, .ellipsis } },        .word_break => .{ .keywords = &.{ .normal, .break_all, .keep_all } },        .overflow_wrap => .{ .keywords = &.{ .normal, .break_word, .anywhere } },        .object_fit => .{ .keywords = &.{ .fill, .contain, .cover, .none, .scale_down } },        .pointer_events => .{ .keywords = &.{ .auto, .none } },        .user_select => .{ .keywords = &.{ .auto, .none, .text, .all } },        .list_style_position => .{ .keywords = &.{ .inside, .outside } },        .background_repeat => .{ .keywords = &.{            .repeat, .repeat_x, .repeat_y, .no_repeat, .space, .round,        } },        .background_size => .{ .length = true, .percent = true, .keywords = &.{            .auto, .cover, .contain,        } },        .background_box => .{ .keywords = &.{ .border_box, .padding_box, .content_box } },        .background_attachment => .{ .keywords = &.{ .scroll, .fixed, .local } },    };}
Called byCallsNo direct callsvalueparsevalueaccepted
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/css/src/value/parse.zig:57

zig
/// Whether `source[start..end]` carries a `var()` reference, which defers the/// value to computed value time.pub fn hasVariable(source: []const u8, start: u32, end: u32) bool {    std.debug.assert(start <= end);    std.debug.assert(end <= source.len);    var tokenizer = token.Tokenizer{ .source = source[0..end], .index = start };    var guard: usize = 0;    while (guard <= source.len + 1) : (guard += 1) {        const next = tokenizer.next();        if (next.kind == .eof) return false;        if (next.kind != .function) continue;        if (std.ascii.eqlIgnoreCase(next.value(source), "var")) return true;    }    return false;}
Called byCallsNo direct callstest sourcelib.css.src.value.parsetest: a variable reference is detecte...valuehasVariable
Static calls · unresolved targets: 0 · external targets: 2.

Source: lib/css/src/value/parse.zig:32

zig
/// Reads `source[start..end]` under `grammar`. String offsets are absolute, so/// a computed string value indexes the same source the sheet borrows./// Returns an invalid value when the text is not a complete match.pub fn parse(grammar: Grammar, source: []const u8, start: u32, end: u32) Value {    std.debug.assert(start <= end);    std.debug.assert(end <= source.len);    const rules = accepted(grammar);    var tokenizer = token.Tokenizer{ .source = source[0..end], .index = start };    const first = nextMeaningful(&tokenizer);    if (first.kind == .eof) return .{};    if (first.kind == .ident) {        if (Keyword.parse(first.value(source))) |word| {            if (contains(&wide, word)) return sealed(&tokenizer, Value.keyword(word));        }    }    if (rules.raw) {        const body = std.mem.trim(u8, source[start..end], " \t\r\n\x0C");        if (body.len == 0) return .{};        const offset = @intFromPtr(body.ptr) - @intFromPtr(source.ptr);        return Value.string(@intCast(offset), @intCast(body.len));    }    const value = single(rules, &tokenizer, first, source);    if (!value.present()) return .{};    return sealed(&tokenizer, value);}
Called byCallsprivate sourcelib.css.src.value.parseexpectValuetest sourcelib.css.src.value.parsetest: a raw grammar keeps the whole t...test sourcelib.css.src.value.parsetest: a string grammar keeps the quot...test sourcelib.css.src.value.parsetest: a url value borrows the resourc...valueacceptedprivate sourcelib.css.src.value.parsecontainsprivate sourcelib.css.src.value.parsenextMeaningfulprivate sourcelib.css.src.value.parsesealedprivate sourcelib.css.src.value.parsesingle+3 morevalueparse
Static calls · unresolved targets: 0 · external targets: 2.

Source: lib/css/src/value/parse.zig:27

zig
/// The four keywords every property accepts.pub const wide = [_]Keyword{ .inherit, .initial, .unset, .revert };
Called byCallsNo direct callsvalueparseprivate sourcelib.css.src.value.parsesingletest sourcelib.css.src.value.scalartest: a keyword round trips through i...value.Keywordparse
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersprivate sourcelib.css.src.value.scalarspellvalue.Keywordspelling
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.css.src.value.parsedimensiontest sourcelib.css.src.value.scalartest: a unit resolves by name and rej...value.Unitparse
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersvalue.ValuevalueKindvalue.ValueasKeyword
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersvalue.ValuevalueKindprivate sourcelib.css.src.value.scalarnumericvalue.ValueasNumber
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersvalue.ValuevalueKindvalue.ValueasString
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.css.src.cascade.resolvecoloredprivate sourcelib.css.src.value.parsefunctionValueprivate sourcelib.css.src.value.parseidentColorprivate sourcelib.css.src.value.parsesinglevalue.Valuecolor
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.css.src.cascade.resolvetest: revert drops its own origin and...test sourcelib.css.src.cascade.resolvetest: the four wide keywords resolve ...propertyexpandprivate sourcelib.css.src.value.parseidentColorvalueparse+4 morevalue.Valuekeyword
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.css.src.cascade.resolvetest: an undeclared property inherits...test sourcelib.css.src.cascade.resolvetest: specificity settles a level bef...test sourcelib.css.src.cascade.resolvetest: the four wide keywords resolve ...private sourcelib.css.src.property.expandflexprivate sourcelib.css.src.value.parsedimension+3 morevalue.Valuelength
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.css.src.property.expandflexprivate sourcelib.css.src.value.parsenumerictest sourcelib.ui.src.style.computedtest: lowering places outline reach a...value.Valuenumber
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.css.src.value.parsesinglevalue.Valuepercent
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersvalue.ValuevalueKindvalue.Valuepresent
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.css.src.value.parsefunctionValuevalueparseprivate sourcelib.css.src.value.parsesingletest sourcelib.css.src.value.scalartest: a string value borrows a span o...value.Valuestring
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsvalue.ValueasKeywordvalue.ValueasNumbervalue.ValueasStringvalue.Valuepresentvalue.ValuevalueKind
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/css/src/value/scalar.zig:263

zig
/// Bit zero of the `flags` word marks an important declaration.pub const flag_important: u16 = 1;

Source: lib/css/src/root.zig:45

zig
pub const value = @import("value/root.zig");

Source: lib/css/src/value/root.zig

zig
//! Typed CSS values and the sixteen byte declaration record they lower into.//!//! A stylesheet parses strings once at load. Everything downstream reads a//! `Declaration`: a property word, a kind, a unit, a flag word, and two scalar//! words. A directly authored inline style writes the same record without//! parsing anything, so one representation serves both producers.//!//! Lengths, percentages, numbers, colours, and keywords fit the two scalar//! words outright. A string keeps a byte offset and a length into the source//! the stylesheet borrows, so no value owns heap memory.//!//! `parse` is driven by a `Grammar` tag rather than by a property identifier,//! which keeps this namespace free of the property table and makes the value//! reader testable one grammar at a time.const parser = @import("parse.zig");const scalar = @import("scalar.zig");pub const color = @import("color.zig");pub const Accept = parser.Accept;pub const Declaration = scalar.Declaration;pub const Grammar = scalar.Grammar;pub const Keyword = scalar.Keyword;pub const Kind = scalar.Kind;pub const Unit = scalar.Unit;pub const Value = scalar.Value;pub const accepted = parser.accepted;pub const flag_important = scalar.flag_important;pub const hasVariable = parser.hasVariable;pub const parse = parser.parse;pub const wide = parser.wide;

Complete call list for value.parse

8 direct calls.

Complete caller list for value.Value.keyword

9 direct callers.

Complete caller list for value.Value.length

8 direct callers.

Audit

Definitions31
Public names31
Members216
Version26.7.0
Revisiondaab053ee433