Horizontal and Vertical Scroll Indicator in CSS

Horizontal and Vertical Scroll Indicator in CSS
Code Snippet:Dynamic Scroll Indicators with Scroll Driven Animations [Polyfilled too!]
Author: Jhey
Published: January 11, 2024
Last Updated: January 22, 2024
Downloads: 858
License: MIT
Edit Code online: View on CodePen
Read More

Scroll indicators are visual elements commonly used in web design to enhance the user experience when scrolling through content. This CSS code implements a scroll indicator for both horizontal and vertical orientations. It enhances the user experience by providing visual cues for scrolling directions.

The code utilizes CSS to create sticky indicators that appear and disappear as you scroll. It helps users navigate through content more efficiently.

How to Create Horizontal And Vertical Scroll Indicator in CSS

1. First of all, load the Normalize CSS by adding the following CDN link into the head tag of your HTML document. (Optional)

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">

2. Create the HTML structure for your scrollable content as follows:

<div class="controls">
  <label for="vertical">Vertical</label>
  <input type="radio" checked name="orientation" id="vertical"/>
  <label for="horizontal">Horizontal</label>
  <input type="radio" name="orientation" id="horizontal"/>
</div>
<section class="scroller">
  <article>
    <div class="indicator indicator--top">
      <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
        <path stroke-linecap="round" stroke-linejoin="round" d="M4.5 15.75l7.5-7.5 7.5 7.5" />
      </svg>
    </div>
   <!-- Your scrollable content goes here -->
<div class="indicator indicator--bottom">
      <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
        <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 8.25l-7.5 7.5-7.5-7.5" />
      </svg>
  </article>
  </div>
</section>

3. Now, add the following CSS styles to your project to design the scrollable boxes. You can modify the CSS rules to get the desired result.

* {
  box-sizing: border-box;
}

body {
  display: grid;
  place-items: center;
  min-height: 100vh;
  background: hsl(0 0% 80%);
  accent-color: hsl(250 90% 70%);
}

.controls {
  position: absolute;
  top: 1rem;
  right: 1rem;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0 1rem;
}

.scroller {
  width: 50ch;
  height: 80vh;
  overflow: auto;
  position: relative;
  background: canvas;
  padding: 0 1rem;
  resize: both;
  color: hsl(0 0% 18%);
  border-radius: 0.5rem;
  box-shadow: 0 0 2rem -1rem hsl(0 0% 10% / 0.75);
}

svg {
  width: 24px;
}

.indicator {
  position: sticky;
  display: flex;
  align-items: center;
  justify-content: center;
  background: canvas;
  height: 48px;
  /* Scroll stuff */
  --scroll-buffer: 2rem;
  opacity: 0;
  -webkit-animation: reveal both linear;
          animation: reveal both linear;
  animation-timeline: scroll(nearest);
  animation-range: 0 var(--scroll-buffer);
}

.indicator--top {
  top: 0;
  border-bottom: 1px solid hsl(0 0% 0% / 0.5);
}

:root:has(#horizontal:checked) article {
  gap: 2rem;
  display: flex;
  align-items: center;
  height: 100%;
  width: 800vw;
}

:root:has(#horizontal:checked) article p {
  flex: 1 0 100cqi;
  display: grid;
  place-items: center;
  padding: 4rem;
  scroll-snap-align: center;
}

:root:has(#horizontal:checked) .scroller {
  padding: 1rem 0;
  overflow-x: auto;
  -ms-scroll-snap-type: x mandatory;
      scroll-snap-type: x mandatory;
}

:root:has(#horizontal:checked) .indicator--bottom svg,
:root:has(#horizontal:checked) .indicator--top svg {
  rotate: -90deg;
}

:root:has(#horizontal:checked) .indicator {
  height: 100%;
  width: 2rem;
  position: absolute;
  animation-timeline: --article;
  -webkit-clip-path: inset(2rem 0 2rem 0);
          clip-path: inset(2rem 0 2rem 0);
}

:root:has(#horizontal:checked) .indicator--top {
  border-bottom: none;
  align-self: flex-start;
  left: 0;
  border-right: 1px solid hsl(0 0% 0% / 0.5);
}


:root:has(#horizontal:checked) .scroller {
  container-type: inline-size;
}

.indicator--bottom {
  bottom: 0;
  border-top: 1px solid hsl(0 0% 0% / 0.5);
  animation-range: calc(100% - var(--scroll-buffer)) 100%;
  animation-direction: reverse;
}

:root:has(#horizontal:checked) .indicator--bottom {
  right: 0;
  bottom: unset;
  border-left: 1px solid hsl(0 0% 0% / 0.5);
  border-top: none;
}

:root:has(#horizontal:checked) article {
  scroll-timeline: --article;
  scroll-timeline-axis: inline;
  width: 100%;
  overflow: auto;
  -ms-scroll-snap-type: x mandatory;
      scroll-snap-type: x mandatory;
}

@-webkit-keyframes reveal {
  to {
    opacity: 1;
  }
}

@keyframes reveal {
  to {
    opacity: 1;
  }
}

4. To make the scroll indicators work based on the user’s scrolling direction, you’ll need to use Scroll Timeline JS. Add the following CDN link (just before closing the body tag) to toggle the visibility of the vertical and horizontal indicators:

<script src='https://flackr.github.io/scroll-timeline/dist/scroll-timeline.js'></script>

That’s all! hopefully, you have successfully created horizontal and vertical scroll indicators. If you have any questions or suggestions, feel free to comment below.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

About CodeHim

Free Web Design Code & Scripts - CodeHim is one of the BEST developer websites that provide web designers and developers with a simple way to preview and download a variety of free code & scripts. All codes published on CodeHim are open source, distributed under OSD-compliant license which grants all the rights to use, study, change and share the software in modified and unmodified form. Before publishing, we test and review each code snippet to avoid errors, but we cannot warrant the full correctness of all content. All trademarks, trade names, logos, and icons are the property of their respective owners... find out more...

Please Rel0ad/PressF5 this page if you can't click the download/preview link

X