69

I've been using Bootstrap's carousel class and it has been straightforward so far, however one problem I've had is that images of different heights cause the arrows to bounce up and down to adjust to the new height..

This is the code I'm using for my carousel:

<div id="myCarousel" class="carousel slide">
    <div class="carousel-inner">
        <div class="item active">
            <img src="image_url_300height"/>
            <div class="carousel-caption">
                <h4>...</h4>
                <p>...</p>
            </div>
        </div>
        <div class="item">
            <img src="image_url_700height" />
        </div>
    </div>
    <!-- Carousel nav -->
    <a class="carousel-control left" href="#myCarousel" data-slide="prev">&lsaquo;</a>
    <a class="carousel-control right" href="#myCarousel" data-slide="next">&rsaquo;</a>
</div>

The problem is also illustrated in this jsfiddle (Admittedly not mine, I found this on a separate question while trying to solve this problem!)

My question is: How can I force the carousel to stay at a fixed height (second thumbnail in the fiddle) and center smaller images while keeping the captions and arrow in a static position relative to the carousel?

mrjimoy_05
  • 3,452
  • 9
  • 58
  • 95
steve-gregory
  • 7,396
  • 8
  • 39
  • 47

14 Answers14

93

It looks like bootstrap less/CSS forces an automatic height to avoid stretching the image when the width has to change to be responsive. I switched it around to make the width auto and fix the height.

<div class="item peopleCarouselImg">
  <img src="http://upload.wikimedia.org/...">
  ...
</div>

I then define img with a class peopleCarouselImg like this:

.peopleCarouselImg img {
  width: auto;
  height: 225px;
  max-height: 225px;
}

I fix my height to 225px. I let the width automatically adjust to keep the aspect ratio correct.

This seems to work for me.

Confused
  • 1,602
  • 15
  • 25
jduprey
  • 1,176
  • 1
  • 9
  • 9
20

Try this (I'm using SASS):

/* SASS */
.carousel {
  max-height: 700px;
  overflow: hidden;

  .item img {
    width: 100%;
    height: auto;
  }
}

You can wrap the .carousel into a .container if you wish.

/* CSS */
.carousel {
  max-height: 700px;
  overflow: hidden;
}

.carousel .item img {
  width: 100%;
  height: auto;
}

The key point will be to keep the height consistent. That's where the max-height comes in, to constraint larger images.

Alternatively, you can set the image as a background image, giving you more flexibility on the height and image positioning (e.g. background-size, background-position, etc.)

For responsiveness, you'll need to use media queries.

EDIT: Thanks all, didn't know this is still being searched for. Vote up to help other devs!

Khairul
  • 840
  • 8
  • 14
15

Try with this jQuery code that normalize Bootstrap carousel slide heights

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 
    });
  }
}

/**
 * Wait until all the assets have been loaded so a maximum height 
 * can be calculated correctly.
 */
window.onload = function() {
  carouselNormalization();
}
Mile Mijatović
  • 2,948
  • 2
  • 22
  • 41
  • 8
    Can't edit your answer, but you need this to call the above function: window.onload = function() { carouselNormalization(); } Worked like a charm AND is responsive!... Plus I found the original here: http://ryanringler.com/blog/2014/08/24/fixed-height-carousel-for-twitter-bootstrap – Malachi Jun 27 '17 at 18:45
  • 1
    this was exactly what I was looking for. Thank you. – Eliezer Wohl Feb 07 '18 at 03:02
  • This deserves more upvotes! Thank you, kind sir/ma'am! – Web Dev Sep 17 '18 at 08:06
11

You can also use this code to adjust to all carousel images.

.carousel-item{
    width: 100%; /*width you want*/
    height: 500px; /*height you want*/
    overflow: hidden;
}
.carousel-item img{
    width: 100%;
    height: 100%;
    object-fit: cover;
}
MrAnyx
  • 234
  • 3
  • 5
  • Top answers have dozens of upvotes and this has 3... All you really need is to set the height for all carousel items: `.carousel-item { height: 500px; }`. Solid answer. – Justin Jun 05 '20 at 23:51
  • this is literally all you would ever need. brilliant man. get this up there!! – SeventhWarhawk Jun 24 '20 at 18:16
  • If your images are particularly tall, setting `object-fit` to `contain` will give you better results. And it bears mentioning that `object-fit` doesn't work in IE. – JamesQMurphy Oct 18 '20 at 13:09
5

Here is the solution that worked for me; I did it this way as the content in the carousel was dynamically generated from user-submitted content (so we could not use a static height in the stylesheet) - This solution should also work with different sized screens:

function updateCarouselSizes(){
  jQuery(".carousel").each(function(){
    // I wanted an absolute minimum of 10 pixels
    var maxheight=10; 
    if(jQuery(this).find('.item,.carousel-item').length) {
      // We've found one or more item within the Carousel...
      jQuery(this).carousel(); // Initialise the carousel (include options as appropriate)
      // Now we iterate through each item within the carousel...
      jQuery(this).find('.item,.carousel-item').each(function(k,v){ 
        if(jQuery(this).outerHeight()>maxheight) {
          // This item is the tallest we've found so far, so store the result...
          maxheight=jQuery(this).outerHeight();
        }
      });
      // Finally we set the carousel's min-height to the value we've found to be the tallest...
      jQuery(this).css("min-height",maxheight+"px");
    }
  });
}

jQuery(function(){
  jQuery(window).on("resize",updateCarouselSizes);
  updateCarouselSizes();
}

Technically this is not responsive, but for my purposes the on window resize makes this behave responsively.

SteJ
  • 1,491
  • 11
  • 13
4

In case someone is feverishly googling to solve the bouncing images carousel thing, this helped me:

.fusion-carousel .fusion-carousel-item img {
    width: auto;
    height: 146px;
    max-height: 146px;
    object-fit: contain;
}
Jason Kim
  • 18,102
  • 13
  • 66
  • 105
Kyle Pennell
  • 5,747
  • 4
  • 52
  • 75
2

The solution given earlier leads to a situation where images may be too small for the carousel box. A proper solution to the problem of bumping controls is to override Bootstraps CSS.

Original code:

.carousel-control {
top: 40%;
}

Override the variable with a fixed value inside your own stylesheet (300px worked in my design):

.carousel-control {
top: 300px;
}

Hopefully this will solve your problem.

Oliveira
  • 49
  • 6
  • When i implemented this the side controls quit working as buttons and the chevrons dropped to the bottom. – Post Impatica Oct 27 '15 at 13:58
  • You should use a fixed value instead of percentages because your container has a variable height. In my design 300px worked. Maybe you should use about 150px. I think they stopped working as buttons because there is or are other elements on top of the buttons. – Oliveira Nov 03 '15 at 14:33
2

Include this JavaScript in your footer (after loading jQuery):

$('.item').css('min-height',$('.item').height());
Bugs
  • 4,491
  • 9
  • 32
  • 41
1

If you want to have this work with images of any height and without fixing the height, just do this:

$('#myCarousel').on("slide.bs.carousel", function(){
     $(".carousel-control",this).css('top',($(".active img",this).height()*0.46)+'px');
     $(this).off("slide.bs.carousel");
});
toha
  • 5,095
  • 4
  • 40
  • 52
1

More recently I am testing this CSS source for the Bootstrap carousel

The height set to 380 should be set equal to the biggest/tallest image being displayed...

/* CUSTOMIZE THE CAROUSEL
-------------------------------------------------- */

/* Carousel base class */
.carousel {
  max-height: 100%;
  max-height: 380px;
  margin-bottom: 60px;
  height:auto;
}
/* Since positioning the image, we need to help out the caption */
.carousel-caption {
  z-index: 10;
    background: rgba(0, 0, 0, 0.45);
}

/* Declare heights because of positioning of img element */
.carousel .item {
  max-height: 100%;
  max-height: 380px;
  background-color: #777;
}
.carousel-inner > .item > img {
 /*  position: absolute;*/
  top: 0;
  left: 0;
  min-width: 40%;
  max-width: 100%;
  max-height: 380px;
  width: auto;
  margin-right:auto;
  margin-left:auto;
  height:auto;
  
}
Ryan M
  • 18,333
  • 31
  • 67
  • 74
CrandellWS
  • 2,708
  • 5
  • 49
  • 111
  • 1
    This caused the side navigation areas to be super dark and it looked strange. I usually like to use the most current answer for some weird reason but the suggested answer worked great so i should have started there. – Post Impatica Oct 27 '15 at 14:04
  • you can remove/change the `background-color: #777;` – CrandellWS Oct 27 '15 at 16:25
0

You can use this lines in the css file:

ul[rn-carousel] {
 > li {
 position: relative;
 margin-left: -100%;

 &:first-child {
   margin-left: 0;
   }
  }
}
Hetdev
  • 1,425
  • 2
  • 21
  • 29
0
 .className{
 width: auto;
  height: 200px;
  max-height: 200px;
   max-width:200px
   object-fit: contain;
}
arvind grey
  • 150
  • 12
0

This jQuery function worked best for me. I'm using bootstrap 4 within a WordPress theme and I've used the full jQuery instead of jQuery slim.

// Set all carousel items to the same height
function carouselNormalization() {

    window.heights = [], //create empty array to store height values
    window.tallest; //create variable to make note of the tallest slide

    function normalizeHeights() {
        jQuery('#latest-blog-posts .carousel-item').each(function() { //add heights to array
            window.heights.push(jQuery(this).outerHeight());
        });
        window.tallest = Math.max.apply(null, window.heights); //cache largest value
        jQuery('#latest-blog-posts .carousel-item').each(function() {
            jQuery(this).css('min-height',tallest + 'px');
        });
    }
    normalizeHeights();

    jQuery(window).on('resize orientationchange', function () {

        window.tallest = 0, window.heights.length = 0; //reset vars
        jQuery('.sc_slides .item').each(function() {
            jQuery(this).css('min-height','0'); //reset min-height
        }); 

        normalizeHeights(); //run it again 

    });

}

jQuery( document ).ready(function() {
    carouselNormalization();
});

Source:

https://gist.github.com/mbacon40/eff3015fe96582806da5

createscape
  • 713
  • 7
  • 20
0

Note that the jQuery solutions that normalize height on here may break with IE.

After some testing (with Bootstrap 3) it looks like IE doesn't bother resizing images unless they're actually being rendered. If you make the window smaller, the image of the active item gets resized but the background images preserve their height, so the "tallest" height stays the same.

In my case we were only rendering images on these items, and the images were only ever a few pixels off. So I opted to style all of the images with the height of the active image. Everything else gets resized to fit the height, so keep that in mind if your aspect ratios vary a lot.

    function carouselNormalization() {
        var items = $('.carousel .item');

        if (items.length) {
            function normalizeHeights() {
                let activeImageHeight = items.filter('.active').find('img').height();
                items.each(function() {
                    $(this).find('img').css('height',  activeImageHeight + 'px');
                });
            };
            normalizeHeights();

            $(window).on('resize orientationchange', function() {
                items.each(function() {
                    $(this).find('img').removeAttr('style');
                });
                normalizeHeights();
            });
        }
    }
    $(window).on('load', carouselNormalization);
James Ford
  • 21
  • 1
  • 3