Define image height through element width

Viewed 240

Problem: I'm currently trying to generate Lightbox/Modals with a slideshow in it, in my case I'm using slick carousel for the slideshow and generate the content with barba.js.

Each image in the slideshow must be have a height of 100vh minus some paddings in the HTML. But I can only control the height of the images through the parent divs width, due to the js carousel and my need to make it work in a modal with a somewhat controllable width.

Wacko solution: If I only had images with the same size/aspect ratio something like that would work:

.content--detail {
  width: 100%;
  max-width: calc((100vh - 120px) / 1.6);
  height: auto;
  max-height: calc(100vh - 150px);
}
.content--detail img {
  width: 100%;
  height: auto;
}

I also tried to get the aspect ratio of the image and try to set the width that way:

$('.slider').on('afterChange', function(){
  var ratio = $('.slick-current').height() / $('.slick-current').width();
  $('.content--detail').css('maxWidth', 'calc((100vh - 120px) /' + ratio + ')');
});

But that doesn't fit aswell, so does someone know how I can make this work? Is there a possible formula to control to a dynamic image to the viewport height through the width? I'm out of ideas, really :)

Thanks a bunch!

Codepen example: https://codepen.io/qubism/pen/ExNgyyy

$(".splide").slick({
  lazyLoad: "ondemand",
  slidesToShow: 1,
  slidesToScroll: 1,
  infinite: false,
  adaptiveHeight: true
});
html,
body {
  overflow: hidden;
  background: #ccc
}

.contrainer-wrap {
  width: 100%;
  height: 100%;
  position: relative;
}

.content {
  font-size: 24px;
  line-height: 29px;
  color: #000;
  background: #fff;
  right: 320px;
  position: absolute;
  z-index: 101;
  overflow-x: auto;
  opacity: 1;
}

.content--detail {
  width: 100%;
  max-width: calc((100vh - 120px) / 1.7);
  height: auto;
  max-height: -webkit-calc(100vh - 150px);
  max-height: calc(100vh - 150px);
  max-height: 100%;
  top: 0;
  padding: 30px 30px 20px 30px;
  margin-left: auto;
  margin-right: auto;
}

.slick-slide img {
  width: 100%;
  height: auto;
}

.gallery-img__detail__desc * {
  font-size: 12px;
  line-height: 18px;
  padding-bottom: 0;
}

.slick-prev,
.slick-next {
  font-size: 0;
  line-height: 0;
  color: transparent;
  width: 30%;
  height: 70%;
  top: 10%;
  transform: none;
  z-index: 9;
  display: none !important;
}

.slick-next:before {
  content: " ";
  background: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1Ni4wMyAzNi42NyI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOiMxZDFkMWI7c3Ryb2tlLW1pdGVybGltaXQ6MTA7c3Ryb2tlLXdpZHRoOjYuOTVweDt9PC9zdHlsZT48L2RlZnM+PGcgaWQ9IkViZW5lXzIiIGRhdGEtbmFtZT0iRWJlbmUgMiI+PGcgaWQ9IkViZW5lXzEtMiIgZGF0YS1uYW1lPSJFYmVuZSAxIj48bGluZSBjbGFzcz0iY2xzLTEiIHkxPSIxOC4zNCIgeDI9IjQ2LjY4IiB5Mj0iMTguMzQiLz48cG9seWxpbmUgY2xhc3M9ImNscy0xIiBwb2ludHM9IjM1LjYxIDIuNDMgNTEuMTcgMTguMzQgMzUuNjEgMzQuMjQiLz48L2c+PC9nPjwvc3ZnPg==") no-repeat;
  width: 50px;
  height: 50px;
  display: block;
  background-repeat: none;
  opacity: 0;
  float: right;
}

.slick-next:hover:before {
  opacity: 1;
}

.slick-next {
  right: -24px;
}

.slick-prev.slick-disabled:before,
.slick-next.slick-disabled:before,
.slick-prev.slick-disabled:hover:before,
.slick-next.slick-disabled:hover:before {
  opacity: 0;
}

.slick-prev:before {
  content: " ";
  background: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1Ni4wMyAzNi42NyI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOiMxZDFkMWI7c3Ryb2tlLW1pdGVybGltaXQ6MTA7c3Ryb2tlLXdpZHRoOjYuOTVweDt9PC9zdHlsZT48L2RlZnM+PGcgaWQ9IkViZW5lXzIiIGRhdGEtbmFtZT0iRWJlbmUgMiI+PGcgaWQ9IkViZW5lXzEtMiIgZGF0YS1uYW1lPSJFYmVuZSAxIj48bGluZSBjbGFzcz0iY2xzLTEiIHkxPSIxOC4zNCIgeDI9IjQ2LjY4IiB5Mj0iMTguMzQiLz48cG9seWxpbmUgY2xhc3M9ImNscy0xIiBwb2ludHM9IjM1LjYxIDIuNDMgNTEuMTcgMTguMzQgMzUuNjEgMzQuMjQiLz48L2c+PC9nPjwvc3ZnPg==") no-repeat;
  width: 50px;
  height: 50px;
  display: block;
  background-repeat: none;
  transform: rotate(-180deg);
  margin-top: -25px;
  opacity: 0;
}

.slick-prev:hover:before {
  opacity: 1;
}

.slick-left {
  left: -24px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js"></script>
<section>
  <div class="container-wrap">
    <div class="content content--detail" data-title="" data-barba="container" data-barba-namespace="detail">
      <div class="splide">
        <div class='splide__slide'>
          <img src="https://via.placeholder.com/900x1600">
          <div class='gallery-img__detail__desc'>Description</div>
        </div>
        <div class='splide__slide'>
          <img src="https://via.placeholder.com/800x1300">
          <div class='gallery-img__detail__desc'>Description</div>
        </div>
        <div class='splide__slide'>
          <img src="https://via.placeholder.com/1000x1600">
          <div class='gallery-img__detail__desc'>Description</div>
        </div>
      </div>
    </div>
  </div>
</section>

TLDR; How can I control the height of an image with the width of a parent?

1 Answers

I wasn't too wrong. It works now with this:

var ratio = $('.slick-current img').get(0).naturalHeight / $('.slick-current img').get(0).naturalWidth;
var elHeight = $(window).height() - 120;
$('.content--detail').css({ width: elHeight / ratio });
Related