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).