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 item
subgrid item
        
        .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).

Item 1
Item 2
Item 3
Item 4
Item 5
        
        .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.

        
        :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.

CSS Corner Shape
        
        .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.

Triangle Clip
        
        #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.

        
        .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.

Conditional CSS with if()
Feature-based Color
        
        .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.

Custom Function Box
Theme Box
        
        @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.

I'm anchored to the button!
        
        .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;
        }