Setting Equal Heights with jQuery
April 2020 note: Hi! Just a quick note to say that this post is pretty old, is no longer our recommended approach. We're keeping it online, but it is deprecated in favor of documentation in the layout-patterns repository, specifically the Equal Heights section
We wrote a script to “equalize” the heights of boxes within the same container and create a tidy grid — with little overhead.
Creating the visual effect of equal-height columns or content boxes has been a challenge ever since we abandoned table-based layouts. When developing complex web applications or site designs we’ve found that it often makes the most sense from a usability and performance standpoint to use a simple JavaScript workaround: our equalHeights() function determines the heights of all sibling elements in a container, and then sets each element’s minimum height to that of the tallest element. When JavaScript is disabled, the boxes or columns appear with varying heights, but the content remains legible and the page is still completely usable.
Why not just use CSS?
Permalink to 'Why not just use CSS?'We advocate using CSS whenever possible, and we often can because there are many clever ways to create the illusion of equal-height boxes without resorting to setting a fixed height, like Dan Cederholm’s faux columns. This and similar techniques are great for columns in a page layout, but they don’t translate very well when we’re building, say, a web application dashboard page where 4 small widget boxes sit in a “row.” In this case we could create an uber tiling background image that has backgrounds for 4 columns, but we’d also have to design the boxes with square corners (or make a big sliding door), fix the widths of each box, and make sure the markup lines up exactly with the background image. Or, because CSS2 only supports one background image per element, we could nest 4 separate divs, each with it’s own positioned background image. No matter how we approach it, we’ve yet to come across a CSS-only solution to this use case that doesn’t require pixel-exact calculations when creating the background images, or a significant amount of unnecessary markup. Let’s not even discuss what you have to do when the boxes can vary in width, too.
JavaScript to the rescue
Permalink to 'JavaScript to the rescue'Calling equalHeights() on DOM ready let’s us keep all of the important factors in play, without adding extra markup or complex CSS workarounds:
- usability. This is strictly a visual effect, so when the script is absent, columns are of varying heights and the page remains totally usable.
- layout flexibility. The script assigns a min-height value (not height), so when content is added through user interaction or via AJAX running in the background, or if the user increases the browser text size, the content box will grow to fit. Columns or boxes can keep their percentage or em-based widths.
- performance. It’s lightweight — has a small footprint, and doesn’t insert any DOM elements or require extra markup — and unobtrusive because, like other jQuery plugins, it’s called on standard CSS selectors.
How it works
Permalink to 'How it works'equalHeights() loops through the top-level child nodes of a specified element and sets their min-height values to that of the tallest. It’s set up as a standard jQuery plugin, and is called on the container element:
$('.container').equalHeights();
In our version of the script the default unit is set to ems so that the content boxes will scale. This requires another of our methods, pxToEm; if it’s not present, the default unit reverts to pixels. Or, if you’re using pxToEm, you can override the default and pass a “true” argument to set the unit in pixels.
Download (and help us improve) the code
Permalink to 'Download (and help us improve) the code'This code is open source and available in a git repository, jQuery-Equal-Heights. If you think you can help on a particular issue, please submit a pull request and we’ll review it as soon as possible.