Go to homepage

Projects /

Pointy Slider

A slideshow with sliding-in panels that unveil new, fixed background images.

Pointy Slider
Check our new component library →

Today’s resource is a simple, responsive slider, with a sharp design and an interesting motion effect: with each new slide item, a sliding-in block of content covers the old one, and unveils a new image.

Inspiration: shft.run

Images: unsplash.com

Creating the structure

The HTML structure is composed by two main elements: a ul.cd-slider for the slides, and a ol.cd-slider-navigation for the slider navigation; both are wrapped inside a div.cd-slider-wrapper.

<div class="cd-slider-wrapper">
   <ul class="cd-slider">
      <li class="is-visible">
         <div class="cd-half-block image"></div>
         <div class="cd-half-block content">
               <h2>Slide Number 1</h2>
                  <!-- content here -->
      </li> <!-- .cd-half-block.content -->

         <!-- item content here -->

      <!-- addition list items here -->
   </ul> <!-- .cd-slider -->

   <!-- The ol.cd-slider-navigation element is created using jQuery and inserted here-->
</div> <!-- .cd-slider-wrapper -->

Note that the ol.cd-slider-navigation element is not directly inserted in the HTML but created using jQuery.

Adding style

On small devices (viewport width smaller than 900px), the slider structure is pretty straightforward: the .cd-slider element has a relative position while its children <li> have an absolute position, with a top and left of zero.
All the list items are translated to the right, outside the viewport (translateX(100%)); the .is-visible class is added to the visible one to move it back into the viewport (translateX(0)).

.cd-slider {
  position: relative;
  height: 100%;
  overflow: hidden;
.cd-slider li {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  transform: translateX(100%);
  transition: transform 0.6s;
.cd-slider li.is-visible {
  transform: translateX(0);

On bigger devices, the list items are moved back inside the viewport (translateX(0)), while their two children elements, .cd-half-block.content and .cd-half-block.image, are translated to the right (translateX(200%) and translateX(100%) respectively). This way, both elements are outside the viewport, overlapping.

When the .is-visible class is added to the selected list item, the two .cd-half-block elements are moved back inside the viewport (translateX(0)).
We used CSS3 Transitions to animate both elements: for the .cd-half-block.content we set a transition-duration of 0.6s and a transition-delay of 0s, while for the .cd-half-block.image we set a transition-duration of 0s and a transition-delay of 0.3s. This way, when the .cd-half-block.content has translated of half the total translation value (100%), the .cd-half-block.image is moved back inside the viewport (translateX(0)) instantaneously (transition-duration: 0s). This creates the unveiling image effect.

Here is a quick animation that explains the logic behind the blocks animation (.gif created using After Effects):


@media only screen and (min-width: 900px) {
  .cd-slider li {
    transform: translateX(0);
  .cd-slider .cd-half-block {
    height: 100%;
    width: 50%;
    float: right;
  .cd-slider .cd-half-block.content {
    transform: translateX(200%);
    transition: transform 0.6s 0s ease-in-out;
  .cd-slider .cd-half-block.image {
    transform: translateX(100%);
    transition: transform 0s 0.3s;
  .cd-slider li.is-visible .cd-half-block.content,
  .cd-slider li.is-visible .cd-half-block.image {
    transform: translateX(0%);
  .cd-slider li.is-visible .cd-half-block.content {
    transition: transform 0.6s 0s ease-in-out;

One thing to note: we set the .cd-half-block.image transition-delay to be equal to half the .cd-half-block.content transition-duration. This is because we used ease-in-out as timing-function, which assures that after half the transition-duration (in our case .3s), the .cd-half-block.content has actually moved of half the total translation value.

Events handling

We used jQuery to create and insert into the DOM the slider navigation.

var sliderPagination = createSliderPagination(sliderContainer); // sliderContainer = $('.cd-slider-wrapper')

function createSliderPagination(container){
   var wrapper = $('<ol class="cd-slider-navigation"></ol>');
      var dotWrapper = (index == 0) ? $('<li class="selected"></li>') : $('<li></li>'),
          dot = $('<a href="#0"></a>').appendTo(dotWrapper);
      var dotText = ( index+1 < 10 ) ? '0'+ (index+1) : index+1;
   return wrapper.children('li');

Besides, we used jQuery to implement a basic slider functionality (touch swipe and slider navigation).

Level up your CSS skills

Each month we email a 1-minute CSS tutorial to 20K developers

Awesome! We just sent you a confirmation link by email

Error - please try again or contact us

Your email address is already subscribed

Project duplicated

Project created

Globals imported

There was an error while trying to export your project. Please try again or contact us.