skip to content

You embed a widget's markup into pages whose CSS you do not control. Using CSS's all shorthand, how do all: initial, all: unset and all: revert differ as the widget's reset, and what does all not cover?

level: seniorimportance: nice to knowfreq 26%

answer

  1. all is a shorthand for every property
  2. only CSS-wide keywords are valid values
  3. direction and unicode-bidi are excluded
  4. custom properties are not reset
  5. initial makes the element display: inline

basics

~20 s

all sets every property to one global keyword: initial gives the specification's blank slate (display becomes inline), unset lets inherited properties come from the host page, and revert restores user-agent styles. all skips direction, unicode-bidi and custom properties, and applies to one element only.

solid answer

~50 s

`all` is a shorthand for every CSS property, and it accepts only the global keywords. `all: initial` applies the specification's initial values — `display` becomes `inline`, controls lose their native look, and the result is rarely usable without rebuilding everything. `all: unset` lets inherited properties keep flowing in from the host page, which is exactly the leakage you were trying to stop for typography. `all: revert` rolls back to the user-agent stylesheet, so a `<div>` stays `block` and a `<button>` still looks like a button — usually the sanest baseline to layer your own styles on. Three caveats: `all` excludes `direction` and `unicode-bidi`, it does not touch **custom properties**, and it affects only the element it is written on, so a real isolation attempt needs it on a descendant-wide selector — which is why genuine encapsulation belongs to shadow DOM rather than to a reset rule.

code

css · 10 lines
css
/* Baseline that keeps native element behaviour, then style deliberately */
.widget-root,
.widget-root * {
  all: revert;
}

.widget-root {
  font: 16px/1.5 system-ui, sans-serif;
  color: #111;
}

go deeper

for a junior

Know that all is a shorthand for every property and only accepts keywords like initial, unset and revert. You are unlikely to be asked more than that at this level.

for a middle

Explain the three outcomes concretely — initial gives inline and a stripped button, unset lets host typography in, revert restores user-agent styles — and name the direction/unicode-bidi exclusion.

for a senior

Argue the choice for a real embed: revert as the baseline, the per-element scope problem, custom properties surviving, and host !important and inline styles still winning.

for a principal

Frame it as a boundary decision — shadow DOM versus a CSS reset versus namespacing — and weigh isolation strength against style-engine cost, theming needs and how much host customisation you actually want to allow.

## What all actually is `all` is a shorthand covering every CSS property, with two deliberate exclusions: `direction` and `unicode-bidi`, which are omitted because resetting bidirectional text handling would break correct rendering of right-to-left content. Its value grammar accepts **only** the CSS-wide keywords — `initial`, `inherit`, `unset`, `revert`, `revert-layer`. You cannot write `all: 0`. It also does **not** reset custom properties. `--brand-color` declared on an ancestor still inherits straight through an `all: initial` element and remains available to `var()` inside it. That is occasionally handy and occasionally a nasty surprise. ## The three candidate resets **`all: initial`** — the specification's blank slate. Every property takes its initial value, which is emphatically *not* the browser's default rendering: `display` becomes `inline`, so your widget root stops being a block; a `<button>` loses its background, border, padding and focus ring; `font-family` falls back to the UA's initial font rather than the host's. You have maximum isolation and minimum usability, and you must now redeclare everything, including affordances users rely on. **`all: unset`** — per property, `inherit` for inherited ones and `initial` for the rest. That means the host page's `color`, `font-family`, `line-height`, `letter-spacing`, `text-transform` and `visibility` all flow straight into your widget. As an isolation strategy it fails at the first hurdle, because typography is precisely what hosts customise. It is a decent *local* reset inside a page you control, and a poor boundary. **`all: revert`** — rolls every property back as if the author origin had contributed nothing, landing on the user origin or the user-agent stylesheet. A `<div>` is `block` again, a `<button>` is a native button, headings have their default sizes. You get the browser's baseline, free of the host's author CSS, which is normally the most useful starting point: predictable, accessible, and something you then style deliberately. ```css .widget-root, .widget-root * { all: revert; } .widget-root { /* now apply your own styles */ } ``` ## The limits you must state **It is per element.** `all` resets the element it matches, not its subtree. Inherited properties will re-enter through the root unless the root itself is reset, and non-inherited host rules that target your inner elements (`.host-page p { margin: 0 }`) still apply unless your selector covers them too. Hence the `.widget-root *` universal selector above — which then has to be beaten by every one of your own rules, so you are now fighting a specificity and source-order problem you created. **Ordering matters.** Anything you write after the reset must actually win the cascade over it. Putting the reset in an earlier cascade layer, or simply first in source order at equal specificity, keeps this manageable. **Custom properties survive.** If the host sets `--spacing: 40px` on `:root` and your widget uses a variable of the same name, `all` will not save you. Namespace your custom properties. **Inline styles and `!important` from the host still win.** `all` is an ordinary declaration; a host rule with `!important` in the author origin beats your non-important one at the same layer position. **It is not free.** `all: revert` on a universal selector inside a large widget touches every property on every element; it is one of the more expensive things you can ask the style engine to do, and it is worth measuring on a big subtree rather than assuming. ## What to say in the interview Say that among the three you would start from `all: revert` because it preserves native element behaviour and accessibility while discarding the host's author styles; that `all: initial` is a legitimate choice only if you intend to redeclare literally everything; that `all: unset` does not isolate at all for typography; and that if the requirement is real isolation rather than best-effort, CSS alone is the wrong layer — shadow DOM is what actually stops author styles at a boundary, and a reset rule is what you use when you cannot have one.

  • Why is all: initial usually the wrong reset for a button?
    Because initial values are the specification's, not the browser's. The button becomes `display: inline`, loses its background, border, padding, pointer cursor and focus ring, and no longer reads as an interactive control. You would have to rebuild the visible focus indicator by hand, which is an accessibility requirement. `all: revert` restores the native button and lets you restyle from a working baseline.
  • After writing an all reset on a widget root, why might your own styles fail to apply?
    Because the reset is an ordinary declaration competing in the same cascade. If you wrote it on `.widget-root *`, that selector has a class's specificity and applies to every descendant, so a later type-selector rule of yours loses. Fix it by placing the reset in an earlier cascade layer, or by keeping it first in source order with specificity no higher than your component rules.
  • Does all give you real isolation from the host page?
    No — it is best effort. Host declarations with `!important`, host inline styles, and custom properties the host sets all pass through, and `all` only affects elements your selector actually matches. If the requirement is a genuine boundary rather than a strong reset, that is shadow DOM's job; a CSS reset is what you reach for when you cannot use one.

saying these in an interview costs you the question

  • Thinks all: initial restores the browser's default look
  • Expects all to reset the element's descendants too
  • Assumes all clears inherited custom properties
  • Uses all: unset and calls the widget isolated
  • Applies a universal all reset without measuring cost

context