Modern CSS Techniques for 2025
Modern CSS Techniques for 2025
CSS has evolved dramatically in recent years. Let’s explore the cutting-edge features that are changing how we style the web.
Container Queries
Finally! Style elements based on their container 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: 1fr 2fr;
}
}
@container card (max-width: 399px) {
.card {
display: block;
}
}
This is a game-changer for component-based design!
Cascade Layers
Control specificity more elegantly with @layer:
@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.5;
}
}
@layer components {
.btn {
padding: 0.5rem 1rem;
border-radius: 0.25rem;
}
}
@layer utilities {
.text-center { text-align: center; }
}
Layers declared first have lower priority, solving specificity wars!
New Color Functions
oklch() - Perceptually Uniform Colors
:root {
--primary: oklch(65% 0.2 250);
--primary-light: oklch(80% 0.15 250);
--primary-dark: oklch(45% 0.25 250);
}
Benefits:
- Consistent perceived brightness
- Better for generating color palettes
- Wider gamut support
color-mix()
Blend colors directly in CSS:
.button:hover {
background: color-mix(in oklch, var(--primary) 80%, black);
}
.overlay {
background: color-mix(in srgb, blue 50%, transparent);
}
The :has() Selector
Finally, a parent selector!
/* Style card when it has an image */
.card:has(img) {
padding: 0;
}
/* Form validation states */
.form-group:has(input:invalid) {
border-color: red;
}
.form-group:has(input:valid) {
border-color: green;
}
/* Conditional layouts */
.sidebar:has(.ad) {
min-height: 400px;
}
Scroll-Driven Animations
CSS-only scroll animations:
@keyframes fade-in {
from { opacity: 0; transform: translateY(50px); }
to { opacity: 1; transform: translateY(0); }
}
.reveal {
animation: fade-in linear;
animation-timeline: view();
animation-range: entry 0% cover 40%;
}
No JavaScript required!
Subgrid
Perfect nested grid alignment:
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
}
.card {
display: grid;
grid-template-rows: subgrid;
grid-row: span 3;
}
Children can now align to the parent grid!
Native Nesting
No preprocessor needed:
.card {
padding: 1rem;
& .title {
font-size: 1.5rem;
&:hover {
color: blue;
}
}
& .content {
margin-top: 1rem;
}
@media (min-width: 768px) {
padding: 2rem;
}
}
Conclusion
Modern CSS is incredibly powerful. These features reduce our dependency on JavaScript and preprocessors while making our stylesheets more maintainable and expressive.
Browser Support: Check https://caniuse.com for current support levels.