Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
00b8842
renew css value processing document
sakupi01 Jul 27, 2025
7a730ad
correct anchor links
sakupi01 Jul 27, 2025
e16c142
use non-code/redirect ref
sakupi01 Jul 27, 2025
0a5567b
update non-inherited/inherited property code description
sakupi01 Jul 27, 2025
da297a2
Apply suggestion from @estelle
sakupi01 Aug 12, 2025
a7ff563
Apply suggestion from @estelle
sakupi01 Aug 12, 2025
a2bc22b
Apply suggestion from @estelle
sakupi01 Aug 12, 2025
ddb85e1
Apply suggestion from @estelle
sakupi01 Aug 12, 2025
57d9f35
links for layers and origins
oihdsf Aug 12, 2025
118b89e
modify&split the first paragraph
oihdsf Aug 12, 2025
10974c4
make all code comments removed and replaced with prose explanations
oihdsf Aug 12, 2025
c24c91f
lowercased the link texts
oihdsf Aug 12, 2025
21f4c15
remove spaces
oihdsf Aug 12, 2025
49ed161
merge bullet items and add link to error handling
oihdsf Aug 12, 2025
8b7cd2a
filtering: include suggestion
oihdsf Aug 12, 2025
4bfb703
Revert "merge bullet items and add link to error handling"
oihdsf Aug 12, 2025
6515be7
merge bullet items and add link to error handling
oihdsf Aug 12, 2025
6467d7d
Update files/en-us/web/css/css_cascade/value_processing/index.md
sakupi01 Aug 27, 2025
1206ee9
Update files/en-us/web/css/css_cascade/value_processing/index.md
sakupi01 Aug 27, 2025
9702e1e
all grammatical changes
oihdsf Aug 27, 2025
864427f
fixed defaulting description with accuracy
oihdsf Aug 27, 2025
af0de08
Add 'Actual value' to CSS value processing index
sakupi01 Aug 27, 2025
e94c0b9
Merge branch 'main' into fix/value-processing
estelle Aug 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 124 additions & 24 deletions files/en-us/web/css/css_cascade/value_processing/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,50 +10,152 @@ For every element in a document tree, the browser assigns a value to every CSS p

## Property values

Every CSS property's value comes from the declaration with the greatest {{cssxref("specificity")}}. If two or more declarations with the same specificity provide different property values for the same element, the declaration value whose selector has the greatest algorithmic weight gets applied.
Every CSS property that has declarations applied to it is set to its [cascaded value](#cascaded_value), which comes from the property declaration that ranks highest in the [cascade sorting order](/en-US/docs/Web/CSS/CSS_cascade/Cascade#cascading_order) based on the [cascade algorithm](/en-US/docs/Web/CSS/CSS_cascade/Cascade).

Each property value comes from a single property-value pair; is single value is applied from each property. Even if the value is a comma separated list of values, that list of values came from a single declaration.
When there are multiple [declared values](#declared_value), with multiple declarations providing the same or different property values for the same element, each property value must still come from a single property name-value pair as only a single value is applied from each property. Even if the value is a comma-separated list of values, that list of values came from a single declaration.

To determine which specified value is applied, the user agent gathers and processes all the styles from different sources, such as inline styles, and internal and external stylesheets.
To determine which [declared value](#declared_value) is applied, the user agent gathers and processes all the styles from different sources, such as inline styles, and internal and external stylesheets.

Certain properties inherit values from their parent elements unless explicitly overridden. [Inheritance](/en-US/docs/Web/CSS/CSS_cascade/Inheritance) occurs when no style information exists for a specific property on an element. If the property is inherited, the value is set to the [computed value](#computed_value) of the parent element. If the property is not inherited, its value is set to the [initial value](#initial_value) for that element.
The [cascade](/en-US/docs/Web/CSS/CSS_cascade/Cascade) determines which value should be applied when multiple conflicting styles target the same element. The [cascade algorithm](/en-US/docs/Web/CSS/CSS_cascade/Cascade#cascading_order) defines how user agents combine property values originating from different sources, scopes, and/or [layers](/en-US/docs/Web/CSS/CSS_cascade/Cascade#cascade_layers). When a selector matches an element, the property's [declared value](#declared_value) from the [origin](/en-US/docs/Web/CSS/CSS_cascade/Cascade#origin_types) with the highest precedence gets applied, even if a selector from a lower precedence [origin](/en-US/docs/Web/CSS/CSS_cascade/Cascade#origin_types) or [layers](/en-US/docs/Web/CSS/CSS_cascade/Cascade#cascade_layers) has greater {{cssxref("specificity")}}.

The [cascade](/en-US/docs/Web/CSS/CSS_cascade/Cascade) determines which value should be applied when multiple conflicting styles target the same element. The cascade algorithm defines how user agents combine property values originating from different sources, scopes, and/or layers. When a selector matches an element, the property's [specified value](#specified_value) from the origin with the highest precedence gets applied, even if a selector from a lower precedence origin or layer has greater {{cssxref("specificity")}}.
Certain properties inherit values from their parent elements unless explicitly overridden. [inheritance](/en-US/docs/Web/CSS/CSS_cascade/Inheritance) occurs when no style information exists for a specific property on an element. If the property is inherited, the value is set to the [computed value](#computed_value) of the parent element. If the property is not inherited, its value is set to the [initial value](#initial_value) for that element.

After applying the cascading rules and resolving values step by step, the browser ensures the visual presentation matches the processed CSS.
After applying the [cascading](#cascading) rules and defaulting values step by step, the browser ensures the visual presentation matches the processed CSS.

## Processing overview

Before diving into the individual value stages, it's important to understand the three main phases that occur in value processing; [filtering](#filtering), [cascading](#cascading), and [defaulting](#defaulting).

### Filtering

**Filtering** is the process of identifying all declarations that apply to each element. A declaration applies to an element only if:

- It belongs to a style sheet that currently applies to this document
- Any [conditional rules](/en-US/docs/Web/CSS/CSS_conditional_rules) (like {{cssxref("@media")}} or {{cssxref("@supports")}}) that contain it are currently true, and it belongs to a style rule whose selector matches the element
- It is syntactically valid: the property name is recognized by the browser and the value matches the expected syntax for that property

Only valid declarations become declared values. Declarations with invalid property names or invalid values get filtered out according to [CSS error handling rules](/en-US/docs/Web/CSS/CSS_syntax/Error_handling).

In this example, only the {{cssxref("font-size")}} and {{cssxref("font-weight")}} declarations are processed. The [CSS parser filters out errors](/en-US/docs/Web/CSS/CSS_syntax/Error_handling#css_parser_errors), ignoring or "filtering" out the declaration with the invalid property name:

```css
p {
font-size: 1.25em;
colr: blue;
font-weight: bold;
}
```

When filtering is complete, every element has zero or more [declared values](#declared-value) for every CSS property. These declared values are the starting point for the [cascading](#cascading) processing stage.

### Cascading

[Cascade](/en-US/docs/Web/CSS/CSS_cascade/Cascade) resolves conflicts when multiple declarations apply to the same property on the same element. [cascade](/en-US/docs/Web/CSS/CSS_cascade/Cascade) sorts declarations using [the cascade sorting order](/en-US/docs/Web/CSS/CSS_cascade/Cascade#cascading_order) algorithm.

For example, if you have the following declarations for `<p class="large">CSS is fun!</p>`, the second declaration wins because it has higher specificity. Both declarations have author origin, but the second selector has specificity of 0,1,1 while the first has 0,0,1:

```css
p {
font-size: 1em;
}

p.large {
font-size: 1.5em;
}
```

After cascading, the browser determines the [**cascaded value**](#cascaded_value) for each property on each element. This value is the one that will be used in the next processing stage; [defaulting](#defaulting).

### Defaulting

**Defaulting** ensures every property on every element has a value, even when no declarations apply. This involves:

- Using **inherited values** for [inherited properties](/en-US/docs/Web/CSS/CSS_cascade/Inheritance#inherited_properties)
- Using **initial values** for [non-inherited properties](/en-US/docs/Web/CSS/CSS_cascade/Inheritance#non-inherited_properties)
- Applying **explicit defaulting keywords** ([`initial`](/en-US/docs/Web/CSS/initial), [`inherit`](/en-US/docs/Web/CSS/inherit), [`unset`](/en-US/docs/Web/CSS/unset), [`revert`](/en-US/docs/Web/CSS/revert), [`revert-layer`](/en-US/docs/Web/CSS/revert-layer))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the parser ever set anything other than initial or inherit? Should the first two read:

Suggested change
- Using **inherited values** for [inherited properties](/en-US/docs/Web/CSS/CSS_cascade/Inheritance#inherited_properties)
- Using **initial values** for [non-inherited properties](/en-US/docs/Web/CSS/CSS_cascade/Inheritance#non-inherited_properties)
- Applying **explicit defaulting keywords** ([`initial`](/en-US/docs/Web/CSS/initial), [`inherit`](/en-US/docs/Web/CSS/inherit), [`unset`](/en-US/docs/Web/CSS/unset), [`revert`](/en-US/docs/Web/CSS/revert), [`revert-layer`](/en-US/docs/Web/CSS/revert-layer))
- Setting `inherit` for [inherited properties](/en-US/docs/Web/CSS/CSS_cascade/Inheritance#inherited_properties)
- Setting `initial` for [non-inherited properties](/en-US/docs/Web/CSS/CSS_cascade/Inheritance#non-inherited_properties)

and the last be removed?

Aren't these already in the browsers UA stylesheet? So is the parser doing this explicitly, or is it just reading the UA styles?

Copy link
Contributor Author

@sakupi01 sakupi01 Aug 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@estelle
Thank you!

initial or inherit keywords itself are not going to be set by CSS parser if I am being accurate to the spec. It could be any initial value defined in spec(, which is not limited to initial) or inherited from the parent (, which is also not limited to inherit), if I read the spec correctly:
https://www.w3.org/TR/css-cascade-4/#defaulting

I also thought using the word "The CSS parser" here is misleading. The parsing phase corresponds to Filtering phase, which is 2 phases before Defaulting phase.

Also, explicit defaulting keywords also contributes to set specified values which is a result of Defaulting process here. (Each explicit defaulting keywords are also converted to the proper specified values.)
So, I thought it'd be better to mention about explicit defaulting keywords conversion, not entirely deleting.

What do you think about: fixed defaulting description with accuracy?


As a result of defaulting, every property is guaranteed to have a [specified value](#specified_value).

## Processing stages

All elements that are part of the document's flattened element tree have declared, cascaded, specified, computed, used, and actual values. For a specific property, these values may or may not be the same. For example, if your large code base includes the CSS `p { font-size: 1.25em; }` and your HTML includes `<p>CSS is fun!</p>`, what size will the paragraph be? The {{cssxref("font-size")}} value moves through a few stages to go from the `em` specified value to the rendered `px` value.
All elements that are part of the document's flattened element tree have declared, cascaded, specified, computed, used, and actual values. For a specific property, these values may or may not be the same. For example, if your large code base includes the CSS `p { font-size: 1.25em; }` and your HTML includes `<p class="large">CSS is fun!</p>`, what size will the paragraph be? The {{cssxref("font-size")}} value moves through a few stages to go from the `em` specified value to the rendered `px` value.

- [Initial value](#initial_value)
The value processing stages are:

- [Declared value](#declared_value)
- [Cascaded value](#cascaded_value)
- [Specified value](#specified_value)
- [Computed value](#computed_value)
- [Used value](#used_value)
Comment on lines +88 to 92
Copy link
Contributor Author

@sakupi01 sakupi01 Jul 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The terminology "Initial value" is used IN the resolution phase of specified value, that is Defaulting phase - it's not the term to describe the part of value processing flow.

https://www.w3.org/TR/css-cascade-4/#value-stages
https://www.w3.org/TR/css-cascade-4/#defaulting


These values are used to determine the final [rendered value](#rendered_values).

### Initial value
### Declared value

A property's **initial value** is the default value as listed in its definition table in the specification. The usage of the initial value depends on whether a property is inherited or not:
A **declared value** is any syntactically valid value from a declaration that applies to an element. An element can have zero or more declared values for each property. These values come from style sheets (author, user, or user-agent) and are identified during the [filtering](#filtering) stage.

- For [inherited properties](/en-US/docs/Web/CSS/CSS_cascade/Inheritance#inherited_properties), the initial value is used on the _root element only_, as long as no [specified value](#specified_value) is supplied.
- For [non-inherited properties](/en-US/docs/Web/CSS/CSS_cascade/Inheritance#non-inherited_properties), the initial value is used on _all elements_, as long as no specified value is supplied.
For our example `p { font-size: 1.25em; }` for `<p class="large">CSS is fun!</p>`, if multiple stylesheets declare font-size for the same paragraph, the user-agent stylesheet might set `font-size: 1em` for paragraphs, while the author stylesheet sets `font-size: 1.25em` for paragraphs and `font-size: 2em` for elements with class "large":

You can explicitly set the initial value by using the {{cssxref("initial")}} keyword.
```css
p {
font-size: 1em;
}

> [!NOTE]
> The initial value for can be found in the formal syntax section of each CSS property reference page. For example, the [initial value of `font-size` is `medium`](/en-US/docs/Web/CSS/font-size#formal_definition). The initial value should not be confused with the value specified by the browser's style sheet.
p {
font-size: 1.25em;
}

.large {
font-size: 2em;
}
```

Only declarations whose selectors match the element become declared values. In this example, if our `<p>` element has `class="large"`, then all three declarations would be declared values for that element.

### Cascaded value

The **cascaded value** is the declared value that wins the [cascade](#cascading). There is at most one cascaded value per property per element.

From our declared values above, the cascaded value would be `font-size: 2em` from the author origin with specificity 0,1,1:

```css
font-size: 2em;
```

If there are no declared values for a property, there is no cascaded value, which means the value will be determined by the [defaulting](#defaulting) process.

### Specified value

The **specified value** is the value initially assigned in the CSS file or by the `style` attribute. The specified value for a given property is determined according to the following rules:
The **specified value** is the result of the [defaulting](#defaulting) process. It is guaranteed to exist for every property on every element. The specified value is determined as follows:

1. If the document's style sheet explicitly specifies a value for the property, the given value will be used.
2. If the document's style sheet doesn't specify a value but it is an inherited property, the value will be taken from the parent element.
3. If none of the above apply, the element's [initial value](#initial_value) will be used.
1. If there is a [cascaded value](#cascaded_value), it becomes the specified value.
2. If there is _no_ [cascaded value](#cascaded_value) and the property is inherited, the specified value is the [computed value](#computed_value) of the parent element.
3. If there is _no_ [cascaded value](#cascaded_value) and the property is _not_ inherited, the specified value is the property's [initial value](#initial_value).

In the example, `p { font-size: 1.25em; }`, the specified value is `1.25em`, unless the codebase includes a `font-size` declaration with greater {{cssxref("specificity")}}.
In our example, since we have a [cascaded value](#cascaded_value) of `2em`, this becomes the specified value:

```css
font-size: 2em;
```

For properties without [cascaded values](#cascaded_value), the [defaulting](#defaulting) process fills in the gaps. For example, if `color` is not specified, it inherits from the parent's computed value since it's an inherited property. If `margin` is not specified, it uses its initial value of `0` since it's a non-inherited property:

```css
color: inherit;
margin: 0;
```

#### Initial value

A property's **initial value** is the default value as listed in its definition table in the specification. The initial value is used during defaulting when:

- For [inherited properties](/en-US/docs/Web/CSS/CSS_cascade/Inheritance#inherited_properties), the initial value is used on the _root element only_, which has no parent element, when no cascaded value exists.
- For [non-inherited properties](/en-US/docs/Web/CSS/CSS_cascade/Inheritance#non-inherited_properties), the initial value is used on _all elements_ when no cascaded value exists.

You can explicitly set the initial value by using the {{cssxref("initial")}} keyword.

> [!NOTE]
> The initial value can be found in the formal syntax section of each CSS property reference page. For example, the [initial value of `font-size` is `medium`](/en-US/docs/Web/CSS/font-size#formal_definition). The initial value should not be confused with the value specified by the browser's style sheet.

### Computed value

Expand All @@ -68,8 +170,6 @@ The computation needed to reach a property's computed value typically involves c

However, for some properties (those where percentages are relative to something that may require layout to determine, such as `width`, `margin-right`, `text-indent`, and `top`), percentage-specified values turn into percentage-computed values. Additionally, unitless numbers specified on the `line-height` property become the computed value, as specified. The relative values that remain in the computed value become absolute when the [used value](#used_value) is determined.

Given `p { font-size: 1.25em; }`, if `em` is `16px`, the computed font size for a paragraph will be `20px`.

### Used value

The **used value** is the property's value after all calculations have been performed on the [computed value](#computed_value) and it has been refined with layout-specific details (e.g., percentages resolved to actual pixel values).
Expand Down Expand Up @@ -145,7 +245,7 @@ Change the window size or rotate your mobile device to change the size and the u

The rendered value is called the [actual value](#actual_value), while the value retrieved via script is called the [resolved value](#resolved_value).

### Actual Value
### Actual value

The **actual value** of a property is the [used value](#used_value) of that property after any necessary approximations have been applied. It is the final rendered value as implemented by the browser, including adjustments for rendering quirks or limitations. For example, a {{glossary("user agent")}} that can only render borders with a whole-number pixel width may round the thickness of the border to the nearest integer.

Expand All @@ -162,7 +262,7 @@ The **resolved value** of a property is the value after applying active styleshe

Historically, `getComputedStyle()` returned the computed value of an element or pseudo-element. As CSS evolved, so did the concept of "computed value", but the values returned by `getComputedStyle()` had to remain the same for backward compatibility with deployed scripts. These values are the "resolved values".

For most properties, the resolved value is the computed value, but for a few legacy properties (including {{cssxref("width")}} and {{cssxref("height")}}), it is the used value. The [CSSOM specification](https://drafts.csswg.org/cssom/#resolved-values) provides per-property details.
For most properties, the resolved value is the computed value, but for a few legacy properties (including {{cssxref("width")}} and {{cssxref("height")}}), it is the used value. The [CSSOM specification](https://drafts.csswg.org/cssom/#resolved_values) provides per-property details.

CSS 2.0 defined _computed value_ as the last step in a property's calculation. CSS 2.1 introduced the distinct definition of "used value". An element could then explicitly inherit the width/height of its parent, whose computed value is a percentage. For CSS properties that don't depend on layout (e.g., `display`, `font-size`, or `line-height`), the computed values and used values are the same. The following list contains the CSS 2.1 properties that _do_ depend on layout, and therefore have a different computed value and used value (taken from [CSS 2.1 Changes: Specified, computed, and actual values](https://www.w3.org/TR/CSS2/changes.html#q21.36)):

Expand Down
2 changes: 1 addition & 1 deletion files/en-us/web/css/css_syntax/error_handling/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ The type and amount of CSS that a browser ignores due to an error depends on the
- For [errors in at-rules](#at-rule_errors), whether a single line or the entire at-rule is ignored (fails) depends on the at-rule and the type of error.
- If the [error is an invalid selector](#errors_in_selector_lists), the entire declaration block is ignored.
- An [error due to a missing semi-colon](#errors_within_css_declaration_blocks) between property declarations causes an invalid value, in which case, multiple property-value declarations are ignored.
- If the [error is a property name or value](#errors_within_css_declaration_blocks), such as an unrecognized property name or invalid data type, the property-value declaration is ignored.
- If the [error is a property name or value](#errors_within_css_declaration_blocks), such as an unrecognized property name or invalid data type, the property-value declaration is ignored. During the [filtering stage](/en-US/docs/Web/CSS/CSS_cascade/Value_processing#filtering), such syntactically invalid declarations are eliminated.
- If the [error is due to a missing end-bracket](#errors_with_auto-closed_endings), the extent of what is ignored depends on the browser's ability to parse the error as nested CSS.

After parsing each declaration, style rule, at-rule, and so on, the browser checks the parsed content against its expected [grammar](#grammar_check) for that construct. If the content does not match the expected grammar for that construct, the browser considers it invalid and ignores it.
Expand Down