CSS Universal Selector (*)

Beginner
5 min read
Updated: Oct 2026
3 examples
Live preview

Definition and Usage

The universal selector (*) matches elements of any type. Alone it styles every element on the page; scoped like .card * it styles every descendant inside that parent.

It is often used for light resets (margins, box-sizing). Prefer typed or class selectors for day-to-day component styles.

Baseline · Widely available.

Not deprecated. Part of CSS from the start; Baseline dating cites July 2015 for the modern web platform set.

Asterisk is often optional.

*.note and .note match the same elements. Write the shorter form unless a namespace needs an explicit *.

CSS Syntax

syntax.css
* { /* declarations */ }

Namespace forms also exist (*|*, ns|*, |*) when mixing HTML with SVG or MathML.

Common Patterns

PatternMatchesTry it
*Every element in the documentTry it
.box *Every descendant inside .boxTry it
* { box-sizing: border-box; }Border-box sizing on all elementsTry it
.floating + *Next sibling after a floating elementTry it

How to Use the Universal Selector

Reach every element — or every element under a parent — with one rule.

  1. Write * { … } for a global rule (resets, base font color).
  2. Scope with a parent: .card * limits the match.
  3. Remember specificity is 0 — classes and types override it easily.
  4. For pseudo-elements, combine explicitly: *::before.

Live Preview

Toggle a scoped .demo * style. Watch every nested tag change together.

Rule applied: /* none */

Demo tree

Title

Paragraph with a span and emphasis.

  • Item one
  • Item two

No universal style applied inside the demo.

CSS Examples

Each snippet focuses on *. Use Try It Yourself for a live editor.

Example 1 — Style All Elements

A bare * paints every element the same color.

CSS
<style>
  * {
    color: #15803d;
  }
</style>

<h1>Heading</h1>
<p>Paragraph</p>
<a href="#">Link</a>
Try It Yourself

How It Works

  1. Match all. * selects every element type.
  2. Shared color. Heading, paragraph, and link all turn green.
  3. Low power. A later a { color: blue; } would override the link.
  4. Use sparingly. Great for demos and base resets, not every component.

Example 2 — Scoped .box *

Limit the universal match to descendants of one container.

CSS
<style>
  .box * {
    color: #1d4ed8;
  }
</style>

<div class="box">
  <p>Inside — blue</p>
  <span>Also inside</span>
</div>
<p>Outside — unchanged</p>
Try It Yourself

How It Works

  1. Parent first. .box narrows the search.
  2. Then any child. * matches every descendant tag.
  3. Outside stays plain. The last paragraph is not under .box.
  4. Component resets. Useful for isolating styles inside one widget.

Example 3 — Border-Box Reset

Make padding and borders count inside width for every element.

CSS
<style>
  * {
    box-sizing: border-box;
  }

  .card {
    width: 160px;
    padding: 16px;
    border: 4px solid #2563eb;
    background: #eff6ff;
  }
</style>

<div class="card">160px total width</div>
Try It Yourself

How It Works

  1. Global sizing. * sets border-box on every element.
  2. Fixed width. The card is 160px wide including padding and border.
  3. Easier layouts. You no longer add padding on top of width by accident.
  4. Often extended. Many resets also set *::before, *::after the same way.

Edge Cases & Pitfalls

Keep these in mind before sprinkling * everywhere.

specificity

Specificity is zero

Any type, class, or id selector beats a bare * on the same property.

pseudo

Does not match pseudo-elements alone

* selects elements only. Use *::before / *::after when you need those boxes too.

optional

Often redundant with classes

*.warning equals .warning. Drop the asterisk unless namespaces require it.

scope

Prefer a parent when possible

.widget * is safer than a page-wide * for component-only resets.

perf

Heavy trees + many properties

Matching every node is fine for a short reset. Avoid stuffing large rule sets onto a bare *.

Browser Support

The universal selector is a browser CSS selector. Node.js, Deno, and Bun do not apply it.

✓ Baseline · Widely available

*

Supported in all browsers since early CSS. Safe for teaching and production.

100% Core support
Google Chrome 1+
Full support
Mozilla Firefox 1+
Full support
Apple Safari 1+
Full support
Microsoft Edge 12+
Full support
Opera 3.5+
Full support
Samsung Internet 1+
Full support
Internet Explorer 7+
Full support
* Universal

Bottom line: No prefixes. No polyfills. It is not a runtime API.

Key Takeaways

  • Role: match elements of any type.
  • Scope: use .parent * to limit the match.
  • Specificity: * adds 0 — easy to override.
  • Tip: great for resets; prefer classes for components.

One line: * styles any element — scope it when you can, and keep the rule light.

Frequently Asked Questions

It matches elements of any type. Alone it selects every element in the document; scoped as .box * it selects every descendant inside that box.
Zero: (0,0,0). Any type, class, or id selector overrides a bare * rule when the same property conflicts.
No. * matches elements only. To style all ::before pseudo-elements, write *::before.
Yes. *.note and .note are equivalent. *#id and #id are equivalent.
Yes. It is a common reset so width and height include padding and border. Many projects also include *::before, *::after for the same reason.
Yes. It is Baseline Widely available. It is a browser CSS selector, not a Node.js or runtime API.

Next: :valid

Learn how to style form controls that pass validation.

:valid tutorial →

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.

8 people found this page helpful