0

I am trying to put together a masonry style looking grid.

For it to work, I need all the grid items to match the height of the tallest (determined by how much content is in it).

Grid items that are double the height should be 2 x the tallest.

I have got it to work pretty well so far EXCEPT when I resize the window, the height does not re-calculate.

I have put together a codepen to illustrate here

https://codepen.io/shereewalker/pen/dymbgVq

I tried switching it to

$( window ).resize(function() {

But then it doesn't work until you re-size the window (I guess that's obvious), and then it only does it once.

How do I set the heights on load AND on resize?

Any help would be appreciated

$(document).ready(function() {
  // Select and loop the containers element of the elements you want to equalise
  $('.achievements-block').each(function() {
    // Cache the highest
    var min_highestBox = 0;
    // Select and loop the elements you want to equalise
    $('.grid-item.single', this).each(function() {
      // If this box is higher than the cached highest then store it
      if ($(this).height() > min_highestBox) {
        min_highestBox = $(this).height();
      }
    });

    // Set the height of all those children to whichever was highest 
    $('.grid-item.single', this).height(min_highestBox);
    $('.grid-item.double', this).height(min_highestBox * 2);


  });

});
.grid-item {
  position: relative;
  float: left;
}

.grid-item.double {
  float: right;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="achievements-block full-width">
  <div class="grid-item single" style="width: 35%; background-color:red">

    <h2>Item 1 - I am a large heading</h2>
    <p> I am some content</p>
  </div>


  <div class="grid-item single" style="width: 45%; background-color:blue">
    <h2>Item 2 - I am a large heading</h2>
    <p> I am some content, I actually have the most content. Way more than the others. Aenean lacinia bibendum nulla sed consectetur. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Maecenas
      sed diam eget risus varius blandit sit amet non magna. Nullam quis risus eget urna mollis ornare vel eu leo. Donec id elit non mi porta gravida at eget metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
      Donec sed odio dui. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Vestibulum id ligula porta felis euismod semper.
      Maecenas faucibus mollis interdum. Vestibulum id ligula porta felis euismod semper. Curabitur blandit tempus porttitor. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Duis mollis,
      est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Sed posuere consectetur est at lobortis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec
      id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque
      nisl consectetur et. Nulla vitae elit libero, a pharetra augue. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Aenean lacinia bibendum nulla sed consectetur.
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Maecenas sed diam eget risus varius blandit sit amet non magna. Nullam quis risus eget urna mollis ornare vel eu leo. Donec id
      elit non mi porta gravida at eget metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec sed odio dui. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi leo risus, porta ac consectetur ac,
      vestibulum at eros. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Vestibulum id ligula porta felis euismod semper. Maecenas faucibus mollis interdum. Vestibulum id ligula porta felis euismod semper. Curabitur blandit tempus porttitor.
      Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Cras justo odio, dapibus ac facilisis
      in, egestas eget quam. Sed posuere consectetur est at lobortis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut
      fermentum massa justo sit amet risus. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Nulla vitae elit libero, a pharetra augue. Cras justo odio, dapibus ac facilisis in, egestas
      eget quam. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.</p>
  </div>


  <div class="grid-item single" style="width: 20%; background-color:yellow">
    <h2>Item 3 - I am a large heading</h2>
    <p> I am some content</p>

  </div>


  <div class="grid-item single" style="width: 40%; background-color:pink">
    <h2>Item 4 - I am a large heading</h2>
    <p> I am some content</p>
  </div>


  <div class="grid-item single" style="width: 25%; background-color:orange">
    <h2>Item 5 - I am a large heading</h2>
    <p> I am some content</p>
  </div>



  <div class="grid-item double" style="width: 35%; background-color:green">
    <h2>Item 6 - I am a large heading</h2>
    <p> I am some content and would like my box to be double the height of others for a masonry look.</p>
  </div>


  <div class="grid-item single" style="width: 30%; background-color:purple">
    <h2>Item 6 - I am a large heading</h2>
    <p> I am some content</p>
  </div>


  <div class="grid-item single" style="width: 35%; background-color:gray">
    <h2>Item 7 - I am a large heading</h2>
    <p> I am some content</p>
  </div>




</section>
Mr Toad
  • 202
  • 2
  • 12
  • 41
  • I see in your CodePen `$(window).on('resize',function)` which is not the correct syntax. I think you mean `$(window).on('resize',function(){` – Twisty Jun 27 '22 at 19:33
  • Oh sorry, I was trying to get it to work I did not realise it had saved. I have removed that code that is formatted wrong and will paste the full code in the question now as well as the codepen – Mr Toad Jun 27 '22 at 19:35
  • If you don't use the `resize()` event, how do you expect anything to change when you resize the window? – Barmar Jun 27 '22 at 19:50
  • If you want to run the function at the beginning as well, use `$(window).resize()` to trigger it. – Barmar Jun 27 '22 at 19:50
  • @Barmar I did try this, but then it ONLY does it on window resize not on page load. I am trying to do both (on page load and on resize) but I don't know how - JS really isn't my strong suit. – Mr Toad Jun 27 '22 at 19:54
  • But the whole point of adding `$(window).resize()` after `$(window).resize(function...)` is to run the function once on page load. – Barmar Jun 27 '22 at 19:54
  • You can even combine them: `$(window).resize(function...).resize()` – Barmar Jun 27 '22 at 19:55

2 Answers2

0

Put the code in the resize() event handler and trigger the resize event when the page loads.

$(document).ready(function() {
  $(window).resize(function() {
    // Select and loop the containers element of the elements you want to equalise
    $('.achievements-block').each(function() {
      // Cache the highest
      var min_highestBox = 0;
      // Select and loop the elements you want to equalise
      $('.grid-item.single', this).each(function() {
        // If this box is higher than the cached highest then store it
        if ($(this).height() > min_highestBox) {
          min_highestBox = $(this).height();
        }
      });
      console.log("Highest = ", min_highestBox);
      // Set the height of all those children to whichever was highest 
      $('.grid-item.single', this).height(min_highestBox);
      $('.grid-item.double', this).height(min_highestBox * 2);
    });
  }).resize(); // trigger the event when the page loads

});
.grid-item {
  position: relative;
  float: left;
}

.grid-item.double {
  float: right;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="achievements-block full-width">
  <div class="grid-item single" style="width: 35%; background-color:red">

    <h2>Item 1 - I am a large heading</h2>
    <p> I am some content</p>
  </div>


  <div class="grid-item single" style="width: 45%; background-color:blue">
    <h2>Item 2 - I am a large heading</h2>
    <p> I am some content, I actually have the most content. Way more than the others. Aenean lacinia bibendum nulla sed consectetur. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Maecenas
      sed diam eget risus varius blandit sit amet non magna. Nullam quis risus eget urna mollis ornare vel eu leo. Donec id elit non mi porta gravida at eget metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
      Donec sed odio dui. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Vestibulum id ligula porta felis euismod semper.
      Maecenas faucibus mollis interdum. Vestibulum id ligula porta felis euismod semper. Curabitur blandit tempus porttitor. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Duis mollis,
      est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Sed posuere consectetur est at lobortis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec
      id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque
      nisl consectetur et. Nulla vitae elit libero, a pharetra augue. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Aenean lacinia bibendum nulla sed consectetur.
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Maecenas sed diam eget risus varius blandit sit amet non magna. Nullam quis risus eget urna mollis ornare vel eu leo. Donec id
      elit non mi porta gravida at eget metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec sed odio dui. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi leo risus, porta ac consectetur ac,
      vestibulum at eros. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Vestibulum id ligula porta felis euismod semper. Maecenas faucibus mollis interdum. Vestibulum id ligula porta felis euismod semper. Curabitur blandit tempus porttitor.
      Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Cras justo odio, dapibus ac facilisis
      in, egestas eget quam. Sed posuere consectetur est at lobortis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut
      fermentum massa justo sit amet risus. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Nulla vitae elit libero, a pharetra augue. Cras justo odio, dapibus ac facilisis in, egestas
      eget quam. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.</p>
  </div>


  <div class="grid-item single" style="width: 20%; background-color:yellow">
    <h2>Item 3 - I am a large heading</h2>
    <p> I am some content</p>

  </div>


  <div class="grid-item single" style="width: 40%; background-color:pink">
    <h2>Item 4 - I am a large heading</h2>
    <p> I am some content</p>
  </div>


  <div class="grid-item single" style="width: 25%; background-color:orange">
    <h2>Item 5 - I am a large heading</h2>
    <p> I am some content</p>
  </div>



  <div class="grid-item double" style="width: 35%; background-color:green">
    <h2>Item 6 - I am a large heading</h2>
    <p> I am some content and would like my box to be double the height of others for a masonry look.</p>
  </div>


  <div class="grid-item single" style="width: 30%; background-color:purple">
    <h2>Item 6 - I am a large heading</h2>
    <p> I am some content</p>
  </div>


  <div class="grid-item single" style="width: 35%; background-color:gray">
    <h2>Item 7 - I am a large heading</h2>
    <p> I am some content</p>
  </div>




</section>
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Thank you for this - I have updated my codepen, but unfortunately it still does not seem to work. https://codepen.io/shereewalker/pen/dymbgVq – Mr Toad Jun 27 '22 at 20:03
  • I'm not sure what I'm supposed to see when I run the code. I don't see anything happening when I resize. – Barmar Jun 27 '22 at 20:05
  • I want the height of the div with the most content in it to resize and therefore all the others resize to match. At the moment, it stays at the same hight that it calculates on page load. When you re-size, it cuts off the content because the hight is not recalculating. – Mr Toad Jun 27 '22 at 20:49
  • Why are you setting the height twice? Why `min_highestBox * 2`? – Barmar Jun 27 '22 at 20:51
  • The first is matching all the heights for blocks that have a height of one row (.single) the second is then doubling that height for all the blocks I want to have a height of two rows (.double) so it looks like a masonry grid. They are targeting two different grid items seperated by class – Mr Toad Jun 27 '22 at 20:54
  • Oops, didn't see the difference between `.single` and `.double`. – Barmar Jun 27 '22 at 20:56
  • I've added a `console.log()`, it shows that the code is running when the page first loads and also when you resize. The value of `min_highestBox` doesn't change. – Barmar Jun 27 '22 at 21:03
  • Sorry I am confused. I WANT it to change on re-size. That is the whole issue I am facing. If you look at the codepen, you will see that at points the content gets chopped off on window resize because the height of the grid items aren'r responsive. – Mr Toad Jun 27 '22 at 22:22
  • What's supposed to cause it to change? You set every box to a specific height, the height isn't related to the window size. – Barmar Jun 27 '22 at 22:30
  • On page load, jquery calculates the size of the tallest box and makes them all the same. All I am wanting it to do it to ALSO do this again when the window is resized. It's not doing it now because I dont know how. What's supposed to cause it to change height is the fact that the text becomes longer as the width decreases. If you resize the browser in Codepen you can see it begins to cut off the text in the box that has the most. – Mr Toad Jun 28 '22 at 09:05
  • But once you set the height of all the boxes with `xxx.height(min_highestBox)` the heights will never change. You need to remove all the heights you set so the browser can recalculate normally. – Barmar Jun 28 '22 at 15:29
  • I'm not 100% sure what you mean, but if you look at the codepen, it's working. When you resize the browser, it recalculates the heights. – Mr Toad Jun 28 '22 at 19:33
0

So in the end, I found a post on here almost identical to the issue I was facing.

jQuery function executes on $(window).resize() or $(document).ready() not both

(I initially couldn't find this)

I have changed my JS to

  function min_highestBox() {
  var tallest = 0;
  $('.grid-item').css('height','auto')
  $('.grid-item').each(function() {
    if ($(this).height() > tallest) {
      tallest = $(this).height();
    }
  });

  $('.grid-item.single').each(function() {
    $(this).height(tallest);
  });
  
   $('.grid-item.double').each(function() {
    $(this).height(tallest * 2);
  });
}
$(document).ready(function() {
  min_highestBox();
  $(window).on('resize', min_highestBox);
});

Which is now working as expected

Mr Toad
  • 202
  • 2
  • 12
  • 41