On this page
Modern CSS Features
Container Queries
Style elements based on their container’s size, not the viewport:
.card-container {
container-type: inline-size;
container-name: card;
}
@container card (min-width: 400px) {
.card {
display: flex;
flex-direction: row;
}
}
Perfect for reusable components in unpredictable layouts.
:has() — Parent Selector
/* Style form when it contains an invalid input */
form:has(:invalid) {
border-color: red;
}
/* Style card when image is present */
.card:has(img) {
padding-top: 0;
}
CSS Subgrid
Share grid tracks between parent and nested grid:
.parent {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.child {
display: grid;
grid-column: span 3;
grid-template-columns: subgrid;
}
Logical Properties
Write direction-aware styles (works for RTL languages):
/* Instead of margin-left / margin-right */
.element {
margin-inline-start: 1rem;
padding-block: 0.5rem 1rem;
border-inline-end: 1px solid #ccc;
}
Modern Color Functions
:root {
--primary: oklch(55% 0.2 250); /* perceptually uniform */
--surface: color-mix(in oklch, white 90%, var(--primary));
}
.text {
color: light-dark(#333, #eee); /* auto light/dark mode */
}
:is() and :where()
Reduce selector repetition:
/* Before */
header p, main p, footer p { line-height: 1.6; }
/* After */
:is(header, main, footer) p { line-height: 1.6; }
/* :where() has zero specificity — good for resets */
:where(h1, h2, h3) { margin: 0; }
@layer for Cascade Control
@layer reset, base, components, utilities;
@layer reset {
* { margin: 0; padding: 0; }
}
@layer components {
.button { background: blue; }
}
Layers control cascade order without specificity hacks.
@property for Typed Custom Properties
@property --angle {
syntax: '<angle>';
initial-value: 0deg;
inherits: false;
}
.spinner {
animation: rotate 2s linear infinite;
}
@keyframes rotate {
to { --angle: 360deg; }
}
Stay current with Can I Use and MDN CSS reference for browser support.