Sunday 13 November 2016

Web Tutorial: The Mini-carousel

Hello, readers!

Have you ever seen that neat row of images on a website (any website, but mostly photo galleries) that just slides from right to left (or vice versa) seamlessly and endlessly? And ever wondered what it would take to make one?

It's fairly simple actually, and today I'm going to show you just how.

If you recall the web tutorial on The Lightbox Effect I made last year, I used pictures of my nephew Paul. Well, little Paul's going to star in this one again. We'll make a carousel of his pictures and animate it.

HTML and CSS3 is needed for this. You won't need JavaScript, but it sure as hell will make your life a whole lot easier.

To begin, let's start off with a standard HTML setup.
<!DOCTYPE html>
<html>
    <head>
        <title>Carousel</title>
    </head>

    <body>

    </body>
</html>


Add a div with a class of carousel, and then style it like so. The width has to be set to 100% of your screen size, or however wide you want your carousel to be. Here, I've given it a margin of 25% from the top. This number is arbitrary and not really important in the general scheme of things. The height is 200 pixels. Again, you may want to change this to suit your purposes.

The overflow property is set to hidden, and I'll explain why in a bit.

<html>
    <head>
        <title>Carousel</title>
        <style>
            .carousel
            {
               width: 100%;
                height: 250px;
                overflow:hidden;
            }
        </style>
    </head>

    <body>
        <div class="carousel">

        </div>
    </body>
</html>


Now add this to your CSS. This will make all divs a translucent shade of red, and give you a really nifty visual guide.
        <style>
            div {background-color:rgba(255,0,0,0.2);}

            .carousel
            {
               width: 100%;
                height: 250px;
                overflow:hidden;
            }
        </style>


That's what you have right now.


Next, we have another div, with a class of carouselitems. The width is set at 200% of its container, and the height is 90%. This div will contain all the items in your carousel.
<html>
    <head>
        <title>Carousel</title>
        <style>
            div {background-color:rgba(255,0,0,0.2);}

            .carousel
            {
               width: 100%;
                height: 250px;
                overflow:hidden;
            }

            .carouselitems
            {
                width:200%;
                height:90%;
            }
        </style>
    </head>

    <body>
        <div class="carousel">
            <div class="carouselitems">

            </div>
        </div>
    </body>
</html>


Refresh. You should see that the carousel is now a deeper shade of red, and paler at the bottom. That's because the new div is also a translucent shade of red, and overlaid nicely on top of the first div. I set the height temporarily at 90% so you could see the parts where the second div doesn't overlap the first.

Although this div is twice as long as the first, you don't see it sticking out because the overflow property of the first div was set to hidden!.


So set the height of the div to 100%, and we're good to go.
            .carouselitems
            {
                width:200%;
                height:100%;
            }


Now add another div inside that last div you created. It should have the class carouselitem. Singular.
        <div class="carousel">
            <div class="carouselitems">
                <div class="carouselitem">

                </div>
            </div>
        </div>


The CSS class carouselitem is like so. It's floated left and has its height set to 100% and width set to 10%. Why 10%? This will become clear shortly.
            .carouselitems
            {
                width:200%;
                height:100%;
            }

            .carouselitem
            {
                width:10%;
                height:100%;
                float:left;
            }


Your carousel should be looking even redder now on the left. That's because the carouselitem is a translucent red, and overlaid on top of the previous two containing divs!


Still with me? We'll add another two divs inside this new div, and style it with the CSS classes carouselitem_image and carouselitem_content. They will now have its width set to 80% of it's parent. The margin property is set to 0 auto 0 auto to place it right in the middle. The first div is supposed to contain the image, and the second div, the caption.
<html>
    <head>
        <title>Carousel</title>
        <style>
            div {background-color:rgba(255,0,0,0.2);}

            .carousel
            {
               width: 100%;
                height: 250px;
                overflow:hidden;
            }

            .carouselitems
            {
                width:200%;
                height:100%;
            }

            .carouselitem
            {
                width:10%;
                height:100%;
                float:left;
            }

            .carouselitem_image,.carouselitem_content
            {
                width:80%;
                margin 0 auto 0 auto;
            }

            .carouselitem_image
            {
                height:70%;
            }

            .carouselitem_content
            {
                text-align:center;
            }
        </style>
    </head>

    <body>
        <div class="carousel">
            <div class="carouselitems">
                 <div class="carouselitem">
                    <div class="carouselitem_image">
              
                    </div>
                    <div class="carouselitem_content">
                        <p>1</p>
                    </div>
                 </div>
            </div>
        </div>
    </body>
</html>


So far so good?



Now copy this div until you have 5 of them in the same containing div. Number them off.

5 of these suckers make up a width of 50% of the div we styled using the CSS class carouselitems. and since that div is 200% as wide as its parent div, that means 50% of its width is 100% of the first containing div!

Simple math - such fun.
            <div class="carouselitems">
                <div class="carouselitem">
                     <div class="carouselitem_image">
              
                     </div>
                     <div class="carouselitem_content">
                          <p>1</p>
                     </div>
                 </div>

                <div class="carouselitem">
                     <div class="carouselitem_image">
              
                     </div>
                     <div class="carouselitem_content">
                          <p>2</p>
                     </div>
                 </div>

                <div class="carouselitem">
                     <div class="carouselitem_image">
              
                     </div>
                     <div class="carouselitem_content">
                          <p>3</p>
                     </div>
                 </div>

                <div class="carouselitem">
                     <div class="carouselitem_image">
              
                     </div>
                     <div class="carouselitem_content">
                          <p>4</p>
                     </div>
                 </div>

                <div class="carouselitem">
                     <div class="carouselitem_image">
              
                     </div>
                     <div class="carouselitem_content">
                          <p>5</p>
                     </div>
                 </div>
            </div>


And once again, your carousel should be looking really red now. Because 5 of these translucent red divs just about covers the entire carousel.


Now change this line...
div {background-color:rgba(255,0,0,0);}


And let's begin adding images to the carousel, along with some captions. The images should be in a separate folder, named img.
            <div class="carouselitems">
                <div class="carouselitem">
                    <div class="carouselitem_image" style="background-image:url(img/01.jpg)">

                    </div>
                    <div class="carouselitem_content">
                        <p>Fresh from the womb</p>
                    </div>
                </div>

                <div class="carouselitem">
                    <div class="carouselitem_image" style="background-image:url(img/01.jpg)">

                    </div>
                    <div class="carouselitem_content">
                        <p>Tiny pale Yoda</p>
                    </div>
                </div>

                <div class="carouselitem">
                    <div class="carouselitem_image" style="background-image:url(img/02.jpg)">

                    </div>
                    <div class="carouselitem_content">
                        <p>Wants to chew on his Uncle's fingers</p>
                    </div>
                </div>

                <div class="carouselitem">
                    <div class="carouselitem_image" style="background-image:url(img/03.jpg)">

                    </div>
                    <div class="carouselitem_content">
                        <p>More fingers</p>
                    </div>
                </div>

                <div class="carouselitem">
                    <div class="carouselitem_image" style="background-image:url(img/04.jpg)">

                    </div>
                    <div class="carouselitem_content">
                        <p>At age 2</p>
                    </div>
                </div>
            </div>


Uh-oh.


No sweat. The CSS just needs some touching up.
            .carouselitem_image
            {
                height:70%;
                border-radius:1em;
                background-size:cover;
                background-position: center center;
                background-repeat: no-repeat;
            }


Here we are. A row full of little Paul's pics! But something's off here. This thing ain't moving. And if it ain't moving, it ain't a carousel.


So we're going to animate this. Add this to your CSS. This defines a CSS animation, named carousel, and assigns it to the CSS class carouselitems. The animation basically moves the div 100% left of its original position, and repeats for eternity.
            .carouselitems
            {
                width:200%;
                height:100%;
                animation-name: carousel;
                -webkit-animation-name: carousel; /* Chrome, Safari, Opera */
                animation-duration: 15s;
                -webkit-animation-duration: 15s; /* Chrome, Safari, Opera */
                 animation-timing-function: linear;
                -webkit-animation-timing-function: linear;
                animation-iteration-count: infinite;
                -webkit-animation-iteration-count: infinite;
               
            }

            /* Chrome, Safari, Opera */
            @-webkit-keyframes carousel {
                0%   {margin-left:0%;}
                100%  {margin-left:-100%;}
            }

            @keyframes carousel {
                0%   {margin-left:0%;}
                100%  {margin-left:-100%;}
            }


It's moving! But wait. We want this to be infinite. Or at least appear infinite.


We have a couple options here. If you want an entirely JavaScript-free solution, just do this. Copy and paste the div code.
            <div class="carouselitems">
                <div class="carouselitem">
                    <div class="carouselitem_image" style="background-image:url(img/00.jpg)">

                    </div>
                    <div class="carouselitem_content">
                        <p>Fresh from the womb</p>
                    </div>
                </div>

                <div class="carouselitem">
                    <div class="carouselitem_image" style="background-image:url(img/01.jpg)">

                    </div>
                    <div class="carouselitem_content">
                        <p>Tiny pale Yoda</p>
                    </div>
                </div>

                <div class="carouselitem">
                    <div class="carouselitem_image" style="background-image:url(img/02.jpg)">

                    </div>
                    <div class="carouselitem_content">
                        <p>Wants to chew on his Uncle's fingers</p>
                    </div>
                </div>

                <div class="carouselitem">
                    <div class="carouselitem_image" style="background-image:url(img/03.jpg)">

                    </div>
                    <div class="carouselitem_content">
                        <p>More fingers</p>
                    </div>
                </div>

                <div class="carouselitem">
                    <div class="carouselitem_image" style="background-image:url(img/04.jpg)">

                    </div>
                    <div class="carouselitem_content">
                        <p>At age 2</p>
                    </div>
                </div>

                <div class="carouselitem">
                    <div class="carouselitem_image" style="background-image:url(img/00.jpg)">

                    </div>
                    <div class="carouselitem_content">
                        <p>Fresh from the womb</p>
                    </div>
                </div>

                <div class="carouselitem">
                    <div class="carouselitem_image" style="background-image:url(img/01.jpg)">

                    </div>
                    <div class="carouselitem_content">
                        <p>Tiny pale Yoda</p>
                    </div>
                </div>

                <div class="carouselitem">
                    <div class="carouselitem_image" style="background-image:url(img/02.jpg)">

                    </div>
                    <div class="carouselitem_content">
                        <p>Wants to chew on his Uncle's fingers</p>
                    </div>
                </div>

                <div class="carouselitem">
                    <div class="carouselitem_image" style="background-image:url(img/03.jpg)">

                    </div>
                    <div class="carouselitem_content">
                        <p>More fingers</p>
                    </div>
                </div>

                <div class="carouselitem">
                    <div class="carouselitem_image" style="background-image:url(img/04.jpg)">

                    </div>
                    <div class="carouselitem_content">
                        <p>At age 2</p>
                    </div>
                </div>
            </div>


See? It works. But damn, that's a lazy solution and will come back to bite you in the ass when you need to update your code.


Of, if this is being run server-side, use PHP, or whatever server-side scripting language floats your boat.
            <div class="carouselitems" id="carouselitems">
                <?php for ($i=0;$1<2;$i++)  { ?>
                <div class="carouselitem">
                    <div class="carouselitem_image" style="background-image:url(img/00.jpg)">

                    </div>
                    <div class="carouselitem_content">
                        <p>Fresh from the womb</p>
                    </div>
                </div>

                <div class="carouselitem">
                    <div class="carouselitem_image" style="background-image:url(img/01.jpg)">

                    </div>
                    <div class="carouselitem_content">
                        <p>Tiny pale Yoda</p>
                    </div>
                </div>

                <div class="carouselitem">
                    <div class="carouselitem_image" style="background-image:url(img/02.jpg)">

                    </div>
                    <div class="carouselitem_content">
                        <p>Wants to chew on his Uncle's fingers</p>
                    </div>
                </div>

                <div class="carouselitem">
                    <div class="carouselitem_image" style="background-image:url(img/03.jpg)">

                    </div>
                    <div class="carouselitem_content">
                        <p>More fingers</p>
                    </div>
                </div>

                <div class="carouselitem">
                    <div class="carouselitem_image" style="background-image:url(img/04.jpg)">

                    </div>
                    <div class="carouselitem_content">
                        <p>At age 2</p>
                    </div>
                </div>
                <?php } ?>
            </div>


But if you aren't running this on server-side and don't want to do the good ol' copy-paste, here's the JavaScript solution. First, undo the copy-paste job. Then add this JavaScript. It's the function duplicate(). It grabs all the code in the carouselitems div and duplicates it.
        <style>
            div {background-color:rgba(255,0,0,0);}

            .carousel
            {
               width: 100%;
                height: 250px;
                overflow:hidden;
            }

            .carouselitems
            {
                width:200%;
                height:100%;
                -webkit-animation-name: carousel; /* Chrome, Safari, Opera */
                animation-name: carousel;
                -webkit-animation-duration: 15s; /* Chrome, Safari, Opera */
                animation-duration: 15s;  
                -webkit-animation-timing-function: linear;
                animation-timing-function: linear;
                -webkit-animation-iteration-count: infinite;
                animation-iteration-count: infinite;
            }

            /* Chrome, Safari, Opera */
            @-webkit-keyframes carousel {
                0%   {margin-left:0%;}
                100%  {margin-left:-100%;}
            }

            @keyframes carousel {
                0%   {margin-left:0%;}
                100%  {margin-left:-100%;}
            }

            .carouselitem
            {
                width:10%;
                height:100%;
                float:left;
            }

            .carouselitem_image,.carouselitem_content
            {
                width:80%;
                margin 0 auto 0 auto;
            }

            .carouselitem_image
            {
                height:70%;
            }

            .carouselitem_content
            {
                text-align:center;
            }
        </style>

        <script>
            function duplicate()
            {
                var wrapper=document.getElementById("carouselitems");
                var content=wrapper.innerHTML;
                content=content+content;
                wrapper.innerHTML=content;
            }
        </script>


Of course, for that to work, the div must have an id...
<div class="carouselitems" id="carouselitems">


And this has to be added to your body tag.
<body onload="duplicate();">


Run your code again. Does it work? Cool, dude.

The Final Touch

Now we want some semblance of control over when the carousel moves and stops. So do this to your CSS. This changes your mouse cursor to a pointer when you hover over the div, and pauses the animation! You could even say the animation was... Paul-sed. (hur hur)
            .carouselitems
            {
                width:200%;
                height:100%;
                cursor:pointer;
                animation-name: carousel;
                -webkit-animation-name: carousel; /* Chrome, Safari, Opera */
                animation-duration: 15s;  
                -webkit-animation-duration: 15s; /* Chrome, Safari, Opera */
                animation-timing-function: linear;
                -webkit-animation-timing-function: linear;
                animation-iteration-count: infinite;
                -webkit-animation-iteration-count: infinite;
            }

            /* Chrome, Safari, Opera */
            @-webkit-keyframes carousel {
                0%   {margin-left:0%;}
                100%  {margin-left:-100%;}
            }

            @keyframes carousel {
                0%   {margin-left:0%;}
                100%  {margin-left:-100%;}
            }

            .carouselitems:hover
            {
                animation-play-state: paused;
                -webkit-animation-play-state: paused; /* Chrome, Safari, Opera */ 
            }


This is how it should perform. Go on, move your cursor over it and out again.



From here on, you can make the pics link to different pages, or even bring up the Lightbox Effect for magnified pics. The possibilities are endless!

Till next time, stay Paul-sitive!
T___T

No comments:

Post a Comment