FroquizFroquiz
HomeQuizzesSenior ChallengeGet CertifiedBlogAbout
Sign InStart Quiz
Sign InStart Quiz
Froquiz

The most comprehensive quiz platform for software engineers. Test yourself with 10000+ questions and advance your career.

LinkedIn

Platform

  • Start Quizzes
  • Topics
  • Blog
  • My Profile
  • Sign In

About

  • About Us
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

Β© 2026 Froquiz. All rights reserved.Built with passion for technology
Blog & Articles

CSS Advanced Techniques: Custom Properties, Container Queries, Grid Masonry and Modern Layouts

Level up your CSS skills with modern techniques. Covers CSS custom properties, container queries, advanced Grid patterns, logical properties, cascade layers, and the has() selector.

Yusuf SeyitoğluMarch 12, 20263 views9 min read

CSS Advanced Techniques: Custom Properties, Container Queries, Grid Masonry and Modern Layouts

CSS has evolved dramatically in the past few years. The gap between what you can do with pure CSS today versus five years ago is enormous. This guide covers the modern CSS features that are changing how developers build layouts and design systems β€” and that increasingly come up in frontend interviews.

CSS Custom Properties (Variables)

CSS custom properties are not just variables β€” they are live, cascading, inherited, and can be modified with JavaScript.

css
:root { --color-primary: #3b82f6; --color-secondary: #64748b; --color-background: #ffffff; --color-text: #1e293b; --spacing-xs: 0.25rem; --spacing-sm: 0.5rem; --spacing-md: 1rem; --spacing-lg: 1.5rem; --spacing-xl: 2rem; --radius-sm: 0.25rem; --radius-md: 0.5rem; --radius-full: 9999px; --font-size-sm: 0.875rem; --font-size-base: 1rem; --font-size-lg: 1.125rem; --font-size-xl: 1.25rem; } /* Dark mode */ [data-theme="dark"] { --color-background: #0f172a; --color-text: #f1f5f9; --color-primary: #60a5fa; } .button { background: var(--color-primary); color: white; padding: var(--spacing-sm) var(--spacing-md); border-radius: var(--radius-md); font-size: var(--font-size-base); }

Scoped custom properties

Custom properties cascade β€” you can scope them to components:

css
.card { --card-padding: var(--spacing-md); --card-radius: var(--radius-md); --card-shadow: 0 1px 3px rgba(0,0,0,0.12); padding: var(--card-padding); border-radius: var(--card-radius); box-shadow: var(--card-shadow); } .card--compact { --card-padding: var(--spacing-sm); /* override just for compact variant */ }

CSS custom properties with JavaScript

javascript
// Read a custom property const primary = getComputedStyle(document.documentElement) .getPropertyValue("--color-primary").trim(); // Set a custom property dynamically document.documentElement.style.setProperty("--color-primary", "#10b981"); // Theme switching function setTheme(theme) { document.documentElement.setAttribute("data-theme", theme); localStorage.setItem("theme", theme); }

Container Queries

Media queries respond to the viewport width. Container queries respond to the container width β€” enabling truly reusable components that adapt to their context.

css
/* Define a containment context */ .card-grid { container-type: inline-size; container-name: card-grid; } /* Style the card based on its container width, not the viewport */ .card { display: grid; grid-template-columns: 1fr; } @container card-grid (min-width: 400px) { .card { grid-template-columns: auto 1fr; gap: 1rem; } } @container card-grid (min-width: 700px) { .card { grid-template-columns: auto 1fr auto; } }

The same card component now works correctly whether it is in a narrow sidebar or a wide main column β€” without any JavaScript or media query hackery.

Advanced CSS Grid

Auto-fit with minmax (responsive without media queries)

css
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1rem; } /* Columns automatically adapt -- 1 column at narrow, up to N at wide */

Masonry-style layout

css
/* Native CSS masonry (experimental, Chrome flags needed as of 2025) */ .masonry { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: masonry; gap: 1rem; } /* Current workaround: multi-column */ .masonry-fallback { columns: 3 250px; column-gap: 1rem; } .masonry-fallback > * { break-inside: avoid; margin-bottom: 1rem; }

Named grid areas

css
.layout { display: grid; grid-template-areas: "header header header" "sidebar content aside" "footer footer footer"; grid-template-columns: 200px 1fr 200px; grid-template-rows: auto 1fr auto; min-height: 100vh; gap: 1rem; } header { grid-area: header; } .sidebar { grid-area: sidebar; } main { grid-area: content; } aside { grid-area: aside; } footer { grid-area: footer; } @media (max-width: 768px) { .layout { grid-template-areas: "header" "content" "sidebar" "aside" "footer"; grid-template-columns: 1fr; } }

The :has() Selector

:has() is the long-awaited "parent selector" β€” style an element based on what it contains:

css
/* Style a form group that contains an invalid input */ .form-group:has(input:invalid) { background: #fef2f2; border-color: #ef4444; } /* Card with an image gets different padding */ .card:has(img) { padding: 0; } .card:has(img) .card-body { padding: var(--spacing-md); } /* Navigation with open dropdown */ .nav-item:has(.dropdown[open]) > .nav-link { color: var(--color-primary); font-weight: 600; } /* Table row that contains a checked checkbox */ tr:has(input[type="checkbox"]:checked) { background: var(--color-selected); } /* Quantity queries -- style list differently based on item count */ li:nth-child(n+4) { /* styles when there are 4+ items */ } ul:has(li:nth-child(4)) li { /* style all items when there are at least 4 */ }

:has() has excellent browser support as of 2025 β€” use it.

CSS Cascade Layers

@layer gives you explicit control over specificity and cascade order β€” solving the specificity wars of large CSS codebases:

css
/* Define layer order -- lower layers have lower priority */ @layer reset, base, tokens, components, utilities; @layer reset { *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } } @layer base { body { font-family: system-ui, sans-serif; color: var(--color-text); } a { color: var(--color-primary); } } @layer components { .button { padding: var(--spacing-sm) var(--spacing-md); border-radius: var(--radius-md); background: var(--color-primary); color: white; } } @layer utilities { .sr-only { position: absolute; width: 1px; height: 1px; clip: rect(0, 0, 0, 0); } .text-center { text-align: center; } }

Styles in utilities always beat components regardless of specificity β€” finally, predictable cascade control.

CSS Logical Properties

Logical properties use start/end instead of left/right, enabling correct layout for RTL languages with no extra CSS:

css
/* Physical properties (language-specific) */ .card { margin-left: 1rem; margin-right: 1rem; padding-left: 1rem; border-left: 3px solid var(--color-primary); text-align: left; } /* Logical equivalents (work for both LTR and RTL) */ .card { margin-inline: 1rem; /* left and right in LTR, right and left in RTL */ padding-inline-start: 1rem; /* left in LTR, right in RTL */ border-inline-start: 3px solid var(--color-primary); text-align: start; }

Quick reference:

  • margin-inline β†’ margin-left + margin-right
  • padding-block β†’ padding-top + padding-bottom
  • inset-inline-start β†’ left (in LTR)
  • block-size β†’ height
  • inline-size β†’ width

Scroll-Driven Animations

CSS animations that respond to scroll position β€” no JavaScript needed:

css
@keyframes fade-in-up { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .reveal-on-scroll { animation: fade-in-up linear both; animation-timeline: view(); /* linked to element's scroll position */ animation-range: entry 0% entry 30%; /* plays as element enters viewport */ } /* Progress bar that fills as user scrolls */ .scroll-progress { position: fixed; top: 0; left: 0; height: 3px; background: var(--color-primary); animation: grow-width linear; animation-timeline: scroll(root); } @keyframes grow-width { from { width: 0%; } to { width: 100%; } }

Common Interview Questions

Q: What is the difference between CSS custom properties and preprocessor variables (Sass)?

Sass variables are resolved at compile time β€” they do not exist in the output CSS. CSS custom properties are live browser values β€” they can be changed at runtime with JavaScript, can be scoped to elements, and participate in the cascade and inheritance. Sass variables are more powerful for build-time logic; CSS custom properties are more powerful for runtime theming.

Q: What are container queries and why are they better than media queries for component libraries?

Media queries respond to the viewport width β€” a component looks the same at a given viewport width regardless of where it is placed. Container queries respond to the parent container's width, enabling components to adapt based on their actual available space. This makes components truly reusable β€” they look right whether in a narrow sidebar or a wide main section.

Q: What does @layer solve?

Without @layer, CSS specificity battles are hard to manage in large codebases β€” a utility class might need !important to override a component's styles. @layer lets you define explicit cascade order: styles in later layers always win, regardless of selector specificity. This makes large CSS architectures predictable.

Practice Frontend on Froquiz

CSS layout and modern techniques are tested in frontend developer interviews. Test your CSS knowledge on Froquiz β€” covering Flexbox, Grid, animations, and more.

Summary

  • CSS custom properties cascade and inherit β€” use them for design tokens and runtime theming
  • Container queries let components respond to their container width, not the viewport
  • auto-fit with minmax creates responsive grids with zero media queries
  • :has() is the parent selector β€” style elements based on their contents
  • @layer gives explicit cascade priority control β€” eliminates specificity wars
  • Logical properties (margin-inline, padding-block) support RTL layouts automatically
  • Scroll-driven animations link CSS animations to scroll position with no JavaScript

About Author

Yusuf Seyitoğlu

Author β†’

Other Posts

  • GraphQL Schema Design: Types, Resolvers, Mutations and Best PracticesMar 12
  • Java Collections Deep Dive: ArrayList, HashMap, TreeMap, LinkedHashMap and When to Use EachMar 12
  • System Design Fundamentals: Scalability, Load Balancing, Caching and DatabasesMar 12
All Blogs