CSS :root Pseudo-Class

The CSS :root pseudo-class selects the root element of a document or document tree. In HTML documents, the root element is <html>. The :root pseudo-class is commonly used to define global CSS custom properties, establish document-wide styles, and manage reusable design values.

:root Syntax

:root {
  property: value;
}

The :root pseudo-class selects the document's root element. It does not accept arguments or require parentheses.

Basic Example

:root {
  color: #333;
  background-color: #fff;
}

Applies text and background colors to the root element. The text color can be inherited by descendants.

Custom Property Example

:root {
  --primary-color: #006699;
}

Defines a custom property that descendants can use through the var() function.

Using a Custom Property

h2 {
  color: var(--primary-color);
}

Uses the custom property defined on the root element to set heading colors.

No Parentheses

The correct syntax is :root, not :root().

How :root Works

Every document tree has a root element. The :root pseudo-class matches that element, allowing styles to be applied at the top of the document's element hierarchy.

HTML Structure

<html lang="en">
  <head>
    <title>Example</title>
  </head>
  <body>
    <h1>CSS Example</h1>
    <p>Example content.</p>
  </body>
</html>

In this document, :root matches the <html> element.

CSS Example

:root {
  font-family: Arial, sans-serif;
  color: #333;
}

The root element receives these styles. Inherited properties, such as font-family and color, can pass their values to descendant elements.

One Root Element

An ordinary HTML document has one root element. The selector does not match every element on the page.

Not a Parent Selector

The :root pseudo-class does not select the parent of an arbitrary element. It specifically matches the root element of the document tree.

Styles and Inheritance

Not all CSS properties inherit. For example, defining a border on :root does not automatically give every descendant the same border.

The Root Element

The root element is the top-level element in a document's element tree. Its identity depends on the document type.

HTML Documents

<html lang="en">
  <head></head>
  <body></body>
</html>

In HTML documents, the <html> element is the root.

CSS Selection

:root {
  --page-background: #f5f7fa;
}

The custom property is defined on the root and normally inherited by descendants.

Document Body

The <body> element is not the document root. It is a descendant of <html>.

Nested Elements

Elements such as <main>, <section>, and <div> are not matched by :root simply because they contain other elements.

Document-Wide Values

Defining reusable values on the root is convenient because most descendants can inherit those values without repeating declarations.

:root vs. html

In an HTML document, both :root and html select the same element. However, they have different specificity values.

HTML Selector

html {
  background-color: #fff;
}

Matches the HTML document's root element by its element name.

Root Pseudo-Class

:root {
  background-color: #f2f2f2;
}

Matches the same element by its position as the document root.

Specificity Difference

Selector Specificity
html0-0-1
:root0-1-0

Cascade Example

:root {
  color: #006699;
}
html {
  color: #333;
}

When both declarations have the same origin, importance, and cascade layer, the :root declaration wins because its specificity is higher, even though the html rule appears later.

Which Should You Use?

Both selectors work for document-level styling in HTML. The :root selector is especially common for CSS custom properties and reusable design tokens.

CSS Custom Properties

CSS custom properties are reusable values defined with names beginning with two hyphens. They are commonly declared on :root so that descendant elements can access them.

Define Custom Properties

:root {
  --primary-color: #006699;
  --secondary-color: #444;
  --page-background: #fff;
  --border-radius: 6px;
  --content-spacing: 16px;
}

Use Custom Properties

.button {
  background-color: var(--primary-color);
  border-radius: var(--border-radius);
  padding: var(--content-spacing);
}

The var() function retrieves the computed custom property value from the element.

Multiple Uses

h1,
h2 {
  color: var(--primary-color);
}
a {
  color: var(--primary-color);
}

Several rules can reuse the same custom property, making updates easier.

Changing One Value

:root {
  --primary-color: #8a2be2;
}

Changing the root custom property updates elements that use the inherited value, unless a more local definition overrides it.

Case Sensitivity

Custom property names are case-sensitive. For example, --primary-color and --Primary-Color are different names.

Custom Property Inheritance

Ordinary custom properties declared with the two-hyphen syntax inherit by default. This allows descendants to use values defined on :root.

Root Definition

:root {
  --text-color: #333;
}

Descendant Usage

article {
  color: var(--text-color);
}

The article can use the inherited custom property without defining it again.

Nested Elements

<article>
  <h2>CSS Custom Properties</h2>
  <p>Reusable values simplify stylesheets.</p>
</article>

Descendants can inherit custom property values through the element tree.

Custom Property vs. Normal Property

Defining a custom property does not automatically change an element's appearance. The value must be used in another CSS declaration.

Registered Custom Properties

Custom properties registered with @property can specify different inheritance behavior. The default inheritance described here applies to ordinary unregistered custom properties.

Overriding Custom Properties

Custom properties defined on :root can be overridden on individual elements or containers. This allows components to use different values without changing the global defaults.

Global Value

:root {
  --accent-color: #006699;
}

Component Override

.warning-box {
  --accent-color: #b3261e;
}

Shared Usage

.info-box,
.warning-box {
  border-left: 4px solid var(--accent-color);
}

The info box uses the inherited blue value, while the warning box uses its local red value.

Nested Override

:root {
  --text-color: #333;
}
.dark-panel {
  --text-color: #fff;
}
.panel-text {
  color: var(--text-color);
}

A .panel-text element inside .dark-panel inherits the local white value, while one outside it uses the root value.

Inheritance and Cascade

A custom property explicitly declared on an element takes precedence over an inherited value from an ancestor, subject to the CSS cascade.

Fallback Values

The var() function supports fallback values when a referenced custom property is missing or has the guaranteed-invalid value.

Basic Fallback

h2 {
  color: var(--heading-color, #006699);
}

If --heading-color is unavailable or guaranteed-invalid, the fallback color is used.

Root Value

:root {
  --heading-color: #444;
}
h2 {
  color: var(--heading-color, #006699);
}

The heading uses #444 because the custom property is defined.

Nested Fallback

h2 {
  color: var(--heading-color, var(--primary-color, #006699));
}

The browser first attempts to use --heading-color, then --primary-color, and finally the literal color.

Invalid Values

A fallback does not automatically correct a custom property that resolves to a value invalid for the receiving property. For example, a defined custom property containing a length cannot be used as a valid color merely because var() includes a color fallback.

Fallback Best Practice

Use fallbacks where a custom property may be undefined, especially in reusable components that can appear outside their original styling context.

Global Document Styles

The :root pseudo-class can also establish document-wide values for inherited properties and root-level behavior.

Font Family

:root {
  font-family: Arial, Helvetica, sans-serif;
}

Sets a font family that descendants can inherit unless they have their own font declarations.

Text Color

:root {
  color: #333;
}

Defines a root text color that can be inherited by descendant elements.

Color Scheme

:root {
  color-scheme: light dark;
}

Indicates that the document supports light and dark color schemes, allowing the browser to adjust supported user-interface elements.

Scroll Behavior

:root {
  scroll-behavior: smooth;
}

Requests smooth scrolling for navigation within the document's viewport when supported and permitted by user preferences.

Background Color

:root {
  background-color: #f5f7fa;
}

Sets the root background, which can contribute to the canvas background in an HTML document.

Root Font Size and rem Units

The CSS rem unit is relative to the root element's font size. The :root pseudo-class can be used to define that base size.

Root Font Size

:root {
  font-size: 16px;
}

Using rem

h1 {
  font-size: 2rem;
}
p {
  font-size: 1rem;
}
.card {
  padding: 1.5rem;
}

With a root font size of 16px, 2rem computes to 32px and 1.5rem computes to 24px.

Root vs. Parent

The rem unit uses the root font size. The em unit generally depends on the font size of the element or its parent, depending on the property.

Respecting User Preferences

:root {
  font-size: 100%;
}

Using a percentage allows the root font size to follow the user's configured browser default more naturally than forcing a fixed pixel size.

Accessibility

Relative units help create layouts that respond to font-size preferences. Test text enlargement and browser zoom to ensure content remains readable.

Themes and Color Schemes

Root-level custom properties make it easier to manage light and dark themes or other site-wide design variations.

Default Theme

:root {
  --background-color: #fff;
  --text-color: #333;
  --accent-color: #006699;
}

Dark Theme

:root[data-theme="dark"] {
  --background-color: #1f2933;
  --text-color: #fff;
  --accent-color: #80cfff;
}

Apply Theme Values

body {
  background-color: var(--background-color);
  color: var(--text-color);
}
a {
  color: var(--accent-color);
}

Elements using these custom properties update when the root theme attribute changes.

HTML Theme Attribute

<html lang="en" data-theme="dark">

The attribute selector in :root[data-theme="dark"] matches when the root has the specified theme value.

System Color Preference

@media (prefers-color-scheme: dark) {
  :root {
    --background-color: #1f2933;
    --text-color: #fff;
  }
}

Uses the user's preferred color scheme to change root custom properties in supporting browsers.

Theme Overrides

Explicit theme selectors and system-preference rules can be combined. Plan their cascade order so a user-selected theme is not unintentionally overridden.

JavaScript and :root

JavaScript can access the root element and change its attributes or custom properties. CSS updates automatically when those values change.

Access the Root Element

const root = document.documentElement;

The documentElement property references the document's root element.

Select the Root with CSS

const root = document.querySelector(":root");

The querySelector() method can select the root element using the pseudo-class.

Set a Custom Property

document.documentElement.style.setProperty("--primary-color", "#8a2be2");

Changes the custom property on the root element.

Read a Custom Property

const styles = getComputedStyle(document.documentElement);
const color = styles.getPropertyValue("--primary-color").trim();
console.log(color);

Reads the computed custom property value from the root element.

Change a Theme Attribute

document.documentElement.dataset.theme = "dark";

Sets the root's data-theme attribute to dark.

Remove a Theme Attribute

document.documentElement.removeAttribute("data-theme");

Removes the attribute so the root returns to the styles selected by the remaining CSS rules.

Other Document Types

The :root pseudo-class is not limited to HTML. It matches the root element in other document types that support CSS selectors.

HTML

<html lang="en">
  <body>
    <p>HTML document</p>
  </body>
</html>

The root is the <html> element.

SVG

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="40" fill="blue" />
</svg>

In a standalone SVG document, the outermost <svg> element is the root.

XML

In an XML document, :root matches the document's root element, whatever its element name may be.

Embedded SVG

An <svg> element embedded inside an HTML document is not the HTML document root. In that document, :root still matches <html>.

Document Context Matters

The matched element depends on the document tree in which the selector is evaluated.

:root Specificity

The :root pseudo-class contributes a specificity of 0-1-0, like other standard pseudo-classes.

Specificity Examples

Selector Specificity
:root0-1-0
html0-0-1
html:root0-1-1
:root[data-theme="dark"]0-2-0
:root.theme-dark0-2-0
:root:not(.dark)0-2-0
:where(:root)0-0-0

Specificity Example

html {
  --primary-color: #333;
}
:root {
  --primary-color: #006699;
}

When both declarations have the same origin, importance, and cascade layer, the :root declaration wins because its selector has greater specificity.

Low-Specificity Alternative

:where(:root) {
  --primary-color: #006699;
}

The :where() pseudo-class gives the selector zero specificity, making it easier for other rules to override the values.

Practical Uses

The :root pseudo-class is useful for reusable CSS values, global styling, and document-wide configuration.

Brand Colors

:root {
  --brand-primary: #006699;
  --brand-secondary: #444;
}

Defines reusable brand colors for a stylesheet.

Spacing Values

:root {
  --space-small: 8px;
  --space-medium: 16px;
  --space-large: 24px;
}

Creates consistent spacing values that components can reuse.

Border Radius

:root {
  --radius-small: 4px;
  --radius-medium: 8px;
}

Defines reusable corner-radius values.

Global Typography

:root {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 100%;
}

Sets a root font family and a relative root font size.

Smooth Scrolling

@media (prefers-reduced-motion: no-preference) {
  :root {
    scroll-behavior: smooth;
  }
}

Requests smooth scrolling when the user has not expressed a preference for reduced motion.

Theme Management

:root {
  --page-background: #fff;
}
:root[data-theme="dark"] {
  --page-background: #1f2933;
}

Changes a reusable background value based on a theme attribute.

Limitations

The :root pseudo-class selects the root element, but it does not automatically apply every declared style to all descendants.

Only Matches the Root

It does not match every element or every parent container.

Not Every Property Inherits

Properties such as borders, padding, and margins do not automatically inherit from the root.

Custom Properties Must Be Used

Defining --primary-color does not change text or background colors until another declaration uses it.

Local Overrides

Descendant elements can override inherited custom properties, so the root value is not necessarily used everywhere.

Invalid Custom Property Values

A custom property can contain a value that is invalid for a receiving CSS property. The browser applies CSS value validation when the custom property is substituted.

Document Scope

Root-level custom properties in one document do not automatically apply inside separate iframe documents or across independent document trees.

Shadow DOM

Inherited custom properties can cross into shadow trees through their hosts, but values can be overridden and registered properties can have different inheritance rules.

Higher Specificity

The :root selector has higher specificity than the html type selector. Consider this when organizing global styles.

Best Practices

  • Use :root to define reusable custom properties that should be available throughout the document.
  • Give custom properties descriptive names such as --primary-color or --content-spacing.
  • Group related custom properties to keep global styles organized.
  • Use var() to reference custom properties instead of repeating values.
  • Use local overrides when components need different values from the global defaults.
  • Provide fallback values where a custom property may be undefined.
  • Remember that :root and html select the same element in HTML but have different specificity.
  • Prefer relative font sizing that respects user preferences.
  • Use theme attributes or media queries to manage document-wide color schemes.
  • Test custom property inheritance and overrides when working with nested components or shadow DOM.

:root Example

This example defines colors, spacing, and border-radius values on :root. The card and button use those values through var(). Click Change Theme to update the root custom properties and change the card's appearance.

HTML

<div class="root-demo">
  <div class="demo-card">
    <h2>CSS Custom Properties</h2>
    <p>This card uses values defined on :root.</p>
    <button type="button" id="theme-toggle">Change Theme</button>
  </div>
</div>

CSS

:root {
  --demo-primary: #006699;
  --demo-background: #eaf6fc;
  --demo-text: #333;
  --demo-spacing: 16px;
  --demo-radius: 8px;
}
:root[data-demo-theme="alternate"] {
  --demo-primary: #8a2be2;
  --demo-background: #f3e8ff;
  --demo-text: #333;
}
.root-demo .demo-card {
  padding: var(--demo-spacing);
  border: 2px solid var(--demo-primary);
  border-radius: var(--demo-radius);
  background-color: var(--demo-background);
  color: var(--demo-text);
}
.root-demo .demo-card h2 {
  margin-top: 0;
  color: var(--demo-primary);
}
.root-demo button {
  padding: 8px 12px;
  border: 0;
  border-radius: var(--demo-radius);
  background-color: var(--demo-primary);
  color: #fff;
  cursor: pointer;
}

JavaScript

const button = document.getElementById("theme-toggle");
button.addEventListener("click", () => {
  const root = document.documentElement;
  const alternate = root.dataset.demoTheme === "alternate";
  if (alternate) {
    root.removeAttribute("data-demo-theme");
  } else {
    root.dataset.demoTheme = "alternate";
  }
  button.textContent = alternate ? "Change Theme" : "Restore Theme";
});

Browser Result

Play in Editor

Note: The card initially uses blue colors defined on :root. Click Change Theme to apply alternate purple values. Click Restore Theme to return to the original colors. The example changes the root element's theme attribute without changing individual component styles.

Browser Support

Baseline: Widely available. The :root pseudo-class is supported in Chrome, Edge, Firefox, Safari, and other major browsers. Support for related features, such as registered custom properties and newer color functions, should be checked separately.

For current compatibility information, visit Can I Use? and search for :root.

Specifications

The :root pseudo-class is defined in CSS Selectors Level 4 as a structural pseudo-class that matches the root element of a document tree.

Selectors Level 4 - The :root Pseudo-Class