16

I have two elements which can vary in heights and both floated next to each other. The problem is that it looks pretty ugly if one box is higher than the other. So I want them to be the same height.

One way I thought might work would be too to wrap them in a container div and hope the taller one resizes it and the smaller one expands to fit the space:

HTML:

<div id="outerBox">
<div class="innerBoxLeft"></div>
<div class="innerBoxRight"><br /><br /><br /></div>
</div>

CSS:

.outerBox
{
width: 100%;
}

.innerBoxLeft
{
float:left;
width: 45%;
height: 100%;
}

.innerBoxRight
{
float:right;
width: 45%;
height: 100%;
}

Doesn't work. I believe this may be because the outer div doesn't have a set height and for some reason the smaller box and it's 100% height has nothing to work on. I cannot give it a set height however because that would defeat the point.

So unless there is a another way, I guess I am asking: How can I set a child element's height to that of it's parent?

Thanks

Damien
  • 13,927
  • 14
  • 55
  • 88

11 Answers11

24

Why don't you use a table?

This is getting ridiculous. User wants to see a table. HTML language provides a table element to achieve exactly the goal user wants. Yet, we use a whole library (I an looking at JQuery answer) to achieve the goal w/o a table even though it means a script running on client!

buti-oxa
  • 11,261
  • 5
  • 35
  • 44
  • jQuery is a pretty lightweight library all things considered and with connection speeds getting faster and faster, it's pretty much a non-issue for most users. Tables are the easiest answer, but not always the best one. For displaying data in fashion similar to a spreadsheet, then tables are by far the way to go, but for a laying out what I'm sure Damien hopes to be a clean, semantic website, it's not the ideal solution. – Andrew Jul 23 '09 at 15:15
  • 10
    The problem is not in the size but in the act of scripting. You solve a static layout problem by dynamic way of the scipt. On slow computer, you can see your layout change as script executes. If a user has switched Javascript off, it gets wrong layout. One should try separate HTML(content) from CSS (layout) from Javascript (action) and not solve problems of one with another. – buti-oxa Jul 23 '09 at 15:32
  • As with anything else, it comes down to client or personal preference. I believe very much in separation of content and layout, but what it really comes down to is your audience. For personal projects, I'll assume a few things about my target audience (Flash support, Javascript on, high speed connections, modern browsers) and I'll develop accordingly. Analytics data usually confirms my assumptions on all these points. In the end, if no easy (or semantically valid) answer is available within HTML/CSS, than I see no point in using a bit of JS to make up for these shortcomings. – Andrew Jul 28 '09 at 19:32
  • 1
    I made this the answer because it is what I did. Tables are horrible for layout but all the over solutions also had problems. I concluded that there is no sensible way to do this with CSS without hacks, a lot of which do not work in same cases (such as boxes with borders all around). – Damien Aug 04 '09 at 16:03
  • 3
    Tables aren't achieving the OP's goal, if it's tabular data use a table, if you're using a table to solve a layout problem, you're not doing it right. – Nik Apr 22 '13 at 04:44
  • The table CSS display rules are compatible from IE8 and later. Its a good option to use those instead of adding html table markup. Also by not using tables, it gives you more flexibility to implement responsive design. – LessQuesar May 24 '13 at 03:21
11

I think that tables should be used for what they were created for - and that is storing data, not showing layout.

If You want good, cross-browser & hack-free CSS solution - check this article.

zeroDivisible
  • 4,041
  • 8
  • 40
  • 62
  • 3
    While I agree with your tables comment, that solution is essentially committing the same sin of un-semantic markup. Using a table for something that isn't really a table (doesn't necessarily have to be strictly data) is committing the same sin because the content is not supposed to be a table. Multiple un-semantic divs which are made purely to make background color faux columns is just as bad on that front, IMO. If you have those wrappers already, for semantic reasons (page > content > section > article etc), then I guess it would work. – kmiyashiro Aug 07 '09 at 14:38
  • Late to the party, but here's [my swing](http://jsfiddle.net/thirdender/vxuUr/) at equal columns (similar to the linked article) using :before psuedo-selectors. Not terribly useful, but someone may find it "interesting" (or bad... thought provoking at least?) – thirdender Jul 31 '12 at 07:33
3

There are several ways with varying degrees of complexity and success. One technique that works for me (I do not remember where I saw it first link, problems) is the following:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
    "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <title>test</title>
    <style type="text/css">
        #page {
            clear:both;
            overflow:hidden;
            width:100%;
        }
        #page div {
            margin:0 0 -6000px 0; /* nothing special about 6000px */
            padding:0 0 6000px 0; /* any large enough value will do */
        }
        div.article {
            background:blue;
            float:left;
            width:70%;
        }
        div.sidebar {
            background:red;
            float:right;
            width:30%;
        }
    </style>
</head>
<body>

<div id="page">
    <div class="article">
        <p>Some content</p>
    </div>
    <div class="sidebar">
        <p>Some content</p>
        <p>Some content</p>
        <p>Some content</p>
    </div>
</div>
</body>
</html>
Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
3

Vote this down to infinity if you like but I think I might as well wack this part of the design in a table...

Damien
  • 13,927
  • 14
  • 55
  • 88
2

Percentages rarely work as heights in CSS. To make the child height the same as their parent, you can use a bit of Javascript. Here's what it would look like in jQuery:

    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript">
        $(function() {      
            var containerheight = $("outerBox").height;
            $(".outerBox").children().css("height",containerheight)
    </script>

If you wanted to just make the boxes within a container the same size, the Filament Group has a great plugin for equalizing box heights with jQuery and it's very well documented:

Equal Heights With jQuery

Andrew
  • 1,819
  • 5
  • 23
  • 31
2

Use display:table-cell;

This is very useful in two columns email design(width responsive).

View demo here.

raven
  • 188
  • 11
1

One way to do the following without using JavaScript is via a technique called Faux-Columns.

It basically involves applying a background-image to the parent elements of the floated elements which makes you believe that the two elements are the same height.

More information available at:

A List Apart: Articles: Faux Columns

Andrew Moore
  • 93,497
  • 30
  • 163
  • 175
  • I saw this but the boxes are quite modular in design (i.e they are styled boxes) so I not to sure how ideal this solution is. – Damien Jul 23 '09 at 14:27
1

Try this: http://www.filamentgroup.com/examples/equalHeights/

It's an easy to use jQuery plugin, that you can just use on the parent container and all the top level child elements are adjusted to the same height as the tallest one.

1

If you really wanted a div to act like a table, you can just customize the css "display" of the div.

display:table for the container div

display:table-cell for the div inside to act as td

Andrew
  • 11
  • 1
0
function evenup(){
        var maxHeight = Math.max.apply(null, $(".myClass").map(function (){
            return $(this).height();
        }).get());  
    $(".myClass").height(maxHeight);
}
Shawn
  • 3,031
  • 4
  • 26
  • 53
0
function setSameHeight(class_name){
  var max_height = 0;
  var cards = getElementsByClassName(class_name);       
  for (var i=0; i<cards.length; i++){
    if (cards[i].offsetHeight > max_height){                
      max_height = cards[i].offsetHeight;
    }
  }
  for (var i=0; i<cards.length; i++){
    cards[i].setAttribute("height", max_height);
    cards[i].height = max_height;           
  }
}

function getElementsByClassName(className){
  var hasClassName = new RegExp("(?:^|\\s)" + className + "(?:$|\\s)");
  var allElements = document.getElementsByTagName("*");
  var results = [];
  var element;
  for (var i = 0; (element = allElements[i]) != null; i++) {
    var elementClass = element.className;
      if (elementClass && elementClass.indexOf(className) != -1 &&     hasClassName.test(elementClass))
      results.push(element);
    }
    return results;
}

used that for tables

takrl
  • 6,356
  • 3
  • 60
  • 69
megamanx
  • 11
  • 2