How to create CSS carousel (slider)

Milos Jankovic
Sep 13, 2016

View demo Get source

Today, almost all websites have some kind of carousel (slider) and for that usually use some open source JavaScript library (like bxSlider or slick), which require usage of some other JavaScript library (like jQuery). In recent times, Google announced that more users use their mobile phones than desktop computers for search. That means higher probability that users are on the move and they don’t have fast and stable internet connection.

In that sense, websites need to load fast, without many external libraries which will slow down loading and block page rendering. Using two external libraries (which are about 120 KB) for creating carousel is demanding, so we will show you how to create carousel just with (S)CSS.


Code looks the same as one which you write when you use JS carousel, with addition of <input type=”radio”>. It is important to have input field for every slide with unique ID which needs to be connected with label.

<div class="css-carousel">

<!-- carousel controls --> <input type="radio" name="carousel" id="carousel-1" checked /> <input type="radio" name="carousel" id="carousel-2" /> <input type="radio" name="carousel" id="carousel-3" />

<!-- carousel navigation --> <div class="carousel-nav"> <label for="carousel-1"></label> <label for="carousel-2"></label> <label for="carousel-3"></label> </div>

<!-- carousel slides --> <div class="carousel-slides"> <div class="carousel-inner"> <div class="carousel-item">Slide 1</div> <div class="carousel-item">Slide 2</div> <div class="carousel-item">Slide 3</div> </div> </div>



We will show here just important parts, whole SCSS is available on our GitHub repository.

Defining options (number of slides and transition speed in seconds):

$css-carousel: ( slides: 4, transition-speed: 1s );

This part is very important although is hidden, because checked input controls which slide is shown.

// hide input radio fields input[name="carousel"] { display: none; }

Labels are our carousel navigation which could be styled nicely and which toggles checked input field.

// carousel navigation .carousel-nav { label { display: inline-block; margin: 0 10px; width: 20px; height: 20px; border: 2px solid #fff; border-radius: 50%; cursor: pointer; transition: background-color 0.25s; } }

This code put all slides in one row and hides all inactive slides.

// carousel slides .carousel-slides { width: 100%; overflow: hidden; .carousel-inner { width: (100% * map_get($css-carousel, slides)); transition: margin map_get($css-carousel, transition-speed); } .carousel-item { float: left; width: (100% / map_get($css-carousel, slides)); } }

Main trick is in use of :checked pseudo class which refers to active slide and ~ (tilde sign) which refers to sibling elements. Thanks to this we are able to mark active navigation point and to move slides.

// active carousel navigation @for $i from 1 through map_get($css-carousel, slides) { #carousel-#{$i}:checked ~ .carousel-nav label[for="carousel-#{$i}"] { background-color: #fff; } } // active carousel slides @for $i from 1 through map_get($css-carousel, slides) { #carousel-#{$i}:checked ~ .carousel-slides .carousel-inner { margin-left: (-100% * ($i - 1)); } }

We used SCSS to create carousel and all what we need is just to edit number of slides, everything else will be done automaticaly during compile process.


  • Without usage of large external libraries

  • Save bandwidth and faster website loading


  • Unlike JS carousel which itself recognize number of slides, in CSS carousel developer must define number of slides.

Browser compatibility

Chrome: Any Safari: 3.2+ Firefox: 4+ Opera: 11.5+ IE / Edge: 10+ Android: Any iOS: Any

Milos Jankovic

Front-end Developer, Belgrade.