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.
Similar Code Snippets:
I code and create web elements for amazing people around the world. I like work with new people. New people new Experiences.
I truly enjoy what I’m doing, which makes me more passionate about web development and coding. I am always ready to do challenging tasks whether it is about creating a custom CMS from scratch or customizing an existing system.