initial, inherit, unset, revert and revert-layer: Undoing Styles Correctly

Sooner or later every stylesheet needs to undo something: a utility that must cancel a component's margin, an embedded widget that should not inherit the page's typography, a print style that should restore a default, a state class that removes a decoration. The traditional move is to set the property to whatever value you think the default was — display: block, margin: 0, color: black — which is wrong as soon as the element, theme or layer is different. CSS has five keywords that roll a property back to a well-defined point instead, and knowing which point each one targets turns "undo" from guesswork into a single word. It belongs to Modern CSS Reset Strategies in the Mastering Container Queries & Responsive Layouts guide.

Why hard-coded "defaults" go wrong

display: block looks like the default for a <div>, but it is not the default for a <li> (which is list-item), a <table> or a <summary>. color: black undoes a component colour in a light theme and breaks the dark theme. margin: 0 undoes a component margin but also removes the default spacing that browsers give to paragraphs and headings when a reset is not used. Each hard-coded value encodes an assumption about the element and context, and assumptions age badly in component libraries.

The CSS-wide keywords are valid for every property and each rolls back to a precise point in the cascade.

Where each keyword rolls back to A stack from bottom to top: specification initial values, the browser's own stylesheet, author layers reset, base and components, and the current layer. initial points to specification values. revert points to the browser stylesheet. revert-layer points to the layers below the current one. inherit and unset point sideways to the parent element's value. Each keyword targets a different level specification initial values browser stylesheet (user agent) author layer: reset author layer: components current layer: utilities initial → revert → ← revert-layer inherit / unset → parent's value
  • initial — the property's initial value from its specification, ignoring the element type. display: initial is inline for every element, including <div>.
  • inherit — the parent element's computed value, for any property.
  • unsetinherit for properties that inherit by default (colour, font), initial for those that do not (border, display). "As if nothing had been declared."
  • revert — the value from the previous origin: for author styles, that is the browser's own stylesheet, so display: revert on a <div> gives block and on an <li> gives list-item.
  • revert-layer — the value from earlier cascade layers, as if the current layer had not declared anything for this property.

The complete implementation

The page below uses each keyword where it is the right tool. The comments explain why a hard-coded value would have been wrong.

Live demorevert-layer and all: revert in practice
The first note is styled by the component layer; the second adds .is-plain, whose revert-layer values fall back to browser defaults; the widget uses all: revert.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CSS-wide keywords</title>
<style>
  @layer reset, components, utilities;

  @layer components {
    .note {
      display: block;
      padding: 1rem;
      border-inline-start: 4px solid #6366f1;
      background: #eef2ff;
      color: #312e81;
    }
    .note a { color: inherit; }             /* links take the note's colour */

    /* A "plain" variant that strips decoration WITHOUT guessing values.
       It lives in the components layer, so revert-layer falls through to
       the reset layer and then to browser defaults, element by element. */
    .note.is-plain {
      border: revert-layer;
      background: revert-layer;
      padding: revert-layer;
    }
  }

  /* An embedded widget must not inherit the page's author styles at all.
     all: revert returns every property to browser defaults, then the
     widget's own rules (declared after) build it up again. */
  .embed-root {
    all: revert;
  }
  .embed-root .embed-title { font: 600 1rem/1.3 system-ui, sans-serif; }

  /* Print: bring back underlines that screen styles removed, using the
     browser's own link style rather than guessing it. */
  @media print {
    a { text-decoration: revert; }
  }

  /* unset for a typography opt-out: inherited properties follow the
     parent again, non-inherited ones go back to initial. */
  .quote cite { font-style: unset; }
</style>
</head>
<body>
  <p class="note">A styled note. <a href="/docs/">Docs</a></p>
  <p class="note is-plain">The same note with decoration reverted to earlier layers.</p>
  <div class="embed-root"><h3 class="embed-title">Third-party widget</h3><p>Default browser styles.</p></div>
</body>
</html>

The .is-plain variant is the showcase for revert-layer. Declared in the components layer, it removes the component's border, background and padding by deferring to whatever the earlier layers would give — here the reset, which sets none of them, so the values fall through to the browser's defaults. On a <p> that means no border, no background and no padding; on a <fieldset> it would restore the browser's fieldset border. One variant, correct for every element.

The key technique: revert-layer hands control back

revert-layer is the keyword that makes layered architectures composable. Without it, a later layer that wants to "switch off" an earlier layer's styling has to redeclare values — which means knowing them. With it, the later layer can say "not me" for a property and let the cascade continue downward.

revert-layer as a fall-through Three layers. The utilities layer declares padding revert-layer. The cascade treats that as no declaration in utilities and falls through to components, which declares padding 1rem. If components had also used revert-layer, it would fall through to reset, and then to the browser default. padding: revert-layer in utilities utilities: padding: revert-layer components: padding: 1rem ← used reset: (no padding declared) The keyword means "ignore this layer for this property", not "use a value".

This fall-through is exactly why the example puts .is-plain in the components layer rather than in utilities. A utility such as .u-plain { padding: revert-layer } declared in the utilities layer skips only the utilities layer, lands on the component's padding: 1rem, and changes nothing — a common and confusing mistake. revert-layer always undoes the layer it is written in, never the ones below it:

/* Does nothing to a .note: falls through to the component's own padding. */
@layer utilities {
  .u-plain { padding: revert-layer; }
}

/* Works: written in the component layer, so it undoes the component's
   padding and falls through to the reset and browser defaults. */
@layer components {
  .note.is-plain { padding: revert-layer; }
}

When a utility genuinely needs to cancel a component style, revert — which skips all author layers and returns to the browser stylesheet — is the keyword to use instead. Understanding exactly which layer a keyword falls through to is the whole skill, and it is the same layer model described in Cascade Layers vs Specificity Hacks.

When to reach for each keyword

  • Undo an author style on a known element: revert. It restores what the browser would give that element.
  • Undo only your current layer's opinion: revert-layer. Use it in variants and utilities inside a layered system.
  • Make a child follow its parent: inherit, typically for color on links or icons, font on form controls, or border-color matching text.
  • Reset to nothing, element-agnostic: unset, useful in all: unset for building a completely custom control from a native element — but remember it removes focus styles and native affordances, so rebuild them.
  • Specification default: initial, rarely the right answer for undoing styles; useful mainly for custom properties and for properties whose initial value you actually want, such as grid-column: initial.

Keywords and custom properties

The CSS-wide keywords behave slightly differently on custom properties, which matters in token-based systems. --brand: initial sets the property to its guaranteed-invalid value, which makes any var(--brand) fall back to its fallback argument — a useful way to "unset" a token for a subtree. --brand: inherit explicitly inherits, which is the default for unregistered custom properties anyway. revert and revert-layer work as usual, rolling the token back to its value from an earlier origin or layer, so a theme layer can say --brand: revert-layer in a particular section to restore the base theme's value without restating it.

For registered properties declared with @property, initial means the initial-value from the registration rather than the guaranteed-invalid value, and inherit only applies if the registration says inherits: true or it is written explicitly. Those distinctions are covered in Registered Properties and Type Safety.

Variation: isolating embedded content

Widgets injected into pages you do not control — support chats, comment embeds — suffer from the host page's global styles. all: revert on the widget's root clears inherited and cascaded author styles in one declaration, restoring browser defaults before the widget's own styles apply. Combined with @scope to keep the widget's own rules contained, it gives a lightweight alternative to shadow DOM for many embeds. Animations the widget defines are unaffected by the revert as long as they are declared after it; for widgets with motion, gate that motion with prefers-reduced-motion as described in Reducing Motion Preferences in CSS, because the host page's reduced-motion rules no longer reach inside.

Browser support

initial, inherit and unset are supported in every browser in use. revert is supported in current versions of Chrome, Edge, Firefox and Safari, as is the all shorthand. revert-layer arrived with cascade layers: supported in current Chrome, Edge, Firefox and Safari, with cascade layers themselves in Chrome and Edge 99+, Firefox 97+ and Safari 15.4+. In an engine without revert-layer, the declaration is invalid and ignored, so the element keeps the current layer's value.

FAQ

What is the difference between initial and revert?initial sets a property to its value from the specification, which for display is inline and for font-family is the browser's generic default. revert rolls the property back to what the browser's own stylesheet would give that element, so display: revert on a div gives block. For undoing author styles, revert is almost always what you mean.

What does revert-layer do? It rolls a property back to the value it would have from earlier cascade layers, ignoring the current layer's declarations. A utility in a late layer can use revert-layer to hand control back to the component layer beneath it instead of guessing a value.

What does all: revert do? It reverts every property except direction and unicode-bidi, so an element returns to browser-default styling with no author styles applied. It is useful for isolating embedded content from a page's global styles.

Is unset the same as inherit? Only for inherited properties. unset behaves like inherit for properties that inherit by default, such as color, and like initial for properties that do not, such as border. It means "act as if nothing had been declared at all".

Related articles

More pages in the same section.