简体   繁体   中英

Making a row of divs all be the same height using CSS

I have a row of divs that must all be the same height, but I have no way of knowing what that height might be ahead of time (the content comes from an external source). I initially tried placing the divs in an enclosing div and floated them left. I then set their height to be "100%", but this had no perceptible effect. By setting the height on the enclosing div to a fixed-height I could then get the floated divs to expand, but only up to the fixed height of the container. When the content in one of the divs exceeded the fixed height, it spilled over; the floated divs refused to expand.

I Googled this floated-divs-of-the-same-height problem and apparently there's no way to do it using CSS. So now I am trying to use a combination of relative and absolute positioning instead of floats. This is the CSS:

<style type="text/css">
div.container {
  background: #ccc;
  position: relative;
  min-height: 10em;
}
div.a {
  background-color: #aaa;
  position: absolute;
  top: 0px;
  left: 0px;
  bottom: 0px;
  width: 40%;
}
div.b {
  background-color: #bbb;
  position: absolute;
  top: 0px;
  left: 41%;
  bottom: 0px;
  width: 40%;
}
</style>

This is a simplified version of the HTML:

   <div class="container">
    <div class="a">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer pretium dui sit amet felis. Integer sit amet diam. Phasellus ultrices viverra velit.</div>
    <div class="b">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer pretium dui sit amet felis. Integer sit amet diam. Phasellus ultrices viverra velit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer pretium dui sit amet felis. Integer sit amet diam. Phasellus ultrices viverra velit.</div>
   </div>

This works, unless you change the min-height to something like 5em (demonstranting what happens when the content exceeds the minimum height), and you can see that while the text doesn't get cutoff, the divs still refuse to expand. Now I am at a lose. Is there any way to do this using CSS?

Here is one of those moments where you can get stuck between being idealistic or realistic. I understand that there is no semantic value to placing non-tabular data in a table strictly for formatting reasons but I don't want to see you bending over backwards to create a non-tabular solution to this problem simply for its own sake.

I am the first to shoot down non-semantic designs, trust me, but sometimes you need to face the fact that CSS + semantic markup does not work for all design scenarios. I don't know the accessibility needs of this site but I would recommend that you look to a more practical solution to this problem.

Cheers to you for approaching this the right way and looking for the proper way to solve it! Unfortunately this is one of the dark corners of CSS (along with vertical positioning within a block) that is just plain impossible to do without faux columns, javascript, or table cells.

Whichever you choose, please don't adhere to a standard for its own sake.

Making them exactly the same height can be a tricky thing, but if they just have to appear to be the same height, you may want to look at the faux columns technique.

I have tried a few other methods, but this is the most reliable way I have found of getting the effect, apart from using tables of course.

You can use JavaScript, but of course it will break without JavaScript enabled. Then there's tables, but this ruins the point of CSS. Perhaps seanb's answer could work, place a background image that creates the illusion that all columns go to the bottom. This is known as the faux background technique .

Or sit tight and wait for display: table-cell to be supported for all/most browsers.

OK, the table thing turned out to be a little trickier than I thought it would be. It turns out the Javascript solution is actually the simplest (for my situation), since my app is an AJAX app and the framework uses Prototype.js. All it takes is a few lines of JS:

$$('div.container').each(function (element) {
 var longest = 0;

 element.descendants().each(function (child) {
  if (child.getHeight() > longest)
   longest = child.getHeight();
 });

 element.descendants().each(function (child) {
  child.style.height = longest + 'px';
 });
});

Thanks again for the help.

Thanks for the answers, guys. I don't think the background image will work because the widths of the columns can also vary depending on how many columns there are (the user can change it). I guess I'll use tables :(

if your looking for a purely css option, and you can seperate the background of the block from the content then the answer is two have two bits of code for each block, one for the content, one for the background. this is how it's done:

<div id="wrapper">
  <div class="content" id='one>
  <div class="content" id="two>
  <div class="content" id="three>
  <div class="background" id="back-one">
  <div class="background" id="back-two">
  <div class="background" id="back-three">
</div>

Position the content divs using floats. Then position the backgrounds using absolute positioning (and a z-index to put them behind)

This works because the floats can set the height, and the absolutely positioned elements can have 100% height. It's a little bit messy, but does the job.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM