<div class="page-wrap">
<div class="slider">
<div class="slider-inner">
<!-- needs a minimum of 3 slides to work -->
<figure class="slides">
<img src="https://picsum.photos/970/340" alt="Slide1" width="970" height="340">
<figcaption class="caption"><span>Slide 1</span></figcaption>
</figure>
<figure class="slides">
<img src="https://picsum.photos/960/330" alt="Slide2" width="960" height="330">
<figcaption class="caption"><span>Slide 2</span></figcaption>
</figure>
<figure class="slides">
<img src="https://picsum.photos/990/350" alt="Slide3" width="990" height="350">
<figcaption class="caption"><span>Slide 3</span></figcaption>
</figure>
<figure class="slides">
<img src="https://picsum.photos/980/360" alt="Slide4" width="970" height="340">
<figcaption class="caption"></span>Slide 4</span></figcaption>
</figure>
<!-- can use divs if preferred
<div class="slides">Slide 5</div>
<div class="slides">Slide 6</div>
<div class="slides">Slide 7</div>
<div class="slides">Slide 8</div>
<div class="slides">Slide 9</div>
<div class="slides">Slide 10</div>
-->
</div>
</div>
<button id="previous" class="prev">Previous</button>
<button id="next" class="next">Next</button>
<!-- <button>stop autoplay</button>-->
<p class="swipe">Swipe Images sideways to see Pictures</p>
</div>
/* the slider speed will be set in the js so this rule will be over-written*/
:root {
--slider-speed: 0.5s;
}
html,
body {
margin: 0;
padding: 0;
font-family: sans-serif;
}
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
.page-wrap {
max-width: 980px;
margin: auto;
}
.slider {
width: 100%;
margin: 20px auto;
position: relative;
border: 5px inset #4c2c2c;
background: #000;
color: #fff;
font-size: 2rem;
}
.slider-inner {
/* Padding-top aspect ratio technique - adjust to suit images aspect ratio - this creates the height of the slides */
padding-top: 35%;
position: relative;
overflow: hidden;
}
.slides {
background: red;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
transform: translate3d(0, 0, 0);
}
.slides:first-child {
z-index: 2;
}
.reverse .slides {
transform: translate3d(-100%, 0, 0);
}
.forwards .slides {
transform: translate3d(100%, 0, 0);
}
.slides.offLeft {
transform: translate3d(-100%, 0, 0);
}
.slides.offRight {
transform: translate3d(100%, 0, 0);
}
.slides.active {
transform: translate3d(0%, 0, 0);
}
.slides.active,
.slides.offLeft,
.slides.offRight {
transition: transform var(--slider-speed) linear;
xtransition-duration: var(--slider-speed);
}
.slides:nth-child(odd) {
background: blue;
}
.slides img {
object-fit: cover;
width: 100%;
height: 100%;
display: block;
}
.prev,
.next {
margin: 5px 10px 5px 0;
border: inset 5px solid #4c2c2c;
padding: 5px 10px;
background: #fefefe;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
cursor: pointer;
}
.prev:hover,
.next:hover,
.prev:focus,
.next:focus {
background: #000;
color: #fff;
outline: 0;
}
.prev:not(.trans-end),
.next:not(.trans-end) {
cursor: wait;
opacity: 0.5;
}
/* captions if needed */
figure.slides {
margin: 0;
padding: 0;
}
.caption {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.caption span {
padding: 20px;
background: rgba(0, 0, 0, 0.5);
}
@media screen and (max-width: 1000px) {
.page-wrap {
margin: 0 10px;
}
}
/* some touch styles*/
.swipe {
display: none;
}
@media (hover: none) {
.swipe {
display: block;
}
.slider-inner {
display: flex;
padding-top: 0;
height: 70vh;
overflow-x: auto;
overflow-y: hidden;
-ms-scroll-snap-coordinate: 0 0;
scroll-snap-coordinate: 0 0;
-ms-scroll-snap-points-x: repeat(100%);
scroll-snap-points-x: repeat(100%);
-ms-scroll-snap-type: x mandatory;
scroll-snap-type: x mandatory;
-webkit-overflow-scrolling: touch;
}
.slider-inner .slides {
position: relative;
flex: 1 0 100%;
width: 100%;
transform: none;
scroll-snap-align: start;
}
#previous,
#next {
display: none;
}
}
// Run function when page loads by putting JS at
// the end of the html before the closing body tag
const browserSupportsTouch =
"ontouchstart" in window ||
navigator.maxTouchPoints > 0 ||
navigator.msMaxTouchPoints > 0;
if (browserSupportsTouch) {
document.documentElement.className += " has-touch";
}
(function makeCarousel(d) {
"use strict";
if (browserSupportsTouch) {
return;
}
const prev = d.querySelector("#previous");
const next = d.querySelector("#next");
const slides = d.querySelectorAll(".slides");
const sliderInner = d.querySelector(".slider-inner");
const time = 6000;
const slide = {
prev: 0,
current: 0,
next: 0,
index: 0
};
// CSS custom variables
const cssSliderSpeedProperty = "--slider-speed";
const cssSliderSpeedValue = "0.5s";
function setCssSliderSpeed() {
document.documentElement.style.setProperty(
cssSliderSpeedProperty,
cssSliderSpeedValue
);
}
function init() {
setCssSliderSpeed();
slides[0].classList.add("active");
sliderInner.classList.add("forwards");
// detect if transitioning or not
prev.classList.add("trans-end");
next.classList.add("trans-end");
// offset left is so slides can go either way
slides[slides.length - 1].classList.add("offLeft");
}
function checkTransition() {
const inTransit = d.querySelector(".slides.active");
inTransit.ontransitionend = function endTransition() {
console.log("Transition ended");
next.classList.add("trans-end");
prev.classList.add("trans-end");
};
}
function initSlides(added, removed) {
// check if moving before moving again
checkTransition();
sliderInner.classList.remove(removed);
sliderInner.classList.add(added);
if (slide.index === slides.length) {
slide.index = 0;
}
if (slide.index === -1) {
slide.index = slides.length - 1;
}
console.log(slide.index);
slide.current = slide.index;
slide.prev = slide.index - 1;
slide.next = slide.index + 1;
if (slide.index === 0) {
slide.prev = slides.length - 1;
slide.next = slide.index + 1;
}
if (slide.index === slides.length - 1) {
slide.prev = slide.index - 1;
slide.next = 0;
}
}
function changeImage() {
if (sliderInner.classList.contains("forwards")) {
next.click();
} else {
prev.click();
}
setTimeout(changeImage, time);
}
function nextSlide() {
if (next.classList.contains("trans-end")) {
initSlides("forwards", "reverse");
slides[slide.current].classList.add("offLeft");
slides[slide.current].classList.remove("active");
slides[slide.prev].classList.remove("offLeft");
slides[slide.next].classList.add("active");
slides[slide.next].classList.remove("offRight");
slide.index += 1;
next.classList.remove("trans-end");
}
}
function prevSlide() {
if (prev.classList.contains("trans-end")) {
initSlides("reverse", "forwards");
slides[slide.current].classList.add("offRight");
slides[slide.current].classList.remove("active");
slides[slide.next].classList.remove("offRight");
slides[slide.prev].classList.add("active");
slides[slide.prev].classList.remove("offLeft");
slide.index -= 1;
prev.classList.remove("trans-end");
}
}
init();
changeImage();
next.addEventListener("click", nextSlide);
prev.addEventListener("click", prevSlide);
})(document);
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.