CSS :has() Selector Playground - Online Test Parent Styling
Test the powerful :has() pseudo‑class. Write selectors like .card:has(img) and see the live result. Revolutionary for CSS architecture.
UD5 Toolkit
Interactive testbed for :is()
:where()
:not()
— real‑time highlighting & specificity insights
Matches any selector in its argument list. Takes the highest specificity among arguments.
Same as :is(), but always has zero specificity. Perfect for base styles you want to easily override.
Excludes elements matching its argument. Specificity equals the argument's specificity.
:is() is a forgiving selector list pseudo-class. It matches any element that matches at least one selector in its argument list. Unlike traditional comma-separated selectors, if one selector inside :is() is invalid, the entire list is not discarded — the browser simply ignores the invalid selector and continues evaluating the rest.
Key use cases:
:is(header, main, footer) p instead of header p, main p, footer p:is(:hover, :focus, :active)Specificity note: :is() adopts the specificity of its most specific argument. For example, :is(#id, .class) has the specificity of an ID selector (1,0,0).
The critical difference is specificity. While :is() takes the highest specificity from its arguments, :where() always contributes zero specificity — regardless of what selectors are inside it.
This makes :where() ideal for:
Example: :where(.dark-theme) a { color: lightblue; } has specificity (0,0,1) — just the a element. This means .dark-theme .nav a { color: white; } (specificity 0,2,1) easily overrides it.
:not() excludes elements that match its argument. It's extremely useful for:
li:not(.active) { opacity: 0.6; }button:not([disabled]) { cursor: pointer; }.card:not(:last-child) { margin-bottom: 16px; }:is(.card, .box):not(.featured)Important: :not() takes only one simple selector in older browsers, but modern browsers support complex selector lists inside :not() (e.g., :not(.a, .b)), matching the forgiving behavior of :is().
Specificity: :not() contributes the specificity of its argument. :not(#id) has the specificity of an ID.
Yes, absolutely! These pseudo-classes can be nested and combined in powerful ways:
:is(.card, .box):not(.disabled) — match cards and boxes that aren't disabled:where(header, main) :is(h1, h2, h3) — zero-specificity heading selection within header or main:not(:is(.excluded, .hidden)) — exclude elements matching any of the listed classes:is(:where(.a, .b), .c) — the :where() part contributes zero specificity, while .c contributes normally; overall specificity = max(0, class) = class-levelThis composability is what makes these pseudo-classes so powerful for building maintainable, scalable CSS architectures.
All modern browsers fully support :is(), :where(), and :not() with complex selector lists:
:is() and :where()Legacy support: Older browsers supported :not() only with simple selectors. The older :matches() (prefixed as :-webkit-any() / :-moz-any()) was the precursor to :is(). If you need to support very old browsers, provide fallback rules.
As of 2024, global support exceeds 96%, making these safe for production use in most projects.
Specificity is calculated as a three-part value (a, b, c):
Rules for our pseudo-classes:
:is(A, B, C) → specificity = max(specificity(A), specificity(B), specificity(C)):where(A, B, C) → specificity = (0, 0, 0) — always zero, regardless of arguments:not(X) → specificity = specificity(X) — the negation itself adds nothingPractical example: :is(#hero, .card) p → specificity of :is() part = max((1,0,0), (0,1,0)) = (1,0,0), plus p = (0,0,1) → total (1,0,1).
:where(#hero, .card) p → :where() = (0,0,0), plus p = (0,0,1) → total (0,0,1).
Two main reasons: brevity and forgiving behavior.
Brevity: Compare header p, main p, footer p, aside p (72 chars) versus :is(header, main, footer, aside) p (37 chars). The longer the shared suffix, the more :is() saves.
Forgiving behavior: In a traditional comma-separated list like ::unknown, .valid, the entire rule is discarded if one selector is invalid. With :is(::unknown, .valid), the invalid ::unknown is simply ignored and .valid still matches. This is invaluable when using experimental or vendor-prefixed selectors.
When NOT to use: If the selectors share no common prefix/suffix, :is() adds unnecessary complexity. Use it when it genuinely simplifies your code.
For the vast majority of use cases, performance differences are negligible. Browsers have optimized selector matching to an extraordinary degree.
However, some nuances exist:
:is(): A selector like :is(*) matches everything and can trigger unnecessary style recalculations. Be specific.:is(:not(:where(:is(...)))) are harder for both humans and browsers to optimize. Keep it readable.:is() with 50+ selectors is technically fine but likely indicates a design problem.Rule of thumb: If your selector is readable and targets a reasonable number of elements, performance won't be an issue. Prioritize clarity and maintainability.
Test the powerful :has() pseudo‑class. Write selectors like .card:has(img) and see the live result. Revolutionary for CSS architecture.
Practice positive/negative lookahead and lookbehind. See matches highlighted live. Master advanced regex.
Interactive checklist of the classic 10 essentials for safe hiking. Check items, see explanations, and never forget critical gear for the trail.
Animated SVG steps showing how to fold a fitted sheet perfectly. Clean visual reference.
Adjust a sleeping bag's EN rating based on sleeping pad R‑value, clothing, and personal warmth.
Enter ambient temperature, precipitation, and whether your horse is clipped to get a recommendation for blanket weight (sheet, medium, heavy).
Enter expected low temperature and get minimum recommended pad R‑value. Visual conductivity guide for winter camping.
Answer where you're sealing (shower, window, baseboard) to get the right type of caulk (100% silicone, acrylic latex, etc.). Avoid moldy seals.
Enter material thickness and get the recommended pop rivet diameter and grip range.
Answer questions about project type and strength needed to get a joint recommendation. Animations.
Explore the new two‑value display syntax like `display: block flex`. See what each inner/outer pair does visually.
Paste your CSS and see rules sorted by specificity. Find overrides and potential collisions. Understand your cascade.
Write modern CSS color functions like oklch(), lab(), hwb() and see the rendered color with fallback. Copy compatible code.
Write CSS like `oklch(from red l c h)` to modify colors dynamically. Preview the output and copy the code.
Chain multiple CSS filter functions and see the result on an image. Copy the filter string. No upload.
Drag a positioned box and see the top/right/bottom/left values change. Understand containing blocks. Visual.
Type text and instantly see it rendered with text‑transform: uppercase, lowercase, capitalize, and full‑width. Copy CSS.
Drag to resize a box and see the Resize Observer callback fire. Get contentRect and borderBoxSize. Learn the API.
Write CSS like `oklch(from red l c h)` to modify colors. Preview the output and copy. Modern color manipulation.
Write JavaScript using element.animate() and see the result in a live preview. Compare with CSS keyframes. Debugger included.
See every touch point with coordinates, radius, and force on your mobile device. Debug gestures with live overlay.
Write a compute shader in WGSL and run it in the browser. See the output on a canvas. Learn WebGPU. Real‑time compilation.
Type directly into a contenteditable div with real‑time CSS filters, shadows, and colors. Download as HTML. Fun demo.
Create an animation that advances with scroll using animation‑timeline: scroll(). See the visual timeline editor. Modern CSS.
Write a pattern and test it against URLs instantly. See which groups match. Learn the modern alternative to regex for routing. Works entirely in the browser.
Write CSS with native nesting (like SCSS) and see the browser’s native parsing. Validator and live output.
Understand @layer by visually ordering style layers and seeing which rules win. Fix specificity battles. Modern CSS architecture.
Pick two images or colors and apply all 16 CSS mix‑blend‑mode values live. See and copy the right CSS for your design.
Experiment with the CSS color-mix() function. Pick two colors and mix them in different color spaces (srgb, oklch). Copy the CSS.
Interactively add and adjust multiple box shadows on a sample element. Drag sliders for offset, blur, spread, and color. Copy the clean CSS code instantly.