Tuesday, September 23, 2014

Customizing and Improving Twitter Bootstrap Carousel

Twitter Bootstrap is a great starting place for many pieces of a website, from basic CSS elements to more complicated JavaScript oriented parts such as tabs. Everything also comes fully responsive,  ready for the mobile and tablet views. So when creating a client’s website with a carousel, it was a no-brainer choice to start with Bootstrap. However, from a look and feel standpoint, we had some work to do.

Our Requirements:

- Captions for slide indicators

- Carousel needed to be full page width while being friendly to CMS uploaded pictures

- Fully responsive without losing content: keep the title and description/button viewable and readable on mobile without covering the entire picture

My solution to go from basic carousel to finished product:

- Add caption text within the indicator and give a height and width

- Replace image with a div that uses the uploaded image as a background-image

- Move title and description to below the picture for mobile, keeping on top of picture would hide a large portion of picture

Demo comparing my version to the default: Comparison Demo

Here's the Html to our updated carousel:

<div class="container-fluid hero">

    <!-- Carousel -->

    <div id="hero-carousel" class="carousel slide" data-ride="carousel">

        <!-- Indicators -->

        <ol class="carousel-indicators row">

            <li data-target="#hero-carousel" data-slide-to="0" class="col-sm-4 message-1 active">

                <div class="caption">CAPTION 1</div>

            </li>

            <li data-target="#hero-carousel" data-slide-to="1" class="col-sm-4 message-2">

                <div class="caption">CAPTION 2</div>

            </li>

            <li data-target="#hero-carousel" data-slide-to="2" class="col-sm-4 message-3">

                <div class="caption">CAPTION 3</div>

            </li>

        </ol>

        <!-- Wrapper for slides -->

        <div class="carousel-inner">

            <div class="item active">

                <div class="carousel-card" style='background-image: url("..."); background-size: cover;'></div>

                <div class="carousel-caption">

                    <h1 class="message-1">Title 1</h1>

                    <p><a href="#" class="btn btn-lg message-1">Link to title 1</a></p>

                </div>

            </div>

            <div class="item">

                <div class="carousel-card" style='background-image: url("..."); background-size: cover;'>

                </div>

                <div class="carousel-caption">

                    <h1  class="message-2">Title 2!</h1>

                    <p><a href="#" class="btn btn-lg message-2">Link to title 2</a></p>

                </div>

            </div>

            <div class="item">

                <div class="carousel-card" style='background-image: url("..."); background-size: cover;'>

                </div>

                <div class="carousel-caption">

                    <h1  class="message-3">Title 3?</h1>

                    <p><a href="#" class="btn btn-lg message-3">Link to title 1</a></p>

                </div>

            </div>

        </div>

    </div>    

</div>

<!-- End Carousel –>

 

The first change to the carousel is to simply insert captions into the carousel indicators:

<!-- Indicators -->

<ol class="carousel-indicators row">

    <li data-target="#hero-carousel" data-slide-to="0" class="col-sm-4 message-1 active">

        <div class="caption">CAPTION 1</div>

    </li>

    <li data-target="#hero-carousel" data-slide-to="1" class="col-sm-4 message-2">

        <div class="caption">CAPTION 2</div>

    </li>

    <li data-target="#hero-carousel" data-slide-to="2" class="col-sm-4 message-3">

        <div class="caption">CAPTION 3</div>

    </li>

</ol>

 

First, we make our indicator group take the entire width of our carousel, and then give each indicator an even amount of width to fill up 100% of our width. I also give each 'li' element custom styling to give the box look.

.hero .carousel-indicators {

    bottom: -10px;

    left: 0;

    margin-left: 0;

    width: 100%;

}

     .hero .carousel-indicators li {

        border: none;

        border-radius: inherit;

        cursor: pointer;

        display: inline-block;

        height: 80px;

        margin: 0px;

        padding: 25px 0;

        opacity: .9;

        text-indent: 0;

    }

        .hero .carousel-indicators li .caption {

            font-size: 20px;

            font-weight: bold;

            height: 100%;

            text-transform: uppercase;

            width: 100%;

        }

 .hero .carousel-indicators .col-sm-4 {

        width: 33.33333333333333%;

    }

 

When it comes to mobile, these don't transfer very well for mobile, so we go right back to bootstrap's default.

@media (max-width: 767px) {

    .hero .carousel-indicators .col-sm-3 {

        width: 10px;

    }

    .hero .carousel-indicators {

        bottom: 250px;

    }

        /* no change from bootstrap code */

        .hero .carousel-indicators li {

            background-color: #000 \9;

            background-color: rgba(0, 0, 0, 0);

            border: 1px solid #fff;

            border-radius: 10px;

            cursor: pointer;

            display: inline-block;

            height: 10px;

            margin: 1px;

            padding: 0;

            text-indent: -999px;

            width: 10px;

        }

        .hero .carousel-indicators .active {

            background-color: #fff;

            height: 12px;

            margin: 0;

            width: 12px;

        }

        .hero .carousel-indicators li .caption {

            display: none;

        }

}

 

I use inline style for the background image as we are using a CMS to import the picture, this is the easiest way to meet those needs. The style background-size: cover;'  takes the image and make sure it covers the entire height and width of our carousel area. We also give the image a fixed height of 500px.

.hero .carousel-inner .item .carousel-card {

    height: 500px;

    width: 100%;

}

 

To move the title and description below for mobile requires some media queries to keep them in a correct position. Since we make the indicators much bigger than default in desktop and tablet, we need to move the carousel-caption up. We then need to position it underneath when we move to mobile.

.hero .carousel-caption {

    bottom: 100px;

}



@media (max-width: 767px) {

    .hero .carousel-caption {

        bottom: 0px;

    }

}

 

I also added plenty of CSS to make it look pretty with individual colors for each section. Also, resize your browser to check out how it reacts responsively.

Here’s the full CSS.

.hero.container-fluid {

    padding: 0;

}

.hero .message-1 {

    background: #356DBF;

    color: #333;

}

.hero .message-2 {

    background: #3BBF6A;

    color: #333;

}

.hero .message-3 {

    background: #BF4042;

    color: #333;

}

    .hero .message-1:hover,

    .hero .message-2:hover,

    .hero .message-3:hover {

        color: #fff;

    }

    .hero .message-1:active,

    .hero .message-2:active,

    .hero .message-3:active {

        color: #fff;

        opacity: 1;

    }

.hero .btn.message-1,

.hero .btn.message-2,

.hero .btn.message-3 {

    color: #fff;

    font-size: 16px;

    font-weight: bold;

}

    .hero .btn.message-1:hover {