W3docs

CSS :root Pseudo Class

The :root CSS pseudo-class selects the elements that match the root element of the document. Read about the pseudo-class and try examples.

The :root pseudo-class matches the root element of the document — the single element that contains every other element on the page.

In an HTML document the root element is always <html>, so writing :root is equivalent to writing the html selector — with one important difference: :root has higher specificity. Because it's a pseudo-class, :root carries the same specificity as a class selector (0,1,0), while the plain html type selector has the lower specificity of a single element (0,0,1). When a rule on :root and a rule on html both target the same property, the :root rule wins.

In SVG and XML documents, :root matches whatever element sits at the top of that document tree, so it isn't tied to <html> there.

Why :root is worth knowing

You could almost always replace :root with html, so why does it exist and why is it everywhere in modern CSS? Two reasons:

  • It is the home for CSS custom properties (variables). Declaring variables on :root makes them available to every element on the page, since custom properties inherit down the tree. This is the single most common use of :root today.
  • Its higher specificity makes it a reliable place to set document-wide defaults that you don't want a stray html { ... } rule to override.

Syntax

:root {
  /* CSS declarations */
}

Defining global CSS variables on :root

A custom property is any property whose name starts with two dashes (--brand-color). You read it back anywhere with the var() function. Putting these declarations on :root is the idiomatic way to create a single source of truth for colors, spacing, and fonts:

<!DOCTYPE html>
<html>
  <head>
    <style>
      :root {
        --brand: #8ebf42;
        --gap: 1.5em;
      }
      h2 {
        color: var(--brand);
      }
      p {
        padding: var(--gap);
        border-left: 4px solid var(--brand);
      }
    </style>
  </head>
  <body>
    <h2>Theme driven by :root variables</h2>
    <p>Change one value in :root and both elements update.</p>
  </body>
</html>

Because the variables live on :root, every rule below it can read them, and changing one value in a single place re-themes the whole page.

Styling the root element itself

:root can also carry ordinary declarations. Here it sets the page background, and body adds an inset block so you can see the root element behind it:

<!DOCTYPE html>
<html>
  <head>
    <style>
      :root {
        background-color: #8ebf42;
        padding: 2em;
      }
      body {
        background-color: #eee;
        padding: 1.5em;
      }
    </style>
  </head>
  <body>
    <h2>:root selector example</h2>
    <p>Lorem ipsum is simply dummy text</p>
  </body>
</html>

Combining :root with other selectors

:root chains with pseudo-elements such as ::after and with other pseudo-classes such as :hover. A handy pattern is :root:hover, which lets a hover anywhere on the page change a variable and cascade the new value everywhere:

<!DOCTYPE html>
<html>
  <head>
    <style>
      :root {
        --accent: tomato;
      }
      :root:hover {
        --accent: rebeccapurple;
      }
      h2 {
        color: var(--accent);
      }
    </style>
  </head>
  <body>
    <h2>Hover anywhere to recolor this heading</h2>
  </body>
</html>

Gotchas

  • :root is not *. :root selects only the one top-level element, while the universal selector * selects every element. Use :root for document-level settings, not to "select everything."
  • Specificity matters. Because :root outranks html, a later html { ... } rule will not override a :root rule on the same property — a common surprise when you mix the two.
  • It's still just one element. Styling :root styles <html>; it does not automatically style <body> or anything inside it.

Browser support and spec

:root is supported in every modern browser. It is defined in the CSS Selectors specification:

Practice

Practice
What is the purpose of the ':root' pseudo-class selector in CSS?
What is the purpose of the ':root' pseudo-class selector in CSS?
Was this page helpful?