2

I want to set the height to match the width for all containers of the same class.

I have a number of images of various sizes across my site. I would like each image's div container to have the same height as its own width.

<div class="wrapper" style="width:600px">
    <img src="image1.jpg">
</div>
<div class="wrapper" style="width:400px">
    <img src="image2.jpg">
</div>
<div class="wrapper" style="width:200px">
    <img src="image3.jpg">
</div>
.wrapper {
    border-radius: 180px;
    overflow: hidden;
}

img {
    width: 100%;
}

I originally attempted the following:

$(document).ready( function() {
    var wrapper = document.querySelector(".wrapper");
    container.style.height = getComputedStyle(wrapper).width;
} );

This solution worked, except it only affected the first occurrence of each wrapper.

I also tried adapting another example I've found on StackOverflow (sorry can't find the link), to no avail:

$(document).ready(function() {
    $('.wrapper').each(function() {
        var maxWidth = 100;    // Max width for the image
        var maxHeight = 100;    // Max height for the image
        var ratio = 0;  // Used for aspect ratio
        var width = $(this).width();    // Current image width
        var height = $(this).height();  // Current image height

        // Check if the current width is larger than the max
        if(width > maxWidth) {
            ratio = maxWidth / width;   // get ratio for scaling image
            $(this).css("width", maxWidth); // Set new width
            $(this).css("height", height * ratio);  // Scale height based on ratio
            height = height * ratio;    // Reset height to match scaled image
            width = width * ratio;    // Reset width to match scaled image
        }

        // Check if current height is larger than max
        if(height > maxHeight) {
            ratio = maxHeight / height; // get ratio for scaling image
            $(this).css("height", maxHeight);   // Set new height
            $(this).css("width", width * ratio);    // Scale width based on ratio
            width = width * ratio;    // Reset width to match scaled image
            height = height * ratio;    // Reset height to match scaled image
        }
    });
});

Any help would be greatly appreciated.

JSFiddle (HTML + CSS): https://jsfiddle.net/h2xnqrL9/

Bakala
  • 407
  • 1
  • 6
  • 10
  • In your example that work's but only the first class .. You could try a `.each` --> `$('.wapper').each(function(i, obj) {` – Zak Aug 16 '19 at 15:30
  • Thank you all so much for your responses. I ended up using Carlos' answer as I feel that it was the most elegant solution to my problem. However, they all worked perfectly and I learnt a lot in the process. – Bakala Aug 19 '19 at 20:24

3 Answers3

4

there's no need for Javascript here.

You can use a trick to set any container height to it's width:

.wrapper {position:relative;}
.wrapper:before {
  content: '';
  display: block;
  width: 100%;
  padding-top: 100%; /*trick here*/
}
.wrapper img {
  position:absolute;
  top: 0;
  left: 0;
  width: 100%;
}

Any padding-top percentage value is relative to the parent container's width. 100% means it will be a square, 50% would give it half it's width.

It's a great trick when you're playing with image ratios ;)

I forked your jsfiddle with the extra code and added an outline so you could see the square container

https://jsfiddle.net/tLw354jm/2/

EDIT: Specification here https://www.w3.org/TR/CSS2/box.html#propdef-padding

Carlos Sá
  • 602
  • 3
  • 10
3

The reason it didn't work for your first solution is because document.querySelector(".wrapper") only returns the first match. What you want to do is get all the matches, in which case you can use document.querySelectorAll(".wrapper") and then loop over the elements.

With jQuery, you can do this using the following code:

$(document).ready(function () {
  $(".wrapper").each(function (index, divElem) {
    divElem.style.height = divElem.style.width;
  });
});
Shahzad
  • 2,033
  • 1
  • 16
  • 23
0

Something like this maybe:

$(document).ready(function() {
  $(".wrapper").each(function() {
    $(this).css('height', $(this).css('width'))
  })
});
.wrapper {
  margin-bottom: 5px;
  background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper" style="width:600px">
  <img src="https://dummyimage.com/600x600/b0b0b0/000000.jpg">
</div>
<div class="wrapper" style="width:400px">
  <img src="https://dummyimage.com/400x400/b0b0b0/000000.jpg">
</div>
<div class="wrapper" style="width:200px">
  <img src="https://dummyimage.com/200x200/b0b0b0/000000.jpg">
</div>
jayarjo
  • 16,124
  • 24
  • 94
  • 138