uf2pka
Last Updated: August 08, 2017
·
30.13K
· estaples
Self portrait cropped

Normalize Twitter Bootstrap Carousel Slide Heights

Bootstrap carousel is fantastic, but its flexibility can be a challenge. Since each slide item is pretty much freeform HTML, varying slides can have varying heights. This is problematic when page content exists in normal flow after and beneath the carousel, since a shape-shifting carousel is constantly pushing content down or pulling it up on slide transition, making reading difficult—especially on mobile devices. I found that its possible to replicate the behavior of other carousels that dynamically set a consistent height for the whole carousel based on the tallest slide item found in the HTML.

You’ll want to execute jQuery akin to the following, after the carousel HTML exists on the page, or once the DOM is ready (either inside $(document).ready()* or at the end of the page body):

function carouselNormalization() {
var items = $('#carousel-example-generic .item'), //grab all slides
    heights = [], //create empty array to store height values
    tallest; //create variable to make note of the tallest slide

if (items.length) {
    function normalizeHeights() {
        items.each(function() { //add heights to array
            heights.push($(this).height()); 
        });
        tallest = Math.max.apply(null, heights); //cache largest value
        items.each(function() {
            $(this).css('min-height',tallest + 'px');
        });
    };
    normalizeHeights();

    $(window).on('resize orientationchange', function () {
        tallest = 0, heights.length = 0; //reset vars
        items.each(function() {
            $(this).css('min-height','0'); //reset min-height
        }); 
        normalizeHeights(); //run it again 
    });
}
}

*With older versions of jQuery at least, IE8 and below don’t respond to $(document).ready(), so you may need a workaround for that.

Say Thanks
Respond

9 Responses
Add your response

16364
145a2037a46e2fedfeddcc6bdaf64614

saved me some time, thank you Eddie. One thing you might mention for is you need to call 'carouselNormalization();' at the end of the function declaration.

over 1 year ago ·
16429
D764d87dfe046bf056c40ae2d7a71ff2

A little cleaner

// Normalize Carousel Heights - pass in Bootstrap Carousel items.
$.fn.carouselHeights = function() {

    var items = $(this), //grab all slides
        heights = [], //create empty array to store height values
        tallest; //create variable to make note of the tallest slide

    var normalizeHeights = function() {

        items.each(function() { //add heights to array
            heights.push($(this).height()); 
        });
        tallest = Math.max.apply(null, heights); //cache largest value
        items.each(function() {
            $(this).css('min-height',tallest + 'px');
        });
    };

    normalizeHeights();

    $(window).on('resize orientationchange', function () {
        //reset vars
        tallest = 0;
        heights.length = 0;

        items.each(function() {
            $(this).css('min-height','0'); //reset min-height
        }); 
        normalizeHeights(); //run it again 
    });

};

jQuery(function($){

    $(window).on('load', function(){
        $('#carousel-hero .item').carouselHeights();
    });

});
over 1 year ago ·
16475
D20c1d02e9281ab53d650abdaa8ca8a5 normal

great article! thanks so much!

over 1 year ago ·
18158
8ro 7dao normal

Thank you!

over 1 year ago ·
18360
None

This code makes the opposite:
takes the shortest image and sets that value as the maximum height.
All other slides appear cropped

HOW TO USE: change the carousel id (#carousel-single) and paste after your carousel

<script> 
jQuery('.carousel').carousel({interval: 3000 });
// Normalize Carousel Heights - pass in Bootstrap Carousel items.
function carouselNormalization() {
var items = jQuery('#carousel-single .item'), //grab all slides
heights = [], //create empty array to store height values
shortest; //create variable to make note of the shortest slide

if (items.length) {
function normalizeHeights() {
items.each(function() { //add heights to array
heights.push(jQuery(this).height());
});
shortest = Math.min.apply(null, heights); //cache largest value
items.each(function() {
jQuery('.carousel-inner').css('height',shortest + 'px').css('overflow','hidden');

});
};
normalizeHeights();

jQuery(window).on('resize orientationchange', function () {
shortest = 0, heights.length = 0; //reset vars
items.each(function() {
jQuery('.carousel-inner').css('height','0'); //reset min-height
});
normalizeHeights(); //run it again
});
}
}
carouselNormalization();
</script>
over 1 year ago ·
20707
0 8geyky2cs9vsj8n 86wsk0mdz rsjlc gly3k0aobnxe6tht2xstoxsrn0k5sg9ot3e8xzrxrew1

I made another version that worked better for me. This one fixes the height of the carousel div to such a height that the biggest image fits in it.

Note that I use a custom way to measure images because, when they are hidden, they sometimes are 0px.

This version supports multiple carousel in one document and does not assume one 'id' is used


function normalizeSizesAllCarousels(){ jQuery('.carousel.slide').each(function(){//we loop all the present carousels normalizeSizesOneCarousel('#' + jQuery(this).attr('id')); }); } function normalizeSizesOneCarousel(idSelectorCarousel){ var images=jQuery(idSelectorCarousel + ' .carousel-inner .item img'); var availableWidht=jQuery(idSelectorCarousel).innerWidth(); var maxHeight=0; var imageHeight=0; var aspectRatio=1;//width/height images.each(function(){ aspectRatio=calcImgWidth(this)/calcImgHeight(this); imageHeight=availableWidht/aspectRatio; if(imageHeight>maxHeight){maxHeight=imageHeight;} }); jQuery(idSelectorCarousel).height(maxHeight); } function calcImgWidth(img){ var width=img.width; if (width>0){ return width; }else{ jQuery('body').append('<div id="tempContainer" style="visibility:hidden;position:absolute"></div>'); jQuery('#tempContainer').append(img.clone().attr('id',false)); width= jQuery('#tempContainer img').width; jQuery('#tempContainer').remove(); return width; } } function calcImgHeight(img){ var height=img.height; if (height>0){ return height; }else{ jQuery('body').append('<div id="tempContainer" style="visibility:hidden;position:absolute"></div>'); jQuery('#tempContainer').append(img.clone().attr('id',false)); height= jQuery('#tempContainer img').height; jQuery('#tempContainer').remove(); return height; } } jQuery(document).ready(function(){normalizeSizesAllCarousels();}); jQuery(window).on('resize orientationchange', function () {normalizeSizesAllCarousels();}); </code> </pre>
over 1 year ago ·
25005
0 glx besmkpeqyn7 mh50mjmm xxfy6p7bv5ytjf796oqj9ccalbpxscmz iu0bp0tvi pz4a0vq6sgwgwgsaxyjgsvqbsg6 agsang2fln3ikqj0cp2xqdgovhab1gltbtoo1iuss4b

The resize event fires twice on my webpage, and I had to use "height" instead of "min-height", that's my version of your script:


$(window).load(function() {
$('.carousel').each(function(){
$(this).carouselHeights();
});
});

// Normalize Bootstrap Carousel Heights
$.fn.carouselHeights = function() {
var items = $(this).find('.item'), // grab all slides
heights = [], // create empty array to store height values
tallest, // create variable to make note of the tallest slide
call;
var normalizeHeights = function() {
items.each(function() { // add heights to array
heights.push($(this).outerHeight());
});
tallest = Math.max.apply(null, heights); // cache largest value
items.css('height', tallest);
};
normalizeHeights();
$(window).on('resize orientationchange', function() {
// reset vars
tallest = 0;
heights.length = 0;
items.css('height', ''); // reset height
if(call){
clearTimeout(call);
};
call = setTimeout(normalizeHeights, 100); // run it again
});
};
</pre>

over 1 year ago ·
25022
None

Does anyone have a working page with this working. I am struggling to get any of the above versions to work.

over 1 year ago ·
29180

Thank you very much Eddie and also tonycronin for providing this efficient solution to Bootstrap's carousel height issue. The code from tonycronin worked great for me.

4 months ago ·