Modern CSS Techniques: Grid, Container Queries, and Advanced Layouts

5 December 2024 · CodeMatic Team

Modern CSS Techniques

Modern CSS has evolved significantly, offering powerful features that simplify complex layouts and improve maintainability. From CSS Grid to Container Queries, these techniques enable more flexible and responsive designs.

CSS Grid: Two-Dimensional Layouts

CSS Grid allows you to create complex two-dimensional layouts with ease. Unlike Flexbox, Grid handles both rows and columns simultaneously.

Basic Grid Layout

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

.item {
  grid-column: span 1;
  grid-row: span 1;
}

Advanced Grid Techniques

/* Named grid lines and areas */
.container {
  display: grid;
  grid-template-columns: [sidebar-start] 250px [sidebar-end main-start] 1fr [main-end];
  grid-template-rows: [header-start] auto [header-end content-start] 1fr [content-end footer-start] auto [footer-end];
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
  gap: 1rem;
}

.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }

/* Auto-fit and auto-fill for responsive grids */
.responsive-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1rem;
}

/* Subgrid (new feature) */
.parent {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}

.child {
  display: grid;
  grid-column: span 2;
  grid-template-columns: subgrid; /* Aligns with parent grid */
}

Container Queries: Component-Based Responsive Design

Container Queries allow you to style elements based on their container's size, not the viewport. This is revolutionary for component-based development.

/* Define containment context */
.card-container {
  container-type: inline-size;
  container-name: card;
}

/* Query based on container size */
@container card (min-width: 400px) {
  .card {
    display: flex;
    flex-direction: row;
  }
  
  .card-image {
    width: 200px;
  }
}

@container card (max-width: 399px) {
  .card {
    display: flex;
    flex-direction: column;
  }
  
  .card-image {
    width: 100%;
  }
}

/* Multiple container queries */
@container card (min-width: 600px) {
  .card-content {
    font-size: 1.125rem;
  }
}

CSS Cascade Layers

Cascade Layers allow you to explicitly control CSS specificity and cascade order, solving specificity conflicts.

/* Define layer order */
@layer reset, base, components, utilities;

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

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

/* Component styles */
@layer components {
  .button {
    padding: 0.5rem 1rem;
    border-radius: 0.25rem;
  }
}

/* Utility classes (always win) */
@layer utilities {
  .text-center {
    text-align: center;
  }
}

/* Unlayered styles have higher priority */
.no-layer {
  color: red; /* Wins over layered styles */
}

Modern CSS Features

CSS Custom Properties (Variables)

:root {
  --primary-color: #28C55E;
  --spacing-unit: 1rem;
  --border-radius: 0.5rem;
  
  /* Dark mode support */
  --bg-color: #0F172A;
  --text-color: #FFFFFF;
}

@media (prefers-color-scheme: light) {
  :root {
    --bg-color: #FFFFFF;
    --text-color: #0F172A;
  }
}

.component {
  background: var(--bg-color);
  color: var(--text-color);
  padding: calc(var(--spacing-unit) * 2);
  border-radius: var(--border-radius);
}

/* Scoped custom properties */
.card {
  --card-padding: 1.5rem;
  padding: var(--card-padding);
}

Logical Properties

/* Logical properties work with writing direction */
.element {
  /* Instead of margin-left/right */
  margin-inline-start: 1rem;
  margin-inline-end: 1rem;
  
  /* Instead of margin-top/bottom */
  margin-block-start: 2rem;
  margin-block-end: 2rem;
  
  /* Size properties */
  inline-size: 100%;
  block-size: auto;
  
  /* Border-radius */
  border-start-start-radius: 0.5rem;
  border-end-end-radius: 0.5rem;
}

CSS Functions

/* clamp() for fluid typography */
h1 {
  font-size: clamp(1.5rem, 5vw, 3rem);
}

/* min(), max() for responsive values */
.container {
  width: min(100%, 1200px);
  padding: max(1rem, 3vw);
}

/* aspect-ratio */
.video {
  aspect-ratio: 16 / 9;
}

/* Color functions */
.element {
  color: oklch(70% 0.2 150); /* Modern color space */
  background: color-mix(in srgb, var(--primary) 50%, white);
}

Advanced Selectors

:has() Pseudo-Class

/* Style parent based on children */
.card:has(.featured) {
  border: 2px solid var(--primary-color);
}

/* Style based on sibling */
.container:has(.error) .submit-button {
  display: none;
}

/* Complex selections */
article:has(h2:first-child) {
  margin-top: 2rem;
}

:is() and :where()

/* :where() has zero specificity */
:where(.button, .link, .nav-item) {
  cursor: pointer;
}

/* :is() uses highest specificity */
:is(.card, .panel, .box).featured {
  background: var(--highlight);
}

Performance Optimizations

  • Use content-visibility to skip rendering off-screen content
  • Leverage will-change sparingly for known animations
  • Use contain property for layout optimization
  • Prefer transform and opacity for animations
  • Use CSS containment for isolated components

Real-World Example

We redesigned a dashboard using modern CSS:

  • CSS Grid for main layout structure
  • Container Queries for responsive components
  • Cascade Layers for better organization
  • Logical properties for RTL support
  • Result: 40% less CSS code, 30% faster rendering

Conclusion

Modern CSS features like Grid, Container Queries, and Cascade Layers enable more maintainable and performant stylesheets. Start with Grid for layouts, experiment with Container Queries for component-based responsive design, and use Cascade Layers to organize your CSS. These tools reduce complexity and improve developer experience.