# CSS Generated Files We generate a significant amount of CSS-related code, taking in one or more .json files in [`Userland/Libraries/LibWeb/CSS`](../Userland/Libraries/LibWeb/CSS) and producing C++ code from them, located in `Build//Lagom/Userland/Libraries/LibWeb/CSS/`. It's likely that you'll need to work with these if you add or modify a CSS property or its values. The generators are found in [`Meta/Lagom/Tools/CodeGenerators/LibWeb`](../Meta/Lagom/Tools/CodeGenerators/LibWeb). They are run automatically as part of the build, and most of the time you can ignore them. ## Properties.json Each CSS property has an entry here, which describes what values it accepts, whether it's inherited, and similar data. This generates `PropertyID.h` and `PropertyID.cpp`. Most of this data is found in the information box for that property in the relevant CSS spec. The file is organized as a single JSON object, with keys being property names, and the values being the data for that property. Each property will have some set of these fields on it: (Note that required fields are not required on properties with `legacy-alias-for` or `logical-alias-for` set.) | Field | Required | Default | Description | Generated functions | |----------------------------|----------|---------|-------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------| | `affects-layout` | No | `true` | Boolean. Whether changing this property will invalidate the element's layout. | `bool property_affects_layout(PropertyID)` | | `affects-stacking-context` | No | `false` | Boolean. Whether this property can cause a new stacking context for the element. | `bool property_affects_stacking_context(PropertyID)` | | `animation-type` | Yes | | String. How the property should be animated. Defined by the spec. See below. | `AnimationType animation_type_from_longhand_property(PropertyID)` | | `inherited` | Yes | | Boolean. Whether the property is inherited by its child elements. | `bool is_inherited_property(PropertyID)` | | `initial` | Yes | | String. The property's initial value if it is not specified. | `NonnullRefPtr property_initial_value(JS::Realm&, PropertyID)` | | `legacy-alias-for` | No | Nothing | String. The name of a property this is an alias for. See below. | | | `logical-alias-for` | No | Nothing | Array of strings. The name of a property this is an alias for. See below. | | | `longhands` | No | `[]` | Array of strings. If this is a shorthand, these are the property names that it expands out into. | `Vector longhands_for_shorthand(PropertyID)` | | `max-values` | No | `1` | Integer. How many values can be parsed for this property. eg, `margin` can have up to 4 values. | `size_t property_maximum_value_count(PropertyID)` | | `percentages-resolve-to` | No | Nothing | String. What type percentages get resolved to. eg, for `width` percentages are resolved to `length` values. | `Optional property_resolves_percentages_relative_to(PropertyID)` | | `quirks` | No | `[]` | Array of strings. Some properties have special behavior in "quirks mode", which are listed here. See below. | `bool property_has_quirk(PropertyID, Quirk)` | | `valid-identifiers` | No | `[]` | Array of strings. Which keywords the property accepts. Consider defining an enum instead and putting its name in the `valid-types` array. | `bool property_accepts_keyword(PropertyID, Keyword)` | | `valid-types` | No | `[]` | Array of strings. Which value types the property accepts. See below. | `bool property_accepts_type(PropertyID, ValueType)` | ### `animation-type` The [Web Animations spec](https://www.w3.org/TR/web-animations/#animation-type) defines the valid values here: | Spec term | JSON value | |-------------------|---------------------| | not animatable | `none` | | discrete | `discrete` | | by computed value | `by-computed-value` | | repeatable list | `repeatable-list` | | (See prose) | `custom` | ### `legacy-alias-for` and `logical-alias-for` These are two separate concepts, with unfortunately similar names: - [Legacy name aliases](https://drafts.csswg.org/css-cascade-5/#legacy-name-alias) are properties whose spec names have changed, but the syntax has not, so setting the old one is defined as setting the new one directly. For example, `font-stretch` was renamed to `font-width`, so `font-stretch` is now a legacy name alias for `font-width`. - Logical aliases are properties like `margin-block-start`, which may assign a value to one of several other properties (`margin-top`, `margin-bottom`, `margin-left`, or `margin-right`) depending on the element they are applied to. List all the properties that they can alias. ### `quirks` The [Quirks spec](https://quirks.spec.whatwg.org/#css) defines these. | Spec term | JSON value | |------------------------------|----------------------| | The hashless hex color quirk | `hashless-hex-color` | | The unitless length quirk | `unitless-length` | ### `valid-types` The `valid-types` array lists the names of CSS value types, as defined in the latest [CSS Values and Units spec](https://www.w3.org/TR/css-values/), without the `<>` around them. For numeric types, we use the [bracketed range notation](https://www.w3.org/TR/css-values-4/#css-bracketed-range-notation), for example `width` can take any non-negative length, so it has `"length [0,∞]"` in its `valid-types` array. ## Keywords.json This is a single JSON array of strings, each of which is a CSS keyword, for example `auto`, `none`, `medium`, or `currentcolor`. This generates `Keyword.h` and `Keyword.cpp`. All keyword values used by any property or media-feature need to be defined here. The generated code provides: - A `Keyword` enum as used by `CSSKeywordValue` - `Optional keyword_from_string(StringView)` to attempt to convert a string into a Keyword - `StringView string_from_keyword(Keyword)` to convert a Keyword back into a string - `bool is_css_wide_keyword(StringView)` which returns whether the string is one of the special "CSS-wide keywords" ## Enums.json This is a single JSON object, with enum names as keys and the values being arrays of keyword names. This generates `Enums.h` and `Enums.cpp`. We often want to define an enum that's a set of a few keywords. `Enums.json` allows you to generate these enums automatically, along with functions to convert them to and from a Keyword, or convert them to a string. These enums also can be used in property definitions in `Properties.json` by putting their name in the `valid-types` array. This helps reduce repetition, for example the `border-*-style` properties all accept the same set of keywords, so they are implemented as a `line-style` enum. The generated code provides these for each enum, using "foo" as an example: - A `Foo` enum for its values - `Optional keyword_to_foo(Keyword)` to convert a `Keyword` to a `Foo` - `Keyword to_keyword(Foo)` to convert the `Foo` back to a `Keyword` - `StringView to_string(Foo)` to convert the `Foo` directly to a string ## PseudoClasses.json This is a single JSON object, with selector pseudo-class names as keys and the values being objects with fields for the pseudo-class. This generates `PseudoClass.h` and `PseudoClass.cpp`. Each entry has a single required property, `argument`, which is a string containing the grammar for the pseudo-class's function parameters - for identifier-style pseudo-classes it is left blank. The grammar is taken directly from the spec. The generated code provides: - A `PseudoClass` enum listing every pseudo-class name - `Optional pseudo_class_from_string(StringView)` to parse a string as a `PseudoClass` name - `StringView pseudo_class_name(PseudoClass)` to convert a `PseudoClass` back into a string - The `PseudoClassMetadata` struct which holds a representation of the data from the JSON file - `PseudoClassMetadata pseudo_class_metadata(PseudoClass)` to retrieve that data ## MediaFeatures.json This is a single JSON object, with media-feature names as keys and the values being objects with fields for the media-feature. This generates `MediaFeatureID.h` and `MediaFeatureID.cpp`. A `` is a value that a media query can inspect. They are listed in the [`@media` descriptor table](https://www.w3.org/TR/mediaqueries-5/#media-descriptor-table) in the latest Media Queries spec. The definitions here are like a simplified version of the `Properties.json` definitions. | Field | Description | |----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `type` | String. How the media-feature is evaluated, either `discrete` or `range`. | | `values` | Array of strings. These are directly taken from the spec, with keywords as they are, and `<>` around type names. Types may be ``, ``, ``, ``, or ``. | The generated code provides: - A `MediaFeatureValueType` enum listing the possible value types - A `MediaFeatureID` enum, listing each media-feature - `Optional media_feature_id_from_string(StringView)` to convert a string to a `MediaFeatureID` - `StringView string_from_media_feature_id(MediaFeatureID)` to convert a `MediaFeatureID` back to a string - `bool media_feature_type_is_range(MediaFeatureID)` returns whether the media feature is a `range` type, as opposed to a `discrete` type - `bool media_feature_accepts_type(MediaFeatureID, MediaFeatureValueType)` returns whether the media feature will accept values of this type - `bool media_feature_accepts_keyword(MediaFeatureID, Keyword)` returns whether the media feature accepts this keyword ## MathFunctions.json This is a single JSON object, describing each [CSS math function](https://www.w3.org/TR/css-values/#math-function), with the keys being the function name and the values being objects describing that function's properties. This generates `MathFunctions.h` and `MathFunctions.cpp`. Each entry currently has a single property, `parameters`, which is an array of parameter definition objects. Parameter definitions have the following properties: | Field | Description | |------------|----------------------------------------------------------------------------------| | `name` | String. Name of the parameter, as given in the spec. | | `type` | String. Accepted types for the parameter, as a single string, separated by `\|`. | | `required` | Boolean. Whether this parameter is required. | The generated code provides: - A `MathFunction` enum listing the math functions - The implementation of the CSS Parser's `parse_math_function()` method ## TransformFunctions.json This is a single JSON object, describing each [CSS transform function](https://www.w3.org/TR/css-transforms/#transform-functions), with the keys being the function name and the values being objects describing that function's properties. This generates `TransformFunctions.h` and `TransformFunctions.cpp`. Each entry currently has a single property, `parameters`, which is an array of parameter definition objects. Parameter definitions have the following properties: | Field | Description | |------------|----------------------------------------------| | `type` | String. Accepted type for the parameter. | | `required` | Boolean. Whether this parameter is required. | The generated code provides: - A `TransformFunction` enum listing the transform functions - `Optional transform_function_from_string(StringView)` to parse a string as a `TransformFunction` - `StringView to_string(TransformFunction)` to convert a `TransformFunction` back to a string - `TransformFunctionMetadata transform_function_metadata(TransformFunction)` to obtain metadata about the transform function, such as its parameter list