The Universal Selector: Global Resets, Box Sizing, and Inherits
Master the CSS Universal Selector. Learn how to target all elements, implement box-sizing border-box resets, and understand performance impacts.
Introduction
If you write a document in Microsoft Word, you don't select every paragraph and word one-by-one to change the font family. You select all text (Ctrl + A) and apply the styling globally.
In CSS, the Universal Selector (represented by the asterisk symbol *) acts as this "Select All" tool. It targets every single HTML element in the DOM tree. While extremely powerful for resetting browser layout defaults and standardizing sizing calculations, using it incorrectly can lead to severe browser performance bottlenecks.
What You Will Learn
- The syntax and behavior of the Universal Selector (
*). - How to implement the industry-standard
border-boxreset. - The performance cost of universal selector calculations.
- Combining the universal selector with pseudo-elements (
*::before,*::after).
Prerequisites
Detailed Explanation: The Asterisk Selector
The Universal Selector matches any element type. It has a specificity score of exactly 0, meaning any element, class, or ID selector will overwrite it.
/* Color every element on the page red (rarely used in production) */
* {
color: red;
}
The Box-Sizing Reset (Must Know)
By default, browsers calculate an element's size using:
$$\text{Total Width} = \text{Width} + \text{Padding} + \text{Border}$$
If you create a sidebar of width 300px and add 20px padding, its actual rendered width becomes 340px, breaking your layout grids.
To fix this, developers use the universal selector to enforce border-box, which includes padding and borders inside the declared width:
*, *::before, *::after {
box-sizing: border-box;
}
Note: We include *::before and *::after to ensure pseudo-elements also follow this sizing rule.
Performance Considerations
Because the universal selector matches every element on the page, the browser has to evaluate this rule against every single node in the DOM.
- Writing complex selectors containing asterisks (like
body * div { ... }) forces the browser to run excessive matches, slowing down page rendering. - Rule of Thumb: Limit the use of the universal selector to global styling resets (margin, padding, box-sizing) at the very top of your stylesheet.
Visual Learning Diagram (Mermaid)
graph TD
A[Universal Selector *] -->|Targets| B[html]
A -->|Targets| C[body]
A -->|Targets| D[div]
A -->|Targets| E[span]
A -->|Targets| F[All pseudo-elements]
Code Examples
Example 1: Standard Global CSS Reset
Here is the baseline reset used by senior frontend architects:
/* Standard Reset */
*, *::before, *::after {
box-sizing: border-box; /* Standardize width calculations */
margin: 0; /* Remove default browser margins */
padding: 0; /* Remove default browser paddings */
}
html {
scroll-behavior: smooth; /* Smooth anchor scrolling */
}
body {
font-family: system-ui, sans-serif;
line-height: 1.5;
background-color: #0f172a;
}
Example 2: Target Direct Children (Combinator Hack)
Sometimes we use the universal selector combined with child combinators to add margins to all direct children of a container, regardless of their tag type:
/* Add vertical spacing to all direct children of the card */
.card > * {
margin-bottom: 12px;
}
/* Remove margin from the last child to prevent trailing whitespace */
.card > *:last-child {
margin-bottom: 0;
}
Summary
The universal selector (*) matches all HTML elements. While it is the standard tool for enforcing global layout resets (clearing margins, standardizing border-box calculations), it should be used sparingly to avoid browser rendering lags on heavy DOM trees.
Related Articles
Next Tutorial
How do we apply the same styling rules to multiple selectors without duplicating code? Let's check: Grouping Selectors.