What Is the Universal Selector?
The CSS universal selector, denoted by the asterisk (*), is a special selector that matches elements of any type in a document. Whether you're targeting a paragraph, a div, a span, or any other HTML element, the universal selector applies to all of them without exception. This makes it both incredibly powerful and potentially dangerous when misused.
According to the MDN Web Docs, the universal selector is a fundamental tool in CSS that provides flexibility in styling, but requires careful consideration of performance implications. Understanding when and how to use this selector effectively is essential for writing maintainable, performant CSS in modern web applications.
The universal selector is particularly useful in three scenarios: establishing baseline styles through CSS resets, debugging layout issues during development, and testing whether styles are being applied correctly. Beyond these use cases, more specific selectors typically provide better performance and maintainability for your /services/web-development/ projects.
Basic Syntax
The simplest form matches every element in of the universal selector the document. When you apply styles using *, those styles affect every HTML element without exception. This comprehensive matching capability is what gives the selector its "universal" name.
The universal selector can also target elements within a specific container. When combined with other selectors, it applies only to descendants of that context, providing more granular control over where the styles apply. This scoping technique is especially useful in component-based architectures where you want to avoid global style conflicts in your /services/web-development/ workflow.
1/* Selects all elements */2* {3 margin: 0;4 padding: 0;5}6 7/* Selects all elements inside article elements */8article * {9 border: 1px solid #e0e0e0;10}The Asterisk Is Optional
One interesting aspect of the universal selector that many developers overlook is that the asterisk can be omitted when combined with simple selectors. These two declarations are functionally identical: *.warning produces the same result as .warning, and *#main-content is equivalent to #main-content.
While this syntax flexibility exists in the CSS specification, modern CSS practice favors the simpler, more readable form without the asterisk. However, understanding this equivalence becomes valuable when reading legacy code or debugging selector behavior in older codebases. You may encounter this pattern in older CSS frameworks or in code written by developers who learned CSS in earlier eras of /services/web-development/.
1/* Both of these are equivalent */2*.warning {3 color: orange;4}5 6.warning {7 color: orange;8}Practical Use Cases
While the universal selector should be used sparingly in production code, it has several valuable applications in web development workflows. Understanding these use cases helps you leverage the selector's power appropriately.
CSS Resets and Normalization
Use the universal selector to set baseline values across all elements, eliminating browser inconsistencies in margin, padding, and box-sizing.
Debugging Layout Issues
Temporarily apply borders to all elements to visualize hidden elements, unexpected margins, and layout boundaries.
Testing Selector Performance
Replace complex selectors with the universal selector to isolate whether issues stem from selector matching or property application.
Global Font and Color Defaults
Set typography defaults at the document level to ensure consistency across all elements, though inheritance is often more efficient.
1/* Simple CSS reset */2* {3 margin: 0;4 padding: 0;5 box-sizing: border-box;6}7 8/* Modern CSS reset approach */9*,10*::before,11*::after {12 box-sizing: border-box;13}Performance Considerations
In modern browsers, the performance impact of the universal selector has been significantly reduced through engine optimizations. Browsers like Chrome, Firefox, and Safari have sophisticated selector matching engines that handle the * selector efficiently, especially for simple property declarations.
According to MDN's CSS performance documentation, applying styles to all elements can impact performance negatively, particularly on larger sites with complex styling requirements. However, for most websites, the difference is imperceptible--the key factor is what properties you're applying rather than the selector itself. For performance-critical applications, consider consulting our /services/web-development/ team for expert optimization strategies.
1/* Better: Apply to body, let inheritance handle the rest */2body {3 font-family: -apple-system, BlinkMacSystemFont, sans-serif;4 color: #333;5}6 7/* Limit universal selector scope */8.widget-container * {9 margin: 0;10}Namespacing and Advanced Usage
The universal selector supports namespacing, which is essential when working with documents containing multiple XML namespaces such as HTML with inline SVG or MathML. The @namespace rule allows you to define namespace prefixes that qualify element selectors.
For most web developers working with standard HTML, SVG, and MathML, namespaces aren't commonly encountered in day-to-day CSS. However, understanding this capability becomes important when debugging or working with complex XML-based documents, or when integrating content from external sources that use different namespaces in your /services/web-development/ projects.
1/* Define a namespace */2@namespace url("http://www.w3.org/1999/xhtml");3 4/* Select all HTML elements (not SVG or MathML) */5html| * {6 margin: 0;7}Combining with Pseudo-Elements
A critical distinction in the universal selector's behavior concerns pseudo-elements. The universal selector matches elements only--it does not directly match pseudo-elements like ::before and ::after. This is a common source of confusion for developers learning CSS.
To style pseudo-elements, you must reference them directly. However, combining the universal selector with pseudo-elements is valid when you want to apply styles to pseudo-elements on all elements simultaneously. This pattern can be useful for adding data-driven content to multiple elements, though it should be used judiciously due to performance implications in production /services/web-development/ applications.
The Universal Selector and Specificity
The universal selector contributes zero specificity to a rule. This means it doesn't affect the cascade in any meaningful way and can be easily overridden by any other selector. This zero-specificity behavior is important when using the universal selector as part of a reset or normalization strategy.
This characteristic makes the universal selector ideal for establishing baseline styles that other selectors can easily override. However, it also means that important styles shouldn't rely solely on the universal selector in situations where you need to guarantee they won't be accidentally overridden by more specific selectors later in your stylesheet when building production-grade /services/web-development/ applications.
1/* All have the same specificity: (0, 0, 1) */2* {3 color: blue;4}5 6div {7 color: blue;8}9 10.warning {11 color: blue;12}Common Mistakes and Misconceptions
Even experienced developers make mistakes when using the universal selector. Understanding these common errors helps you avoid performance pitfalls and maintain cleaner CSS in your /services/web-development/ projects.
One frequent error is overusing the universal selector for spacing on large production sites. While setting margin: 0 and padding: 0 on all elements works, it's inefficient compared to more targeted approaches. The all property introduced in CSS3 offers a cleaner alternative for resets in certain scenarios.
1/* Misses pseudo-elements */2* {3 box-sizing: border-box;4}5 6/* Correct approach */7*,8*::before,9*::after {10 box-sizing: border-box;11}The Universal Selector in Modern CSS Workflows
In modern frameworks like Next.js, the universal selector plays a different role than in traditional CSS. Utility-first frameworks like Tailwind CSS reduce the need for broad selectors, while CSS Modules provide local scoping that limits selector scope naturally.
However, the universal selector remains valuable for global styles in a Next.js project's globals.css file, particularly for establishing the box-sizing reset that ensures consistent layout behavior across all components. When combined with CSS custom properties, it provides an effective foundation for theming systems that can be extended at the component level for your /services/web-development/ projects.
The key insight for modern CSS workflows is that the universal selector should be part of your foundational layer--your reset and base styles--while more specific selectors and utility classes handle component-level styling. This separation of concerns keeps your stylesheet maintainable and performant.
1/* globals.css in a Next.js project */2*,3*::before,4*::after {5 box-sizing: border-box;6}7 8body {9 margin: 0;10 font-family: var(--font-geist-sans), system-ui, sans-serif;11}When to Use the Universal Selector
Understanding when to use--and when to avoid--the universal selector is key to writing performant, maintainable CSS. Use it for CSS resets and debugging, but avoid it for production styling where more specific selectors would work better.
The universal selector excels at establishing baseline consistency across browsers, testing whether styles are being applied correctly during development, and visualizing layout problems. However, it should be avoided when applying computationally expensive properties, when inheritance would be more efficient, and in performance-critical rendering scenarios with large DOM trees in your /services/web-development/ applications.
Good Use Cases
CSS resets for box-sizing, development debugging to visualize layout, establishing base styles that are easily overridden, testing selector matching during troubleshooting.
When to Avoid
Large production sites with complex styling, performance-critical rendering scenarios, applying expensive properties like shadows and filters, when inheritance would suffice.
Summary
The universal selector (*) is a fundamental CSS tool that matches every element in a document. While its power can lead to misuse, understanding its behavior--zero specificity, performance characteristics, and namespacing support--enables developers to leverage it effectively.
In modern web development with Next.js and modern CSS frameworks, the universal selector remains valuable for CSS resets, debugging layout issues, and establishing baseline styles. However, it should be used judiciously in production code where more specific selectors, utility classes from frameworks like Tailwind, and CSS custom properties offer better maintainability and performance.
The key to using the universal selector effectively is knowing when it accelerates your workflow and when it introduces unnecessary complexity. Reserve it for foundational styles and debugging, and prefer more targeted selectors for component-level styling in your production code. For teams looking to optimize their CSS architecture, our /services/web-development/ experts can help establish best practices across your projects.
Frequently Asked Questions
What is the CSS universal selector?
The CSS universal selector (*) is a special selector that matches every HTML element in a document. It's represented by an asterisk and can be used alone or in combination with other selectors to apply styles universally or within specific contexts.
Does the universal selector have specificity?
No, the universal selector has zero specificity. This means styles applied with * can be easily overridden by any other selector, making it ideal for baseline styles but unsuitable for rules that must take precedence.
Does * match pseudo-elements?
No, the universal selector matches elements only. To match pseudo-elements like ::before and ::after, use them directly without the asterisk, or combine *::before to apply styles to the ::before pseudo-element of every element.
Is the universal selector bad for performance?
In modern browsers, the performance impact is minimal for simple properties. However, applying computationally expensive properties (box-shadow, filter, transform) to all elements can slow rendering, especially on large pages with complex DOM structures.
When should I use the universal selector?
Use it for CSS resets (especially box-sizing), debugging layout issues, and establishing baseline styles. Avoid using it for production styling when more specific selectors or utility classes would work better.
Sources
- MDN Web Docs: Universal Selectors - Official reference covering syntax, namespacing, and pseudo-element behavior
- W3Schools: CSS Universal Selector - Practical examples and basic syntax
- MDN: CSS Performance Optimization - Performance considerations and best practices