::scroll-button()

Experimental: This is an experimental technology
Check the Browser compatibility table carefully before using this in production.

The ::scroll-button() CSS pseudo-element represents a button for controlling the scrolling of a scroll container. They are generated on scroll containers when their content value is not none. The direction of the scrolling is determined by the parameter value.

Syntax

css
::scroll-button() {
  /* ... */
}

Parameters

A value representing which direction of scroll button you want to select. The following values are available:

*

Selects all the originating element's scroll buttons, allowing styles to be applied to each of them in a single rule.

down

Selects the button that will scroll the content downward.

left

Selects the button that will scroll the content left.

Selects the button that will scroll the content right.

up

Selects the button that will scroll the content upward.

block-end

Selects the button that will scroll the content in the block-end direction.

block-start

Selects the button that will scroll the content in the block-start direction.

inline-end

Selects the button that will scroll the content in the inline-end direction.

inline-start

Selects the button that will scroll the content in the inline-start direction.

The specification also defines two other values — next and prev — but these are not currently supported in any browser.

Description

The ::scroll-button() pseudo-elements are generated inside a scroll container only when their content properties are set to a value other than none. They are generated as siblings of the scroll container's child DOM elements, immediately preceding them and any ::scroll-marker-group generated on the container.

You can generate up to four scroll buttons per scroll container, which will scroll the content towards the start and end of the block and inline axes. The selector's argument specifies which scrolling direction is selected. You can also specify a value of * to target all of the ::scroll-button() pseudo-elements, providing styles to all the buttons in a single rule.

The generated buttons behave just like regular

Examples

See Creating CSS carousels for more carousel examples.

Creating scroll buttons

In this example, we demonstrate how to create scroll buttons on a CSS carousel.

HTML

We have a basic HTML

    list with several
  • list items.

    html
    • Item 1
    • Item 2
    • Item 3
    • Item 4
    • Item 5
    • Item 6
    • Item 7
    • Item 8

    CSS

    We convert our

      into a carousel by setting the display to flex, creating a single, non-wrapping row of
    • elements. The overflow-x property is set to auto, meaning if the items overflow their container on the x-axis, the content will scroll horizontally. We then convert the
        into a scroll-snap container, ensuring that items always snap into place when the container is scrolled with a scroll-snap-type value of mandatory.

        css
        ul {
          display: flex;
          gap: 4vw;
          padding-left: 0;
          overflow-x: auto;
          overscroll-behavior-x: contain;
          scroll-snap-type: x mandatory;
        }
        

        Next, we style the

      • elements, using the flex property to make them 100% of the width of the container. The scroll-snap-align value of start causes the left-hand side of the left-most visible item to snap to the left edge of the container when the content is scrolled.

        css
        li {
          list-style-type: none;
          background-color: #eee;
          flex: 0 0 100%;
          height: 100px;
          padding-top: 20px;
          scroll-snap-align: start;
          text-align: center;
        }
        
        Creating the scroll buttons

        First, all scroll buttons are targeted with some rudimentary styles, as well as styling based on different states. It is important to set :focus styles for keyboard users. Also, as scroll buttons are automatically set to disabled when no more scrolling can occur in that direction, we use the :disabled pseudo-class to target this state.

        css
        ul::scroll-button(*) {
          border: 0;
          font-size: 2rem;
          background: none;
          color: rgb(0 0 0 / 0.7);
          cursor: pointer;
        }
        
        ul::scroll-button(*):hover,
        ul::scroll-button(*):focus {
          color: rgb(0 0 0 / 1);
        }
        
        ul::scroll-button(*):active {
          translate: 1px 1px;
        }
        
        ul::scroll-button(*):disabled {
          color: rgb(0 0 0 / 0.2);
          cursor: unset;
        }
        

        Note: We also set a cursor value of pointer on the scroll buttons to make it more obvious that they can be interacted with (an improvement for both general UX and cognitive accessibility), unsetting it when the scroll buttons are :disabled.

        Next, an appropriate icon is set on the left and right scroll buttons via the content property, which is also what causes the scroll buttons to be generated:

        css
        ul::scroll-button(left) {
          content: "◄";
        }
        
        ul::scroll-button(right) {
          content: "►";
        }
        

        We don't need to set alternative text for the icons on the content as the browser takes care of providing appropriate accessible names automatically.

        Result

        Note how the scroll buttons are created at the bottom left on the carousel. Try pressing them to see how they cause the content to be scrolled.

Positioning the scroll buttons

The previous example works, but the buttons are not ideally placed. In this section, we will add some CSS to position them using anchor positioning.

CSS

First of all, a reference anchor-name is set on the

    to define it as a named anchor. Next, each scroll button has its position set to absolute and its position-anchor property set to the list's anchor-name, to associate the two together.

    css
    ul {
      anchor-name: --myCarousel;
    }
    
    ul::scroll-button(*) {
      position: absolute;
      position-anchor: --myCarousel;
    }
    

    To actually position each scroll button, we first set an align-self value of anchor-center on both of them, to center them vertically on the carousel:

    css
    ul::scroll-button(*) {
      align-self: anchor-center;
    }
    

    We then set values on their inset properties to handle the horizontal positioning. We use anchor() functions to position the specified sides of the buttons relative to the sides of the carousel. In each case, the calc() function is used to add some space between the button edge and the carousel edge. For example, the right-hand edge of the left scroll button is positioned 45 pixels to the right of the carousel's left-hand edge.

    css
    ul::scroll-button(left) {
      right: calc(anchor(left) - 45px);
    }
    
    ul::scroll-button(right) {
      left: calc(anchor(right) - 45px);
    }
    

    Result

Specifications

Specification
CSS Overflow Module Level 5
# scroll-buttons

Browser compatibility

See also