Learn how to design a fully functional, responsive image slider using only CSS. This step-by-step tutorial includes code examples and easy explanations for beginners.
Creating an image slider usually requires JavaScript, but you can build a beautiful and functional image slider using only CSS. In this tutorial, we’ll walk you through every step of creating a responsive CSS-only image slider with easy-to-understand code.
How to structure HTML for a slider
Use CSS animations and transitions
Add navigation using radio buttons or checkboxes
Make the slider responsive for mobile devices
First, we’ll set up the HTML skeleton. This includes a container, radio inputs for navigation, slide images, and labels as controls.
<div class="slider">
<input type="radio" name="slider" id="slide1" checked>
<input type="radio" name="slider" id="slide2">
<input type="radio" name="slider" id="slide3">
<div class="slides">
<div class="slide" id="s1">
<img src="image1.jpg" alt="Image 1">
</div>
<div class="slide" id="s2">
<img src="image2.jpg" alt="Image 2">
</div>
<div class="slide" id="s3">
<img src="image3.jpg" alt="Image 3">
</div>
</div>
<div class="navigation">
<label for="slide1" class="nav-btn"></label>
<label for="slide2" class="nav-btn"></label>
<label for="slide3" class="nav-btn"></label>
</div>
</div>
<input type="radio">
helps control which slide is shown.
Each slide
is wrapped in a container called .slides
.
Labels (<label>
) are styled to look like navigation dots or buttons.
Now let’s add the styling that will make the slider work.
/* Basic setup */
.slider {
width: 80%;
max-width: 600px;
margin: 40px auto;
position: relative;
overflow: hidden;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0,0,0,0.3);
}
/* Hide radio buttons */
.slider input[type="radio"] {
display: none;
}
/* Slide container */
.slides {
display: flex;
width: 300%;
transition: transform 0.5s ease-in-out;
}
/* Individual slides */
.slide {
width: 100%;
flex-shrink: 0;
}
.slide img {
width: 100%;
display: block;
}
/* Navigation buttons */
.navigation {
position: absolute;
bottom: 10px;
left: 50%;
display: flex;
gap: 10px;
transform: translateX(-50%);
}
.nav-btn {
width: 12px;
height: 12px;
border-radius: 50%;
background: #ccc;
cursor: pointer;
}
input#slide1:checked ~ .slides {
transform: translateX(0%);
}
input#slide2:checked ~ .slides {
transform: translateX(-100%);
}
input#slide3:checked ~ .slides {
transform: translateX(-200%);
}
input#slide1:checked ~ .navigation label[for="slide1"],
input#slide2:checked ~ .navigation label[for="slide2"],
input#slide3:checked ~ .navigation label[for="slide3"] {
background: #333;
}
The .slides
container is a flexbox showing all slides in a row.
When a radio button is checked, we use :checked ~
sibling selector to shift the slides using transform
.
The navigation dots change color depending on the selected slide.
Let’s make sure it works on mobile too.
@media (max-width: 600px) {
.slider {
width: 100%;
}
}
You can add more slides by adding more radio buttons and CSS rules.
You can replace navigation dots with thumbnails or arrows using <label>
and background images.
All of this works without a single line of JavaScript!
You can add a screenshot of your final slider here.
In this tutorial, you learned how to:
✅ Build a responsive image slider using only HTML and CSS
✅ Use radio buttons to manage slider state
✅ Animate slide transitions using CSS transforms and transitions
✅ Style navigation and make it mobile-friendly
<div class="slider">
<input type="radio" name="slider" id="slide1" checked>
<input type="radio" name="slider" id="slide2">
<input type="radio" name="slider" id="slide3">
<div class="slides">
<div class="slide"><img src="image1.jpg" alt="Image 1"></div>
<div class="slide"><img src="image2.jpg" alt="Image 2"></div>
<div class="slide"><img src="image3.jpg" alt="Image 3"></div>
</div>
<div class="navigation">
<label for="slide1" class="nav-btn"></label>
<label for="slide2" class="nav-btn"></label>
<label for="slide3" class="nav-btn"></label>
</div>
</div>
<style>
.slider {
width: 80%;
max-width: 600px;
margin: 40px auto;
position: relative;
overflow: hidden;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0,0,0,0.3);
}
.slider input[type="radio"] { display: none; }
.slides {
display: flex;
width: 300%;
transition: transform 0.5s ease-in-out;
}
.slide {
width: 100%;
flex-shrink: 0;
}
.slide img {
width: 100%;
display: block;
}
.navigation {
position: absolute;
bottom: 10px;
left: 50%;
display: flex;
gap: 10px;
transform: translateX(-50%);
}
.nav-btn {
width: 12px;
height: 12px;
border-radius: 50%;
background: #ccc;
cursor: pointer;
}
input#slide1:checked ~ .slides {
transform: translateX(0%);
}
input#slide2:checked ~ .slides {
transform: translateX(-100%);
}
input#slide3:checked ~ .slides {
transform: translateX(-200%);
}
input#slide1:checked ~ .navigation label[for="slide1"],
input#slide2:checked ~ .navigation label[for="slide2"],
input#slide3:checked ~ .navigation label[for="slide3"] {
background: #333;
}
@media (max-width: 600px) {
.slider { width: 100%; }
}
</style>
Thank you for visiting! Enjoy exploring our diverse collection of blogs, crafted with passion and insight to inspire and inform. Happy reading!