Munna Tripathi
Munna Tripathi

Reputation: 105

How to make equal height of Bootstrap v5.0 Carousel slider all images

I am trying to create a slider with Bootstrap v5.0 Carousel. I am having some issue with the slider images. The height of the pictures is not equal. That look the slider ugly.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Carousel</title>
</head>

<body>
    <div class="bg-light">
        <div class="container">
            <div class="carousel slide" id="carousel1" data-bs-ride="carousel">
                <div class="carousel-inner">
                    <div class="carousel-item active">
                        <img src="./images/slider 00.jpg" class="d-block w-100 h-100">
                    </div>
                    <div class="carousel-item">
                        <img src="./images/slider 01.jpg" class="d-block w-100 h-100">
                    </div>
                    <div class="carousel-item">
                        <img src="./images/slider 02.jpg" class="d-block w-100 h-100">
                    </div>
                    <div class="carousel-item">
                        <img src="./images/slider 03.jpg" class="d-block w-100 h-100">
                    </div>
                </div>
                <button class="carousel-control-prev" type="button" data-bs-target="#carousel1" data-bs-slide=
                prev>
                    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
                    <span class="visually-hidden">Previous</span>
                </button>
                <button class="carousel-control-next" type="button" data-bs-target="#carousel1" data-bs-slide=
                next>
                    <span class="carousel-control-next-icon" aria-hidden="true"></span>
                    <span class="visually-hidden">Next</span>
                </button>
            </div>
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf"
        crossorigin="anonymous"></script>
</body>

</html>

How can I make them all equal height?

I tried with CSS img height height: x px; but that looks ugly. How can I solve the issue?

Upvotes: 0

Views: 2139

Answers (2)

rexblack
rexblack

Reputation: 171

Since it is only showing two slides at a time, a javascript solution would inevitably need to switch display in order to read out image dimensions which would most probably cause a reflow. So, why not go for a server-side solution? Though, of course you could apply the same pattern to client-side logics, too.

So, the idea is to determine the aspect ratio of the tallest image and then apply it to all of the items. Natural resizing can be achieved by applying the aspect ratio to an svg and wrap it inside a display grid container.

Here's an implementation in wordpress context:

<?php
  global $wp_query;

  $max = array_reduce($wp_query->posts, function($result, $post) use ($size) {
    list($src, $width, $height) = wp_get_attachment_image_src($post->ID, $size, false);

    if ($width * $height > $result['width'] * $result['height']) {
      $result['width'] = $width;
      $result['height'] = $height;
    }

    return $result;
  }, [
    'width' => 0,
    'height' => 0
  ]);

  $greatestCommonDivisor = static function($width, $height) use (&$greatestCommonDivisor) {
    return ($width % $height) ? $greatestCommonDivisor($height, $width % $height) : $height;
  };

  $divisor = $greatestCommonDivisor($max['width'], $max['height']);

  $ratio_x = $max['width'] / $divisor;
  $ratio_y = $max['height'] / $divisor;
?>
<div
  id="<?= $id ?>-carousel"
  <?php if (get_theme_mod('carousel_colorscheme') !== 'dark'): ?>
    data-bs-theme="dark"
  <?php endif; ?>
  class="carousel slide h-100"
  data-bs-ride="false"
  data-bs-interval="<?= !$autoplay ? 'false' : $interval; ?>"
>
  <div class="carousel-indicators" data-control>
    <?php while( have_posts()) : the_post() ?>
      <button
        data-bs-target="#<?= $id ?>-carousel"
        data-bs-slide-to="<?= $wp_query->current_post; ?>"
        class="<?= $wp_query->current_post === 0 ? 'active' : '' ?>"
      ></button>
    <?php endwhile; ?>
  </div>
  <div class="carousel-inner h-100">
    <?php while( have_posts()) : the_post() ?>
      <div class="carousel-item h-100<?= $wp_query->current_post === 0 ? ' active' : '' ?>">
        <div style="display: grid;">
          <svg viewBox="0 0 <?= $ratio_x ?> <?= $ratio_y ?>" style="grid-area: 1 / 1 / 2 / 2;"></svg>
          <div class="w-100 h-100" style="grid-area: 1 / 1 / 2 / 2;">
            <?= wp_get_attachment_image($post->ID, $size, false, [
              'class' => "img-fluid m-0 w-100 h-100",
              'style' => "object-fit: contain; object-position: center",
              'loading' => 'lazy'
            ]); ?>
            <?php if ($caption = wp_get_attachment_caption()): ?>
              <div class="carousel-caption d-none">
                <?= $caption ?>
              </div>
            <?php endif; ?>
          </div>
        </div>
      </div>
    <?php endwhile; ?>
  </div>
  <button class="carousel-control-prev" type="button" data-bs-target="#<?= $id ?>-carousel" data-bs-slide="prev" data-control>
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    <span class="visually-hidden">Previous</span>
  </button>
  <button class="carousel-control-next" type="button" data-bs-target="#<?= $id ?>-carousel" data-bs-slide="next" data-control>
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
    <span class="visually-hidden">Next</span>
  </button>
</div>

Upvotes: 0

Sifat Haque
Sifat Haque

Reputation: 6057

You can use fix height in this selector .carousel-inner div

.carousel-inner div {
    height: 400px;
    object-fit: cover;

}

.carousel-inner div {
    height: 400px;
    object-fit: cover;
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Carousel</title>
</head>

<body>
    <div class="bg-light">
        <div class="container">
            <div class="carousel slide" id="carousel1" data-bs-ride="carousel">
                <div class="carousel-inner">
                    <div class="carousel-item active">
                        <img src="https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg" class="d-block w-100 h-100">
                    </div>
                    <div class="carousel-item">
                        <img src="https://neilpatel.com/wp-content/uploads/2017/09/image-editing-tools.jpg" class="d-block w-100 h-100">
                    </div>
                    <div class="carousel-item">
                        <img src="https://helpx.adobe.com/content/dam/help/en/photoshop/using/convert-color-image-black-white/jcr_content/main-pars/before_and_after/image-before/Landscape-Color.jpg" class="d-block w-100 h-100">
                    </div>
                    <div class="carousel-item">
                        <img src="https://thumbs.dreamstime.com/b/environment-earth-day-hands-trees-growing-seedlings-bokeh-green-background-female-hand-holding-tree-nature-field-gra-130247647.jpg" class="d-block w-100 h-100">
                    </div>
                </div>
                <button class="carousel-control-prev" type="button" data-bs-target="#carousel1" data-bs-slide=
                prev>
                    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
                    <span class="visually-hidden">Previous</span>
                </button>
                <button class="carousel-control-next" type="button" data-bs-target="#carousel1" data-bs-slide=
                next>
                    <span class="carousel-control-next-icon" aria-hidden="true"></span>
                    <span class="visually-hidden">Next</span>
                </button>
            </div>
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf"
        crossorigin="anonymous"></script>
</body>

</html>

Upvotes: 2

Related Questions