<style>
html,
body,
.page {
margin: 0;
width: 100%;
height: 100%;
}
html {
overflow-y: scroll;
font-size: 62.5%;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
html,
body {
margin: 0;
height: 100%;
width: 100%;
}
body {
font-family: "Roboto", sans-serif;
font-weight: normal;
font-size: 16px;
font-size: 1.6rem;
}
.slider-wrapper {
background: #212121;
background: linear-gradient(to bottom, #212121 0%, #262626 100%);
}
.page {
background: #333;
}
.page-header {
display: block;
width: 100%;
height: 64px;
background: #333;
}
.page-title {
text-transform: uppercase;
color: #eee;
font-size: 36px;
font-weight: 300;
line-height: 64px;
margin-left: 24px;
}
h1 {
margin: 0;
padding: 0;
}
.slider-container {
width: 380px;
margin: 0 auto;
padding: 60px 0;
}
@media (min-width:670px) {
.slider-container {
width: 600px;
}
}
@media (min-width:1040px) {
.slider-container {
width: 968px;
}
}
@media (min-width:1270px) {
.slider-container {
max-width: 1200px;
}
}
#slider-1 .slider__slide {
height: 400px;
}
#slider-2 .slider__slider,
#slider-2 .slider__slide {
border: 1px solid #212121;
background: #FF8F00;
height: 250px;
}
.slider-container-fixed {
width: 800px;
margin: 0 auto;
padding: 60px 0;
}
#slider-3 {
width: 800px;
}
.nuance-1 {
background: #D6A465;
}
.nuance-2 {
background: #A37041;
}
.nuance-3 {
background: #D69F66;
}
.nuance-4 {
background: #895734;
}
.nuance-5 {
background: #573724;
}
.slider__text {
color: #eee;
background: #444;
width: 100%;
height: 100%;
padding: 40px;
}
</style>
<div class="page">
<div class="page-header">
<h1 class="page-title">Slider</h1>
</div>
<div class="page-content">
<div class="slider-wrapper">
<div class="slider-container">
<div id="slider-1" class="slider">
<div class="slider__slides">
<div class="slider__slide nuance-1">
Slide 1
<p class="slider__slide__caption">
Title 1
</p>
</div>
<div class="slider__slide nuance-2">Slide 2
<p class="slider__slide__caption">
Title 2
</p>
</div>
<div class="slider__slide nuance-3">Slide 3
<p class="slider__slide__caption">
Title 3
</p>
</div>
<div class="slider__slide nuance-4">Slide 4
<p class="slider__slide__caption">
Title 4
</p>
</div>
<div class="slider__slide nuance-5">Slide 5
<p class="slider__slide__caption">
Title 5
</p>
</div>
</div>
<div class="slider__buttons">
<a href="#" class="slider__button--prev">
<i class="material-icons">chevron_left</i>
</a>
<a href="#" class="slider__button--next">
<i class="material-icons">chevron_right</i>
</a>
</div>
</div>
</div>
</div>
<div class="slider-section">
<div class="slider-container">
<div id="slider-2" class="slider">
<div class="slider__slides">
<div class="slider__slide">Slide 1</div>
<div class="slider__slide">Slide 2</div>
<div class="slider__slide">Slide 3</div>
<div class="slider__slide">Slide 4</div>
<div class="slider__slide">Slide 5</div>
<div class="slider__slide">Slide 6</div>
<div class="slider__slide">Slide 7</div>
<div class="slider__slide">Slide 8</div>
<div class="slider__slide">Slide 9</div>
<div class="slider__slide">Slide 10</div>
<div class="slider__slide">Slide 11</div>
<div class="slider__slide">Slide 12</div>
<div class="slider__slide">Slide 13</div>
</div>
<div class="slider__buttons">
<div class="slider__gradient--left"></div>
<div class="slider__gradient--right"></div>
<a href="#" class="slider__button--prev">
<i class="material-icons">chevron_left</i>
</a>
<a href="#" class="slider__button--next">
<i class="material-icons">chevron_right</i>
</a>
</div>
</div>
</div>
</div>
<div class="slider-wrapper">
<div class="slider-container-fixed">
<div id="slider-3" class="slider">
<div class="slider__slides">
<div class="slider__slide">
<img src="http://pipsum.com/800x500.jpg">
</div>
<div class="slider__slide">
<img src="http://pipsum.com/801x500.jpg">
</div>
<div class="slider__slide">
<img src="http://pipsum.com/802x500.jpg">
</div>
<div class="slider__slide">
<img src="http://pipsum.com/803x500.jpg">
</div>
<div class="slider__slide">
<div class="slider__text">
<h2>My title</h2>
<p>My message</p>
</div>
</div>
</div>
<div class="slider__buttons">
<div class="slider__gradient--left"></div>
<div class="slider__gradient--right"></div>
<a href="#" class="slider__button--prev">
<i class="material-icons">chevron_left</i>
</a>
<a href="#" class="slider__button--next">
<i class="material-icons">chevron_right</i>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
function main () {
var slider = new Slider(document.querySelector('#slider-1'),{
items : 1,
autoplay: true,
responsive : false
}),
slider2 = new Slider(document.querySelector('#slider-2'),{
items : 4,
responsive : true,
mobile : {
items : 1
},
tablet : {
width : 670,
items : 2
},
desktop : {
width : 1040,
items : 3
},
deviceChanged : function(e){
console.log(e);
},
navChanged : function (e){
console.log(e);
}
}),
slider3 = new Slider(document.querySelector('#slider-3'),{
items : 1,
autoplay: false,
responsive : false,
maxHeight : 600
});
}
document.addEventListener('DOMContentLoaded', main);
</script>
$color: rgba(255, 255, 255, .8);
$background-button: rgba(0, 0, 0, .6); //#e67e22;
$color-inactive: rgba(230, 126, 33, .6);
@import url(https://fonts.googleapis.com/css?family=Roboto:400,100,100italic,300,300italic,400italic,500,500italic,700,700italic,900,900italic);
@import url(https://fonts.googleapis.com/icon?family=Material+Icons);
* {
box-sizing: border-box;
}
.slider {
display: block;
width: 100%;
position: relative;
z-index: 1;
}
.slider__slides {
display: flex;
box-sizing: content-box;
position: relative;
z-index: 1;
transition: transform .3s ease-in-out;
}
.slider__viewport {
border-radius: 2px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
overflow: hidden;
}
.slider__slide {
display: flex;
justify-content: center;
/* Horizontal */
align-items: center;
/* Vertical */
text-align: center;
flex-shrink: 0;
width: 100%;
position: relative;
font-size: 18px;
background: transparent;
}
.img-responsive {
display: block;
width: 100%;
height: auto;
}
.slider__button--prev,
.slider__button--next {
display: inline-block;
height: 54px;
width: 54px;
border-radius: 50%;
line-height: 54px;
padding: 0;
border: none;
outline: none;
cursor: pointer;
background-color: $background-button;
position: absolute;
top: 50%;
transform: translateY(-50%);
box-shadow: rgba(0, 0, 0, 0.4) 0 2px 5px;
transition: box-shadow .3s;
transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55);
z-index: 50;
i {
display: inline-block;
width: inherit;
color: $color;
line-height: 54px;
text-align: center;
}
&:hover {
box-shadow: 0 25px 55px 0 rgba(0, 0, 0, 0.21), 0 16px 28px 0 rgba(0, 0, 0, 0.22);
}
}
.slider__button--prev {
left: -27px;
}
.slider__button--next {
right: -27px;
}
.slider__nav {
width: 100%;
position: absolute;
bottom: -30px;
text-align: center;
margin: 0;
padding: 0;
z-index: 50;
li {
display: inline-block;
margin: 0 6px;
zoom: 1;
}
li a {
display: block;
width: 11px;
height: 11px;
border-radius: 50%;
background: #666;
background: $color-inactive;
cursor: pointer;
box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3);
}
li a.active {
pointer-events: none;
background: #000;
background: rgba(0, 0, 0, 0.9);
cursor: default;
}
}
.slider__slide__caption {
display: block;
margin: 0;
padding: 30px 24px;
width: 100%;
background: rgba(0, 0, 0, 0.5);
position: absolute;
left: 0;
bottom: 0;
font-size: 14px;
color: #fff;
text-align: left;
text-shadow: 0 -1px 0 rgba(0, 0, 0, .3);
}
#slider-2 .slider__nav .active {
background: rgba(62, 39, 35, .6);
}
.slider-section {
width: 100%;
box-sizing: border-box;
display: block;
background: #000;
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
-webkit-user-select: none;
overflow: hidden;
}
.slider__gradient--right,
.slider__gradient--left {
height: 100%;
width: 50%;
position: absolute;
top: 0;
z-index: 40;
}
.slider__gradient--left {
left: 0;
background: linear-gradient(to right, #000, rgba(0, 0, 0, 0.1) 20%, rgba(0, 0, 0, 0.1)) !important;
}
.slider__gradient--right {
right: 0;
background: linear-gradient(to left, #000, rgba(0, 0, 0, 0.1) 20%, rgba(0, 0, 0, 0.1)) !important;
}
.hidden {
display: none;
}
View Compiled
var extend = function(source, target) {
if (typeof source == 'object') {
for (var property in source) {
if (!target[property]) {
target[property] = source[property];
}
}
}
return target;
}
function Slider(el, options) {
var self = this,
slide_container,
slides,
prev_button,
next_button,
slider_nav,
current_nav,
steps,
current_step,
item_per_step,
play_timer,
resize_timer,
windowState,
listeners = [];
var defaults = {
autoplay: false,
interval: 4000,
createNav: true,
items: 1,
responsive: false,
mobile: {
items: 2
},
tablet: {
width: 600,
items: 3
},
desktop: {
width: 968,
items: 4
},
maxHeight: undefined,
deviceChanged: undefined,
navchanged: undefined
};
function wrap(element, start, end) {
var html = start + element.outerHTML + end;
element.outerHTML = html;
}
function create_nav() {
slider_nav = document.createElement('ul');
slider_nav.classList.add('slider__nav');
create_nav_links();
el.appendChild(slider_nav);
}
function update_nav() {
var links_count = slider_nav.querySelectorAll('li').length;
if (links_count !== steps) {
slider_nav.innerHTML = '';
create_nav_links();
raiseEvent({
type: 'navchanged',
currentStep: current_step,
itemPerStep: item_per_step,
steps: steps
});
}
}
function getIndex(element) {
var nodes = element.parentNode.childNodes;
for (var i = 0; i < nodes.length; i++) {
if (nodes[i] == element) {
return i;
}
}
return -1;
}
function create_nav_links() {
for (var i = 0; i < steps; i++) {
var li = document.createElement('li');
var nav_link = document.createElement('a');
nav_link.setAttribute('href', '#');
nav_link.addEventListener('click', function(e) {
e.preventDefault();
var index = getIndex(this.parentElement);
moveTo(index);
});
li.appendChild(nav_link);
slider_nav.appendChild(li);
}
}
function get_current_left_slides() {
if (current_step == 0) {
return 0;
} else if (current_step == steps - 1) {
var previous_step_slide_total = (current_step - 1) * item_per_step, // 8
slides_left = (slides.length - current_step * item_per_step), // 1
result = previous_step_slide_total + slides_left; // --> 9
return result;
} else {
var result = current_step * item_per_step;
return result;
}
}
function get_slides_to_move(step) {
// back
if (step < current_step) {
if (step == steps - 2) {
// ex slides.length = 13 | steps 4 | step 2
var slide_total = slides.length, // 13
slides_left = (slides.length - step * item_per_step), // 1
slides_to_move = slide_total - slides_left; // --> 12
return slides_to_move;
} else {
return step * item_per_step;
}
}
// forward
if (step > current_step) {
if (step == steps - 1) {
// ex slides.length = 13 | steps 4 | step 3
var previous_step_slide_total = (step - 1) * item_per_step, // 8
slides_left = (slides.length - step * item_per_step), // 1
slides_to_move = previous_step_slide_total + slides_left; // --> 9
return slides_to_move;
} else {
return step * item_per_step;
}
}
return 0;
}
function onResize() {
if (options.autoplay) {
pause();
clearTimeout(resize_timer);
resize_timer = setTimeout(function() {
play();
}, 250);
}
// repositionne les slides sans animation
var percentage = 100 / item_per_step,
x = item_per_step > 1 ?
percentage * get_current_left_slides() :
current_step * percentage;
slide_container.style.transition = 'none';
slide_container.style.transform = 'translateX(-' + x + '%)';
update_nav();
update_buttons();
setTimeout(function() {
slide_container.style.removeProperty('transition');
}, 500);
if (window.innerWidth < options.tablet.width) {
if (windowState != 'mobile') {
windowState = 'mobile';
if (options.responsive) setItems(options.mobile.items);
raiseEvent({
type: 'devicechanged',
device: 'mobile'
});
}
} else if (window.innerWidth < options.desktop.width) {
if (windowState != 'tablet') {
windowState = 'tablet';
if (options.responsive) setItems(options.tablet.items);
raiseEvent({
type: 'devicechanged',
device: 'tablet'
});
}
} else if (window.innerWidth > options.desktop.width) {
if (windowState != 'desktop') {
windowState = 'desktop';
if (options.responsive) setItems(options.desktop.items);
raiseEvent({
type: 'devicechanged',
device: 'desktop'
});
}
}
}
function onPlay(e) {
play();
}
function onPause(e) {
pause();
}
function update_buttons() {
if (prev_button) {
if (current_step <= 0) {
prev_button.classList.add('hidden');
} else {
prev_button.classList.remove('hidden');
}
}
if (next_button) {
if (current_step >= steps - 1) {
next_button.classList.add('hidden');
} else {
next_button.classList.remove('hidden');
}
}
// navs
if (options.createNav) {
var current_nav = slider_nav.querySelectorAll('a')[current_step];
var active = slider_nav.querySelector('a.active');
if (active) {
active.classList.remove('active');
}
current_nav.classList.add('active');
}
}
function raiseEvent(event) {
if (typeof event == 'string') event = {
type: event
};
if (!event.target) event.target = this;
if (!event.type) throw new Error("Event object missing 'type' property.");
if (listeners[event.type] instanceof Array) {
var _listeners = listeners[event.type];
for (var i = 0; i < _listeners.length; i++) {
_listeners[i].call(self, event);
}
}
}
function init() {
if (!el) throw new Error("'El' cannot be null");
options = extend(defaults, options || {});
wrap(el.querySelector('.slider__slides'), '<div class="slider__viewport">', '</div>');
slide_container = el.querySelector('.slider__slides');
slides = el.querySelectorAll('.slider__slide');
prev_button = el.querySelector('.slider__button--prev');
next_button = el.querySelector('.slider__button--next');
if (options.maxHeight) {
slide_container.style.maxHeight = options.maxHeight + 'px';
}
if (options.deviceChanged) {
addListener('devicechanged', options.deviceChanged);
}
if (options.navChanged) {
addListener('navchanged', options.navChanged);
}
current_step = 0;
if (options.responsive) {
if (window.innerWidth < options.tablet.width) {
setItems(options.mobile.items);
} else if (window.innerWidth < options.desktop.width) {
setItems(options.tablet.items);
} else if (window.innerWidth > options.desktop.width) {
setItems(options.desktop.items);
}
} else {
setItems(options.items);
}
if (options.createNav) {
create_nav();
}
// events
window.addEventListener('resize', function() {
onResize();
});
if (prev_button) {
prev_button.addEventListener('click', function(e) {
e.preventDefault();
moveBack();
});
}
if (next_button) {
next_button.addEventListener('click', function(e) {
e.preventDefault();
moveForward();
});
}
//
// onResize();
update_buttons();
if (options.autoplay) {
el.addEventListener('mouseover', onPause);
el.addEventListener('mouseleave', onPlay);
play();
}
}
function addListener(type, listener) {
if (typeof listeners[type] == "undefined") {
listeners[type] = [];
}
listeners[type].push(listener);
}
function play() {
clearInterval(play_timer);
play_timer = setInterval(function() {
if (current_step == steps - 1) {
moveTo(0);
} else {
moveForward();
}
}, options.interval);
}
function pause() {
clearInterval(play_timer);
}
function stop() {
el.removeEventListener('mouseover', onPause);
el.removeEventListener('mouseleave', onPlay);
clearInterval(play_timer);
}
function moveBack() {
if (current_step <= 0) return false;
moveTo(current_step - 1);
}
function moveForward() {
if (current_step >= steps - 1) return false;
moveTo(current_step + 1);
}
function setItems(count) {
item_per_step = count;
steps = Math.ceil(slides.length / item_per_step);
if (item_per_step > 1) {
var slide_width = 100 / item_per_step;
for (var i = 0; i < slides.length; i++) {
var slide = slides[i];
if (slide) {
slide.style.width = slide_width + '%';
}
}
} else {
for (var i = 0; i < slides.length; i++) {
var slide = slides[i];
if (slide) {
slide.style.removeProperty('width');
}
}
}
// repositionne les slides sans animation
var percentage = 100 / item_per_step,
x = item_per_step > 1 ?
percentage * get_current_left_slides() :
current_step * percentage;
slide_container.style.transition = 'none';
slide_container.style.transform = 'translateX(-' + x + '%)';
setTimeout(function() {
slide_container.style.removeProperty('transition');
}, 500);
}
/**
* déplacer le container soit en avant soit en arrière, si step == current step on ne fait rien
* translateX supérieur au précédent (positif ou non) > vers droite
* translateX inférieur au précédent (négatif ou non) < vers gauche
* prendre en compte la bordure et la marge (offsetWidth)
* @param string step
*/
function moveTo(step) {
if (step < 0 || step > steps - 1) return false;
var percentage = 100 / item_per_step,
x = item_per_step > 1 ?
percentage * get_slides_to_move(step) :
step * percentage;
slide_container.style.transform = 'translateX(-' + x + '%)';
current_step = step;
update_buttons();
}
init();
return {
addEventListener: addEventListener,
moveBack: moveBack,
moveForward: moveForward,
moveTo: moveTo,
pause: pause,
play: play,
setItems: setItems
}
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.