This page describes how CSS property values are represented internally in LibWeb, how calc() and related math functions are modeled as a calculation tree, how that tree is simplified and resolved to concrete values, and how the CSS Typed Object Model (Typed OM) exposes these values to JavaScript.
For how the CSS parser creates these values from source text, see 4.3. For how StyleComputer selects and assigns values to elements, see 4.2. For how resolved Length values are used during layout, see 4.6.
StyleValue Class HierarchyStyleValue (defined in Libraries/LibWeb/CSS/StyleValues/StyleValue.h) is the reference-counted base class for all internal CSS value representations. Subclasses are selected via a Type enum, and the ENUMERATE_CSS_STYLE_VALUE_TYPES macro generates both the enum members and accessor helpers (is_length(), as_length(), etc.).
StyleValue inheritance and key subtypes
Sources: Libraries/LibWeb/CSS/StyleValues/StyleValue.h35-120 Libraries/LibWeb/CSS/StyleValues/StyleValue.cpp121-185
The full set of concrete types is enumerated by ENUMERATE_CSS_STYLE_VALUE_TYPES in StyleValue.h. The table below lists the most commonly referenced types:
| Type enum | Class | Stores |
|---|---|---|
Calculated | CalculatedStyleValue | A CalculationNode tree |
Length | LengthStyleValue | A Length (px, em, %, …) |
Angle | AngleStyleValue | An Angle (deg, rad, …) |
Number | NumberStyleValue | A double |
Integer | IntegerStyleValue | An i64 |
Percentage | PercentageStyleValue | A Percentage |
Keyword | KeywordStyleValue | A Keyword enum value |
Color | ColorStyleValue | A Gfx::Color |
Transformation | TransformationStyleValue | TransformFunction + arg list |
StyleValueList | StyleValueList | Vector<StyleValue> with separator |
Unresolved | UnresolvedStyleValue | Raw ComponentValue tokens |
Image | ImageStyleValue | A URL-loaded image |
Easing | EasingStyleValue | An easing function |
Sources: Libraries/LibWeb/CSS/StyleValues/StyleValue.h35-100
CalculatedStyleValue and the Calculation TreeCalculatedStyleValue (Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.h38-140) wraps a tree of CalculationNode objects that represent CSS math functions such as calc(), min(), max(), clamp(), and trigonometric/exponential functions.
CalculationContext (Parse Time)CalculationContext (Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.h30-36) holds information available at parse time:
CalculationContext::for_property() uses property_resolves_percentages_relative_to() and property_accepted_type_ranges() to configure the context for a given CSS property.
CalculationResolutionContext (Resolution Time)A separate CalculationResolutionContext struct (used during layout) provides the runtime environment: the viewport size, font metrics, and parent dimension needed to evaluate relative units. It contains a Length::ResolutionContext.
CalculationNode TreeCalculationNode (Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.h172-256) is the abstract, ref-counted base for all nodes. Nodes are categorized as:
Variant<Number, Angle, Flex, Frequency, Length, Percentage, Resolution, Time>Sum, Product, Negate, InvertMin, Max, Clamp, trig, Pow, Sqrt, etc.)The full node type list is defined by ENUMERATE_CALCULATION_NODE_TYPES (Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.h142-169):
CSS math functions → CalculationNode types
Sources: Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.h142-256 Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp1-50
NumericType and Type AlgebraEach CalculationNode stores an Optional<NumericType> computed at construction time. NumericType tracks the CSS type system used to validate and resolve calc expressions. Helper functions add_the_types() and multiply_the_types() implement the CSS type-addition and type-multiplication rules (Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp51-117).
The free function simplify_a_calculation_tree() (Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp120-215) walks the tree bottom-up. For each node, it:
with_simplified_children() on the node if any child changed.run_operation_if_possible() — if all children have resolved to numeric values, the operation is evaluated immediately and replaced with a NumericCalculationNode.After simplification, a NumericCalculationNode at the top level is clamped and NaN-censored by clamp_and_censor_numeric_value().
CalculatedStyleValue exposes per-type resolution methods. Callers check resolves_to_length() first, then call resolve_length(context):
| Method | Returns |
|---|---|
resolve_length(ctx) | Optional<Length> |
resolve_angle(ctx) | Optional<Angle> |
resolve_number(ctx) | Optional<double> |
resolve_integer(ctx) | Optional<i64> |
resolve_percentage(ctx) | Optional<Percentage> |
resolve_time(ctx) | Optional<Time> |
resolve_frequency(ctx) | Optional<Frequency> |
resolve_flex(ctx) | Optional<Flex> |
resolve_resolution(ctx) | Optional<Resolution> |
All resolution methods internally call resolve_value(), which evaluates the simplified tree using CalculationResult arithmetic (Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.h40-66).
serialize_a_math_function() (Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp237-400) follows the CSS Values 4 specification:
10px).calc(infinity * 1px).calc(...).sin(...), min(...), etc.CalculatedOr<T> PatternMany CSS properties accept either a plain dimension value or a calc() expression. The CalculatedOr<T> template (defined in Libraries/LibWeb/CSS/CalculatedOr.h) models this as a union that holds either a concrete T or a NonnullRefPtr<CalculatedStyleValue const>.
Concrete instantiations (Libraries/LibWeb/CSS/CalculatedOr.cpp):
| Type alias | Concrete type |
|---|---|
AngleOrCalculated | CalculatedOr<Angle> |
LengthOrCalculated | CalculatedOr<Length> |
NumberOrCalculated | CalculatedOr<Number> |
PercentageOrCalculated | CalculatedOr<Percentage> |
TimeOrCalculated | CalculatedOr<Time> |
FrequencyOrCalculated | CalculatedOr<Frequency> |
FlexOrCalculated | CalculatedOr<Flex> |
IntegerOrCalculated | CalculatedOr<i64> |
ResolutionOrCalculated | CalculatedOr<Resolution> |
Each specialization implements resolve_calculated() by delegating to the matching method on CalculatedStyleValue — for example, AngleOrCalculated::resolve_calculated() calls calculated->resolve_angle(context).
The create_style_value() method on each produces the matching StyleValue subclass for serialization.
TransformationStyleValue and Matrix ConversionTransformationStyleValue (Libraries/LibWeb/CSS/StyleValues/TransformationStyleValue.h) represents a single CSS transform function (e.g., translate(10px, 20px), rotate(45deg)). It stores:
TransformFunction enum value identifying the function.StyleValueVector holding the function arguments (each argument is a StyleValue).to_matrix()TransformationStyleValue::to_matrix() (Libraries/LibWeb/CSS/StyleValues/TransformationStyleValue.cpp101) converts the transform function and its arguments to a FloatMatrix4x4. The method:
resolve_length() or resolve_angle() on any CalculatedStyleValue arguments (requiring a PaintableBox for relative lengths).ErrorOr<FloatMatrix4x4> — failing if the value contains non-resolvable relative units and no PaintableBox is provided.Sources: Libraries/LibWeb/CSS/StyleValues/TransformationStyleValue.cpp38-200
TransformationStyleValue::identity_transformation(TransformFunction) (Libraries/LibWeb/CSS/StyleValues/TransformationStyleValue.cpp38-99) creates a no-op transform for a given function type (e.g., translate(0), rotate(0deg), scale(1)).
TransformationStyleValue::reify() converts the value to the appropriate CSSTransformComponent subclass:
CSSTranslate, CSSRotate, CSSScale, CSSSkew, CSSSkewX, CSSSkewY, CSSPerspective, CSSMatrixComponent.The CSS Typed OM provides typed JavaScript access to CSS property values. There are two separate class hierarchies that must not be confused:
StyleValue (Libraries/LibWeb/CSS/StyleValues/StyleValue.h) — internal C++ representation, RefCounted.CSSStyleValue (Libraries/LibWeb/CSS/CSSStyleValue.h) — JavaScript-exposed PlatformObject, GC-managed.CSS Typed OM class hierarchy
Sources: Libraries/LibWeb/CSS/CSSStyleValue.h Libraries/LibWeb/Forward.h262-297 Libraries/LibWeb/idl_files.cmake43-79
StyleValue::reify(JS::Realm&, FlyString const& associated_property) (Libraries/LibWeb/CSS/StyleValues/StyleValue.cpp172-176) is the default reification path: it creates a bare CSSStyleValue wrapping the internal value. Subclasses override this to produce richer Typed OM objects:
| Internal class | reify() produces |
|---|---|
CalculatedStyleValue | CSSMathSum / CSSMathProduct / CSSMathClamp / … |
NumericCalculationNode | CSSUnitValue |
TransformationStyleValue | CSSTranslate / CSSRotate / … |
Default StyleValue | CSSStyleValue (wraps source value) |
reify_children() (Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp217-227) handles creating CSSNumericArray from child CalculationNode objects for math operations.
CSSStyleValue::parse_a_css_style_value() (Libraries/LibWeb/CSS/CSSStyleValue.cpp74-104) is the entry point for the CSSStyleValue.parse() static method. It:
PropertyNameAndID::from_name().parse_css_value().subdivide_into_iterations() on the result to handle multi-valued properties.reify() on each iteration to produce CSSStyleValue instances.CSSStyleValue::create_an_internal_representation() (Libraries/LibWeb/CSS/CSSStyleValue.cpp130-137) is used when setting values back onto the CSSOM — each CSSStyleValue subclass implements this to produce the appropriate internal StyleValue.
CSSNumberish TypeThe Typed OM uses a CSSNumberish typedef (Libraries/LibWeb/Forward.h487):
This allows IDL operations that accept either a plain number or a CSSNumericValue.
The following diagram shows how a CSS property value flows from parsed text through to JavaScript-accessible typed values and back.
End-to-end value lifecycle
Sources: Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.h Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp Libraries/LibWeb/CSS/CSSStyleValue.cpp Libraries/LibWeb/CSS/CalculatedOr.cpp
Math function names and their parameter type rules are defined in a JSON data file processed by GenerateCSSMathFunctions.cpp (Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSMathFunctions.cpp), which generates:
MathFunction enum (with entries for each supported function name).math_function_from_string(StringView) for parsing.matches_angle(...), matches_length(...), etc.) used to validate calculation argument types at parse time.The CalculationContext provided at parse time controls which value types are accepted for a given property, and the generated code is used when constructing CalculationNode instances for each named function.
Sources: Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSMathFunctions.cpp1-130
Refresh this wiki