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"> <div> <h2>Slide Number 1</h2> <p> <!-- content here --> </p> </div> </div> </li> <!-- .cd-half-block.content --> <li> <!-- item content here --> </li> <!-- 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>'); container.children('.cd-slider').find('li').each(function(index){ var dotWrapper = (index == 0) ? $('<li class="selected"></li>') : $('<li></li>'), dot = $('<a href="#0"></a>').appendTo(dotWrapper); dotWrapper.appendTo(wrapper); var dotText = ( index+1 < 10 ) ? '0'+ (index+1) : index+1; dot.text(dotText); }); wrapper.appendTo(container); return wrapper.children('li'); }

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