DEV Community

Cover image for The 10 Best New CSS Features in 2026 Already Supported in All Major Browsers
DevUnionX
DevUnionX

Posted on

The 10 Best New CSS Features in 2026 Already Supported in All Major Browsers

CSS has evolved far beyond styling colors, spacing, and layouts. Modern CSS can respond to a component's available space, react to elements inside a selector, generate more consistent color palettes, improve typography, and handle UI behavior that once required JavaScript.

But there is an important distinction: a feature being available in 2026 does not mean it was invented in 2026, or that every browser version supports it.

In this updated guide, we'll look at ten practical groups of CSS features worth knowing in 2026, including several from my 2025 CSS roundup. We'll also explore three newer capabilities that deserve attention but should be introduced progressively.

The support notes use Web Platform Baseline and current MDN documentation. Baseline is a useful starting point for cross-browser decisions, but it doesn't guarantee compatibility with older browsers, embedded webviews, or every detail of a feature.

Let's get into it.

1. Container Queries: Make Components Responsive to Their Own Space

Traditional media queries respond to the viewport. That's useful for page layouts, but it can become awkward when the same component appears in different places.

Imagine a product card used in a full-width grid, a narrow sidebar, and a mobile layout. A viewport media query tells the card how wide the screen is, not how much room the card actually has.

Container queries solve this problem by letting a component respond to its container's size.

.product-card {
  container-type: inline-size;
}

.product-card__content {
  display: grid;
  gap: 1rem;
}

@container (min-width: 34rem) {
  .product-card__content {
    grid-template-columns: 9rem 1fr;
    align-items: center;
  }
}
Enter fullscreen mode Exit fullscreen mode

The card's content switches to a two-column layout when the container becomes wide enough. The same component can now work in different layouts without relying on viewport-specific breakpoints.

This is especially useful for reusable components in design systems, dashboards, product grids, and component-driven React applications.

Why it matters: You can make components more independent of the page layout in which they are used.

Browser support: Container size queries are widely available in modern browsers. See MDN's container queries guide.

2. Container Style Queries: Let Components React to Their Context

Size queries ask, "How much space does my container have?"

Style queries ask a different question: "What styling context does my container provide?"

For example, a component might need a different appearance when its parent declares a dark theme or a compact layout. Container style queries can check a custom property on the container and apply styles to its descendants.

.theme-context {
  --theme: dark;
}

@container style(--theme: dark) {
  .card {
    background: #111827;
    color: #f9fafb;
    border-color: #374151;
  }
}
Enter fullscreen mode Exit fullscreen mode

Here, the .card can react to the value of --theme on an ancestor container rather than requiring JavaScript to attach another class to every card.

You can use the same principle for design-system variants, compact components, and other context-dependent styling decisions.

One important detail: style queries can use custom properties, but their support and syntax should still be checked against the browser versions your application targets.

Why it matters: CSS can express more component-level styling rules without making every variation a JavaScript-managed state.

Browser support: Container style queries became Baseline Newly Available in 2026. That makes them worth learning, but older browser versions may not support them. See MDN.

3. The :has() Selector: CSS Can React to Descendants

For a long time, styling an element based on what it contained often meant adding a class with JavaScript.

The :has() pseudo-class gives CSS a way to select an element based on matching descendants or related elements.

For example, you can highlight an entire form group when one of its inputs is invalid:

.form-group:has(input:invalid) {
  border: 1px solid crimson;
  background: #fff5f5;
}

.card:has(img) {
  padding: 0;
  overflow: hidden;
}
Enter fullscreen mode Exit fullscreen mode

The first selector reacts to the state of an input inside the form group. The second changes a card's layout when it contains an image.

You can also combine :has() with other selectors to build more expressive UI rules:

.form-group:has(input:focus-visible) label {
  color: #6d28d9;
}
Enter fullscreen mode Exit fullscreen mode

This is useful for forms, navigation, selected cards, and UI states that can be described through the DOM.

There is one limitation worth remembering: :has() doesn't replace all JavaScript state management. Use JavaScript when the behavior involves application logic, asynchronous data, or state that cannot be inferred reliably from the document.

Why it matters: It reduces the need for extra classes and DOM-manipulation code when the desired style depends on element relationships.

Browser support: :has() is widely available in modern browsers. It was also one of the most-used features in the State of CSS 2026 survey.

4. CSS Nesting, Cascade Layers, and :where(): Keep Large Stylesheets Manageable

CSS projects become difficult to maintain when component rules are scattered throughout a stylesheet, specificity keeps increasing, and third-party styles conflict with application styles.

Three established features can help: native CSS nesting, cascade layers, and the :where() selector.

Native CSS nesting

You can group related selectors inside a parent rule:

.card {
  border: 1px solid #e5e7eb;
  border-radius: 0.75rem;
  overflow: hidden;

  .card__title {
    font-size: 1.25rem;
    font-weight: 700;
  }

  &:hover {
    box-shadow: 0 8px 24px rgb(0 0 0 / 10%);
  }
}
Enter fullscreen mode Exit fullscreen mode

The card's title and hover styles now live beside the styles they belong to. This is built into CSS, so a preprocessor such as Sass is not required just to nest selectors.

Cascade layers

Use @layer to define a deliberate order for your stylesheet:

@layer reset, base, components, utilities;

@layer base {
  :where(h1, h2, h3) {
    line-height: 1.15;
  }
}

@layer components {
  .button {
    padding: 0.75rem 1rem;
    border-radius: 0.5rem;
  }
}

@layer utilities {
  .text-red {
    color: crimson;
  }
}
Enter fullscreen mode Exit fullscreen mode

For normal declarations, later named layers take precedence over earlier layers, regardless of selector specificity. There is an important caveat: normal declarations outside named layers take precedence over normal layered declarations. For predictable results, plan how your project uses layered and unlayered styles.

Reduce specificity with :where()

The :where() pseudo-class has zero specificity:

:where(.button, .link) {
  border-radius: 0.5rem;
  text-decoration: none;
}
Enter fullscreen mode Exit fullscreen mode

This makes it useful for resets, default styles, and shared design-system rules that should be easy to override.

Why it matters: These features help make CSS easier to read, organize, and maintain as a project grows.

Browser support: CSS nesting, cascade layers, and :where() are widely available in modern browsers. See MDN's CSS nesting documentation and cascade layers guide.

5. Better Typography: text-wrap, font-size-adjust, and Ruby Layout

Good typography is more than choosing a font. Line breaks, fallback fonts, and annotations can all affect readability.

Balance headings with text-wrap: balance

A heading can look awkward when a single word is left on its own line. text-wrap: balance asks the browser to distribute text across lines more evenly.

h1,
h2,
h3 {
  text-wrap: balance;
}
Enter fullscreen mode Exit fullscreen mode

It's especially useful for titles, hero headings, and short text blocks. Avoid applying it indiscriminately to every long paragraph: balancing text has a computational cost, and browsers limit how many lines they balance.

Improve paragraph wrapping with text-wrap: pretty

For longer text, text-wrap: pretty asks the browser to favor more pleasing line breaks, including reducing awkward short final lines.

.article-content {
  text-wrap: pretty;
}
Enter fullscreen mode Exit fullscreen mode

It's a useful enhancement for blogs, documentation, and editorial websites. However, support for this value varies more than support for text-wrap: balance, so test the browsers your readers use.

Keep fallback fonts more consistent with font-size-adjust

When a preferred font is unavailable or hasn't loaded, the fallback may have very different lowercase letter proportions.

body {
  font-family: "MyWebFont", Arial, sans-serif;
  font-size-adjust: 0.52;
}
Enter fullscreen mode Exit fullscreen mode

The value is only an example; choose one appropriate to your intended font metrics. This property adjusts font sizing to help preserve visual proportions when different fonts are rendered.

Use Ruby layout for annotated text

For languages and learning materials that use ruby annotations, such as Japanese furigana, the ruby-align and ruby-position properties can provide more control.

ruby {
  ruby-align: center;
  ruby-position: over;
}
Enter fullscreen mode Exit fullscreen mode

This is a specialized feature rather than a universal requirement, but it is valuable for multilingual education and reference content.

Why it matters: These properties make it possible to improve readability and text layout with less manual adjustment.

Browser support: text-wrap is broadly available, but individual values can differ in support. font-size-adjust and Ruby layout properties are also available in current browsers; check their precise compatibility before relying on a particular value. Useful references: text-wrap, font-size-adjust, and ruby-position.

6. More Stable Layouts and Faster Long Pages: aspect-ratio and content-visibility

Two features can make visual content more predictable and reduce unnecessary rendering work.

Reserve the right shape with aspect-ratio

When an image container has a known aspect ratio, the browser can reserve the correct space before the image is displayed.

.thumbnail {
  aspect-ratio: 16 / 9;
  overflow: hidden;
}

.thumbnail img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
Enter fullscreen mode Exit fullscreen mode

This is handy for video thumbnails, product images, article cards, and galleries. Consistent dimensions help keep surrounding content from jumping around.

Skip unnecessary rendering work with content-visibility

Long pages often contain large sections that are far outside the visible area. content-visibility: auto allows the browser to skip much of the rendering work for off-screen content until it becomes relevant.

.article-section {
  content-visibility: auto;
  contain-intrinsic-size: 42rem;
}
Enter fullscreen mode Exit fullscreen mode

The intrinsic size provides a placeholder estimate so the browser can account for the section's space while its contents are not being rendered normally.

This can help with long articles, large repeated lists, and other pages with expensive off-screen content. It's not a substitute for measuring performance, though: choose a sensible placeholder size and test scrolling, anchor links, and layout stability with realistic content.

Why it matters: aspect-ratio helps create predictable layouts, while content-visibility can reduce work on pages with a lot of content.

Browser support: Both features are widely available in modern browsers. References: aspect-ratio and content-visibility.

7. Modern Color: oklch(), color-mix(), light-dark(), and Relative Colors

Color management is another area where CSS has become considerably more capable.

Use oklch() for more controlled color palettes

oklch() represents a color using perceptual lightness, chroma, and hue. This can make it easier to generate coherent variants of a brand color than manually guessing a collection of unrelated hex values.

:root {
  --brand: oklch(62% 0.2 255);
}
Enter fullscreen mode Exit fullscreen mode

Changing the lightness while keeping chroma and hue stable can produce more consistent visual variations, although the resulting color should still be checked for gamut and contrast.

Mix colors with color-mix()

.button {
  background: var(--brand);
}

.button:hover {
  background: color-mix(in oklch, var(--brand) 85%, white);
}
Enter fullscreen mode Exit fullscreen mode

This lets you generate color variations in CSS rather than maintaining a separate hard-coded value for every state.

Support light and dark themes with light-dark()

:root {
  color-scheme: light dark;

  --surface: light-dark(#ffffff, #171717);
  --text: light-dark(#171717, #f5f5f5);
}

body {
  background: var(--surface);
  color: var(--text);
}
Enter fullscreen mode Exit fullscreen mode

The color-scheme declaration tells the browser that the page supports both schemes. light-dark() then chooses a value based on the active color scheme.

Derive colors from an existing color

Relative color syntax lets you create a new color from an existing one:

:root {
  --brand: oklch(62% 0.2 255);
  --brand-light: oklch(from var(--brand) calc(l + 0.12) c h);
}
Enter fullscreen mode Exit fullscreen mode

Here, the lightness is increased while chroma and hue are retained. The exact result still depends on the source color and the target color space.

Why it matters: These features help build consistent themes and interactive color states with fewer duplicated values.

Browser support: oklch(), color-mix(), and light-dark() are available in current mainstream browsers. Relative color syntax should be checked for the browser versions you support. Always test color contrast rather than assuming that a perceptually uniform color space guarantees accessibility. References: OKLCH and color functions, light-dark(), and relative colors.

8. Better Forms with field-sizing and accent-color

Form controls are essential to most applications, but custom styling can become complicated when developers rebuild native inputs from scratch.

Two properties offer simpler alternatives.

Let fields size themselves around their content

.comment-box {
  field-sizing: content;
  min-height: 3rem;
  max-height: 14rem;
  width: 100%;
}
Enter fullscreen mode Exit fullscreen mode

On a supported browser, a textarea can grow or shrink with its content instead of remaining at a fixed preferred size. Minimum and maximum constraints help keep it usable.

<textarea
  class="comment-box"
  rows="2"
  placeholder="Write a comment..."
></textarea>
Enter fullscreen mode Exit fullscreen mode

This can reduce the need for JavaScript that measures text and updates the field's height.

Match native controls to your theme

input[type="checkbox"],
input[type="radio"],
input[type="range"] {
  accent-color: #7c3aed;
}
Enter fullscreen mode Exit fullscreen mode

This changes the accent color of supported native controls while preserving their standard behavior. For many forms, that's a better starting point than hiding native inputs and recreating their appearance and interactions manually.

Why it matters: Native form controls can look more consistent with your design while retaining familiar behavior and accessibility features.

Browser support: accent-color is widely supported. field-sizing became Baseline Newly Available in 2026, so it may not work on older browser versions. Keep the default field behavior usable as a fallback. References: field-sizing and accent-color.

9. More Declarative UI with :open, Exclusive Accordions, and Popovers

HTML already provides useful building blocks for interactive interfaces. Modern CSS and browser features make it easier to style these controls without implementing every state from scratch.

Style open elements with :open

details:open > summary {
  color: #7c3aed;
  font-weight: 700;
}
Enter fullscreen mode Exit fullscreen mode

The :open pseudo-class can select elements in an open state, including relevant details and dialog elements.

For a straightforward disclosure widget, the traditional attribute selector is also a useful fallback:

details[open] > summary {
  color: #7c3aed;
}
Enter fullscreen mode Exit fullscreen mode

Create exclusive accordions with native HTML

When only one item in an accordion group should stay open, the name attribute on <details> can provide that behavior without a custom JavaScript controller.

<details name="faq">
  <summary>What is container querying?</summary>
  <p>It lets a component respond to its container's size.</p>
</details>

<details name="faq">
  <summary>What is CSS nesting?</summary>
  <p>It lets related selectors be written inside a parent rule.</p>
</details>
Enter fullscreen mode Exit fullscreen mode

Give the related <details> elements the same name value to place them in the same exclusive group.

Use the Popover API for simple overlays

<button popovertarget="help-panel">
  Open help
</button>

<div id="help-panel" popover>
  <p>Helpful information goes here.</p>
</div>
Enter fullscreen mode Exit fullscreen mode

The browser handles showing and hiding the popover through the built-in HTML behavior. An automatically dismissed popover can close when the user clicks outside it or presses Escape, depending on its configuration.

The Popover API is not a replacement for a modal dialog in every situation. A modal has different focus and interaction requirements; use <dialog> and its appropriate behavior when a truly modal interaction is needed.

Why it matters: Native HTML behavior can replace fragile custom interaction code, while CSS handles the appearance of each state.

Browser support: :open became Baseline Newly Available in 2026. The Popover API is available in current major browsers, but version support differs. For older targets, use the appropriate fallback or keep the essential interaction independent of the newer selector. References: :open, HTML <details>, and Popover API.

10. Small Improvements That Make Interfaces Feel More Polished

Not every useful CSS feature transforms an entire architecture. Sometimes, a tiny improvement solves a persistent UX problem.

Prevent scrollbar-related layout shifts

.scroll-panel {
  overflow: auto;
  scrollbar-gutter: stable;
}
Enter fullscreen mode Exit fullscreen mode

On systems that use classic scrollbars, reserving the gutter can help prevent content from shifting when a scrollbar appears. Overlay scrollbars behave differently, so the visible result depends on the platform.

Style the scrollbar

.scroll-panel {
  scrollbar-color: #64748b #e2e8f0;
}
Enter fullscreen mode Exit fullscreen mode

This sets the thumb and track colors in browsers that support scrollbar-color. Keep adequate contrast and avoid making the scrollbar difficult to see or operate.

Highlight text reached through a text fragment

::target-text {
  background: #fef08a;
  color: #111827;
}
Enter fullscreen mode Exit fullscreen mode

When a supported text-fragment link navigates to a specific part of a page, ::target-text lets you style the matched text. This can be helpful for documentation and long articles.

Keep ruby annotations readable

For text that uses ruby annotations, ruby-align and ruby-position provide finer control over alignment and placement. These are especially useful for Japanese learning materials and similar content, rather than a requirement for most websites.

Why it matters: These improvements refine usability, navigation, and content presentation without requiring a larger JavaScript framework.

Browser support: scrollbar-gutter and font-size-adjust are Baseline 2024 features, while scrollbar-color and ::target-text became Baseline Newly Available in later cycles. Ruby properties also have broad support in current browsers, but individual values can vary. See scrollbar-gutter, scrollbar-color, and ::target-text.

Three More Capabilities to Adopt Progressively

The ten groups above cover many practical improvements. Three additional capabilities are worth experimenting with, but they deserve more care when supporting a broad range of browsers.

11. CSS Anchor Positioning: Position UI Relative to Another Element

Tooltips, menus, and small popovers often need to stay attached to a trigger button. Traditionally, developers used JavaScript to measure element positions and update them during scrolling or resizing.

CSS Anchor Positioning lets a positioned element refer to another element through an anchor relationship.

.trigger {
  anchor-name: --help-trigger;
}

.tooltip {
  position: absolute;
  position-anchor: --help-trigger;
  top: anchor(bottom);
  left: anchor(left);
  margin-top: 0.5rem;
}
Enter fullscreen mode Exit fullscreen mode

This is a simplified example of the relationship; real interfaces may also need fallbacks for collisions with the viewport or other layout constraints.

Some anchor-positioning capabilities reached Baseline Newly Available during 2026, but support for the wider set of positioning and fallback behaviors is not identical across all browsers. Don't assume that one supported declaration guarantees all the advanced behavior you want.

For production use, provide a sensible fallback and feature-detect the functionality you rely on:

.tooltip {
  position: absolute;
  top: 100%;
  left: 0;
}

@supports (position-anchor: --help-trigger) {
  .tooltip {
    position-anchor: --help-trigger;
    top: anchor(bottom);
    left: anchor(left);
  }
}
Enter fullscreen mode Exit fullscreen mode

Best use cases: Tooltips, dropdown menus, contextual labels, and other UI elements positioned relative to a trigger.

Support note: Check the precise feature and browser versions using MDN's anchor-positioning documentation before replacing a mature positioning library.

12. Scroll-Driven Animations: Let Scrolling Control the Animation

Traditional CSS animations progress with time. Scroll-driven animations can tie an animation's progress to scrolling or to an element entering the viewport.

For example, you can enhance a content-reveal effect without making it a requirement for the page to work:

.reveal {
  opacity: 1;
  transform: none;
}

@supports (animation-timeline: view()) {
  .reveal {
    animation: reveal linear both;
    animation-timeline: view();
    animation-range: entry 0% cover 40%;
  }

  @keyframes reveal {
    from {
      opacity: 0;
      transform: translateY(1rem);
    }

    to {
      opacity: 1;
      transform: translateY(0);
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

The normal state remains visible when the browser doesn't support scroll-driven animation timelines. Supported browsers receive the additional effect.

Use motion thoughtfully. Animations should help users understand changes rather than distract them, and you should consider reduced-motion preferences.

Best use cases: Reading-progress indicators, subtle content reveals, scroll-linked visual effects, and other experiences that benefit from a scroll-based timeline.

Support note: Scroll-driven animations remain a feature to adopt progressively. Check MDN's documentation and use feature detection.

13. transition-behavior: allow-discrete: Transition Properties Such as display

Not every CSS property can interpolate smoothly between two values. Properties with discrete values, such as display, normally switch from one value to another rather than gradually changing.

The transition-behavior property adds an allow-discrete option for certain discrete transitions:

.panel {
  transition:
    opacity 200ms,
    display 200ms allow-discrete;
}

.panel.is-hidden {
  opacity: 0;
  display: none;
}
Enter fullscreen mode Exit fullscreen mode

This can be useful when combining visibility changes with opacity transitions. Entry animations from display: none often need additional setup, such as @starting-style; consult the relevant documentation rather than assuming the simple example covers every case.

Best use cases: Small UI transitions where content appears or disappears, including some popover and panel effects.

Support note: transition-behavior is not yet Baseline across all major browsers. Keep the basic show/hide functionality working without it. See MDN's transition-behavior reference.

A Related Platform Feature: The Navigation API

The 2026 research also covers the Navigation API. It is worth knowing about, but it is a JavaScript web API, not a CSS feature, so it shouldn't be presented as another CSS property.

The Navigation API provides browser navigation events and methods that can simplify certain client-side routing implementations. Whether it's a good fit depends on your routing architecture, browser targets, and framework.

For a broader look, see MDN's Navigation API documentation.

How to Use These Features in Production

Learning a new property is only half the job. The other half is deciding when to use it and how to handle browsers that don't support it.

1. Start with the support status

Web Platform Baseline distinguishes widely available features, newly available features, and features with limited availability.

  • Widely available: A good starting point for most new projects, while still considering your actual browser targets.
  • Newly available: Supported in recent Baseline browsers, but older browser releases may lack support.
  • Limited availability: Use feature detection or a fallback when the feature matters to your design.

Baseline is a compatibility signal, not a guarantee that every user will see identical results. Older devices, embedded webviews, assistive technology, and specific feature details may require additional testing.

Read the official Baseline overview.

2. Prefer progressive enhancement

Start with a working interface. Add the advanced behavior only when the browser supports it.

For CSS, @supports is often enough:

.card {
  padding: 1rem;
}

@supports (container-type: inline-size) {
  .card {
    container-type: inline-size;
  }
}
Enter fullscreen mode Exit fullscreen mode

The fallback should preserve essential readability and functionality. A visual enhancement shouldn't make the entire component unusable when it's unavailable.

3. Measure performance instead of assuming

A feature can reduce code without automatically improving performance in every situation. content-visibility, for example, is most helpful when it avoids work on substantial off-screen content. Adding it everywhere without measuring can lead to disappointing results.

Test actual workloads using browser developer tools and realistic content. Pay attention to rendering, scrolling, input responsiveness, and layout shifts.

4. Avoid JavaScript when CSS or native HTML already solves the problem

You don't need JavaScript for every visual state. Container queries can handle component sizing, :has() can respond to DOM relationships, and native controls can provide useful behavior without custom event handlers.

But CSS isn't a replacement for application logic. Keep state, validation rules, data fetching, and other complex interactions in the parts of your application that are designed to manage them.

Top comments (0)