HomeBytesheetsRoadmapsUI TemplatesUI ToolsStack Discussion
4 Topics
Chapter•80 Minutes

Modern CSS Features

Explore modern capabilities including nesting, cascade layers, :is(), :where(), :has(), color functions, scroll behavior, and progressive enhancement.

Native CSS Nesting

Modern CSS supports nesting directly in stylesheets. Nesting can improve local readability when used carefully, but excessive nesting can recreate the specificity and coupling problems associated with deeply nested preprocessors.

Keep nesting shallow and avoid using it as a substitute for clear component boundaries.

Native CSS Nesting
Native Nesting
.card {
  padding: 1rem;

  & .title {
    margin: 0;
  }

  &:hover {
    transform: translateY(-2px);
  }
}
💡 The nested selectors are associated with the parent .card rule.
Key Takeaways
  • Native nesting reduces the need for preprocessors in many cases.
  • Keep nesting shallow to avoid complexity.
Knowledge Check

What is a major benefit of native CSS nesting?

:is() and :where()

:is() groups selectors and adopts the specificity of its most specific argument. :where() also groups selectors but always has zero specificity.

:where() is particularly useful for framework or component defaults that should be easy for consumers to override.

:is() vs :where()
Grouping Selectors
:is(h1, h2, h3) {
  line-height: 1.1;
}

:where(.card, .panel) {
  border-radius: 1rem;
}
💡 Both functions simplify selector grouping, but they differ in specificity behavior.
Key Takeaways
  • :is() contributes the specificity of its most specific argument.
  • :where() always contributes zero specificity.
Knowledge Check

What is special about the specificity of `:where()`?

:has() Relational Selector

The :has() pseudo-class allows a selector to match an element based on descendants or relative conditions. It enables patterns that historically required JavaScript or additional classes.

For example, a form field can be styled when it contains an invalid input.

:has() Relational Matching
Parent Based on Child State
.field:has(input:invalid) {
  border-color: #dc2626;
}

.card:has(img) {
  padding-top: 0;
}
💡 The parent is selected based on whether a relative selector matches inside it.
Key Takeaways
  • :has() enables parent-aware styling.
  • It can remove some JavaScript or state-class requirements.
Knowledge Check

What makes `:has()` powerful?

Progressive Enhancement

Modern CSS features should be introduced in ways that preserve a useful experience when a feature is unavailable. Feature queries using @supports allow CSS to detect support before applying an enhancement.

This is especially useful for advanced layout features, modern color functions, and experimental capabilities.

Progressive Enhancement with @supports
Feature Query
.layout {
  display: flex;
}

@supports (display: grid) {
  .layout {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
  }
}
💡 The fallback works first and Grid is used when supported.
Key Takeaways
  • @supports enables feature-based progressive enhancement.
  • Provide a useful baseline before applying advanced capabilities.
Knowledge Check

Which at-rule tests whether a CSS feature is supported?