The simplest reliable image slider uses a semantic list inside a horizontally scrolling element. CSS scroll-snap-type makes the list stop at each slide, while scroll-snap-align marks every slide as a stopping point. This approach needs no JavaScript and works with touch, mouse, keyboard, and ordinary browser scrolling.
Use the complete example below as a starting point, then choose whether your project needs optional CSS carousel controls or a JavaScript implementation.
Build a CSS scroll-snap slider
A slider must have three layers: a labelled region for the component, a scroll container with a defined width and overflow, and individual slide elements. The container—not the slides—gets scroll-snap-type. Each slide gets scroll-snap-align. Without a constrained container and overflow, there is nothing to scroll and snapping cannot occur.
Complete HTML
<section class="image-slider" aria-labelledby="gallery-title">
<h2 id="gallery-title">Featured landscapes</h2>
<ul class="slides">
<li class="slide">
<figure>
<img src="images/mountain.jpg" alt="Snow-covered mountain above a blue lake">
<figcaption>Mountain lake</figcaption>
</figure>
</li>
<li class="slide">
<figure>
<img src="images/forest.jpg" alt="Sunlight passing through a green forest" loading="lazy">
<figcaption>Forest light</figcaption>
</figure>
</li>
<li class="slide">
<figure>
<img src="images/coast.jpg" alt="Rocky coast beside calm blue water" loading="lazy">
<figcaption>Rocky coast</figcaption>
</figure>
</li>
</ul>
</section>
A list is appropriate when the slides are a collection of related items. Give every image meaningful alternative text; if a caption repeats the same information, make the alt text concise rather than duplicating the caption.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware match#1 Best Overall
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
Responsive CSS
* {
box-sizing: border-box;
}
.image-slider {
max-width: 70rem;
margin-inline: auto;
padding: 1rem;
}
.slides {
display: grid;
grid-auto-flow: column;
grid-auto-columns: 100%;
gap: 1rem;
margin: 0;
padding: 0;
list-style: none;
overflow-x: auto;
overscroll-behavior-x: contain;
scroll-snap-type: x proximity;
scrollbar-width: thin;
}
.slide {
min-width: 0;
scroll-snap-align: start;
}
.slide figure {
margin: 0;
}
.slide img {
display: block;
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
border-radius: .5rem;
}
.slide figcaption {
margin-top: .5rem;
font-size: 1rem;
}
@media (min-width: 48rem) {
.slides {
grid-auto-columns: calc((100% - 2rem) / 3);
}
}
@media (prefers-reduced-motion: reduce) {
.slides {
scroll-behavior: auto;
}
}
The mobile layout shows one full slide at a time. At 48rem and wider, three cards are visible while the container remains horizontally scrollable. Change the breakpoint and column calculation to suit your design. aspect-ratio reserves image space before loading, and object-fit: cover prevents uneven card heights.
Understand the snapping rules
scroll-snap-type: x proximity enables horizontal snapping when the user stops near a snap point. mandatory forces the browser to land on a snap point after every scroll. MDN warns that mandatory snapping can make overflowing content inside a child impossible to reach; use it only when every slide can be viewed without internal overflow. The scroll-snap container and slide roles are documented in MDN’s CSS scroll snap guide and its basic concepts reference.
Make the slider usable without JavaScript
Touch, mouse, and keyboard
Native horizontal scrolling works on touchscreens and trackpads. Keyboard users can focus the list or a link inside a slide and use arrow keys or Shift plus the mouse wheel, depending on the browser and platform. Add visible focus styles to interactive content:
.slide a:focus-visible,
.slide button:focus-visible {
outline: 3px solid #165dff;
outline-offset: 4px;
}
Do not hide the scrollbar unless you provide another obvious way to discover additional slides. A heading, visible partial next card, or “scroll horizontally” instruction can make the interaction clearer.
Free tools Windows power users keep installed
One-click scans. No signup required.
Rank #2
Keep controls large and legible
If you add links or buttons inside the component, provide sufficient color contrast and a target of at least 44 × 44 CSS pixels, the sizing recommendation in the W3C WAI carousel styling guidance. Ensure text remains readable over images by using a solid caption area or a contrast-tested overlay.
Automatic movement needs a pause mechanism
This example does not autoplay. If you later add automatic movement, provide a pause or stop button. The W3C Web Accessibility Initiative states: “Users must be able to pause carousel movement because it can be too fast or distracting, making text hard to read.” Follow the semantic and interaction guidance in the WAI Carousels Tutorial.
Optional CSS carousel controls
Modern CSS includes carousel-related features such as generated ::scroll-button() controls, ::scroll-marker-group, and ::scroll-marker. MDN demonstrates these features in its CSS carousels guide. They can add browser-generated previous/next buttons and markers without JavaScript, but support is still a volatile implementation detail. Verify the exact pseudo-elements in every browser version you support before making them your only navigation.
Keep the semantic list and native scrolling as the fallback. Generated control text and alternative names may not be sufficient for WCAG in every user agent, so test with keyboard navigation and the screen readers used by your audience. If the feature is unavailable, users should still be able to scroll the list.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Rank #3
When to choose JavaScript
Use JavaScript when you need synchronized thumbnails, URL or history updates, a controlled autoplay timer, analytics for next/previous actions, or complex focus management. A script must preserve the same fundamentals: real buttons with accessible names, a visible pause control for autoplay, focus that moves predictably, and a scrollable fallback if the script fails. The sources for this guide do not establish comparative browser coverage or capability for a particular JavaScript library, so evaluate the library and its accessibility behavior separately.
Images, sizing, and performance
Prevent layout shifts
- Set
widthandheightattributes when the intrinsic dimensions are known, or useaspect-ratio. - Serve images close to the largest rendered size; oversized originals increase download time.
- Use
loading="lazy"for slides below the initial viewport, but leave the first visible image eager. - Use descriptive alt text for informative images and empty alt text for purely decorative images.
Handle long or interactive slide content
Do not put an independently scrollable article, table, or form inside a slide that uses scroll-snap-type: mandatory without testing. Users can become trapped between snap points. proximity is safer for mixed-height content. For predictable cards, keep the slide width stable and let the slide itself grow vertically.
Testing checklist
- Resize the viewport from a narrow phone width to a wide desktop width.
- Drag or swipe through every slide and confirm each one aligns at its start edge.
- Use only the keyboard. Check that focus is visible and no control is unreachable.
- Zoom text to 200 percent and confirm captions and controls do not overlap.
- Test with images disabled or delayed; the layout should remain understandable.
- Run a screen reader and verify the section heading, image names, captions, and any buttons.
- Test the browser versions your audience actually supports before enabling newer CSS carousel pseudo-elements.
Troubleshooting
The slider does not move
Confirm that .slides has a constrained width, overflow-x: auto, and children wider than the visible area. Inspect computed styles: scroll-snap-type belongs on .slides, not on .slide.
Slides do not stop cleanly
Check that every slide has scroll-snap-align: start and that the gap and column calculation do not exceed the container unexpectedly. Remove conflicting transforms or nested horizontal scroll regions while diagnosing.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsRank #4
- Brand: Wiley
- Set of 2 Volumes
- A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
Part of a slide is unreachable
Replace mandatory with proximity, remove the nested overflow, or redesign the slide so all of its content fits within one snap area. This is the specific failure mode highlighted in MDN’s scroll-snap guidance.
Images have different heights
Set a consistent aspect-ratio and object-fit, or reserve each image’s intrinsic dimensions with HTML width and height attributes.
Generated controls are missing
The browser may not support the CSS carousel pseudo-elements. Keep native scrolling as the fallback, or implement tested buttons with JavaScript. Do not assume a generated marker or button has an accessible name in every user agent.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
If your goal is to capture the finished slider as an image or PDF rather than build the component, ScreenshotNeo provides a one-request website screenshot API. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and billing status. Its MCP server includes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.
Use the API after deploying your slider. The complete parameter reference is in the ScreenshotNeo documentation.
Best Value
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com/slider -o slider.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.com/slider"}, timeout=90)
r.raise_for_status()
open("slider.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com/slider' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('slider.webp', Buffer.from(await res.arrayBuffer()));
Free use includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. Create a free ScreenshotNeo account.
Frequently Asked Questions
Can I build an image slider with only HTML and CSS?
Yes. A horizontally overflowing list with CSS scroll snap provides native scrolling and predictable stopping points without JavaScript.
Should I use scroll-snap-type mandatory or proximity?
Use proximity for general-purpose content. Choose mandatory only when each slide and all content inside it can be reached within one snap area.
Are CSS carousel pseudo-elements supported everywhere?
Support varies by browser and version. Check the target browser set and retain native scrolling as a fallback.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

