How the Browser Arrives at the Styles DevTools Shows You

Every front-end developer has stared at the Computed tab in browser DevTools, trying to figure out why an element looks the way it does. That panel is more than a list of final styles — it's the end result of a multi-step resolution process that combines your stylesheet, inherited values, and the browser's own defaults.

Unlike the Styles tab (called Rules in Firefox), which shows you the rulesets exactly as you wrote them, the Computed tab shows you what those declarations actually resolve to. Write .subhead {font-size: 75%} and the Styles tab dutifully shows you that declaration; the Computed tab shows you the real value, say 13.2px. That distinction matters when the rendered page doesn't match your intentions.

The Cascade and Inheritance in Brief

The cascade is the mechanism CSS uses to resolve conflicting declarations. When the same property is set multiple times for an element, the cascade algorithm prioritizes declarations by origin, !important flag, specificity, and order of appearance to settle on a single winner. A declaration that appears later in the stylesheet beats an earlier one with equal specificity, unless !important overrides that ordering.

Inheritance kicks in when the cascade produces no winning declaration. In that case, an element pulls the computed value of the property from its parent — provided the property is one that inherits by default. For non-inherited properties, the element falls back to the property's initial value.

Four keywords let you control this behavior explicitly:

  • initial — sets the property to its default value as defined in the CSS spec
  • inherit — forces inheritance even for non-inherited properties
  • unset — acts like inherit for inherited properties and initial for non-inherited ones
  • revert — rolls back to the browser's default styles, but still permits inheritance from an ancestor's explicitly set value

That last one trips people up. If you set a green color on body and then apply revert to a nested span, the span will fall back to the browser default for color where no author styles exist — but since you explicitly set green on the body, the span inherits that green rather than reverting to black.

The Stages of Style Computation

The CSS Cascading and Inheritance Level 4 specification defines a sequence of values that a declared style passes through before a pixel hits the screen. Understanding each stage helps you read what DevTools is showing you.

Declared values

A declared value is any valid property declaration that matches an element: it must live in a stylesheet that applies to the document, have a matching selector, and use valid syntax. If an element matches several declarations for the same property, you have multiple declared values.

Cascaded values

The cascade reduces those competing declared values to a single winner. Origin, importance, specificity, and source order all factor in. If no declaration wins, there is no cascaded value — but the element still needs a style, which is where inheritance and initial values come in.

Specified values

The specified value is what the browser intends to use on the element, whether that comes from a winning cascade declaration, an inherited parent value, or a property's initial value. In many cases the cascaded value and specified value are identical; they diverge when the cascade came up empty and the browser had to look elsewhere.

Computed values

This is where relative units get resolved. A specified value like 1.5em needs to become an absolute pixel value before it can be inherited or rendered. The property's definition table in the spec dictates how that resolution happens.

For example, suppose a <main> element has a font-size of 1.2em and a child paragraph uses 1.5em. If no other font sizes are declared above that — no :root rule, say — the browser's default 16px font size feeds the calculation. The paragraph's 1.5em multiplies against main's computed value, yielding something like 28.8px. That number is the computed value.

With rem units, the reference point shifts to the root element. If the root itself uses a relative unit like a percentage, the browser must first resolve that against its own default font size, then use that result to compute all rem-based values. That browser default is commonly 16px but is not guaranteed; you can check yours by selecting the <html> element in DevTools and looking at its computed font size.

During this stage, relative URLs also become absolute, and keywords like bolder for font-weight get resolved to concrete values.

Computed values are the ones inheritance actually passes down. A pixel value, a number, or a keyword like left is ready for inheritance — a percentage like 85% is not, because it still needs a reference to resolve against.

Used values

The used value is the final output after all calculations are done on the computed value. Some relative values only resolve here, once layout has happened. A percentage-based width, for instance, needs the containing block's final dimensions before it can become a pixel value. Frequently the computed value and used value are the same, but not always.

Sometimes there is no used value at all. Per the spec, a property that doesn't apply to an element has no used value — the flex property has none on elements that aren't flex items, for example.

Actual values

Even the used value may need adjustment before rendering. Browsers may approximate non-integer values or tweak font sizes based on available fonts. That adjusted value is the actual value — what you effectively see on screen.

What the Computed Tab Actually Shows

One important caveat: the values shown in the Computed tab aren't necessarily the "computed values" from the spec's pipeline. The panel displays what getComputedStyle() returns, which depending on the property is either the computed value or the used value. They're related, but not identical, and knowing which one you're looking at helps you interpret what you see.

Inheritance in action

Consider a color declaration. If you set color: blue on a <main> element, the computed value is blue, and any descendant <p> inherits that blue because color is inherited by default — no color: inherit declaration needed. Color values then go through their own resolution process to produce used values.

Font sizes follow the same pattern. A percentage-based font size on an element gets absolutized before inheritance, so a child inherits a fixed pixel value, not the original percentage.

When layout changes the math

Some computed values only resolve post-layout, and DevTools shows that split. Take a contrived example: two div elements both inheriting a width: 50% from their parent. For a div that's in the layout flow, the Computed tab shows an absolute pixel value — the post-layout, used value. For a sibling with display: none, the width remains 50% because there's no layout to resolve it against.

The parent's own width moves through the pipeline as a percentage-specified value, becomes a percentage-computed value, and only reaches a pixel value once layout determines the containing block's width — which means it recomputes on every viewport resize.

Which Properties Inherit?

Whether a property inherits by default is baked into its spec definition. MDN's property pages list this in their specifications section. The pattern is largely intuitive: typography-related properties tend to inherit, layout and visual ones generally don't.

Inherited by default include color, direction, font-family, font-size, font, letter-spacing, line-height, list-style-type, tab-size, text-align, text-justify, text-transform, visibility, and word-wrap.

Non-inherited properties that you can force to inherit with the inherit keyword include box-shadow, border, content, height, margin, object-fit, opacity, padding, position, transform, transition, width, and z-index.

W3C's specification properties section and community references round out the picture for anything ambiguous. Understanding the full resolution pipeline — from declared value through cascade, specification, computation, and finally use — makes the Computed tab a much more powerful debugging tool than a simple stylesheet mirror.