Demo Slider
How this slider works (no JavaScript)
This “native CSS slider” is really just a horizontal-scrolling container that feels like a slideshow because of scroll snapping and new browser-generated controls. Instead of JavaScript moving slides, the browser handles the movement.
Key parts that make it function
-
The slider container (
.slider) is a horizontally scrolling flex row:display:flex+overflow-x:auto. -
Scroll snapping makes it “slide” one image at a time:
scroll-snap-type: x mandatoryon the container +scroll-snap-alignon each.slide. -
Native arrows are created with:
.slider::scroll-button(). The CSS gives them content + styling, and the browser wires them to scrolling behavior. -
Native dots are created with:
scroll-marker-groupand.slide::scroll-marker. Again, the browser creates the UI and connects it to the scroll position. -
Current slide indicator uses:
:target-currentto style the dot that matches the slide currently in view (works when you use arrows, dots, or even trackpad scrolling).
Why this is cutting edge
CSS is never “done.” It's a language that evolves constantly as browser makers and standards groups add new features that used to require JavaScript. The carousel features on this page are part of newer CSS work around scrolling UI.
That’s why this demo is labeled cutting edge: some pieces are still experimental and may only work in the newest browsers. In unsupported browsers, this will fall back to a scroll-snap image gallery.
Why CSS is adding features like this
- Common UI pattern: carousels are everywhere, so browsers want a built-in, consistent way to do them.
- Performance: when the browser handles scrolling UI natively, it can be smoother and more efficient.
- Less code to maintain: fewer custom scripts means fewer bugs, fewer dependencies, and fewer updates.
How this differs from vanilla JavaScript and jQuery sliders
jQuery / plugin approach (like Slick)
- A plugin builds the slider for you (lots of features), but you’re adding a dependency and accepting the plugin’s structure, limitations, and behaviors.
- Great for quick results, but it can feel like a “black box” until you learn how to read plugin docs and options.
Vanilla JavaScript approach
- You control everything: click handlers, slide index, transforms, active dot logic, edge cases.
- Powerful and flexible, but it’s also more complex code and easier to break when you try to integrate it into a larger site.
Native CSS approach (this page)
- No slider logic to write. You’re mostly describing layout + styling.
- The browser provides the “slider behavior” (arrows + dots + scroll position tracking) in supported browsers.
- If a feature isn’t supported, the core still works as a scroll-snap gallery (progressive enhancement).
Why someone would choose this instead of JavaScript
- You want a lightweight slider: a simple “one image at a time” gallery without a big JS footprint.
- You want fewer moving parts: less custom JS means fewer bugs and fewer integration issues.
- You’re okay with only modern-browser audiences: portfolios, internal tools, demos, or audiences mostly on Chrome/Edge/Safari.
- You still want a good fallback: unsupported browsers still get a usable scrollable gallery.
When NOT to use this
- If you need guaranteed support across all browsers and versions.
- If you need advanced features like autoplay, looping, dynamic content, or complex animations.
- If you need full control of state and behavior (JavaScript will still be the best tool for that).
Student customization ideas
- Change
height+object-fiton.slide img(this changes the “look” the most). - Restyle arrows in
.slider::scroll-button(*)(size, color, shape, hover). - Restyle dots in
.slide::scroll-markerand:target-current(size, spacing, active state).




