CSS :root Selector

Beginner
⏱️ 7 min read
📚 Updated: Jul 2026
🎯 4 Examples
Global Styles

What You’ll Learn

The :root pseudo-class represents the document’s root element — usually <html>. It is the go-to place for defining global CSS custom properties that power consistent themes across your site.

01

Root element

<html> in HTML.

02

Variables

--token-name.

03

var()

Use tokens.

04

Themes

Color palette.

05

Responsive

Media queries.

06

vs html

Specificity.

Introduction

The CSS :root selector targets the highest-level parent in the document tree. In an HTML page, that is the <html> element.

It is especially useful for defining CSS custom properties (variables) and global defaults that every component can inherit and reuse with var().

Definition and Usage

Declare shared design tokens inside :root, then reference them anywhere: color: var(--primary-color). This keeps colors, spacing, and typography consistent and easy to update in one place.

💡
Beginner Tip

Think of :root as your project’s settings file. Store brand colors and font sizes there once, then use var(--name) throughout your CSS instead of repeating hex codes.

📝 Syntax

The syntax for the :root pseudo-class is:

syntax.css
:root {
  /* CSS properties */
}

The :root pseudo-class targets the document root and behaves like html with higher specificity.

Basic Example

root-variables.css
:root {
  --primary-color: #2563eb;
  --secondary-color: #16a34a;
  --font-size: 1rem;
}

body {
  font-size: var(--font-size);
  color: var(--primary-color);
}

h1 {
  color: var(--secondary-color);
}
:root { --color: ... } var(--color) @media :root :root vs html

:root vs html

SelectorTargetsSpecificity
:rootDocument root (<html>)(0, 1, 0) — pseudo-class
html<html> element(0, 0, 1) — element

Syntax Rules

  • Custom properties must start with --: --primary-color.
  • Use var(--name) to read a variable; add a fallback: var(--color, #000).
  • Variables inherit to all descendants of :root.
  • Override tokens locally on any element by redefining --name in a smaller scope.
  • Reserve :root for global tokens — not every style rule.

Related Topics

  • var() — function to use custom property values
  • html — element selector for the same root element
  • @media — change :root variables at breakpoints
  • prefers-color-scheme — dark/light theme tokens
  • color — often set via var(--token)

⚡ Quick Reference

QuestionAnswer
Selector typePseudo-class (structural)
What it targetsDocument root (<html> in HTML)
Most common useGlobal CSS custom properties
Declare variable:root { --name: value; }
Use variableproperty: var(--name);
Browser supportAll modern browsers

When to Use :root

:root is ideal for global design configuration:

  • Brand color palette — Store primary, accent, and neutral colors once.
  • Typography scale — Define base font size and heading sizes as variables.
  • Spacing system — Shared padding and margin tokens (--space-sm, --space-lg).
  • Dark mode — Swap token values inside prefers-color-scheme: dark.
  • Responsive design — Adjust --font-size or --container-width in media queries.

👀 Live Preview

This card uses CSS variables defined on its wrapper (same pattern as :root tokens):

Hello from :root

Colors and spacing come from --root-* custom properties, just like global :root variables.

Powered by var()

Examples Gallery

Practice :root with basic variables, theme tokens, responsive font sizes, and dark mode overrides.

📜 Core Patterns

Define global custom properties and consume them with var().

Example 1 — Basic CSS variables in :root

Declare primary color, accent color, and font size once; use them across the page.

root-basic.css
:root {
  --primary-color: #2563eb;
  --secondary-color: #16a34a;
  --font-size: 1rem;
}

body {
  font-size: var(--font-size);
  color: var(--primary-color);
}

h1 {
  color: var(--secondary-color);
}
Try It Yourself

How It Works

Variables on :root are inherited by every element. Change --primary-color once and every var(--primary-color) reference updates.

Example 2 — Design token palette

Organize a small set of semantic tokens for backgrounds, text, and borders.

root-theme.css
:root {
  --bg: #f8fafc;
  --surface: #ffffff;
  --text: #1e293b;
  --muted: #64748b;
  --border: #e2e8f0;
  --accent: #2563eb;
}

.card {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  padding: 1rem;
}
Try It Yourself

How It Works

Semantic names like --text and --surface describe purpose, not raw color values. Components stay readable and theme changes stay centralized.

📄 Responsive & Themes

Adjust :root variables for breakpoints and color schemes.

Example 3 — Responsive font size

Change --font-size inside a media query for fluid typography.

root-responsive.css
:root {
  --font-size: 1rem;
}

@media (min-width: 768px) {
  :root {
    --font-size: 1.125rem;
  }
}

body {
  font-size: var(--font-size);
}
Try It Yourself

How It Works

Because every element uses var(--font-size), updating the variable in :root at a breakpoint scales typography site-wide without duplicating rules.

Example 4 — Dark mode tokens

Override :root colors when the user prefers a dark color scheme.

root-dark.css
:root {
  --bg: #ffffff;
  --text: #1e293b;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f172a;
    --text: #f1f5f9;
  }
}

body {
  background: var(--bg);
  color: var(--text);
}
Try It Yourself

How It Works

Components keep using var(--bg) and var(--text). Only the token values on :root change, so the entire page theme flips automatically.

💬 Usage Tips

  • Name semantically — Use --text-primary not --blue-500 when possible.
  • Provide fallbacksvar(--color, #2563eb) guards against missing variables.
  • Keep :root lean — Store tokens globally; put component rules elsewhere.
  • Override locally — Redefine --accent on .card for scoped variants.
  • Pair with media queries — Responsive and dark-mode tokens live in nested :root blocks.
  • Prefer :root over html — Slightly higher specificity protects global variables.

⚠️ Common Pitfalls

  • Putting all CSS in :root — It is for global tokens, not every layout rule.
  • Missing -- prefix — Custom properties must start with two hyphens.
  • Forgetting var()color: --primary is invalid; use var(--primary).
  • Over-nesting variables — Keep token layers simple for beginners.
  • Assuming instant IE support — CSS variables need modern browsers (fine for new projects).
  • Duplicating html and :root — Pick one primary place for design tokens.

♿ Accessibility

  • Contrast in themes — Ensure --text on --bg meets WCAG contrast in light and dark modes.
  • Respect prefers-color-scheme — Offer readable dark tokens when users prefer dark UI.
  • Respect prefers-reduced-motion — Store animation durations as tokens you can zero out.
  • Don’t shrink text too much — Keep minimum font-size tokens at least 1rem for body text.
  • Test focus colors — Define --focus-ring on :root for consistent keyboard visibility.

🧠 How :root Works

1

Declare tokens on :root

Custom properties like --primary-color are set on the document root.

CSS
2

Variables inherit

Every element in the document tree can access inherited custom properties.

Cascade
3

Components use var()

Rules reference var(--token) instead of hard-coded values.

var()
=

One place to update

Change a token on :root and the whole site reflects it.

🖥 Browser Compatibility

The :root pseudo-class and CSS custom properties are supported in all modern browsers.

Baseline · Modern browsers

Global variables everywhere

:root and var() work in Chrome, Firefox, Safari, Edge, and Opera.

98% Global support
Google Chrome 49+ · Desktop & Mobile
Full support
Mozilla Firefox 31+ · Desktop & Mobile
Full support
Apple Safari 9.1+ · macOS & iOS
Full support
Microsoft Edge 15+
Full support
Opera 36+
Full support
:root + CSS variables 98% supported

Bottom line: Safe for modern projects. Use fallbacks in var() when supporting very old browsers.

🎉 Conclusion

The CSS :root selector is a powerful tool for defining and managing global styles, particularly CSS custom properties. Its slightly higher specificity makes it the standard home for design tokens that keep your site consistent and maintainable.

Start with a small token set on :root, consume values with var(), and extend with responsive or dark-mode overrides as your project grows.

💡 Best Practices

✅ Do

  • Define design tokens on :root
  • Use semantic variable names
  • Add var() fallbacks for critical values
  • Override tokens in media queries
  • Keep component CSS separate from :root

❌ Don’t

  • Put every style rule inside :root
  • Forget the -- prefix on variables
  • Hard-code colors when a token exists
  • Duplicate tokens on both html and :root
  • Create overly deep variable chains

Key Takeaways

Knowledge Unlocked

Five things to remember about :root

Use these points when setting up global CSS variables.

5
Core concepts
-- 02

Custom props

--token-name.

Syntax
var() 03

Use tokens

Anywhere.

Consume
html 04

Higher spec

Than html.

Tip
🌐 05

98% support

All browsers.

Compat

❓ Frequently Asked Questions

The :root pseudo-class targets the document's root element — the <html> element in HTML. It is the standard place to define global CSS custom properties (variables) and site-wide defaults.
In HTML documents they select the same element, but :root has higher specificity (a pseudo-class vs an element selector). Developers prefer :root for global CSS variables because it won't be accidentally overridden by a bare html rule.
Custom properties declared on :root are inherited by every element in the document. Any component can use var(--token-name) to access shared colors, spacing, or font sizes from one central location.
Yes. You can redefine :root variables inside media queries or @media (prefers-color-scheme: dark) to create responsive or theme-aware design tokens.
:root is supported in all modern browsers. CSS custom properties used inside :root are also widely supported in current browsers.

Practice in the Live Editor

Open the HTML editor and experiment with :root, CSS variables, and var() theming.

HTML Editor →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful