Chrome 150 beta ships 12 new CSS features — from system accent colors and polygon rounding to the native text-fit property and animatable zoom. Here's everything you need to start using them today.
Chrome 150 beta landed on June 3, 2026, and it's a significant release for
CSS developers. With 12 new or enhanced CSS capabilities — ranging from system-level accent
color integration to a native text-fit property that eliminates JavaScript font-scaling
libraries — this release continues the trend of browsers absorbing functionality that previously
required third-party code.
These features align with the trajectory we saw at Google I/O 2026, where the web platform team emphasized making browsers more capable out of the box. Chrome 150 delivers on that promise with practical, production-ready CSS enhancements.
In this overview, I'll walk through each feature with code examples, browser support notes, and practical tips for adoption. Let's dive in.
Chrome 150 adds AccentColor and AccentColorText to the CSS system colors
palette. These match the operating system's native accent color and its associated contrast text
color — the same colors used by native checkbox highlights, radio button fills, and switch toggles.
/* Custom checkbox that matches the OS accent color */
.custom-checkbox {
appearance: none;
width: 20px;
height: 20px;
border: 2px solid AccentColor;
border-radius: 4px;
transition: background 0.2s;
}
.custom-checkbox:checked {
background: AccentColor;
border-color: AccentColor;
}
.custom-checkbox:checked::after {
content: "✓";
color: AccentColorText;
display: block;
text-align: center;
line-height: 16px;
}
These colors adapt automatically to the user's OS theme — on macOS, they follow the accent color from System Settings; on Windows, they match the Windows accent color. This is a clean way to make custom UI elements feel native without hardcoding brand colors.
The polygon() CSS function now accepts an optional rounding parameter. This lets you
create clipped shapes with rounded corners directly in CSS, without needing SVG clip-paths or
layered border-radius tricks.
/* Traditional polygon: sharp corners */
.element-sharp {
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
}
/* Chrome 150: polygon with rounded corners */
.element-rounded {
clip-path: polygon(0 0 round 12px, 100% 0 round 12px,
100% 100% round 12px, 0 100% round 12px);
}
/* Asymmetric rounding */
.element-asymmetric {
clip-path: polygon(0 0 round 20px 0, 100% 0 round 0 20px,
100% 100% round 20px 0, 0 100% round 0 20px);
}
/* Star shape with rounding */
.star-rounded {
clip-path: polygon(50% 0%, 61% 35%, 98% 35%,
68% 57%, 79% 91%, 50% 70%,
21% 91%, 32% 57%, 2% 35%,
39% 35% round 4px);
}
Each vertex in the polygon() can specify its own rounding radius, giving you precise
control over the final shape. This is particularly useful for creating organic-looking cards,
badges, and decorative elements.
The zoom property is now animatable via CSS transitions and animations. Previously,
zoom was a binary property that jumped instantly between values. Chrome 150 makes it
interpolatable, opening up smooth zoom effects in pure CSS.
/* Smooth zoom on hover */
.image-card {
overflow: hidden;
border-radius: 12px;
}
.image-card img {
transition: zoom 0.3s ease;
zoom: 1;
}
.image-card:hover img {
zoom: 1.2;
}
/* CSS animation with zoom */
@keyframes zoom-pulse {
0% { zoom: 1; }
50% { zoom: 1.15; }
100% { zoom: 1; }
}
.pulsing-element {
animation: zoom-pulse 2s ease-in-out infinite;
}
/* Interactive gallery grid */
.gallery-item {
transition: zoom 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
zoom: 1;
cursor: pointer;
}
.gallery-item:focus-visible,
.gallery-item:hover {
zoom: 1.5;
z-index: 10;
}
Note that zoom is not the same as transform: scale() — zoom affects
layout and triggers repaints, while transform only affects rendering. For gallery hover effects
and interactive elements, zoom's layout impact can be desirable (it pushes surrounding content
to make room for the zoomed element).
Chrome 150 introduces CSS URL request modifiers that let you attach crossorigin,
integrity, and referrerpolicy attributes directly to CSS resource URLs.
This is a major improvement for loading external fonts, images, and stylesheets with proper
security headers.
/* Cross-origin font loading */
@font-face {
font-family: 'Custom Font';
src: url('https://cdn.example.com/fonts/custom.woff2')
crossorigin("anonymous");
}
/* Subresource integrity for background images */
.element {
background-image: url('https://cdn.example.com/bg.webp'
integrity("sha384-abc123..."));
}
/* Referrer policy on imported stylesheets */
@import url('https://analytics.example.com/widgets.css')
referrerpolicy("no-referrer");
/* Combined modifiers */
@font-face {
font-family: 'Secure Font';
src: url('https://fonts.example.com/secure.woff2')
crossorigin("use-credentials")
integrity("sha384-def456...")
referrerpolicy("strict-origin-when-cross-origin");
}
These modifiers bring CSS resource loading in line with the security controls available in HTML
and JavaScript. They're especially valuable for sites using a CDN for fonts or images who need
crossorigin="anonymous" to enable proper caching and CORS handling.
The text-fit property is perhaps the most anticipated CSS feature in Chrome 150.
It provides a native way to scale font size so text fills its container — no JavaScript
libraries like FitText.js required.
/* Grow: scale text up until it fills the container */
.headline-grow {
text-fit: grow;
font-size: 1rem; /* starting size */
}
/* Shrink: scale text down when it overflows */
.card-title {
text-fit: shrink;
font-size: 1.5rem;
}
/* Per-line: fit each line individually (good for headlines) */
.banner-title {
text-fit: per-line;
font-size: 2rem;
}
/* Consistent: uniform scaling across all lines */
.hero-text {
text-fit: consistent;
font-size: 3rem;
}
/* With min/max constraints */
.safe-headline {
text-fit: shrink;
font-size: 1.5rem;
min-font-size: 1rem; /* proposed companion property */
max-font-size: 3rem;
}
The four modes cover different use cases:
Chrome 150 adds border-area as a new value for background-clip. This
extends the background image or color to render behind the element's border — not just behind
the padding box, but underneath the border itself.
/* Background extends behind the border */
.border-bg-card {
background: linear-gradient(135deg, #667eea, #764ba2);
background-clip: border-area;
border: 4px solid transparent;
border-radius: 12px;
padding: 1.5rem;
}
/* Combined with border-image for rich effects */
.gradient-border {
background: linear-gradient(white, white) padding-box,
linear-gradient(135deg, #667eea, #764ba2) border-area;
border: 4px solid transparent;
background-clip: padding-box, border-area;
border-radius: 12px;
padding: 1rem;
}
/* Faux border glow effect */
.glow-card {
background: #1a1a2e padding-box,
radial-gradient(ellipse at center, #667eea, transparent) border-area;
background-clip: padding-box, border-area;
border: 8px solid transparent;
border-radius: 16px;
}
This eliminates many workarounds where developers used extra wrapper divs with overflow hidden
to create background-under-border effects. Combined with border-image, it enables
complex layered border styles with a single element.
Chrome 150 implements the image() function with color fallback support. The
image(<color>) syntax creates a gradient-like image from a solid color,
which can be used anywhere an image is expected in CSS.
/* Fallback color image when the actual image fails to load */
.fallback-safe {
background-image: image('hero.webp', #667eea);
}
/* Pure color image as a gradient substitute */
.color-bg {
background-image: image(#0f766e);
}
/* With multiple fallbacks */
.robust-background {
background-image: image('hero.avif', 'hero.webp', #667eea);
}
/* In list-style for custom bullets */
li {
list-style-image: image(#667eea);
list-style-type: square;
}
The image() function accepts multiple fallbacks — if the first source fails to load,
it moves to the next, with a solid color as the final fallback. This is cleaner than stacking
multiple background-image declarations and gives you reliable color fallbacks for
image-dependent designs.
The light-dark() function, previously limited to color values, now works with image
values in Chrome 150. This lets you specify different background images, gradients, or patterns
for light and dark mode in a single declaration.
/* Different backgrounds for light/dark mode */
.adaptive-background {
background-image: light-dark(
linear-gradient(135deg, #f0f9ff, #e0f2fe),
linear-gradient(135deg, #1e293b, #0f172a)
);
}
/* Different images for light/dark theme */
.hero-section {
background-image: light-dark(
url('hero-light.webp'),
url('hero-dark.webp')
);
}
/* Pattern fallbacks with light-dark */
.card-pattern {
background-image: light-dark(
image('dots-light.svg', #f0f0f0),
image('dots-dark.svg', #1a1a2e)
);
}
This simplifies theme management significantly — instead of duplicating entire CSS blocks inside
@media (prefers-color-scheme: dark) queries, you can express light/dark variants
inline. It works with any CSS image type: gradients, url(), image(),
and linear-gradient().
Chrome 150 enhances relative color syntax to support alpha channel manipulation. You can now extract and modify the alpha component of any color using relative color syntax, making it trivial to create opacity variants of your design tokens.
/* Create a semi-transparent variant of a CSS variable */
:root {
--primary: #0f766e;
}
.semitransparent-bg {
background: rgb(from var(--primary) r g b / 0.5);
}
/* Modify alpha in any color space */
.faded-accent {
color: hsl(from var(--primary) h s l / 0.3);
}
/* Lighten by reducing alpha over a white background */
.light-overlay {
background: oklch(from var(--primary) l c h / 0.15);
}
/* Extract and use the alpha channel */
.alpha-only {
opacity: alpha(from var(--primary));
}
This is particularly powerful for design systems where you need consistent color variants with
different opacity levels. Instead of manually computing rgba() equivalents, you can derive them
directly from your CSS custom properties. The alpha() extractor makes it easy to
work with existing colors programmatically.
Chrome 150 adds new pseudo-classes for media elements (<video> and
<audio>) that let you style elements based on their playback state:
:playing, :paused, and :seeking.
/* Style controls differently when media is playing */
video:playing + .custom-controls .play-btn {
background: #dc2626; /* red = stop */
}
video:paused + .custom-controls .play-btn {
background: #16a34a; /* green = play */
}
/* Visual indicator during seeking */
video:seeking {
cursor: wait;
}
video:seeking + .time-display {
color: #f59e0b;
}
/* Auto-hide controls during playback */
.player-controls {
opacity: 1;
transition: opacity 0.3s;
}
video:playing ~ .player-controls {
opacity: 0;
}
video:playing:hover ~ .player-controls {
opacity: 1;
}
These pseudo-classes eliminate the need for JavaScript event listeners to track playback state for UI styling. Combined with CSS sibling selectors, you can build fully reactive media players where the control appearance responds to playback state without any JS.
A new balance value for flex-wrap that distributes flex items across
multiple lines in a visually balanced way — minimizing the ragged edge that occurs when items
don't partition evenly.
/* Standard flex-wrap: items flow left-to-right */
.standard-grid {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
/* Balanced wrap: minimizes ragged edges */
.balanced-grid {
display: flex;
flex-wrap: balance;
gap: 1rem;
}
/* Before: 7 items in a 3-column layout
[A] [B] [C]
[D] [E] [F]
[G]
→ last row has one lonely item */
/* After with flex-wrap: balance:
[A] [B] [C]
[D] [E]
[F] [G]
→ items redistributed for visual balance */
/* Practical: tag cloud with balanced rows */
.tag-cloud {
display: flex;
flex-wrap: balance;
gap: 0.5rem;
justify-content: center;
}
.tag-cloud .tag {
padding: 0.25rem 0.75rem;
background: var(--surface-2);
border-radius: 4px;
font-size: 0.85rem;
}
This is a subtle but impactful feature for layouts with a variable number of items — tag clouds, category filters, navigation menus, and card grids. Instead of the default left-to-right fill that leaves unsightly gaps on the last row, balanced wrap redistributes items for a more polished appearance.
Chrome 150 adds chain as a new value for overscroll-behavior. Unlike
contain (which prevents scroll chaining entirely) or the default auto
(which chains unconditionally), chain lets scroll momentum propagate from a nested
scrollable area to its parent — but only when the nested area has reached its scroll boundary.
/* Nested scrollable sidebar that chains to the page */
.sidebar {
overscroll-behavior: chain;
overflow-y: auto;
height: 100%;
}
/* Image gallery with smooth page transitions */
.image-viewport {
overscroll-behavior: chain;
overflow-x: auto;
scroll-snap-type: x mandatory;
}
/* Modals: contain internal scroll, no chain to body */
.modal-content {
overscroll-behavior: contain;
overflow-y: auto;
}
/* Horizontal carousel that chains to vertical page scroll */
.horizontal-carousel {
overscroll-behavior-x: chain;
overscroll-behavior-y: auto;
overflow-x: auto;
scroll-snap-type: x mandatory;
display: flex;
gap: 1rem;
}
The chain value solves a long-standing UX problem: nested scrollable regions that
feel unnatural because they either trap all scroll momentum (contain) or steal it
from the parent (auto). With chain, scrolling a sidebar to its bottom
then continuing to scroll naturally transitions to scrolling the page — the most intuitive
behavior for users.
Chrome 150 beta features are available now for testing via Chrome Beta and Chrome Canary. The
stable release is expected in approximately 4 weeks (early July 2026). As with all new CSS
features, use the @supports rule to provide graceful fallbacks:
/* Progressive enhancement pattern */
@supports (text-fit: shrink) {
.card-title {
text-fit: shrink;
}
}
@supports not (text-fit: shrink) {
.card-title {
font-size: clamp(1rem, 2.5vw, 1.5rem);
}
}
/* For zoom animation support */
@supports (transition: zoom 0.3s) {
.zoomable {
transition: zoom 0.3s ease;
}
}
For a deeper look at the broader web platform trends that Chrome 150 builds on, check out my Google I/O 2026 Day 2 recap and the Google I/O 2026 for Web Developers overview covering on-device AI, scroll-driven animations, and more.
I offer web development services with modern CSS
Chrome 150 beta is available for testing now. The features covered here will roll out to stable in approximately 4-6 weeks, and cross-browser support will follow as other engines implement the specifications.
These 12 CSS features represent a meaningful step forward for the web platform. The trend is clear: browsers are becoming more capable design tools, reducing the need for JavaScript libraries and enabling developers to write cleaner, more declarative code. Building a web application and want to know which of these new CSS features makes sense for your project? As a full-stack developer with 20+ years of experience, I can help you navigate the landscape and build with the right tools. Get in touch for a free consultation.
I build modern web applications using the latest platform features. Let's discuss your project and find the right approach — free of charge.