Top New CSS Features showcase
Created by Hosein Hamzenejadi
I've also written a comprehensive blog post about this topic: Check it out!
This page serves as a learning resource and demonstration of new CSS features. To ensure proper functioning and cross-browser compatibility, it's always recommended to consider fallbacks. Some of these features are still experimental or work only on chromium browsers for now. View this page using the latest version of Chrome for the best learning experience.
1. resize and container queries
Dynamic styles based on container instead of the whole window.
.resizable {
resize: horizontal;
overflow: auto;
}
.container {
container-type: inline-size;
padding: 1rem;
}
@container (min-width: 400px) {
.child {
font-weight: bolder;
}
}
2. scroll and view driven animations
Makes gradual animations based on scroll or the element being visible or not possible. superior performance to JS based solutions.
@keyframes fadeInRotate {
from {
opacity: 0;
transform: scale(0) rotate(-180deg) translateX(200%);
}
to {
opacity: 1;
transform: scale(1) rotate(0deg) translateX(0%);
}
}
.animated-box {
animation: fadeInRotate linear both;
animation-timeline: view();
animation-range: 25vh 75vh;
}
3. nested classes (&) - :has parent selector and user-valid/invalid
the styles are apllied only if the user has at least interacted with the input for once and has unfocused it thanks to the new user-valid and user-invalid pseudo classes.
Handling 3 input states using CSS 'has' and user-valid/invalid.
.card {
/* other styles */
&:has(input:user-invalid) {
background-color: lightpink;
}
&:has(input:user-valid) {
background-color: lightgreen;
}
}
4. @propery CSS variables
More detailed variables. unlike regular variables has type checking, defaults and inheritence
This is a primary text with propery variable color!
@property --primary-color {
syntax: '<color>';
initial-value: #5a62f8;
inherits: false;
}
.text-primary {
color: var(--primary-color);
}
5. subgrid
Subgrid makes it possible for grid items to have grid display which enables grid shareability and nested grids to align to ancestors and siblings.
.grid {
display: grid;
grid-template-columns: repeat(9, 1fr);
grid-template-rows: repeat(4, minmax(6.25rem, auto));
}
.item {
display: grid;
grid-column: 2 / 7;
grid-row: 2 / 4;
grid-template-columns: subgrid;
grid-template-rows: repeat(3, 5rem);
}
.subitem {
grid-column: 3 / 6;
grid-row: 1 / 3;
}
6. variable fonts
Variable fonts are an evolution of the OpenType font specification that enables many different variations of a typeface to be incorporated into a single file, rather than having a separate font file for every width, weight, or style.
This is a text with variable bold font
This is a text with variable bolder font
This is a text with variable light font
This is a text with variable italic font
.text-bold {
font-variation-settings: 'wght' 700;
}
.text-light {
font-variation-settings: 'wght' 200;
}
.text-bolder {
font-variation-settings: 'wght' 900;
}
.text-italic {
font-variation-settings: 'ital' 1;
}
7. @layer
The @layer rule in CSS is a feature that allows developers to define layers of styles in their stylesheets.
/* specify exact cascading order */
@layer bgblue, bgpink;
/* layer 1 */
@layer bgpink {
body {
background: pink; /* wins */
}
}
/* layer 2 */
@layer bgblue {
body {
background: lightblue;
}
}
8. Scroll Snap
Scroll Snap allows you to create smooth scrolling experiences by snapping scroll positions to specific points within a scroll container (shift + scroll in PC).
.scroll-snap-container {
overflow-x: scroll;
white-space: nowrap;
scroll-snap-type: x mandatory;
-webkit-overflow-scrolling: touch;
max-width: 18.75rem;
}
.scroll-snap-item {
display: inline-block;
width: 18.75rem;
height: 12.5rem;
scroll-snap-align: start;
/* other styles */
}
9. color and color-mix functions
The color() function is used to create colors based on color spaces (like sRGB, Display-P3, etc.). The color-mix() function allows you to blend two colors together by specifying a color space and a ratio.
.srgb-box {
background-color: color(srgb 0.1 0.5 0.8);
}
.red-blue-mix-box {
background-color: color-mix(in srgb, red 50%, blue 50%);
}
10. Animating Auto sizes with interpolate-size
Once a significant and annoying challenge in CSS, Animating Auto sizes like auto hight is now possible using interpolate-size.
- Hover to smoothly collapse
- Hover to smoothly collapse
- Hover to smoothly collapse
- Hover to smoothly collapse
- Hover to smoothly collapse
- Hover to smoothly collapse
- Hover to smoothly collapse
:root {
interpolate-size: allow-keywords;
}
.animated-collapse-box {
/* other styles */
height: 3.125rem;
overflow: hidden;
transition: height ease 1s;
&:hover {
height: auto;
text-overflow: unset;
white-space: wrap;
}
}
11. light-dark function
light-dark() function is a new and simpler alternative to @prefers-color-scheme media query to specify styles of different elements for dark ad light mode. it only works if color-scheme is set. this feature is used allover this page!
this div is white if your OS settings is light and black if it's dark!
:root {
color-scheme: light dark;
--light-bg: snow;
--light-color: black;
--dark-bg: black;
--dark-color: snow;
}
.light-dark-box {
background-color: light-dark(var(--light-bg), var(--dark-bg));
color: light-dark(var(--light-color), var(--dark-color));
}
12. Corner Shapes (corner-shape)
Lets you define non-rectangular corner styles (e.g., scoop, notch, squircle) beyond simple border-radius.
.corner-shape-card {
width: 12.5rem;
height: 7.5rem;
background: #4CAF50;
border-radius: 1.875rem;
corner-shape: scoop notch;
}
13. shape() Function with clip-path
The new shape() replaces older path() syntax for more intuitive shape definitions using CSS. You can define shapes for clipping or motion paths.
#clip-triangle {
width: 11.25rem;
height: 11.25rem;
background: teal;
clip-path: shape(
from 0 0,
line to 11.25rem 0,
line to 5.625rem 11.25rem,
close
);
}
.shape-animated {
width: 2.5rem;
height: 2.5rem;
background: salmon;
position: absolute;
offset-path: shape(
from 0 0,
hline by 6.25rem,
vline by 6.25rem,
close
);
animation: moveShape 4s infinite linear;
}
@keyframes moveShape {
0% { offset-distance: 0%; }
100% { offset-distance: 100%; }
}
14. Custom Selects (appearance: base-select)
Chromium browsers now support rich select styling with appearance: base-select, plus pseudo-elements like ::picker, ::picker-icon, :open, and :checked.
.custom-select,
.custom-select::picker(select) {
appearance: base-select;
padding: 0.5em;
border: 0.125rem solid #444;
border-radius: 0.5rem;
}
.custom-select::picker-icon {
color: #444;
font-size: 1.2em;
transition: rotate 0.3s ease;
}
.custom-select:open::picker-icon {
rotate: 180deg;
}
.custom-select::picker(select) option:checked {
background: #222;
color: white;
}
15. sibling-index() Function
Returns an integer representing an element's position among its siblings — useful for sequenced styles or animations.
- Step One
- Step Two
- Step Three
- Step Four
.sibling-steps li {
width: calc(sibling-index() * 3.75rem);
background: hsl(calc(90 * (sibling-index() - 1)), 70%, 60%);
color: white;
padding: 0.5em;
margin-bottom: 0.5em;
}
16. if() Function (CSS Conditionals)
Real conditional logic inside property values — similar to if in programming.
.responsive-if {
padding: if(
media(width < 500px): 0.5rem;
else: 1.25rem
);
background: lightgoldenrodyellow;
}
.color-test-if {
color: if(
supports(color: oklch(50% 0.2 180)): oklch(50% 0.2 180);
else: #333
);
}
17. CSS Custom Functions (@function)
Write reusable logic blocks in CSS — similar to functions in languages like Sass but native.
@function --half-size(--value) {
result: calc(var(--value) / 2);
}
.custom-func-box {
--size: 6.25rem;
width: --half-size(var(--size));
height: --half-size(var(--size));
background: coral;
}
@function --theme-color() {
result: if(
style(--dark-mode: true): #222;
else: #eee
);
}
.theme-box {
background: --theme-color();
padding: 1rem;
}
18. CSS Anchor Positioning
Anchor positioning allows you to position elements relative to other elements (anchors) anywhere on the page, perfect for tooltips, popovers, and dropdowns without JavaScript calculations.
.anchor-button {
anchor-name: --my-anchor;
}
.tooltip {
position: absolute;
position-anchor: --my-anchor;
bottom: anchor(top);
left: anchor(center);
translate: -50% 0;
}
19. text-wrap: balance
Automatically balances text across multiple lines for better typography, especially useful for headlines and titles to avoid awkward line breaks.
This is a long headline that might break awkwardly without balance
This is a long headline that might break awkwardly without balance
.unbalanced {
text-wrap: wrap;
}
.balanced {
text-wrap: balance;
}
20. field-sizing: content
Allows form inputs and textareas to automatically size themselves based on their content, eliminating the need for JavaScript-based auto-resize solutions.
.auto-resize-textarea {
field-sizing: content;
min-height: 3rem;
max-height: 15rem;
width: 100%;
max-width: 25rem;
}