0
votes

I have a bootstrap 4 carousel:

<section id="carousel-landing" class="carousel slide" data-ride="carousel">
  <div class="carousel-inner" role="listbox">
    <div class="carousel-item active">
      <h1>Title 1</h1>
      <p>text 1</p>
      <img src="img.jpg">
    </div>
    <div class="carousel-item">
      <h1>Title 2</h1>
      <p>text 2</p>
      <img src="img.jpg">
    </div>
    <div class="carousel-item">
      <h1>Title 3</h1>
      <p>text 3</p>
      <img src="img.jpg">
    </div>
  </div>
  <a class="left carousel-control" href="#carousel-landing" role="button" data-slide="prev">
    <span class="icon-prev" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="right carousel-control" href="#carousel-landing" role="button" data-slide="next">
    <span class="icon-next" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>
</section>

The #carousel-landing, .carousel-inner and .carousel-item all have heights set to 100%. h1, p and img are stacked beneath each other. If the h1 and p on each slide have diferent heights, how do I set the height of each image to fill the rest of the viewport?

I tried with this:

$(document).ready(imgResize);
$(window).on('resize',imgResize);

function imgResize() {  
    $('#carousel-landing .carousel-item').each(function() {
            var dynamic_height = ($('#carousel-landing .carousel-item').height() - $('#carousel-landing .carousel-item h1').outerHeight() - $('#carousel-landing .carousel-item p').outerHeight()) - 40;
            $('#carousel-landing .carousel-item img').css("height", dynamic_height + "px");
    });
}

but this targets only the first slide and it sets the rest of the images to have the same heights as the first. On browser resize it works only on the first slide, When the next slide slides in and the browser is resized the image suddenly resizes to 100% height as if h1 and p elements don't even exist

2
can you post an image here what you want to accomplish? just some screenshot edited in paint or something - neuronet
Basically I want the slider to be 100% height, h1 and p on each slide would be of differing heights, and the image should fill the rest of the viewport on each slide. - Goran Tesic
any luck? did you implement any any response? - neuronet
Nothing really helped. I ended up setting "var carouselHeight = $("#carousel-landing").outerHeight()", "textHeight = 265" and "height = carouselHeight - textHeight", so now at least I don't get bugs with subsequent slides, since, as Denis pointed out, the issue seems to be that the code for height is applied before the next bootstrap carousel slide is rendered. It does the job for now because the slides have content of similar heights, but it's not really the solution I hoped for. - Goran Tesic

2 Answers

0
votes

You have to subtract the height of your text from the height of your carousel-item div, here you go: https://jsfiddle.net/aufbhkdv/37/

$(".carousel-item").each(function(){
      var carouselHeight = $(this).outerHeight(),
              textHeight = $(this).children("h1").outerHeight() + $(this).children("p").outerHeight();

      $(this).children("img").height(carouselHeight - textHeight);
    });
0
votes

if you want to fill your content to bee 100% filled with image you must "crop" your picture to preserve image ratio, image will not be stretched then

when your slide is visible (you must have some events to be notified about this)

you must do this to all of your slides after they are shown (to be able to measure everything)

  1. get carousel inner height (carouselHeight)
  2. calculate how much space left (under the h1 and p) leftSpace = (carouselHeight - h1.height - p.height)
  3. get image dimensions
  4. calculate ratio after widening the image to 100% (ratio= carousel width / image width)
  5. set new img height like newImageHeight = ratio * image height
  6. set margin top to negative value = -(0.5*newImageHeight - 0.5*leftSpace) (this will center the image vertically)
  7. wrap your image in div "image-wrapper" and set overflow of this div to hidden (to crop your picture)

but if you want to browser do it automatically for you then you can use background-size:cover;

just get image src and replace img with div with background set to this src and set height this div to fill left space and set background-size to cover

$(".carousel-item").each(function(){
      let carouselHeight = $(this).outerHeight();
      let textHeight = $(this).children("h1").outerHeight() + $(this).children("p").outerHeight();

      let src=$(this).children("img").attr('src');
      $(this).append('<div style="background:url('+src+') center center;background-size:cover;width:100%;height:'+(carouselHeight-textHeight)+'px"></div>');
      $(this).children("img").remove();
    });

https://jsfiddle.net/aufbhkdv/46/