Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      CodeSOD: A Unique Way to Primary Key

      July 22, 2025

      BrowserStack launches Figma plugin for detecting accessibility issues in design phase

      July 22, 2025

      Parasoft brings agentic AI to service virtualization in latest release

      July 22, 2025

      Node.js vs. Python for Backend: 7 Reasons C-Level Leaders Choose Node.js Talent

      July 21, 2025

      The best CRM software with email marketing in 2025: Expert tested and reviewed

      July 22, 2025

      This multi-port car charger can power 4 gadgets at once – and it’s surprisingly cheap

      July 22, 2025

      I’m a wearables editor and here are the 7 Pixel Watch 4 rumors I’m most curious about

      July 22, 2025

      8 ways I quickly leveled up my Linux skills – and you can too

      July 22, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      The Intersection of Agile and Accessibility – A Series on Designing for Everyone

      July 22, 2025
      Recent

      The Intersection of Agile and Accessibility – A Series on Designing for Everyone

      July 22, 2025

      Zero Trust & Cybersecurity Mesh: Your Org’s Survival Guide

      July 22, 2025

      Execute Ping Commands and Get Back Structured Data in PHP

      July 22, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured

      A Tomb Raider composer has been jailed — His legacy overshadowed by $75k+ in loan fraud

      July 22, 2025
      Recent

      A Tomb Raider composer has been jailed — His legacy overshadowed by $75k+ in loan fraud

      July 22, 2025

      “I don’t think I changed his mind” — NVIDIA CEO comments on H20 AI GPU sales resuming in China following a meeting with President Trump

      July 22, 2025

      Galaxy Z Fold 7 review: Six years later — Samsung finally cracks the foldable code

      July 22, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»News & Updates»CSS Carousels

    CSS Carousels

    April 9, 2025
    CSS Carousels

    The CSS Overflow Module Level 5 specification defines a couple of new features that are designed for creating carousel UI patterns:

    • Scroll Buttons: Buttons that the browser provides, as in literal <button> elements, that scroll the carousel content 85% of the area when clicked.
    • Scroll Markers: The little dots that act as anchored links, as in literal <a> elements that scroll to a specific carousel item when clicked.

    Chrome has prototyped these features and released them in Chrome 135. Adam Argyle has a wonderful explainer over at the Chrome Developer blog. Kevin Powell has an equally wonderful video where he follows the explainer. This post is me taking notes from them.

    First, some markup:

    <ul class="carousel">
      <li>...</li>
      <li>...</li>
      <li>...</li>
      <li>...</li>
      <li>...</li>
    </ul>

    First, let’s set these up in a CSS auto grid that displays the list items in a single line:

    .carousel {
      display: grid;
      grid-auto-flow: column;
    }

    We can tailor this so that each list item takes up a specific amount of space, say 40%, and insert a gap between them:

    .carousel {
      display: grid;
      grid-auto-flow: column;
      grid-auto-columns: 40%;
      gap: 2rem;
    }

    This gives us a nice scrolling area to advance through the list items by moving left and right. We can use CSS Scroll Snapping to ensure that scrolling stops on each item in the center rather than scrolling right past them.

    .carousel {
      display: grid;
      grid-auto-flow: column;
      grid-auto-columns: 40%;
      gap: 2rem;
    
      scroll-snap-type: x mandatory;
    
      > li {
        scroll-snap-align: center;
      }
    }

    Kevin adds a little more flourish to the .carousel so that it is easier to see what’s going on. Specifically, he adds a border to the entire thing as well as padding for internal spacing.

    So far, what we have is a super simple slider of sorts where we can either scroll through items horizontally or click the left and right arrows in the scroller.

    We can add scroll buttons to the mix. We get two buttons, one to navigate one direction and one to navigate the other direction, which in this case is left and right, respectively. As you might expect, we get two new pseudo-elements for enabling and styling those buttons:

    • ::scroll-button(left)
    • ::scroll-button(right)

    Interestingly enough, if you crack open DevTools and inspect the scroll buttons, they are actually exposed with logical terms instead, ::scroll-button(inline-start) and ::scroll-button(inline-end).

    DevTools with an arrow pointing at the two scroll buttons in the HTML showing them with logical naming.

    And both of those support the CSS content property, which we use to insert a label into the buttons. Let’s keep things simple and stick with “Left” and “Right” as our labels for now:

    .carousel::scroll-button(left) {
      content: "Left";
    }
    .carousel::scroll-button(right) {
      content: "Right";
    }

    Now we have two buttons above the carousel. Clicking them either advances the carousel left or right by 85%. Why 85%? I don’t know. And neither does Kevin. That’s just what it says in the specification. I’m sure there’s a good reason for it and we’ll get more light shed on it at some point.

    But clicking the buttons in this specific example will advance the scroll only one list item at a time because we’ve set scroll snapping on it to stop at each item. So, even though the buttons want to advance by 85% of the scrolling area, we’re telling it to stop at each item.

    Remember, this is only supported in Chrome at the time of writing:

    CodePen Embed Fallback

    We can select both buttons together in CSS, like this:

    .carousel::scroll-button(left),
    .carousel::scroll-button(right) {
      /* Styles */
    }

    Or we can use the Universal Selector:

    .carousel::scroll-button(*) {
      /* Styles */
    }

    And we can even use newer CSS Anchor Positioning to set the left button on the carousel’s left side and the right button on the carousel’s right side:

    .carousel {
      /* ... */
      anchor-name: --carousel; /* define the anchor */
    }
    
    .carousel::scroll-button(*) {
      position: fixed; /* set containment on the target */
      position-anchor: --carousel; /* set the anchor */
    }
    
    .carousel::scroll-button(left) {
      content: "Left";
      position-area: center left;
    }
    .carousel::scroll-button(right) {
      content: "Right";
      position-area: center right;
    }

    Notice what happens when navigating all the way to the left or right of the carousel. The buttons are disabled, indicating that you have reached the end of the scrolling area. Super neat! That’s something that is normally in JavaScript territory, but we’re getting it for free.

    CodePen Embed Fallback

    Let’s work on the scroll markers, or those little dots that sit below the carousel’s content. Each one is an <a> element anchored to a specific list item in the carousel so that, when clicked, you get scrolled directly to that item.

    We get a new pseudo-element for the entire group of markers called ::scroll-marker-group that we can use to style and position the container. In this case, let’s set Flexbox on the group so that we can display them on a single line and place gaps between them in the center of the carousel’s inline size:

    .carousel::scroll-marker-group {
      display: flex;
      justify-content: center;
      gap: 1rem;
    }

    We also get a new scroll-marker-group property that lets us position the group either above (before) the carousel or below (after) it:

    .carousel {
      /* ... */
      scroll-marker-group: after; /* displayed below the content */
    }

    We can style the markers themselves with the new ::scroll-marker pseudo-element:

    .carousel {
      /* ... */
    
      > li::scroll-marker {
        content: "";
        aspect-ratio: 1;
        border: 2px solid CanvasText;
        border-radius: 100%;
        width: 20px;
      }
    }

    When clicking on a marker, it becomes the “active” item of the bunch, and we get to select and style it with the :target-current pseudo-class:

    li::scroll-marker:target-current {
      background: CanvasText;
    }

    Take a moment to click around the markers. Then take a moment using your keyboard and appreciate that we can all of the benefits of focus states as well as the ability to cycle through the carousel items when reaching the end of the markers. It’s amazing what we’re getting for free in terms of user experience and accessibility.

    CodePen Embed Fallback

    We can further style the markers when they are hovered or in focus:

    li::scroll-marker:hover,
    li::scroll-marker:focus-visible {
      background: LinkText;
    }

    And we can “animate” the scrolling effect by setting scroll-behavior: smooth on the scroll snapping. Adam smartly applies it when the user’s motion preferences allow it:

    .carousel {
      /* ... */
    
      @media (prefers-reduced-motion: no-preference) {
        scroll-behavior: smooth;
      }
    }

    Buuuuut that seems to break scroll snapping a bit because the scroll buttons are attempting to slide things over by 85% of the scrolling space. Kevin had to fiddle with his grid-auto-columns sizing to get things just right, but showed how Adam’s example took a different sizing approach. It’s a matter of fussing with things to get them just right.

    CodePen Embed Fallback

    This is just a super early look at CSS Carousels. Remember that this is only supported in Chrome 135+ at the time I’m writing this, and it’s purely experimental. So, play around with it, get familiar with the concepts, and then be open-minded to changes in the future as the CSS Overflow Level 5 specification is updated and other browsers begin building support.


    CSS Carousels originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    Source: Read More 

    Facebook Twitter Reddit Email Copy Link
    Previous Article13 Free and Open Source Simple GUI Based Linux Text Editors
    Next Article Spring Boot for Automation Testing: A Tester’s Guide

    Related Posts

    News & Updates

    The best CRM software with email marketing in 2025: Expert tested and reviewed

    July 22, 2025
    News & Updates

    This multi-port car charger can power 4 gadgets at once – and it’s surprisingly cheap

    July 22, 2025
    Leave A Reply Cancel Reply

    For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.

    Continue Reading

    Convert Special Characters to ASCII with Laravel’s Str::transliterate Method

    Development

    Celebrating Perficient’s Third Databricks Champion

    Development

    Why Good Design Matters — Even in Instagram Ads

    Web Development

    SonicWall SSLVPN Vulnerability Let Remote Attackers Crash Firewall Appliances

    Security

    Highlights

    CVE-2025-3637 – Moodle CSRF Information Disclosure

    April 25, 2025

    CVE ID : CVE-2025-3637

    Published : April 25, 2025, 3:15 p.m. | 3 hours, 46 minutes ago

    Description : A security vulnerability was found in Moodle where confidential information that prevents cross-site request forgery (CSRF) attacks was shared publicly through the site’s URL. This vulnerability occurred specifically on two types of pages within the mod_data module: edit and delete pages.

    Severity: 3.1 | LOW

    Visit the link for more details, such as CVSS details, affected products, timeline, and more…

    How to Switch Screens on Windows: The Complete Guide to Multi-Monitor Productivity 

    June 18, 2025

    Effectively use prompt caching on Amazon Bedrock

    April 7, 2025

    CVE-2025-23395 – Screen Root Privilege Escalation Vulnerability

    May 26, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.