Modern CSS Features: Container Queries, Subgrid, and More
Explore cutting-edge CSS features like Container Queries, CSS Subgrid, :has() selector, and how they're changing responsive design patterns.
Modern CSS is evolving rapidly, introducing powerful features that solve long-standing design challenges. Let's explore the most impactful new CSS features changing how we build responsive layouts.
Container Queries
Container queries allow elements to respond to their container's size, not just the viewport.
.card-container {
container-type: inline-size;
container-name: card;
}
@container card (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 200px 1fr;
gap: 1rem;
}
.card-image {
grid-row: 1 / -1;
}
}
@container card (max-width: 399px) {
.card {
display: block;
}
.card-image {
width: 100%;
margin-bottom: 1rem;
}
}
Real-world Example
// Component that adapts to its container
const ProductCard = ({ product }: { product: { name: string; description: string; price: number; image: string } }) => (
<div className="product-card-container">
<div className="product-card">
<img src={product.image} className="product-image" />
<div className="product-info">
<h3>{product.name}</h3>
<p>{product.description}</p>
<span className="price">${product.price}</span>
</div>
</div>
</div>
)
CSS Subgrid
Subgrid allows nested grids to participate in their parent's grid.
.main-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 1rem;
}
.card-group {
grid-column: span 2;
display: grid;
grid-template-rows: subgrid;
gap: inherit;
}
.card {
display: grid;
grid-template-rows: subgrid;
}
.card-header,
.card-content,
.card-footer {
/* Each part aligns across all cards */
}
The :has() Selector
The :has() pseudo-class enables parent selection based on descendants.
/* Style form based on validation state */
.form-group:has(.error) {
border-color: red;
background-color: #fee;
}
.form-group:has(.success) {
border-color: green;
background-color: #efe;
}
/* Style card with specific content */
.article-card:has(.featured-badge) {
border: 2px solid gold;
box-shadow: 0 4px 20px rgba(255, 215, 0, 0.3);
}
/* Navigation highlighting */
.nav-item:has(.dropdown:hover) {
background-color: #f0f0f0;
}
Cascade Layers
Control the cascade with explicit layer ordering.
@layer reset, base, components, utilities;
@layer reset {
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
}
@layer base {
body {
font-family: system-ui, sans-serif;
line-height: 1.6;
}
}
@layer components {
.button {
padding: 0.5rem 1rem;
border: none;
border-radius: 0.25rem;
cursor: pointer;
}
}
@layer utilities {
.text-center { text-align: center; }
.hidden { display: none; }
}
CSS Nesting
Write more maintainable styles with native nesting.
.navigation {
background: white;
padding: 1rem;
ul {
list-style: none;
display: flex;
gap: 1rem;
li {
a {
text-decoration: none;
color: #333;
transition: color 0.2s;
&:hover {
color: #007bff;
}
&.active {
font-weight: bold;
color: #007bff;
}
}
}
}
@media (max-width: 768px) {
padding: 0.5rem;
ul {
flex-direction: column;
gap: 0.5rem;
}
}
}
New Color Functions
Enhanced color manipulation with modern CSS.
:root {
--primary-hue: 220;
--primary-sat: 100%;
--primary-light: 50%;
}
.button-primary {
background: hsl(var(--primary-hue) var(--primary-sat) var(--primary-light));
}
.button-primary:hover {
background: hsl(var(--primary-hue) var(--primary-sat) calc(var(--primary-light) - 10%));
}
/* Color mixing */
.mixed-color {
background: color-mix(in srgb, red 30%, blue);
}
/* Relative colors */
.lighter-variant {
background: rgb(from var(--base-color) r g b / 0.5);
}
View Transitions API
Smooth transitions between page states.
@view-transition {
navigation: auto;
}
.page-transition {
view-transition-name: page-content;
}
::view-transition-old(page-content) {
animation: fade-out 0.3s ease-out;
}
::view-transition-new(page-content) {
animation: fade-in 0.3s ease-in;
}
@keyframes fade-out {
to { opacity: 0; }
}
@keyframes fade-in {
from { opacity: 0; }
}
Logical Properties
Build truly international layouts with logical properties.
.content {
/* Instead of margin-left */
margin-inline-start: 1rem;
/* Instead of margin-top/bottom */
margin-block: 2rem;
/* Instead of padding-left/right */
padding-inline: 1rem;
/* Instead of border-top */
border-block-start: 1px solid #ccc;
}
/* Responsive spacing */
.section {
padding-inline: clamp(1rem, 5vw, 3rem);
margin-block: clamp(2rem, 8vh, 6rem);
}
Browser Support Strategy
/* Progressive enhancement with feature queries */
@supports (container-type: inline-size) {
.modern-layout {
container-type: inline-size;
}
@container (min-width: 400px) {
.modern-layout .item {
display: grid;
grid-template-columns: 1fr 2fr;
}
}
}
/* Fallback for older browsers */
@supports not (container-type: inline-size) {
.modern-layout .item {
display: flex;
flex-wrap: wrap;
}
@media (min-width: 400px) {
.modern-layout .item {
flex-wrap: nowrap;
}
}
}
These modern CSS features represent a significant leap forward in web styling capabilities. Start experimenting with them today to build more robust, maintainable, and responsive designs.
Enjoyed this article?
Subscribe to our newsletter for more insights on web development, design, and technology.