On our home page we need simple multi slide-slide carousel. It is our highest traffic page, in order to increase page speedso we are removing unnecessarydecided to remove all libraries ( includingincluding jQuery), so we decided in order to go pure JS routeincrease page speed.
Here is the code we have now: Codepen
HTML
<div class="carousel">
<div class="arrow-container">
<span class="arrow left"><</span>
</div>
<div class="display-container">
<div class="slide-container">
<div class="slide">1</div>
<div class="slide">2</div>
<div class="slide">3</div>
<div class="slide">4</div>
<div class="slide">5</div>
<div class="slide">6</div>
<div class="slide">7</div>
<div class="slide">8</div>
</div>
</div>
<div class="arrow-container">
<span class="arrow right">></span>
</div>
</div>
CSS
body *::selection {
background: none;
}
.carousel {
--height: 128px;
--width: 120px;
display: block;
margin: 100px auto 0;
height: var(--height);
text-align: center;
}
.carousel * {
display: inline-block;
position: relative;
vertical-align: top;
height: 100%;
}
.arrow-container {
--width-arrow: 64px;
width: var(--width-arrow);
}
.arrow {
--arrow-width: calc(var(--width-arrow) / 2);
position: absolute;
top: 50%;
left: 50%;
width: var(--arrow-width);
height: var(--arrow-width);
background-color: white;
font-weight: bold;
line-height: var(--arrow-width);
border-radius: 50%;
transform: translate(-50%) translateY(-50%);
transition: background-color 111ms, color 222ms;
cursor: pointer;
}
.arrow:hover {
background-color: rgba(0, 0, 0, 0.2);
color: white;
}
.arrow:active {
transform: scale(0.9) translate(-50%) translateY(-50%);
}
.arrow.left {
display: none;
}
.display-container {
/* * 4 to show 4 slides */
width: calc(var(--width) * 4 - 2px);
overflow-x: hidden;
}
.slide-container {
/* * 8 cause that's the number of slides */
width: calc(var(--width) * 8);
/* start by going left 2 slides */
/* transform: translate(calc(var(--width) * -2)); */
transition: transform 333ms;
}
.slide {
margin-left: -4px;
width: var(--width);
background-color: salmon;
}
.slide:nth-child(2n) {
background-color: cornflowerblue;
}
JS
function getStyleValue(elem, property) {
return window.getComputedStyle(elem).getPropertyValue(property);
}
const arrows = document.querySelectorAll(".carousel .arrow"),
[leftArrow, rightArrow] = arrows,
slideContainer = document.querySelector(".carousel .slide-container"),
slides = document.getElementsByClassName("slide"),
amt = parseInt(getStyleValue(slides[0], "width"));
try {
let trans = parseInt(
getStyleValue(slideContainer, "transform")
.split(",")[4]
.trim()
);
} catch (e) {
console.log("`trans` being set to 0");
trans = 0;
}
function slide() {
if (this === rightArrow) {
trans -= amt;
} else if (this === leftArrow) {
trans += amt;
}
if (trans <= amt * slides.length / 2 * -1) {
rightArrow.style.display = "none";
} else if (trans >= 0) {
leftArrow.style.display = "none";
} else {
arrows.forEach(arrow => (arrow.style.display = "inline-block"));
}
slideContainer.style.transform = `translate(${trans}px)`;
}
arrows.forEach(arrow => arrow.addEventListener("click", slide));
body *::selection {
background: none;
}
.carousel {
--height: 128px;
--width: 120px;
display: block;
margin: 100px auto 0;
height: var(--height);
text-align: center;
}
.carousel * {
display: inline-block;
position: relative;
vertical-align: top;
height: 100%;
}
.arrow-container {
--width-arrow: 64px;
width: var(--width-arrow);
}
.arrow {
--arrow-width: calc(var(--width-arrow) / 2);
position: absolute;
top: 50%;
left: 50%;
width: var(--arrow-width);
height: var(--arrow-width);
background-color: white;
font-weight: bold;
line-height: var(--arrow-width);
border-radius: 50%;
transform: translate(-50%) translateY(-50%);
transition: background-color 111ms, color 222ms;
cursor: pointer;
}
.arrow:hover {
background-color: rgba(0, 0, 0, 0.2);
color: white;
}
.arrow:active {
transform: scale(0.9) translate(-50%) translateY(-50%);
}
.arrow.left {
display: none;
}
.display-container {
/* * 4 to show 4 slides */
width: calc(var(--width) * 4 - 2px);
overflow-x: hidden;
}
.slide-container {
/* * 8 cause that's the number of slides */
width: calc(var(--width) * 8);
/* start by going left 2 slides */
/* transform: translate(calc(var(--width) * -2)); */
transition: transform 333ms;
}
.slide {
margin-left: -4px;
width: var(--width);
background-color: salmon;
}
.slide:nth-child(2n) {
background-color: cornflowerblue;
}
<div class="carousel">
<div class="arrow-container">
<span class="arrow left"><</span>
</div>
<div class="display-container">
<div class="slide-container">
<div class="slide">1</div>
<div class="slide">2</div>
<div class="slide">3</div>
<div class="slide">4</div>
<div class="slide">5</div>
<div class="slide">6</div>
<div class="slide">7</div>
<div class="slide">8</div>
</div>
</div>
<div class="arrow-container">
<span class="arrow right">></span>
</div>
</div>
function getStyleValue(elem, property) {
return window.getComputedStyle(elem).getPropertyValue(property);
}
const arrows = document.querySelectorAll(".carousel .arrow"),
[leftArrow, rightArrow] = arrows,
slideContainer = document.querySelector(".carousel .slide-container"),
slides = document.getElementsByClassName("slide"),
amt = parseInt(getStyleValue(slides[0], "width"));
try {
let trans = parseInt(
getStyleValue(slideContainer, "transform")
.split(",")[4]
.trim()
);
} catch (e) {
console.log("`trans` being set to 0");
trans = 0;
}
function slide() {
if (this === rightArrow) {
trans -= amt;
} else if (this === leftArrow) {
trans += amt;
}
if (trans <= amt * slides.length / 2 * -1) {
rightArrow.style.display = "none";
} else if (trans >= 0) {
leftArrow.style.display = "none";
} else {
arrows.forEach(arrow => (arrow.style.display = "inline-block"));
}
slideContainer.style.transform = `translate(${trans}px)`;
}
arrows.forEach(arrow => arrow.addEventListener("click", slide));