Lab 04: Modern CSS Features

Time: 30 minutes | Level: Advanced | Docker: docker run -it --rm node:20-alpine sh

Overview

Explore cutting-edge CSS: native nesting with &, @scope, advanced :has() patterns, CSS anchor positioning, View Transitions API, and scroll-driven animations.


Step 1: Native CSS Nesting

/* CSS nesting (baseline 2023) — no preprocessor needed */

.card {
  background: white;
  border-radius: 8px;
  padding: 1rem;

  /* Nested: & refers to .card */
  & .card__title {
    font-size: 1.25rem;
    color: #111;
  }

  /* Pseudo-class on the parent */
  &:hover {
    box-shadow: 0 4px 12px rgba(0,0,0,0.1);
    transform: translateY(-2px);
  }

  /* Pseudo-element */
  &::before {
    content: '';
    display: block;
    height: 4px;
    background: var(--color-primary);
    border-radius: 8px 8px 0 0;
  }

  /* Modifier (BEM-like) */
  &.card--featured {
    border-color: gold;
  }

  /* Descendant (without &) — shorthand */
  .card__body {
    color: #666;
    line-height: 1.6;
  }

  /* Media query inside rule */
  @media (min-width: 768px) {
    & {
      padding: 1.5rem;
    }
  }

  /* Container query inside rule */
  @container (min-width: 400px) {
    & {
      display: flex;
      gap: 1rem;
    }
  }
}

💡 Starting a nested rule with & is safe in all contexts. Without &, the nested selector is treated as a descendant — but & is clearer and required when nesting pseudo-elements.


Step 2: @scope


Step 3: Advanced :has() Patterns


Step 4: CSS Anchor Positioning


Step 5: View Transitions API


Step 6: Scroll-Driven Animations


Step 7: Scroll Snap


Step 8: Capstone — CSS Feature Compatibility Checker

(Create the file:)

📸 Verified Output:


Summary

Feature
Syntax
Support 2024

CSS nesting

& .child {}

88%+

@scope

@scope (.card) {}

85%+

:has() advanced

:has(input:invalid)

89%+

Anchor positioning

anchor-name: --x; top: anchor(bottom)

30% (limited)

View Transitions

document.startViewTransition()

Chrome/Edge

::view-transition-*

::view-transition-new(hero)

Chrome/Edge

Scroll timeline

animation-timeline: scroll()

72%

View timeline

animation-timeline: view()

72%

animation-range

entry 0% entry 100%

72%

Scroll snap

scroll-snap-type: x mandatory

97%+

Last updated