npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@arc-lang/arc-sliders

v0.1.0

Published

CSS scroll-snap carousel, before/after comparison slider, and enhanced infinite marquee. CSS-first, ~700B optional JS, zero dependencies.

Readme

arc-sliders

components JS size dependencies license Part of Arc

Five CSS-first UI slider components. CSS drives everything — the optional JS (~1KB total) adds interactivity only where CSS alone cannot.

Part of Arc — the zero-dependency web framework.

Install

npm install arc-sliders

CDN:

<link rel="stylesheet" href="https://unpkg.com/arc-sliders/index.css">

Components

Carousel

CSS scroll-snap carousel. Works without JS — users can swipe and scroll natively. Add js/carousel.js for prev/next buttons and dot sync.

<div class="carousel" style="--slides-visible: 2; --carousel-gap: 16px;">
  <div class="carousel__track">
    <div class="carousel__slide">Slide 1</div>
    <div class="carousel__slide">Slide 2</div>
    <div class="carousel__slide">Slide 3</div>
  </div>
  <button class="carousel__prev">&#8592;</button>
  <button class="carousel__next">&#8594;</button>
  <div class="carousel__dots">
    <button class="carousel__dot is-active"></button>
    <button class="carousel__dot"></button>
    <button class="carousel__dot"></button>
  </div>
</div>
<script src="https://unpkg.com/arc-sliders/js/carousel.js"></script>

| Modifier | Effect | |----------|--------| | .carousel--peek | Reveals edge of next slide (set --carousel-peek) | | .carousel--fade | Fades track edges with mask-image | | .carousel--vertical | Vertical scroll-snap (set --carousel-height) | | .carousel--crossfade | Crossfade between slides (opacity transition, no scroll) | | .carousel--loop | True infinite loop — no content duplication needed |

Infinite loop: Add .carousel--loop — JS clones the minimum number of edge slides needed to fill one viewport, then uses scrollend to silently reset position when the user reaches a clone. Requires no content duplication in HTML. Requires scrollend event support (Chrome 114+, Firefox 109+, Safari 17.4+).

Autoplay: Add data-autoplay="3000" for 3s auto-advance. Pauses on hover/focus, skipped if prefers-reduced-motion is active. Works with .carousel--loop.

<div class="carousel" data-autoplay="4000">...</div>

| CSS property | Default | Description | |---|---|---| | --slides-visible | 1 | How many slides show at once | | --carousel-gap | 0px | Gap between slides | | --carousel-peek | 0px | How much of the next slide to reveal | | --carousel-height | 400px | Height for vertical and crossfade carousels | | --carousel-crossfade-duration | 0.5s | Transition duration for .carousel--crossfade | | --carousel-dot-color | rgba(0,0,0,0.25) | Inactive dot color | | --carousel-dot-active | #000 | Active dot color |


Comparison

Before/after image reveal. Drag the handle or use arrow keys to compare. JS sets --comparison-split; CSS drives the entire visual via clip-path.

<div class="comparison" style="height: 400px;">
  <img class="comparison__before" src="before.jpg" alt="Before">
  <img class="comparison__after" src="after.jpg" alt="After">
  <div class="comparison__handle"></div>
  <span class="comparison__label-before">Before</span>
  <span class="comparison__label-after">After</span>
</div>
<script src="https://unpkg.com/arc-sliders/js/comparison.js"></script>

| CSS property | Default | Description | |---|---|---| | --comparison-split | 50% | Divider position (set by JS on drag) | | --comparison-handle-color | #fff | Handle line and knob color | | --comparison-handle-size | 44px | Knob diameter |

Accessibility: Keyboard navigable (arrow keys ±5%), role="slider", aria-valuenow — all added automatically by js/comparison.js.


Marquee

Enhanced infinite scrolling ticker. Duplicate content inside .marquee__track for a seamless loop.

<div class="marquee marquee--pause-hover marquee--fade">
  <div class="marquee__track">
    <span class="marquee__item">Item <span class="marquee__sep"></span></span>
    <span class="marquee__item">Item <span class="marquee__sep"></span></span>
    <!-- duplicate for seamless loop -->
    <span class="marquee__item">Item <span class="marquee__sep"></span></span>
    <span class="marquee__item">Item <span class="marquee__sep"></span></span>
  </div>
</div>

| Modifier | Effect | |----------|--------| | .marquee--reverse | Scrolls right instead of left | | .marquee--pause-hover | Pauses on hover (opt-in) | | .marquee--slow | 40s duration | | .marquee--fast | 10s duration | | .marquee--fade | Fades left/right edges | | .marquee--vertical | Vertical scrolling |

| CSS property | Default | Description | |---|---|---| | --marquee-duration | 20s | Animation speed | | --marquee-gap | 2rem | Gap between items |


Range

Styled <input type="range"> — single or dual handle. CSS custom properties control colors and sizing; JS (js/range.js) syncs the fill bar and prevents handles from crossing in dual mode.

<!-- Single handle -->
<div class="range">
  <input type="range" min="0" max="100" value="40">
</div>

<!-- Dual handle -->
<div class="range range--dual">
  <input type="range" min="0" max="100" value="20">
  <input type="range" min="0" max="100" value="80">
</div>
<script src="https://unpkg.com/arc-sliders/js/range.js"></script>

| CSS property | Default | Description | |---|---|---| | --range-track-height | 4px | Track thickness | | --range-thumb-size | 18px | Thumb diameter | | --range-color | #3b82f6 | Thumb + fill color | | --range-track-color | #e2e8f0 | Unfilled track color | | --range-track-fill | var(--range-color) | Fill bar color (override separately) |


Scroll progress + fade-in-view

Pure CSS, zero JS. Uses animation-timeline: scroll() and animation-timeline: view().

Browser support: Chrome 115+, Firefox 114+, Safari 18+. Graceful fallback: bar invisible, content visible.

<!-- Reading progress bar (place once near top of <body>) -->
<div class="scroll-progress"></div>

<!-- Reveal element as it enters the viewport -->
<div class="fade-in-view">Any content</div>

| CSS property | Default | Description | |---|---|---| | --scroll-progress-height | 3px | Progress bar height | | --scroll-progress-color | #3b82f6 | Progress bar color |


Tree-shaking

Import only what you need:

<link rel="stylesheet" href="https://unpkg.com/arc-sliders/src/base.css">
<link rel="stylesheet" href="https://unpkg.com/arc-sliders/src/marquee.css">

| File | Size (approx) | |------|---------------| | src/base.css | ~0.5 KB | | src/carousel.css | ~2 KB | | src/comparison.css | ~1.5 KB | | src/marquee.css | ~1.5 KB | | src/range.css | ~1.5 KB | | src/scroll.css | ~0.5 KB | | js/carousel.js | ~600 B | | js/comparison.js | ~400 B | | js/range.js | ~300 B | | Full bundle | ~7.5 KB CSS + ~1.3 KB JS |


Browser support

| Feature | Chrome | Firefox | Safari | Edge | |---------|--------|---------|--------|------| | Carousel (scroll-snap) | 69+ | 68+ | 11+ | 79+ | | Comparison (clip-path) | 55+ | 54+ | 9.1+ | 79+ | | Marquee (CSS animations) | 43+ | 16+ | 9+ | 79+ | | Marquee fade (mask-image) | 120+ | — | 15.4+ | 120+ | | Range (input styling) | 4+ | 23+ | 4+ | 12+ | | Scroll progress (animation-timeline) | 115+ | 114+ | 18+ | 115+ | | Fade-in-view (animation-timeline) | 115+ | 114+ | 18+ | 115+ |


Accessibility

  • prefers-reduced-motion: marquee pauses; carousel scroll-behavior collapses to instant; carousel autoplay is skipped; crossfade is instant; scroll progress shows static
  • Comparison slider: keyboard navigable (←/→ keys ±5%), role="slider", aria-valuenow — added automatically by the JS
  • Carousel buttons: standard <button> elements, keyboard-focusable
  • Range inputs: native <input type="range"> semantics — full keyboard, screen reader, and platform accessibility built in
  • Focus ring: comparison container gets :focus-visible ring (2px, #5956f0)

License

MIT © Arc contributors