Experiment: JavaScript Boxed Carousel with Progress Indicator

Here’s an awesome JavaScript carousel built for a client project, but then scrapped. It definitely has potential for unlimited items.

Currently it has a 5 second delay between slides and a neat progress indicator.

Vanilla JavaScript Boxed Carousel Demo

Vanilla JavaScript Boxed Carousel
Vanilla JavaScript Boxed Carousel

Vanilla JavaScript Boxed Carousel Codepen

See the Pen Experiment: Boxed Carousel by Ciprian (@ciprian) on CodePen.

HTML Code

<ol class="s1-slider s1-slider--active-1">
    <li class="s1-slider__item s1-slider__item--1 ui-dark is-active" data-active="1">
        <div class="s1-slider__item__wrapper">
            <div class="s1-slider__item__text">
                <h2>Mark Haddon</h2>
                <p>Reading is a conversation. All books talk. But a good book listens as well.</p>
                <p><a href="#">Learn more</a></p>
            </div>
        </div>
    </li>
    <li class="s1-slider__item s1-slider__item--2 ui-primary" data-active="2">
        <div class="s1-slider__item__wrapper">
            <div class="s1-slider__item__text">
                <h2>Paul Sweeney</h2>
                <p>You turn the last page and feel a little as if you have lost a friend.</p>
                <p><a href="#">Learn more</a></p>
            </div>
        </div>
    </li>
    <li class="s1-slider__item s1-slider__item--3 ui-light" data-active="3">
        <div class="s1-slider__item__wrapper">
            <div class="s1-slider__item__text">
                <h2>Celeste Ng</h2>
                <p>The story is truly finished when the reader enters.</p>
                <p><a href="#">Learn more</a></p>
            </div>
        </div>
    </li>
</ol>

CSS

ol {
    margin: 0;
    padding: 0;
}
ol li {
    margin: 0;
    list-style: none;
}

.s1-slider__item__text h2 {
    font-weight: 400;
    color: #000;
}
.form-control-range__handle p,
.s1-slider__item__text p {
    font-size: 18px;
    line-height: 1.25;
}

.s1-slider__item__text a {
    font-size: 14px;
    background-color: #000000;
    color: #ffffff;
    padding: 12px 24px;
    display: inline-block;
    text-decoration: none;
}

.s1-slider__item__text h2 {
    font-size: 20px;
    line-height: 1.5;
    margin-top: 0;
}
.s1-slider__item:before {
    font-size: 0.8rem;
    line-height: 2em;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.s1-slider {
    font-weight: 300;
    counter-reset: slider;
    position: absolute;
    z-index: 10;
    margin: 0;
    width: 21.05263vw;
    height: 21.05263vw;
    right: 48px;
    bottom: 48px;
    transition-timing-function: cubic-bezier(0.55, 0, 0.1, 1);
    transition-duration: 0.9s;
    transition-property: transform;
}
.s1-slider--active-2 {
    transform: translateY(-21.05263vw);
}
.s1-slider--active-3 {
    transform: translate(-21.05263vw, -21.05263vw);
}

.s1-slider__item {
    counter-increment: slider;
    position: absolute;
    cursor: pointer;
    width: 31.57895vw;
    height: 31.57895vw;
    transition-timing-function: cubic-bezier(0.55, 0, 0.1, 1);
    transition-duration: 0.9s;
    transition-property: transform;
    transform: scale(0.33333);
}
.s1-slider__item__wrapper {
    position: relative;
    overflow: hidden;
    width: 31.57895vw;
    height: 31.57895vw;
}
.s1-slider__item__wrapper:before {
    content: "";
    position: absolute;
    left: -5%;
    top: -5%;
    width: 110%;
    height: 110%;
}

.s1-slider__item--1 .s1-slider__item__wrapper:before {
    background: #ffffff;
}
.s1-slider__item--2 .s1-slider__item__wrapper:before {
    background: #546de5;
}
.s1-slider__item--3 .s1-slider__item__wrapper:before {
    background: #c44569;
}

.s1-slider__item--1 .s1-slider__item__text h2,
.s1-slider__item--1 .s1-slider__item__text p {
    color: #000000;
}
.s1-slider__item--2 .s1-slider__item__text h2,
.s1-slider__item--2 .s1-slider__item__text p {
    color: #ffffff;
}
.s1-slider__item--3 .s1-slider__item__text h2,
.s1-slider__item--3 .s1-slider__item__text p {
    color: #ffffff;
}

.s1-slider__item--1:before {
    color: #000000;
}
.s1-slider__item--1:after {
    color: #ffffff;
}
.s1-slider__item--2:after {
    color: #ffffff;
}
.s1-slider__item--3:after {
    color: #ffffff;
}

.s1-slider__item a {
    pointer-events: none;
}
.s1-slider__item.is-active a {
    pointer-events: all;
}
.s1-slider__item.is-active {
    cursor: default;
    transform: scale(1);
}
.s1-slider__item--1 {
    right: 10.52632vw;
    bottom: 10.52632vw;
    transform-origin: 100% 100%;
    z-index: 1;
}
.s1-slider--active-3 .s1-slider__item--1 {
    transform: scale(0.33333) translateX(100%);
}
.s1-slider__item--2 {
    right: 10.52632vw;
    top: 10.52632vw;
    transform-origin: 100% 0;
}
.s1-slider__item--3 {
    left: 10.52632vw;
    top: 10.52632vw;
    transform-origin: 0 0;
}
.s1-slider--active-1 .s1-slider__item--3 {
    transform: scale(0.33333) translateY(-100%);
}
.s1-slider__item:before {
    content: "0" counter(slider);
    position: absolute;
    z-index: 1;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%) scale(3);
    transition-timing-function: cubic-bezier(0.55, 0, 0.1, 1);
    transition-duration: 0.6s;
    transition-property: opacity;
}
.s1-slider__item.is-active:before {
    opacity: 0;
}
.s1-slider__item__text {
    position: relative;
    padding: 32px;
    transition-timing-function: cubic-bezier(0.55, 0, 0.1, 1);
    transition-duration: 0.9s;
    transition-property: transform, opacity;
    transition-delay: 0ms, 0.15s;
    opacity: 0;
}
.s1-slider__item--1 .s1-slider__item__text {
    color: #ffffff;
    transform-origin: 100% 100%;
    transform: scale(2) translate(100%, 100%);
}
.s1-slider__item--2 .s1-slider__item__text {
    transform-origin: 100% 0;
    transform: scale(2) translate(100%, -100%);
}
.s1-slider__item--3 .s1-slider__item__text {
    transform-origin: 0 0;
    transform: scale(2) translate(-100%, -100%);
}
.s1-slider__item.is-active .s1-slider__item__text {
    transform: scale(1);
    opacity: 1;
}

.s1-text {
    position: absolute;
    z-index: 1;
    left: 6.25vw;
    top: 6.25vw;
    margin: 0;
    color: #fff;
    font-size: 1.2rem;
    line-height: 1.25em;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.s1-slider__item.is-active .s1-slider__item__text {
    position: relative;
}
.s1-slider__item.is-active .s1-slider__item__text:before {
    content: "";
    position: absolute;
    top: 0%;
    left: 0;
    height: 3px;
    z-index: 2;
    background-color: #000000;

    animation: 5s linear slider--interval;
}

@keyframes slider--interval {
    from {
        right: 100%;
    }
    to {
        right: 0%;
    }
}

JavaScript

document.addEventListener("DOMContentLoaded", function () {
    [].forEach.call(
        document.querySelectorAll(".s1-slider .s1-slider__item"),
        function (sliderItem) {
            sliderItem.addEventListener("click", function (event) {
                document
                    .querySelector(".s1-slider")
                    .classList.remove("s1-slider--active-1");
                document
                    .querySelector(".s1-slider")
                    .classList.remove("s1-slider--active-2");
                document
                    .querySelector(".s1-slider")
                    .classList.remove("s1-slider--active-3");

                document
                    .querySelector(".s1-slider")
                    .classList.add(
                        "s1-slider--active-" + sliderItem.dataset.active
                    );

                Array.from(
                    document.getElementsByClassName("s1-slider__item is-active")
                ).forEach((el) => el.classList.remove("is-active"));

                sliderItem.classList.add("is-active");
            });
        }
    );

    const slideArray = [
        ".s1-slider__item--1",
        ".s1-slider__item--2",
        ".s1-slider__item--3"
    ];

    let slideLoop = function (i) {
        if (slideArray[i]) {
            setTimeout(function () {
                i = i === 2 ? -1 : i;
                console.log(i);
                slideLoop(i + 1);
                document
                    .querySelector(".s1-slider " + slideArray[i + 1])
                    .click();
            }, 5000);
        }
    };
    slideLoop(0);
});

Find more JavaScript tutorials, code snippets and samples here or more jQuery tutorials, code snippets and samples here.

Added by Ciprian on Monday, June 15, 2020 in Blog, JavaScript

Unlimited Automated Page Speed Monitoring & Tracking.
Use SpeedFactor to track your website. It’s simple and reliable.
See how real people experience the speed of your website. Then find (and fix) your web performance problems.
Get Started

Related Articles

Privacy Policy