MastorsCDN CSS 2027
CSS 2027 Documentation

The future of CSS
is already here.

Every major CSS feature landing in 2027 — container queries, anchor positioning, scroll-driven animations — with live demos and full browser support tables.

16 Features
96% Chrome
2027 Spec Year
styles.css — CSS 2027
/* 📌 New in 2027 */
@starting-style {
  .dialog {
    opacity: 0;
    translate: 0 -16px;
  }
}

@property --angle {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}

:root {
  interpolate-size:
    allow-keywords;
}

h1 {
  text-wrap: balance;
}
16 new features

What's New in CSS 2027

CSS 2027 consolidates years of specification work into stable, interoperable features across all major engines. From native scoping to physics-aware animations, this is the most significant CSS release in a decade.

Container Queries

Style elements based on their container's size — not the viewport.

Cascade Layers

Explicit control over cascade precedence with @layer.

Color Level 5

Relative colors, color-mix(), and wide-gamut OKLCH spaces.

Native CSS Nesting

Nest selectors inside parents — no preprocessor needed.

@scope

Limit style rules to a specific DOM subtree with a lower boundary.

Anchor Positioning

Position floated elements relative to any anchor — zero JS.

View Transitions

Animate between DOM states and cross-page navigations.

:has() Selector

The long-awaited parent selector — style based on descendants.

Scroll-Driven Animations

Tie animation progress to scroll position — no JS required.

@property

Typed, animatable custom properties with inheritance control.

CSS Subgrid

Align nested grid children on the parent's track definitions.

Math Functions

sin(), cos(), round(), pow(), sqrt(), and more — in native CSS.

Logical Properties

Writing-mode-aware layout that works across LTR and RTL.

@starting-style

Define entry animation states — animate from display:none without JS.

interpolate-size

Animate to and from intrinsic sizes like height: auto natively.

text-wrap: balance

Balance heading line lengths and prevent orphaned words — pure CSS.

Browser Support Matrix

As of mid-2026, all major features are shipping in Chromium. Firefox and Safari are close behind. The table below reflects stable releases, not experimental flags.

Feature Chrome Firefox Safari Edge
Container Queries 105+ 110+ 16+ 105+
Cascade Layers @layer 99+ 97+ 15.4+ 99+
Color Level 5 color-mix() 111+ 113+ 16.2+ 111+
Native CSS Nesting 112+ 117+ 17.2+ 112+
@scope 118+ Partial 17.4+ 118+
Anchor Positioning 125+ Flag Preview 125+
View Transitions API 111+ 128+ 18+ 111+
:has() Selector 105+ 103+ 15.4+ 105+
Scroll-Driven Animations 115+ 110+ Preview 115+
@property 85+ 128+ 16.4+ 85+
CSS Subgrid 117+ 71+ 16+ 117+
Math Functions sin()/cos() 111+ 108+ 15.4+ 111+
Logical Properties 89+ 41+ 15+ 89+
@starting-style 117+ 129+ 17.5+ 117+
interpolate-size 129+ Flag Preview 129+
text-wrap: balance 114+ 121+ 17.5+ 114+
Fully Supported Partial / Flag Not Supported

Container Queries

Stable

Apply styles based on a parent container's size instead of the viewport. This enables truly portable, self-contained components that adapt to any context they're placed in.

CSS
.card-wrapper {
  container-type: inline-size;
  container-name: card;
}

@container card (min-width: 380px) {
  .card {
    display: flex;
    gap: 1rem;
  }
  .card__image {
    width: 110px;
    flex-shrink: 0;
  }
}

@container card (max-width: 379px) {
  .card {
    display: block;
  }
  .card__image {
    width: 100%;
    height: 120px;
  }
}
Live Output

Resize the browser to see the card adapt:

Adaptive Card
Responds to its container, not the viewport.
Use container-type: inline-size on the wrapper. Name containers with container-name to scope queries to specific ancestors. Containers can be nested.

Cascade Layers

Stable

@layer gives you explicit control over the cascade. Later-declared layers always win over earlier ones, regardless of selector specificity — ending the specificity war for good.

CSS
/* Declare order — last wins */
@layer base, components, utilities;

@layer base {
  .button {
    background: gray;
    padding: .5rem 1rem;
    color: white;
  }
}

@layer components {
  .button {
    background: blue;
    border-radius: .5rem;
  }
}

@layer utilities {
  /* Wins — even at low specificity */
  .button-hot {
    background: hotpink;
  }
}
Live Output

Layer order: base → components → utilities

The purple button uses a class from @layer utilities — overriding blue without specificity hacks.

Color Level 5

Stable

CSS Color Level 5 introduces color-mix(), relative color syntax, and wide-gamut spaces like oklch() for perceptually uniform, design-token-friendly color systems.

CSS
/* Blend two colors */
.mixed {
  background: color-mix(in oklch, blue 40%, white);
}

/* Relative color syntax */
:root { --brand: oklch(55% .22 264); }
.lighter {
  background: oklch(from var(--brand) calc(l + .2) c h);
}

/* Wide-gamut OKLCH palette */
:root {
  --primary:    oklch(55% .22 264);
  --primary-lg: oklch(70% .22 264);
  --primary-dk: oklch(35% .22 264);
}

/* Display-P3 vivid colors */
.vivid { color: color(display-p3 0 0.5 1); }
color-mix() — 20% steps
OKLCH hue rotation

Native CSS Nesting

Stable

Nest selectors directly inside parent rules — the same syntax you know from SASS, now a native CSS standard. No preprocessor, no build step, just CSS.

CSS
.nav {
  display: flex;
  gap: 1rem;
  background: #0f172a;
  padding: .75rem 1rem;
  border-radius: .75rem;

  & a {
    color: #94a3b8;
    text-decoration: none;
    transition: color .2s;

    &:hover { color: #818cf8; }

    &.active {
      color: white;
      font-weight: 600;
    }
  }

  /* Responsive — nested media query */
  @media (max-width: 600px) {
    flex-direction: column;
  }
}
Live Output

Hover links to see &:hover styles applied.

@scope

Chrome 118+

@scope restricts style rules to a specific DOM subtree. You can even define a lower boundary — a "scope limit" — so styles never leak into nested child components.

CSS
/* Rules apply only inside .card */
@scope (.card) {
  p {
    color: #60a5fa;
    font-size: .875rem;
  }
  h3 { color: white; font-weight: 700; }
}

/* Scope with a lower boundary:
   stops before entering .child-component */
@scope (.card) to (.child-component) {
  a {
    color: #818cf8;
    text-decoration: underline;
  }
}
Live Output

Scoped Card

This paragraph is styled by @scope(.sc-card).

This paragraph is outside the scope — unstyled.

Anchor Positioning

Chrome 125+

Position absolutely-placed elements relative to any anchor in the DOM — without JavaScript. Perfect for tooltips, dropdowns, and context menus that need to stay tethered to their trigger.

CSS
.anchor-btn {
  anchor-name: --my-btn;
}

.tooltip {
  position: absolute;
  position-anchor: --my-btn;

  top: anchor(top);
  left: anchor(center);
  translate: -50% calc(-100% - 8px);

  background: #1e293b;
  color: white;
  padding: .25rem .75rem;
  border-radius: .5rem;
  font-size: .75rem;
  white-space: nowrap;
}
Live Output
✦ Pure CSS anchored tooltip

Tooltip tethered via CSS — no JS scroll listeners.

Anchor positioning also supports position-try-fallbacks — automatically flip the tooltip if it overflows the viewport.

View Transitions API

Stable

Animate between DOM states smoothly. JavaScript triggers the transition with document.startViewTransition(), and CSS controls the animation via ::view-transition-old/new pseudo-elements.

CSS + JS
::view-transition-old(root) {
  animation: 300ms ease-out slide-out;
}
::view-transition-new(root) {
  animation: 300ms ease-in slide-in;
}

@keyframes slide-out {
  to { opacity: 0; transform: translateY(-16px); }
}
@keyframes slide-in {
  from { opacity: 0; transform: translateY(16px); }
}

/* Per-element named transitions */
.hero { view-transition-name: hero; }
Interactive Demo
◆ State A

CSS animation demo. Real View Transitions require Chrome 111+.

:has() Selector

Stable

The :has() pseudo-class lets you style a parent based on its descendants — the "parent selector" the web has wanted for decades. It's one of the most powerful CSS selectors ever added.

CSS
/* Style a card that contains an image */
.card:has(img) {
  grid-template-rows: 200px 1fr;
}

/* Strike through li when checkbox checked */
li:has(input[type="checkbox"]:checked) {
  text-decoration: line-through;
  opacity: .5;
}

/* Float-label pattern — no JS */
.field:has(input:not(:placeholder-shown)) label {
  color: #818cf8;
  transform: translateY(-1.5rem) scale(.85);
}

/* Dark sibling that follows a .featured card */
.card:has(+ .card.featured) {
  filter: brightness(.8);
}
Live — Checkbox list

Check items to see :has() apply styles:

  • Container Queries docs
  • Test anchor positioning
  • Write scroll-driven demo
  • Explore color-mix()

Scroll-Driven Animations

Chrome 115+

Link an animation's progress directly to the scroll position using animation-timeline. Works for both global scroll and element visibility — zero JS required.

CSS
/* Reading progress bar */
#progress-bar {
  position: fixed;
  top: 0; left: 0;
  height: 3px; background: #5b8dee;
  transform-origin: left;
  animation: scaleX linear;
  animation-timeline: scroll(root block);
}

@keyframes scaleX {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* Fade in as element enters view */
.reveal {
  animation: fade-in linear both;
  animation-timeline: view();
  animation-range: entry 0% entry 40%;
}

@keyframes fade-in {
  from { opacity: 0; translate: 0 30px; }
  to   { opacity: 1; translate: 0 0; }
}
Scroll inside this box ↓
Scroll down to reveal items ↓
First scroll-triggered element
Second element fades in
Third — keeps going…
Almost at the end…
🎉 Scroll progress: 100%

@property — Typed Custom Properties

Stable

@property registers a custom property with a specific syntax type, initial value, and inheritance setting. This enables smooth animation of values that were previously unanimatable — like gradients.

CSS
@property --gradient-angle {
  syntax: '';
  initial-value: 0deg;
  inherits: false;
}

.spinning-gradient {
  background: conic-gradient(
    from var(--gradient-angle),
    #5b8dee, #8b5cf6,
    #ec4899, #5b8dee
  );
  animation: spin 3s linear infinite;
}

@keyframes spin {
  to { --gradient-angle: 360deg; }
}

/* Typed integer counter */
@property --counter {
  syntax: '';
  initial-value: 0;
  inherits: false;
}
.count { animation: count-up 2s ease-out; }
@keyframes count-up { to { --counter: 100; } }
Live Output

Animated via @property --rot-angle: <angle>

CSS Subgrid

Stable

Subgrid lets nested grid children participate in the parent grid's track definitions. Card footers align perfectly across cards of different content lengths — no flexbox hacks needed.

CSS
.card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: auto;
  gap: 1rem;
}

.card {
  display: grid;
  grid-row: span 3;
  /* Inherit parent row tracks */
  grid-template-rows: subgrid;
}

/* Inner elements now align across cards */
.card__title  { grid-row: 1; }
.card__body   { grid-row: 2; }
.card__footer { grid-row: 3; align-self: end; }
Aligned card rows via subgrid
Title
Short description text here.
Read more →
Longer Title Here
This card has much more body text content, yet the footer stays aligned with the others thanks to subgrid — zero extra JS.
Read more →
Card Three
Medium amount of text in this body area.
Read more →

Footers align at the bottom regardless of body height.

Math Functions

Stable

CSS 2027 expands the math suite with round(), mod(), sin(), cos(), atan2(), pow(), and sqrt() — enabling true computational layouts without JavaScript.

CSS
/* Fluid typography */
.fluid { font-size: clamp(1rem, 2.5vw + .5rem, 2rem); }

/* Snap to 4px grid */
.snapped {
  width: round(nearest, 37px, 4px); /* → 36px */
}

/* Circular layout — no JS */
.orbit-item {
  --angle: 45deg;
  --r: 80px;
  translate:
    calc(cos(var(--angle)) * var(--r))
    calc(sin(var(--angle)) * var(--r));
}

/* Fluid columns without media queries */
.auto-grid {
  grid-template-columns:
    repeat(auto-fill, minmax(min(260px, 100%), 1fr));
}

/* pow() and sqrt() */
.golden { width: calc(pow(1.618, 3) * 1rem); }
.diagonal { height: calc(sqrt(pow(3, 2) + pow(4, 2)) * 20px); }
Circular layout — cos() & sin()
CSS
A
B
C
D
E
F

Positioned using cos() and sin() — pure CSS

Logical Properties

Stable

Logical properties decouple layout from physical directions. Using inline and block instead of left/right/top/bottom makes your CSS work correctly in LTR, RTL, and vertical writing modes.

CSS
/* Physical → Logical mapping:
   margin-left  → margin-inline-start
   margin-right → margin-inline-end
   margin-top   → margin-block-start
   width        → inline-size
   height       → block-size
*/

.card {
  margin-inline: auto;       /* centered */
  padding-block: 1.5rem;
  padding-inline: 1rem;
  border-inline-start: 3px solid #5b8dee;
  max-inline-size: 600px;
}

.scrollable {
  block-size: 200px;
  overflow-block: auto;      /* = overflow-y */
}

/* Works identically in RTL */
[dir="rtl"] .card {
  /* border-inline-start auto-flips to right */
}
LTR vs RTL — same CSS
LTR direction
border-inline-start renders on the left.
نص بالعربية — RTL direction
border-inline-start auto-flips to the right.

@starting-style

Chrome 117+

@starting-style defines an element's styles before its first paint, enabling smooth entry animations from display: none — no JavaScript, no class toggling, no requestAnimationFrame hacks required.

CSS
/* Animate dialog entry — zero JS */
dialog {
  opacity: 1;
  translate: 0 0;
  transition:
    opacity .3s ease,
    translate .3s ease,
    display .3s ease allow-discrete;

  @starting-style {
    opacity: 0;
    translate: 0 -20px;
  }
}

dialog[open] { display: block; }

/* Toast notification */
.toast {
  opacity: 1;
  transform: translateX(0);
  transition: opacity .4s, transform .4s,
    display .4s allow-discrete;

  @starting-style {
    opacity: 0;
    transform: translateX(100%);
  }
}

.toast.hidden {
  display: none;
  opacity: 0;
  transform: translateX(100%);
}
Interactive Demo
Entry animated via @starting-style

Each click removes and re-adds the element, triggering @starting-style.

Pair with transition: display allow-discrete to also animate the exit state when the element is hidden with display: none.

interpolate-size

Chrome 129+

Set interpolate-size: allow-keywords on :root to unlock smooth transitions to and from intrinsic sizing keywords like height: auto, max-content, and fit-content — the accordion animation devs have wanted for years.

CSS
/* Opt in once at the root */
:root {
  interpolate-size: allow-keywords;
}

/* Accordion: animate to height: auto */
.accordion-body {
  height: 0;
  overflow: hidden;
  transition: height .4s ease;
}

.accordion-body.open {
  height: auto; /* now animatable! */
}

/* Any intrinsic keyword works */
.chip {
  width: fit-content;
  transition: width .3s ease;
}

.chip:hover {
  width: max-content;
}

/* Details element native accordion */
details {
  height: 2rem;
  overflow: hidden;
  transition: height .4s ease;

  &[open] { height: auto; }
}
Animate to height: auto
interpolate-size: allow-keywords unlocks CSS transitions to intrinsic sizing values. No JS height measurement, no max-height hacks. Just native CSS animation from height: 0 to height: auto.

This accordion animates using only CSS transitions.

text-wrap: balance & pretty

Stable

Two values that eliminate the most common typographic headaches. balance evens out line lengths in short headings; pretty prevents orphaned words in long body text — both with zero JavaScript.

CSS
/* balance: even line lengths in headings */
h1, h2, h3 {
  text-wrap: balance;
  /* Limit: ~6 lines (Chromium), 10 lines (Firefox) */
}

/* pretty: prevent orphans in body text */
p, .prose {
  text-wrap: pretty;
}

/* Shorthand */
.hero-title {
  text-wrap: balance;
  /* Previously required JS + ResizeObserver! */
}

/* text-wrap is now a shorthand for: */
.full-control {
  text-wrap-mode: wrap;     /* wrap | nowrap */
  text-wrap-style: balance; /* auto | balance | pretty | stable */
}
balance vs default
Default wrap
Introducing powerful CSS features in 2027
text-wrap: balance
Introducing powerful CSS features in 2027
Use balance on headings (up to 6 lines) and pretty on paragraphs. text-wrap: pretty has a small performance cost, so apply it selectively.
◆ Ready to experiment?

Try it in the Playground

Write HTML and CSS side-by-side and see results update in real time. Load any of the 2027 feature snippets and edit live.

Open Playground