Want 2 equal-sized side-by-side Boxes

For layout purposes, I would like two containing boxes that are equal Height and Width that are side-by-side. (Think of a 1 row table with 2 columns.)

I would like to avoid using an HTML table, since I don’t think it is necessary or appropriate.

My best guess at how to do this would be to…

1.) Create two DIVs
2.) Give each a Width
3.) Float them to the Left

But if that is a start, then I have some other issues I’m not sure how to handle…

  • I can’t rely on Padding to give them an equal Height because each “box” will have different content

  • I’ve always been confused about using Height because I seem to recall Paul O’ and others staying it doesn’t work like you’d expect it to and is not even honored by all browsers?!

What are your thoughts on all of this?

Thanks,

Debbie

  • I’ve always been confused about using Height because I seem to recall Paul O’ and others staying it doesn’t work like you’d expect it to and is not even honored by all browsers?!

Right, well… the rules are more complicated for height than they are for width. And when content enlarges, “height” (rather than min-height) can cause problems with cutting content off.

Setting height in a % is ignored by browsers unless the thing’s parent already has a set (non-%) height.

I would like to avoid using an HTML table, since I don’t think it is necessary or appropriate.

My best guess at how to do this would be to…

1.) Create two DIVs
2.) Give each a Width
3.) Float them to the Left

Lessee, there are a few things off the top of my head; they all have drawbacks.

While an HTML table may not be appropriate, there is the CSS equivalent: display: table.
I’m not sure if all current browsers who support display: table still need a “table” element, a “row” element and then the “cell” elements, but if they all do (Safari used to need all three for example) then you’d have two wrapping divs rather than one.

Outer-est one would be display: table
inner wrapper would be display: table-row
the two side-by-sides would be display: table-cell

Because they’ll follow the rules like a table, if any one “cell” gets taller, the whole row gets taller. Meaning also the other “cell” div.

IE6 and 7 don’t support display: table in any reasonable way. If you need to support them AND it’s an absolute MUST that these two boxes are definitely exactly always the same height, you can’t use this one.

If the same-height thing is approximate though and you’re kinda loose with the restrictions, you can do this (with plain floats, for all browsers):

Find the longest div. If you know what the most amount of content the longest div will have, set a min-height on that div in em’s. Use ugly background colours to see that your stated min-height is taller than the content.

Both divs can then have that min-height (and IE6 gets “height”). If content in one of them grows, it won’t make the other div grow, but unlike height, it won’t stop the div from growing to accomodate the growth of the content.
(so this works pretty well in previews where the preview text is limited to x-characters or never goes beyond so-many lines or something… tho it does break the illusion if the user has text-enlarge)

Those two techniques are the first I consider.

Others include doing fancy tricks with absolute positioning and Javascript. I don’t like those ones as much : )

Yes Mallory has explained well :slight_smile:

This is my preferred method if IE6 and 7 support is required but is a little complicated.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<style type="text/css">
p, h1, h2 {
    margin:0 0 1em
}
html, body {
    margin: 0;
    padding: 0;
}
body {
    background:#fcf9f0;
    color:#162847;
    font-family:Verdana, Arial, Helvetica, sans-serif;
}
#content {
    width:940px;
    margin: 0 auto;
    padding:10px 0;
    position: relative;
    overflow:hidden;/* clear floats*/
    border:1px solid #000;
}
/* equal column routine */
.row {
    width:410px;
    position:relative;
    float:left;
    margin:0;
}
.row p {
    margin:10px
}
/* .box cannot be position:relative or this won't work */
/* use an inner if stacking context needed but leave .bg outside */
.box {
    width:190px;
    float:left;
    margin:0 5px;
    display:inline;
}
/* if you don't want an inner then use this instead
.box * {
    position:relative;
    z-index:2;
}
*/
.inner {
    position:relative;
    z-index:2;
    width:190px;
    border-top:1px solid #000;
}
.box .bg {
    width:188px;
    background:#d9db56;
    position:absolute;
    top:0;
    bottom:0;
    z-index:1;
    border:1px solid #000;
    border-top:none;
}
.box .bg2 {
    background:#f2f2f2;
}
</style>
<!--[if lte IE 6]>
<style type="text/css">
* html .row{overflow:hidden}
* html .box .bg{
    top:auto;
    bottom:0;
    height:999em;
}

</style>
<![endif]-->
</head>
<body>
<div id="content">
    <div class="row">
        <div class="box">
            <div class="inner">
                <p>test</p>
                <p>test</p>
                <p>test</p>
            </div>
            <div class="bg bg2"></div>
        </div>
        <div class="box">
            <div class="inner">
                <p>test</p>
                <p>test</p>
                <p>test</p>
                <p>test</p>
                <p>test</p>
            </div>
            <div class="bg"></div>
        </div>
    </div>
    <!-- end pair of items -->
    <div class="row">
        <div class="box">
            <div class="inner">
                <p>test</p>
                <p>test</p>
                <p>test</p>
                <p>test</p>
                <p>test</p>
                <p>test</p>
                <p>test</p>
                <p>test</p>
                <p>test</p>
                <p>test</p>
            </div>
            <div class="bg"></div>
        </div>
        <div class="box">
            <div class="inner">
                <p>test</p>
                <p>test</p>
                <p>test</p>
                <p>test</p>
                <p>test</p>
            </div>
            <div class="bg bg2"></div>
        </div>
    </div>
    <!-- end pair of items -->
</div>
</body>
</html>


Similar live example here. (This technique is based and improved form my [URL=“http://www.pmob.co.uk/search-this/absolute-columns3-hide.htm”]old article here.)

Here is one cross browser way using display table. http://www.tjkdesign.com/articles/float-less_css_layouts.asp

if you only need two ( or 3) equal size boxes, this my own personal method of achieving this. The nice thing about it that that mark up structure allows me to switch to CSS: display table… easily.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Untitled Document</title>





<style>
.rowWrap  { background:silver; width:960px; margin:0 auto; text-align:center; line-height:0}/*note this would be the color of your boxes*/
 .row{ width:20px;   background:#fff;display:inline-block; line-height:1; text-align:left}/* a fixed space between the boxes... there are other options that can be used, but lets keep it simple*/
.l, .r{  width:470px;}
.r{float:right; margin-right:-470px;}
.l{float:left; margin-left:-460px;}

</style>
</head>
<body>
        <div class="rowWrap">
        		<div class="row">
                      <div class="box l">
                          <p>test</p>
                          <p>test</p>
                          <p>test</p>
                          <p>test</p>
                          <p>test</p>
                          <p>test</p>
                          <p>test</p>
                          <p>test</p>
                          <p>test</p>
                          <p>test</p>
                      </div>
                      <div class="box r">
                          <p>test</p>
                          <p>test</p>
                          <p>test</p>
                          <p>test</p>
                          <p>test</p>
                      </div>
            <!--row--></div>
    </div>
    <!-- end pair of items -->
</body>
</html>

the down side… IE… is int always… the fix is irksome , but not troublesome. This is more IE friendly, but requires ONE line of non-semantic mark up:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Untitled Document</title>





<style>
.rowWrap  { background:silver; width:960px; margin:0 auto;}/*note this would be the color of your boxes*/
 .row{ width:20px;   background:#fff; margin:0 auto;}/* a fixed space between the boxes... there are other options that can be used, but lets keep it simple*/
.l, .r{  width:470px;}
.r{float:right; margin-right:-470px;}
.l{float:left; margin-left:-460px;}
.clear{clear:both}
</style>
</head>
<body>
        <div class="rowWrap">
        		<div class="row">
                      <div class="box l">
                          <p>test</p>
                          <p>test</p>
                          <p>test</p>
                          <p>test</p>
                          <p>test</p>
                          <p>test</p>
                          <p>test</p>
                          <p>test</p>
                          <p>test</p>
                          <p>test</p>
                      </div>
                      <div class="box r">
                          <p>test</p>
                          <p>test</p>
                          <p>test</p>
                          <p>test</p>
                          <p>test</p>
                      </div>
<div class="clear"></div>
            <!--row--></div>
    </div>
    <!-- end pair of items -->
</body>
</html>

Actually, this to accommodate IE6-7 that only gives inline-block to inline elements … BLAST. however… I was working on a third version of this solution ( tho I cant recall it at the time) double bast!

When dealing with Fixed Widths and BG Colors (not images) it doesn’t get much easier than the old Border Trick. :slight_smile:

No extra elements (in the markup) needed for that method but it has it’s limitations.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
 "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Equal Height Columns Border Trick</title>

<style type="text/css">
#wrap {
    width:300px;/*600px total width*/
    margin:0 auto;
    background:#EEF;
    border-right:300px solid #CDF;/*300px rt column color*/
}
#wrap:after { /*clear floats shifted out of parent*/
    clear:both;
    content:"";
    display:block;
}
#left {
    float:left;
    width:300px;
}
#right {
    float:right;
    width:300px;
    margin-right:-300px;
    position:relative;/*IE6*/
}
p {margin:1em;}
</style>

</head>
<body>

<div id="wrap">
    <div id="left">
        <p>Left column content</p>
        <p>Left column content</p>
        <p>Left column content</p>
        <p>Left column content</p>
        <p>Left column content</p>
        <p>Left column content</p>
    </div>
    <div id="right">
        <p>Right column content</p>
        <p>Right column content</p>
        <p>Right column content</p>
        <p>Right column content</p>
    </div>
</div>

</body>
</html>

Another approach.

I’ve often said IE7- should not be the common denominator for my CSS.

In this case, since simulating table layout is the target, for modern browsers, that understand CSS table and adjacent sibling selector, the answer is simple and clear:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
  "http://www.w3.org/TR/html4/strict.dtd">

<html lang="en"><head>

  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Two Equal Divs</title>
 
  <style type="text/css">

    div {
        display:table-cell;
        background:red;
        width:20em;
        height:15em;
      }
      
    div+div {
        background:green;
        width:30em;
        height:12em;
      }
        
  </style>
  
</head><body>

  <div>First</div>
  <div>Second</div>

</body></html>

This goes to show how clean and fast things can be done, for IE8+ also. The highest div will dictate both divs height.

If I have to also provide IE7- support, I choose to go back with my CSS and mark up only for it. I keep my modern CSS, and I pay the CC price, which is fine by me: HTML tables for IE7-.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
  "http://www.w3.org/TR/html4/strict.dtd">

<html lang="en"><head>

  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Two Equal Divs</title>
 
  <style type="text/css">

    div {
        display:table-cell;
        background:red;
        width:20em;
        height:15em;
      }
      
    div+div {
        background:green;
        width:30em;
        height:12em;
      }
        
  </style>
 
  <!--[if lt IE 8]>
    <style type="text/css">
        
      td, td div {
          background:red;
          width:20em;
          height:15em;
          vertical-align:top;
        }
        
      td.second, td.second div {
          background:green;
          width:30em;
          height:12em;
        }
          
    </style>
  <![endif]-->
  
</head><body>

  <!--[if lt IE 8]>
    <table cellspacing="0">
      <tr>
        <td>
  <![endif]-->

  <div>First</div>

  <!--[if lt IE 8]>
      </td>
      <td class="second">
  <![endif]-->

  <div>Second</div>

  <!--[if lt IE 8]>
      </tr>
    </table>
  <![endif]-->

</body></html>

One note: the markup doesn’t have to look like this one. Using SSI, for example, the initial markup is CC clutter free. :wink:

I think we’ve given Debbie too much to think about :slight_smile:

There’s loads of good methods above and all will work depending on circumstance and use.

I believe I’m right in saying that the none of the methods mentioned above, as they stand, (apart from mine) will work if you want space between the elements and you want full borders all around each element. However, some of the other methods are simpler to implement than mine so may be better if that function isn’t required.

I’m at work right now, but I couldn’t resist to throw a little demo to challenge what Paul said. :lol:

It needs a little more work to make it consistent, but you get the idea. Anyway, it’s just to open a little door for those who like to follow every possible avenue. It’s often that a post is more about the forum than about what the OP wants. :slight_smile:

Take it like a PoC, don’t dwell too much on little details. I’m sure those can easily be tuned down. Also notice that IE8 falls under the less capable browser category now. Also, Op 11 seems to ignore -o-transform.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
  "http://www.w3.org/TR/html4/strict.dtd">

<html lang="en"><head>

  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Two Equal Divs</title>
 
  <style type="text/css">

    div {
        display:table-cell;
        background:red;
        width:20em;
        height:15em;
      }
      
    div+div {
        background:green;
        width:30em;
        height:12em;
        transform:translate(10px, 0);
        -moz-transform:translate(10px, 0);
        -webkit-transform:translate(10px, 0);
        -o-transform:translate(10px, 0);
      }
        
  </style>
 
  <!--[if lte IE 8]>
    <style type="text/css">
        
      td, td div {
          background:red;
          width:20em;
          height:15em;
          vertical-align:top;
        }
        
      td.second, td.second div {
          background:green;
          width:30em;
          height:12em;
        }
          
    </style>
  <![endif]-->
  
</head><body>

  <!--[if lte IE 8]>
    <table cellspacing="10px">
      <tr>
        <td>
  <![endif]-->
  <div>First</div>
  <!--[if lte IE 8]>
      </td>
      <td class="second">
  <![endif]-->
  <div>Second</div>
  <!--[if lte IE 8]>
      </tr>
    </table>
  <![endif]-->

</body></html>

lol - I like it :slight_smile: