1

i've been looking around a lot on how to do different carousels, but i'm struggling to find a resource that teaches me what it actually does instead of just throwing code at me. Time wasted on misleading videos where you have to download their special script at the end! :-(

i want to understand it first in vanilla JS/Css first, and then work towards understanding Pug/Scss.

i have the below:

.MenuContainer {
    position: relative;
    width: 300px;
    height: 175px;
    background-color: black;
    border-radius: 10px;
}

.Imagebox {
    height: 150px;
    margin-top: 15px;
    margin-bottom: 27px;
    bottom: -17px;
    width: 260px;
    margin-left: 20px;
    margin-right: 15px;
    background-color: lavender;
    align-self: center;
    position: absolute;
    border-radius: 5px;
}

.ListReel {
    position: inherit;
    height: 120px;
    background-color: white;
    width: 217px;
    bottom: 8px;
    margin-left: 20px;
    display: flex;
    flex-direction: row;
    overflow-x: hidden;
    justify-content: space-evenly;
}

.fa-chevron-left {
    position: inherit;
    left: 30px;
    bottom: 93px;
    font-size: 1.5em;
}

.fa-chevron-right {
    position: inherit;
    left: 236px;
    bottom: 93px;
    font-size: 1.5em;
}

.MenuItem {
    position: inherit;
    height: 85px;
    width: 85px;
    top: 1px;
    position: inherit;
    border-color: lawngreen;
    border-style: solid;
    border-width: 1px;
    display: table-row;
}
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
    <script src="https://kit.fontawesome.com/a427ef628d.js" crossorigin="anonymous"></script>
    <script src="../Scripts/JQuery"></script>
    <script src="../Scripts/jquery-ui.min.js"></script>
    <link rel="stylesheet" href="../Scripts/jquery-ui.min.css">
    <link rel="stylesheet" href="Test.css">
    <title>TESTING</title>
</head>

<body>
    <h1>Hello!</h1>
    <div class="MenuContainer">
        <h5 style="text-align: center; margin-top: 5px; color: white;">Select Item</h5>
        <div class="Imagebox"></div>
        <ul class=ListReel>
            <li class="MenuItem"></li>
            <li class="MenuItem"></li>
            <li class="MenuItem"></li>
            <li class="MenuItem"></li>
            <li class="MenuItem"></li>
            <li class="MenuItem"></li>
        </ul>
        <i class="fas fa-chevron-left"></i>
        <i class="fas fa-chevron-right"></i>
    </div>
</body>
</html>

I tried going my own way but i'm completely stuck - i envision that the green boxes will need to be spaced evenly, and in a straight row, the items that fall outside the box, won't be visisble and the scroll will cycle the items "Carousel" style..

Ive tried a lot of things so far and i cant even seem to be able to flex my container/green boxes across let alone make a start on the animation!

Does anyone have any tips or resources or code ideas that can point me in the correct direction? preferably well explained tutorials? please?

Many Thanks

2 Answers2

1

Let's start by thinking what the carousel should do. It should roll new images / items from the sides of the viewing container, right?

This means we want our carousel items to be full width of the carousel container, so the items fill the container and rest are left hanging out. Now we don't want to see the other carousel items outside the carousel and for that we can use overflow: hidden on the carousel container. This CSS declaration means that everything that doesn't fit inside the carousel container is hidden.

The other crucial thing is to lay out the carousel items next to eachother, so that when we move them they appear from the sides.

There are of course multiple ways to achieve this but here's what I would've done.

<div class="carousel">
    <div id="carousel-item-wrapper">
        <div style="background-color: red" class="carousel-item"></div>
        <div style="background-color: blue" class="carousel-item"></div>
        <div style="background-color: yellow" class="carousel-item"></div>
    </div>
</div>

We have a container for the carousel (class: carousel) and the items within it (class carousel-item). Here I have added also a "carousel-item-wrapper" element here. Its job is to contain all the carousel items so we can just slide this bad boy around and the displayed carousel item will change.

Now for the CSS of this mf.

.carousel {
    width: 600px;
    height: 200px;
    border: 3px solid #333;

    overflow: hidden;
}

#carousel-item-wrapper {
    display: flex;
    flex-direction: row;

    position: relative;
    left: 0;

    transition: left 0.5s;
}

.carousel-item {
    display: inline-block;
    min-width: 600px;
    height: 200px;
}

Let's start with .carousel and .carousel-item.

We set defined width and height attributes for the carousel container according to our needs. We want the same width and height to be applied to carousel-item so they fill the carousel window. We also want to set the aforementioned overflow: hidden on the .carousel container so the other items are not displayed when they don't need to.

Now I have set the width of the carousel items with min-width: 600px. The reason is that the carousel-item-wrapper where we have the items uses flexbox layout display: flex. If the items don't have a min-width attribute set, the flexbox would shrink all of them until they all fit side by side inside the carousel container. We don't want that!

Now we get to talk about the mystical #carousel-item-wrapper element. Firstly, it has flex properties needed for horizontal layout: display: flex to actually use flexbox and flex-direction: row (which is default actually..) which tells flexbox to align the items next to eachother.

Then I have set the wrapper element position to relative which means that if no other settings (left, right, top, bottom) is set the element will be where it would naturally go. The reasoning for relative positioning is that we can then change the left (or right) value to move the long horizontal list of carousel items so that the element we want will be aligned with the .carousel element (the "display window" so to speak).

Lastly, it has transitition: left 0.5s which tells the browser that any time the left attribute is changed (usually by JS), the browser will animate the change of the value. That is, if we first have left: 0px and change it to left: -600px (sliding the carousel one item over, as my carousel has width of 600px) the change will be animated (0.5s refers to the time you want it to take)

Now we have all of the HTML and CSS set up and if you change the left property of #carousel-item-wrapper it will move and animate the carousel.

Only thing we need is to create some JS to move it around. I have opted for a button which just moves the carousel one item.

I wasn't going to explain the JS but seeing that this answer got so long, I might as well do that as well.

function moveCarousel() {
    const carouselWrapper = document.getElementById("carousel-item-wrapper");
    let left = carouselWrapper.style.left.slice(0, -2);
    left = (left - 600) % 1800;

    carouselWrapper.style.left = left + 'px';
}

First we start by getting a reference to the wrapper element with document.getElementById. We can use this to read the current value of left attribute on the element and change it. carouselWrapper.style.left is the value of the left property and slice(0, -2), well you can read up on it on your own but here it just strips the "px" from the value (because the value of left is a string of <value>px. Next we want to subtract carousel width from this (so the items slide up correctly). I also used the modulo operator, which is just remainder division. This will mean that once I have subtracted too much, it will wrap over. Now the only thing left is to apply this new value of left to the wrapper.

All in all the implementation would look a bit like this: (EDIT: I change height to be 100px instead of 200px to make it fit inside the run code snippet window)

function moveCarousel() {
            const carouselWrapper = document.getElementById("carousel-item-wrapper");
            let left = carouselWrapper.style.left.slice(0, -2);
            left = (left - 600) % 1800;

            carouselWrapper.style.left = left + 'px';
        }
.carousel {
    width: 600px;
    height: 100px;
    border: 3px solid #333;

    overflow: hidden;
}

#carousel-item-wrapper {
    display: flex;
    flex-direction: row;

    position: relative;
    left: 0;

    transition: left 0.5s;
}

.carousel-item {
    display: inline-block;
    min-width: 600px;
    height: 100px;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="style.css" rel="stylesheet">
    <title>Document</title>
</head>
<body>
    
    <div class="carousel">
        <div id="carousel-item-wrapper">
            <div style="background-color: red" class="carousel-item"></div>
            <div style="background-color: blue" class="carousel-item"></div>
            <div style="background-color: yellow" class="carousel-item"></div>
        </div>
    </div>

    <button role="button" onclick="moveCarousel()">Move carousel</button>

</body>
</html>
tikki
  • 26
  • 4
0

One quick thing before I answer your question: try and post Minimum Working Examples (MWEs) on stackoverflow, because
a) this will make your answer more useful to others;
b) because it will help you isolate and debug. To go from full website to MWE, remove stuff until only the problem remains, and none of the other stuff.

Now: I'm not sure whether you understand the implications of display:flex on .ListReel. This is a flexbox, a web technology that allows simplified formatting of things, and you may have seen it around a few tutorials. But flexbox setups require a bit more than just display:flex. You can read more here: CSS-Tricks post on Flexbox (not mine but i regularly use it)

For starters, try adding flex: 0 0 100% to your .MenuItem, which tells the browser that you want your carousel menu items to take up 100% of the width of the .ListReel. Then, for the moment, set overflow-x to auto, which will show the scrollbar.

Later you might not want the scrollbar; so you can set overflow-x back to hidden. I will assume that you know some javascript - the next step would be to add some javascript to make it work:

<script>
function moveTheListItems(){
    var listReel = document.getElementsByClassName("ListReel")[0]; // get a reference to the listReel
    listReel.scrollBy(listReel.clientWidth,0); // scroll it to reveal the next frame
}
setInterval(moveTheListItems,500); // run this function every 500ms = half a second
</script>

Hope it helps!

Ruben Helsloot
  • 12,582
  • 6
  • 26
  • 49
acenturyandabit
  • 1,188
  • 10
  • 24
  • 1
    Hi! just wanted to thank you for your response, i know you got here first but the length that guy went to to explain it all, really helps for me.., sorry you didn't get a tick :-( i voted though! – jackjsmith1988 Jun 12 '20 at 16:59