Skip to main content
AI Assist is now on Stack Overflow. Start a chat to get instant answers from across the network. Sign up to save and share your chats.
Updated to reflect modern approach
Source Link
Lee
  • 10.6k
  • 4
  • 39
  • 45



Years later this is still getting upvotes, with flexbox widely supported these days you may want to consider just plain CSS for this, unless there's a specific reason you are using JS for it

.container { display: flex; border: 2px dashed red; margin: 10px 0; } .container > .column { padding: 10px; } .container.fill-width { justify-content: stretch; } .container.fill-width>.column { flex-grow: 1 } .container>.column:nth-child(1) { background: yellow; } .container>.column:nth-child(2) { background: blue; } .container>.column:nth-child(3) { background: green; }
<div class="container"> <div class="column">Some<br>text</div> <div class="column">Some<br>more<br>text<br>here</div> <div class="column">One line</div> </div> <div class="container"> <div class="column">Some<br>more<br>even<br>longer<br>text<br>here</div> <div class="column">Some<br>text</div> <div class="column">One line</div> </div> <div class="container fill-width"> <div class="column">Some<br>more<br>text<br>here</div> <div class="column">Some<br>text</div> <div class="column">One line</div> </div>



Years later this is still getting upvotes, with flexbox widely supported these days you may want to consider just plain CSS for this, unless there's a specific reason you are using JS for it

.container { display: flex; border: 2px dashed red; margin: 10px 0; } .container > .column { padding: 10px; } .container.fill-width { justify-content: stretch; } .container.fill-width>.column { flex-grow: 1 } .container>.column:nth-child(1) { background: yellow; } .container>.column:nth-child(2) { background: blue; } .container>.column:nth-child(3) { background: green; }
<div class="container"> <div class="column">Some<br>text</div> <div class="column">Some<br>more<br>text<br>here</div> <div class="column">One line</div> </div> <div class="container"> <div class="column">Some<br>more<br>even<br>longer<br>text<br>here</div> <div class="column">Some<br>text</div> <div class="column">One line</div> </div> <div class="container fill-width"> <div class="column">Some<br>more<br>text<br>here</div> <div class="column">Some<br>text</div> <div class="column">One line</div> </div>

Imported code from JSFiddle, added library i found, cleaned up the explanation for easier reading (answer appears to still get upvoted so wanted to make it more informative and useful to the community)
Source Link
Lee
  • 10.6k
  • 4
  • 39
  • 45

http://jsfiddle.net/bw3KZ/Answer to your specific question

Check out the fiddle, think it does what you want. Your code was checking all columns within any container, what you neededneed to do was loop through every container, then get the heights of each column within that container, find the highest one then apply that height to every column in that container before moving on to the next one.is:

In future i recommend setting up a jsfiddle for any javascript related issues. It helps us provide you with an answer quicker, and you get to see what people have suggested actually working.

  • Loop through each container
  • Get the heights of each column within that container
  • Find the highest one
  • Apply that height to every column in that container before moving on to the next one.

For snowblind, copy of code from jsfiddle:

Note: Try to provide an example jsfiddle of your issue, it enables us to more easily help you and understand the issue, you get to see the working solution straight away and it encourages quicker responses.

JSQuick (Rough) Example

$(document).ready(function(){ $('.container').each(function(){ var highestBox = 0; $('.column', this).each(function(){ if($(this).height() > highestBox) highestBox = $(this).height(); }); $('.column',this).height(highestBox); }); });​ 

$(document).ready(function(){ // Select and loop the container element of the elements you want to equalise $('.container').each(function(){ // Cache the highest var highestBox = 0; // Select and loop the elements you want to equalise $('.column', this).each(function(){ // If this box is higher than the cached highest then store it if($(this).height() > highestBox) { highestBox = $(this).height(); } }); // Set the height of all those children to whichever was highest $('.column',this).height(highestBox); }); });
.container { border 1px solid red; } .column { border: 1px solid blue; float:left; width: 30%; text-align:center; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <div class="container"> <div class="column">This is<br />the highest<br />column</div> <div class="column">One line</div> <div class="column">Two<br />lines</div> </div> <div class="container"> <div class="column">One line</div> <div class="column">Two<br>lines</div> <div class="column">One line</div> </div>

Library!

Here's a library i found that looks promising if you want some more clever equalisation controls

http://brm.io/jquery-match-height-demo/






Edit: To address Addressing @Mem's question

Question: Will $(document).ready() work if you have images that need to load which in turn modify the heights of the containers?

Question: Will $(document).ready() work if you have images that need to load which in turn modify the heights of the containers?


Answer:Equalising heights after image load

The document.ready event is triggered at the earliest possible time by jQuery. This isn't a jQuery specific event as suchIf you are loading images, but jQueryyou will emulate it in browsersfind that do not supportthis solution doesn't always work. This is because DOMContentLoadeddocument.ready is fired at the earliest possible time. This event as you can see from the link, which means it does not wait for any external resources to load, it will trigger as soonbe loaded in (such as the HTML document has been downloaded and parsed by the browser, which is why it is not suitable if you have images which would modify the height of container elements).

You could use the window.load event, which may be a reasonably easy solution if you don't have a lot of external resources. However this event wait's for ALL external resources to load before triggering, so that includes waiting for all CSS and JS files to download. Even ifWhen your images are downloaded before the other external'sfinally load, you will have to wait. Of course if your using slow CDN's or 3rd party hostingthey may distort the heights of any resourcestheir containers after the equalisation script has run, this event just won't be any good for youcausing it too appear not too work.

 

The appearingSolving equalising heights with images

  1. Bind to image loading events

This is the best solution is to bind(at the time of writing) and involves binding to the img.load event, with some management code. All you have to know when the last image has loadeddo is get a count of how many img's there are (i.e. push all img elements into an array,$('img').length and pluck them off as their load events triggerthen for each load, -1 from that count until the array is emptyyou hit zero, then you know its all loaded). Howeverfire the equaliser.

The caveat here is thatload may not fire in all browsers if the browser cache can completely mess you up, WebKit for example, last time i tried to do image load events, doesn't triggeris in the load event on cached images, and you really don't want to use cache-busting techniques on your images!

There are however quite. Look around google/github, there should be a few librariessolution script out there, that try to ensure cached image events are still triggered, and some libraries that go further in order to support non-<img/> images. One example isAt the time of writing i found waitForImages from Alexander Dickson but i'm sure there are plenty others (note: i'veuntested, this is not usedan endorsement).

  1. Another more reliable solution is the window.load event. This should generally always work. However, if you check the docs out, you'll notice this event fires after ALL external resources are loaded. This means if your images are loaded but there's some javascript waiting to download it won't fire until that completes.

If you load the majority of your externals asyncronously and are clever with minimising, compressing and spreading the load you probably wont have any issues with this jquery plugin myselfmethod, however a suddenly slow CDN (happens all the time) could cause issues.

In both cases, you could take a dumb approach and apply fallback timers. Have the equalise script run automatically after a set few seconds just in case the event doesn't fire or something is slow out of your control. It's not fool proof, but in reality you'll satisfy 99% of your visitors with this fallback if you tune the timer correctly.

http://jsfiddle.net/bw3KZ/

Check out the fiddle, think it does what you want. Your code was checking all columns within any container, what you needed to do was loop through every container, then get the heights of each column within that container, find the highest one then apply that height to every column in that container before moving on to the next one.

In future i recommend setting up a jsfiddle for any javascript related issues. It helps us provide you with an answer quicker, and you get to see what people have suggested actually working.

For snowblind, copy of code from jsfiddle:

JS

$(document).ready(function(){ $('.container').each(function(){ var highestBox = 0; $('.column', this).each(function(){ if($(this).height() > highestBox) highestBox = $(this).height(); }); $('.column',this).height(highestBox); }); });​ 




Edit: To address @Mem's question

Question: Will $(document).ready() work if you have images that need to load which in turn modify the heights of the containers?

Answer:

The document.ready event is triggered at the earliest possible time by jQuery. This isn't a jQuery specific event as such, but jQuery will emulate it in browsers that do not support DOMContentLoaded. This event as you can see from the link, does not wait for any external resources to load, it will trigger as soon as the HTML document has been downloaded and parsed by the browser, which is why it is not suitable if you have images which would modify the height of container elements.

You could use the window.load event, which may be a reasonably easy solution if you don't have a lot of external resources. However this event wait's for ALL external resources to load before triggering, so that includes waiting for all CSS and JS files to download. Even if your images are downloaded before the other external's, you will have to wait. Of course if your using slow CDN's or 3rd party hosting of any resources, this event just won't be any good for you.

The appearing best solution is to bind to the img.load event, with some management code to know when the last image has loaded (i.e. push all img elements into an array, and pluck them off as their load events trigger, until the array is empty, then you know its all loaded). However the caveat here is that the browser cache can completely mess you up, WebKit for example, last time i tried to do image load events, doesn't trigger the load event on cached images, and you really don't want to use cache-busting techniques on your images!

There are however quite a few libraries out there, that try to ensure cached image events are still triggered, and some libraries that go further in order to support non-<img/> images. One example is waitForImages from Alexander Dickson but i'm sure there are plenty others (note: i've not used this jquery plugin myself).

Answer to your specific question

Your code was checking all columns within any container, what you need to do is:

  • Loop through each container
  • Get the heights of each column within that container
  • Find the highest one
  • Apply that height to every column in that container before moving on to the next one.

Note: Try to provide an example jsfiddle of your issue, it enables us to more easily help you and understand the issue, you get to see the working solution straight away and it encourages quicker responses.

Quick (Rough) Example

$(document).ready(function(){ // Select and loop the container element of the elements you want to equalise $('.container').each(function(){ // Cache the highest var highestBox = 0; // Select and loop the elements you want to equalise $('.column', this).each(function(){ // If this box is higher than the cached highest then store it if($(this).height() > highestBox) { highestBox = $(this).height(); } }); // Set the height of all those children to whichever was highest $('.column',this).height(highestBox); }); });
.container { border 1px solid red; } .column { border: 1px solid blue; float:left; width: 30%; text-align:center; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <div class="container"> <div class="column">This is<br />the highest<br />column</div> <div class="column">One line</div> <div class="column">Two<br />lines</div> </div> <div class="container"> <div class="column">One line</div> <div class="column">Two<br>lines</div> <div class="column">One line</div> </div>

Library!

Here's a library i found that looks promising if you want some more clever equalisation controls

http://brm.io/jquery-match-height-demo/



Addressing @Mem's question

Question: Will $(document).ready() work if you have images that need to load which in turn modify the heights of the containers?


Equalising heights after image load

If you are loading images, you will find that this solution doesn't always work. This is because document.ready is fired at the earliest possible time, which means it does not wait for external resources to be loaded in (such as images).

When your images finally load, they may distort the heights of their containers after the equalisation script has run, causing it too appear not too work.

 

Solving equalising heights with images

  1. Bind to image loading events

This is the best solution (at the time of writing) and involves binding to the img.load event. All you have to do is get a count of how many img's there are $('img').length and then for each load, -1 from that count until you hit zero, then fire the equaliser.

The caveat here is load may not fire in all browsers if the image is in the cache. Look around google/github, there should be a solution script out there. At the time of writing i found waitForImages from Alexander Dickson (untested, this is not an endorsement).

  1. Another more reliable solution is the window.load event. This should generally always work. However, if you check the docs out, you'll notice this event fires after ALL external resources are loaded. This means if your images are loaded but there's some javascript waiting to download it won't fire until that completes.

If you load the majority of your externals asyncronously and are clever with minimising, compressing and spreading the load you probably wont have any issues with this method, however a suddenly slow CDN (happens all the time) could cause issues.

In both cases, you could take a dumb approach and apply fallback timers. Have the equalise script run automatically after a set few seconds just in case the event doesn't fire or something is slow out of your control. It's not fool proof, but in reality you'll satisfy 99% of your visitors with this fallback if you tune the timer correctly.

spelling fixes
Source Link
Lee
  • 10.6k
  • 4
  • 39
  • 45

There are however quickquite a few libraries out there, that try to ensure cached image events are still triggered, and some libraries that go further in order to support non-<img/> images. One example is waitForImages from Alexander Dickson but i'm sure there are plenty others (note: i've not used this jquery plugin myself).

There are however quick a few libraries out there, that try to ensure cached image events are still triggered, and some libraries that go further in order to support non- images. One example is waitForImages from Alexander Dickson but i'm sure there are plenty others (note: i've not used this jquery plugin myself).

There are however quite a few libraries out there, that try to ensure cached image events are still triggered, and some libraries that go further in order to support non-<img/> images. One example is waitForImages from Alexander Dickson but i'm sure there are plenty others (note: i've not used this jquery plugin myself).

Formatting
Source Link
Lee
  • 10.6k
  • 4
  • 39
  • 45
Loading
added 472 characters in body
Source Link
Lee
  • 10.6k
  • 4
  • 39
  • 45
Loading
Source Link
Lee
  • 10.6k
  • 4
  • 39
  • 45
Loading