Skip to content

samirarezai/Modern-CSS-features

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 

Repository files navigation

Modern CSS Features (2026)

A practical, example-driven reference for Modern CSS features you can use in 2026.

Table of contents


CSS Container Queries

What: Style an element based on the size of its container (not the viewport).
Why: Build truly reusable components that adapt anywhere they’re placed.

Example (size-based container query)

<div class="card-list">
  <article class="card">
    <h3>Card title</h3>
    <p>Responsive to the container.</p>
  </article>
</div>
.card-list {
  container-type: inline-size; /* enables container queries */
  container-name: list;
}

.card {
  display: grid;
  gap: 0.5rem;
  padding: 1rem;
  border: 1px solid color-mix(in oklch, CanvasText 20%, transparent);
  border-radius: 0.75rem;
}

@container list (min-width: 36rem) {
  .card {
    grid-template-columns: 1fr 2fr;
    align-items: center;
  }
}

:has() (parent selector)

What: Select an element if it contains something matching a selector.
Why: Parent-aware styling without JS (e.g., “highlight card if it contains an error”).

Example (highlight a card if it contains an invalid input)

<label class="field">
  <span>Email</span>
  <input type="email" required value="not-an-email" />
  <small class="hint">Enter a valid email.</small>
</label>
.field {
  display: grid;
  gap: 0.25rem;
  padding: 0.75rem;
  border: 1px solid color-mix(in oklch, CanvasText 18%, transparent);
  border-radius: 0.75rem;
}

.field:has(input:invalid) {
  border-color: oklch(62% 0.22 25); /* red-ish */
  background: color-mix(in oklch, oklch(62% 0.22 25) 10%, Canvas);
}

.field:has(input:invalid) .hint {
  color: oklch(62% 0.22 25);
}

Native CSS Nesting

What: Write nested selectors in plain CSS (similar to Sass), using & for the parent selector when needed.
Why: Cleaner component styles with less repetition.

Example (nesting with &)

.button {
  padding: 0.6rem 0.9rem;
  border-radius: 0.75rem;
  border: 1px solid color-mix(in oklch, CanvasText 18%, transparent);
  background: Canvas;
  color: CanvasText;

  &:hover {
    background: color-mix(in oklch, CanvasText 6%, Canvas);
  }

  &[data-variant="primary"] {
    background: oklch(62% 0.18 255);
    border-color: color-mix(in oklch, oklch(62% 0.18 255) 70%, black);
    color: white;

    &:hover {
      background: color-mix(in oklch, oklch(62% 0.18 255) 88%, black);
    }
  }
}

CSS Custom Properties (scoping + fallbacks)

What: Variables like --brand that can be scoped to a subtree and can use fallbacks via var(--x, fallback).
Why: Theme components, override locally, and keep safe defaults.

Example (scoped theme + fallback)

<section class="theme theme--ocean">
  <button class="cta">Buy now</button>
</section>
.theme {
  --accent: oklch(62% 0.18 255); /* default */
}

.theme--ocean {
  --accent: oklch(70% 0.16 215);
}

.cta {
  background: var(--accent, rebeccapurple);
  color: white;
  border: none;
  padding: 0.75rem 1rem;
  border-radius: 0.75rem;
}

Logical Properties (direction-agnostic styling)

What: Use properties like margin-inline, padding-block, inset-inline, etc.
Why: Your layout automatically works for LTR/RTL and vertical writing modes.

Example (works in LTR and RTL)

<div class="chip">New</div>
.chip {
  padding-inline: 0.6rem;
  padding-block: 0.25rem;
  border-radius: 999px;
  border: 1px solid color-mix(in oklch, CanvasText 18%, transparent);
}

/* Equivalent to "left" but direction-aware */
.chip {
  margin-inline-start: 1rem;
}

subgrid

What: Let a child grid align to the track sizing of its parent grid.
Why: Perfect alignment across repeated cards/rows without hacks.

Example (card content aligns across cards)

<div class="products">
  <article class="product">
    <h3>Alpha</h3>
    <p>Short description.</p>
    <button>Buy</button>
  </article>
  <article class="product">
    <h3>Beta</h3>
    <p>Much longer description that would normally misalign the button.</p>
    <button>Buy</button>
  </article>
</div>
.products {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: auto auto auto; /* title / desc / actions */
}

.product {
  display: grid;
  grid-row: span 3;
  grid-template-rows: subgrid; /* inherit the 3 rows */
  padding: 1rem;
  border: 1px solid color-mix(in oklch, CanvasText 18%, transparent);
  border-radius: 0.75rem;
}

.product button {
  justify-self: start;
}

color-mix()

What: Mix two colors directly in CSS (optionally in a specific color space).
Why: Generate consistent borders/hover states without hardcoding many color values.

Example (generate subtle surfaces)

:root {
  --brand: oklch(62% 0.18 255);
}

.panel {
  background: color-mix(in oklch, var(--brand) 8%, Canvas);
  border: 1px solid color-mix(in oklch, var(--brand) 22%, transparent);
  border-radius: 0.75rem;
  padding: 1rem;
}

@layer (Cascade Layers)

What: Control cascade priority by grouping CSS into named layers.
Why: Predictable overrides (great for design systems + app overrides + utilities).

Example (base < components < utilities)

@layer reset, base, components, utilities;

@layer reset {
  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }
}

@layer base {
  :root {
    color-scheme: light dark;
  }
  body {
    font-family: system-ui, sans-serif;
  }
}

@layer components {
  .btn {
    padding: 0.6rem 0.9rem;
    border-radius: 0.75rem;
  }
}

@layer utilities {
  .btn {
    border-radius: 999px;
  } /* intentionally wins inside utilities */
}

Scroll Snap

What: Make scrolling “snap” to child elements.
Why: Great UX for carousels, onboarding screens, horizontal galleries.

Example (horizontal snapping gallery)

<div class="snap-row">
  <div class="snap-item">1</div>
  <div class="snap-item">2</div>
  <div class="snap-item">3</div>
</div>
.snap-row {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 80%;
  gap: 1rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding: 1rem;
}

.snap-item {
  scroll-snap-align: start;
  border-radius: 1rem;
  min-height: 10rem;
  background: color-mix(in oklch, CanvasText 8%, Canvas);
  display: grid;
  place-items: center;
  font-size: 2rem;
}

View Transitions

What: Smooth transitions between DOM “states” or page navigations (when supported by your platform/framework).
Why: App-like navigation polish with minimal code.

Example (basic view transition wrapper)

<button id="toggle">Toggle</button>
<main id="content" class="a">A</main>
<script>
  const btn = document.querySelector("#toggle");
  const el = document.querySelector("#content");
  btn.addEventListener("click", () => {
    if (!document.startViewTransition) {
      el.classList.toggle("b");
      return;
    }
    document.startViewTransition(() => el.classList.toggle("b"));
  });
</script>
main {
  font-size: 3rem;
  padding: 2rem;
  border-radius: 1rem;
}
.a {
  background: color-mix(in oklch, oklch(70% 0.16 215) 18%, Canvas);
}
.b {
  background: color-mix(in oklch, oklch(70% 0.16 120) 18%, Canvas);
}

oklch() colors

What: A perceptual color space (OKLCH) where adjustments are more visually consistent than RGB/HSL.
Why: Better theming, more predictable “lighter/darker” tweaks.

Example (theme palette using OKLCH)

:root {
  --bg: oklch(98% 0.02 250);
  --text: oklch(20% 0.02 250);
  --accent: oklch(62% 0.18 255);
}

body {
  background: var(--bg);
  color: var(--text);
}

a {
  color: var(--accent);
}

Scroll-driven animations (animation-timeline / view())

What: Drive an animation’s progress based on scroll position (page scroll or element-in-view).
Why: Reveal effects, progress indicators, parallax-like motion—without JS.

Example (animate a progress bar on page scroll)

<div class="progress"></div>
<div style="height: 200vh;"></div>
@keyframes grow {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}

.progress {
  position: fixed;
  inset-inline: 0;
  inset-block-start: 0;
  height: 6px;
  transform-origin: left;
  background: oklch(62% 0.18 255);
  animation: grow linear;
  animation-timeline: scroll(root);
}

Example (reveal when entering viewport)

@keyframes fade-up {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.reveal {
  animation: fade-up both;
  animation-timeline: view();
  animation-range: entry 10% cover 30%;
}

@scope (scoped styling)

What: Limit selector matching to a subtree.
Why: Safer component styling without heavy naming conventions.

@scope (.card) {
  :scope {
    padding: 1rem;
    border-radius: 0.75rem;
    border: 1px solid color-mix(in oklch, CanvasText 18%, transparent);
  }

  h3 {
    margin: 0 0 0.5rem;
  }
}

@property (typed custom properties)

What: Register a custom property with a type so it can interpolate (animate) safely.
Why: Smooth animations with CSS variables.

@property --fill {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 0%;
}

.meter {
  --fill: 20%;
  background: linear-gradient(
    to right,
    oklch(62% 0.18 255) var(--fill),
    color-mix(in oklch, CanvasText 8%, Canvas) 0
  );
  transition: --fill 600ms ease;
}

.meter:hover {
  --fill: 85%;
}

text-wrap: balance (better headings)

What: Balance line breaks in headings.
Why: Instantly nicer typography.

h1,
h2 {
  text-wrap: balance;
}

:where() + :is() (selector helpers)

What: Group selectors; :where() has zero specificity, :is() keeps the most specific argument.
Why: Cleaner CSS and fewer specificity fights.

/* zero-specificity base styles */
:where(button, input, select, textarea) {
  font: inherit;
}

/* group variants */
.alert:is(.success, .info) {
  border-color: oklch(70% 0.12 160);
}

accent-color (native form controls)

What: Tint checkboxes/radios/progress controls.
Why: Better-looking forms with almost no CSS.

:root {
  accent-color: oklch(62% 0.18 255);
}

About

A practical, example-driven reference for Modern CSS features you can use in 2026.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors