unraveljs.com
Menu
tips β€’

10 Modern CSS Techniques You're Probably Missing

Discover powerful CSS features you might not be using yet. Container queries, cascade layers, modern color spaces, and more techniques that will level up your frontend game.

#css #modern-css #performance #frontend #css-features #web-development

10 Modern CSS Techniques You’re Probably Missing

Frontend development moves fast. While you’ve been mastering flexbox and grid, CSS has evolved with game-changing features. Let me share the modern techniques that have transformed my workflow - and probably aren’t in your daily toolkit yet.


🎨 1. CSS Container Queries - Responsive Design at the Component Level

Remember struggling with components that break in different layouts? Container queries fix this beautifully.

/* Define the container */
.card-grid {
  container-type: inline-size;
}

/* Style based on container width, not viewport */
@container (min-width: 400px) {
  .card {
    display: grid;
    grid-template-columns: 1fr 2fr;
    gap: 1rem;
  }
}

@container (min-width: 600px) {
  .card {
    grid-template-columns: 1fr 3fr;
    padding: 2rem;
  }
}

Why this changes everything:

Browser support: Chrome 106+, Firefox 110+, Safari 16+


🎭 2. CSS Cascade Layers - Control Your Specificity Wars

Tired of !important and specificity battles? Cascade layers let you define the order your CSS rules apply.

/* Define layers in order of importance */
@layer reset, base, components, utilities;

/* Reset layer - lowest priority */
@layer reset {
  * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }
}

/* Base layer */
@layer base {
  body {
    font-family: system-ui;
    line-height: 1.5;
  }
}

/* Components layer */
@layer components {
  .btn {
    padding: 0.5rem 1rem;
    border: none;
    background: blue;
    color: white;
  }
}

/* Utilities layer - highest priority */
@layer utilities {
  .btn-red {
    background: red !important; /* Safe to use here */
  }
}

Game-changing benefits:


🌈 3. Modern Color Functions - Finally, Better Color Manipulation

CSS now has powerful color functions that make Sass functions look primitive.

/* Color mixing */
.primary {
  background: color-mix(in srgb, #ff0000 50%, #0000ff 50%);
  /* Result: purple */
}

/* Color adjustments with better control */
.button {
  background: hsl(220 90% 50%);
}

.button:hover {
  background: hsl(from hsl(220 90% 50%) h s calc(l + 10%));
  /* Increase lightness by 10% */
}

.button:active {
  background: hsl(from hsl(220 90% 50%) h s calc(l - 10%));
  /* Decrease lightness by 10% */
}

/* Relative color syntax */
.theme-dark {
  --text-color: #333;
  --bg-color: color-mix(in srgb, white 90%, var(--text-color));
  /* 90% white, 10% text color */
}

/* Modern color spaces */
.gradient {
  background: linear-gradient(
    in oklch longer hue,
    oklch(70% 0.3 200),
    oklch(70% 0.3 280)
  );
  /* Smoother gradients in perceptual color space */
}

Why this matters:


πŸ” 4. :has() Selector - The Parent Selector We’ve Always Wanted

Finally select elements based on their children!

/* Style a form group based on its content */
.form-group:has(:invalid) {
  border-color: red;
}

.form-group:has(:focus-within) {
  border-color: blue;
  box-shadow: 0 0 0 2px rgba(0, 0, 255, 0.2);
}

/* Card layouts with conditional styling */
.card:has(.featured) {
  border: 2px solid gold;
}

.card:has(img) {
  display: flex;
  flex-direction: column;
}

/* Navigation state */
.nav:has(.active) {
  background: var(--highlight-color);
}

/* Error states in forms */
.input-wrapper:has(input:focus) label {
  transform: translateY(-20px) scale(0.8);
  color: var(--primary-color);
}

Real-world applications:


πŸ“ 5. Logical Properties - Bidirectional Layout by Default

Stop writing margin-left and start thinking in logical terms.

/* ❌ Physical properties */
.card {
  margin-left: 1rem;
  margin-right: 1rem;
  padding-top: 2rem;
  border-bottom: 1px solid #ccc;
}

/* βœ… Logical properties */
.card {
  margin-inline: 1rem;
  margin-block: 0;
  padding-block-start: 2rem;
  border-block-end: 1px solid #ccc;
}

/* Trigonometry for diagonal layouts */
.diagonal-section {
  transform: rotate(2deg);
  margin-block: 4rem;
  padding-block: 6rem;
  background: linear-gradient(
    135deg,
    var(--color-primary),
    var(--color-secondary)
  );
}

/* Writing mode aware */
.sidebar {
  inline-size: 300px; /* width in horizontal writing */
  block-size: 100vh;   /* height in horizontal writing */
}

/* Writing mode changes */
.arabic-text {
  writing-mode: horizontal-tb;
  direction: rtl;
}

.japanese-text {
  writing-mode: vertical-rl;
}

Benefits:


πŸŽͺ 6. CSS @property - Typed Custom Properties

Type-safe custom properties with better browser optimization.

/* Register custom properties */
@property --hue {
  syntax: '<angle>';
  inherits: true;
  initial-value: 0deg;
}

@property --theme-color {
  syntax: '<color>';
  inherits: true;
  initial-value: #0066cc;
}

@property --spacing {
  syntax: '<length-percentage>';
  inherits: false;
  initial-value: 1rem;
}

/* Use them with animations */
.theme-switcher {
  --hue: 0deg;
  background: hsl(var(--hue) 70% 50%);
  transition: --hue 0.3s ease;
}

.theme-switcher:hover {
  --hue: 180deg;
}

/* Dynamic theming */
.dark-theme {
  --theme-color: #ffffff;
  --text-bg: #1a1a1a;
}

.light-theme {
  --theme-color: #000000;
  --text-bg: #ffffff;
}

/* Validated values */
.button {
  padding: var(--spacing, 1rem); /* Falls back if invalid */
  color: var(--theme-color, #000);
}

Advantages over regular custom properties:


🎯 7. Scroll-driven Animations - Performance-optimized Scroll Effects

Create complex scroll animations without JavaScript performance issues.

/* Scroll progress indicators */
.progress-bar {
  position: fixed;
  top: 0;
  left: 0;
  height: 4px;
  background: linear-gradient(90deg, #0066cc, #00cc66);
  transform-origin: left;
  animation: progress-grow linear;
  animation-timeline: scroll(root);
}

@keyframes progress-grow {
  to {
    transform: scaleX(1);
  }
}

/* Parallax effects */
.parallax-image {
  animation: parallax linear;
  animation-timeline: scroll(root block nearest);
}

@keyframes parallax {
  to {
    transform: translateY(-100px);
  }
}

/* View-based animations */
.fade-in-section {
  animation: fade-in both;
  animation-timeline: view(70% 20%);
}

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

/* Scroll-triggered counters */
.counter {
  animation: count-to-100 linear forwards;
  animation-timeline: scroll(root);
}

@keyframes count-to-100 {
  to {
    --value: 100;
  }
}

.counter::after {
  content: counter(counter-value);
  counter-reset: counter-value var(--value);
}

Performance benefits:


πŸ“± 8. Modern Selectors - More Precise Element Targeting

New pseudo-classes that solve common selection problems.

/* :not() with multiple selectors */
button:not(:disabled, [aria-busy="true"]) {
  cursor: pointer;
}

/* :where() with zero specificity */
.accordion :where(h2, h3, h4) {
  margin: 0;
  font-size: 1.2rem;
}

/* :is() for grouping selectors */
.card :is(img, video, iframe) {
  width: 100%;
  height: auto;
  object-fit: cover;
}

/* Form validation states */
input:invalid:not(:placeholder-shown) {
  border-color: #dc3545;
}

input:valid:not(:placeholder-shown) {
  border-color: #28a745;
}

/* User preference selectors */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #1a1a1a;
    --text: #ffffff;
  }
}

/* Focus-visible for better accessibility */
button:focus-visible {
  outline: 2px solid #0066cc;
  outline-offset: 2px;
}

button:focus:not(:focus-visible) {
  outline: none;
}

🎨 9. CSS Grid Subgrid - Nested Grid Perfection

Child elements can now participate in parent grids.

/* Parent grid */
.page-grid {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
  gap: 2rem;
}

/* Child becomes subgrid */
.sidebar {
  display: grid;
  grid-template-rows: subgrid; /* Inherits parent rows */
  grid-row: span 3;
}

/* Complex nested layouts */
.card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}

.featured-card {
  display: grid;
  grid-column: span 2;
  grid-template-rows: auto 1fr auto; /* Participates in parent */
  gap: 1rem;
}

/* Alignment control */
.align-content {
  display: grid;
  grid-template-columns: subgrid;
  align-content: center; /* Aligns in subgrid context */
}

Use cases:


⚑ 10. Content-visibility Performance Optimization

Massive performance gains for long pages with minimal effort.

/* Skip rendering off-screen content */
.offscreen-section {
  content-visibility: auto;
  contain-intrinsic-size: 1000px;
}

/* For completely hidden content */
.collapsed-content {
  content-visibility: hidden;
  contain-intrinsic-size: 0 100px;
}

/* Combined with intersection observer */
.lazy-load {
  content-visibility: auto;
  contain-intrinsic-size: 500px 200px;
}

/* Performance measurement */
.performance-section {
  content-visibility: auto;
  contain-intrinsic-size: 800px;
}

Performance impact:


πŸ› οΈ Putting It All Together

Here’s a modern component using multiple techniques:

/* Modern card component */
.card-container {
  container-type: inline-size;
  content-visibility: auto;
  contain-intrinsic-size: 400px;
}

@layer components {
  @container (min-width: 300px) {
    .card {
      display: grid;
      grid-template-columns: 1fr 2fr;
      gap: 1rem;
      padding: 1.5rem;
      border: 1px solid var(--border-color);
      border-radius: 8px;
      transition: transform 0.2s ease;
      
      /* Modern hover effect */
      &:has(:focus-within) {
        border-color: var(--primary-color);
        box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary-color) 20%, transparent);
      }
      
      &:hover {
        transform: translateY(-2px);
      }
    }
    
    .card-title {
      color: hsl(from var(--text-color) h s calc(l - 10%));
      font-size: clamp(1rem, 2vw, 1.25rem);
    }
    
    .card-button {
      --button-bg: var(--primary-color);
      background: var(--button-bg);
      color: white;
      border: none;
      padding: 0.75rem 1.5rem;
      border-radius: 6px;
      
      &:hover {
        --button-bg: hsl(from var(--primary-color) h s calc(l + 10%));
      }
    }
  }
}

πŸ“Š Browser Support Checklist

FeatureChromeFirefoxSafariNote
Container Queriesβœ… 106+βœ… 110+βœ… 16+Safe to use
Cascade Layersβœ… 99+βœ… 97+βœ… 15.4+Widely supported
Color Functionsβœ… 111+βœ… 113+βœ… 16.2+Use with fallbacks
:has() Selectorβœ… 105+βœ… 121+βœ… 15.4+Safari missing full support
Logical Propertiesβœ… 87+βœ… 66+βœ… 14.1+Excellent support
@propertyβœ… 85+βœ… 128+βœ… 16.4+Firefox recently added
Scroll Animationsβœ… 115+❌❌Chrome-only for now
Modern Selectorsβœ… 88+βœ… 82+βœ… 14+Good support
Subgridβœ… 117+βœ… 71+βœ… 16+Solid support
Content-visibilityβœ… 85+βœ… 85+βœ… 16+Good fallback options

πŸš€ Migration Strategy

Phase 1: Low-risk wins

Phase 2: Component upgrades

Phase 3: Performance focus

Phase 4: Advanced features


πŸ”§ Testing Strategy

/* Feature detection in CSS */
@supports (container-type: inline-size) {
  .component {
    /* Container query styles */
  }
}

@supports not (container-type: inline-size) {
  .component {
    /* Fallback styles */
  }
}

/* Progressive enhancement */
.modern-features {
  /* Base styles */
}

@supports (color-mix(in srgb, red, blue)) {
  .modern-features {
    /* Enhanced styles */
  }
}

🎯 Final Thoughts

Modern CSS is more powerful than ever. These features aren’t just syntax sugar - they solve real problems that we’ve been hacking around for years.

Start small:

  1. Use logical properties in new code
  2. Try cascade layers on your next project
  3. Experiment with container queries in components

Build up:

Remember: The web is evolving, and staying current makes you a more valuable developer. But don’t chase trends - adopt features that solve real problems in your projects.

What modern CSS feature are you most excited about? How are you using these in production?

Happy modern CSS coding! 🎨


This article covers techniques that are actively used in production. Browser support is improving rapidly - always check caniuse.com for the latest compatibility information.