tags:

views:

2139

answers:

5

I am trying to float two divs with different font-sizes. I can't find a way to align the text on the same baseline. Here is what I have been trying:

<div id="header">
    <div id="left" style="float:left; font-size:40px;">BIG</div>
    <div id="right" style="float:right;">SMALL</div>
</div>
A: 

If you put the right floated div before the left floated div in the HTML and they'll line up vertically.

Alternatively, you can float both divs left - that's perfectly valid - and how most CSS designs are coded.

slightlymore
That doesn't help them match match up at the baseline, which is the question (I made the same mistake til I reread it).
cletus
I thought the same thing too!
rpflo
+3  A: 

Ok, firstly the pure CSS way. You can get vertical alignment to the bottom using relative+absolute positioning like this:

<div id="header">
  <div id="left">BIG</div>
  <div id="right">SMALL</div>
</div>
<style type="text/css">
html, body { margin: 0; padding: 0; }
#header { position: relative; height: 60px; }
#left { font-size: 40px; position: absolute; left: 0; bottom: 0; }
#right { position: absolute; right: 0; bottom: 0; }
</style>

You may have some issues with this, like IE6 behaviour as well as z-index issues with things like menus (last time I tried this my menus appeared under the absolute content).

Also, depending on whether all the elements need to be absolutely positioned or not, you may need to start doing things like specifying the height of the containing element explicitly, which is usually undesirable. Ideally, you'd want the container to auto-size for its children.

The problem is that the baselines of the different-sized fonts will not match up and I don't know of a "pure" CSS way of doing this.

With tables however the solution is trivial:

<table id="header">
<tr>
  <td id="left">BIG</td>
  <td id="right">SMALL</td>
</tr>
</table>
<style type="text/css">
#header { width: 100%; }
#header td { vertical-align: baseline; }
#left { font-size: 40px; }
#right { text-align: right; }
</style>

Try it and you'll see it works perfectly.

The anti-table crowd will scream blue murder but the above is the simplest, most browser-compatible way (particularly if IE6 support is required) of doing this.

Oh and always prefer using classes to inline CSS styles.

cletus
Mostly ditto. I prefer to define a height on the container than resort to tables, but I do mostly web app development where the whole stinking layout is absolutely positioned already. I wouldn't expect IE6 to struggle with that unless there's a bunch of other crap going on :)
rpflo
If you want to align to the text baseline, I can't see how else you can do it than to use tables. Things within a div are fundamentally too independent of each other, and spans can't be aligned willy-nilly. Using tables when tables are the wrong thing is wrong, using tables when they're the right thing is right. Using them when they're the only thing that works is, however, perfectly acceptable in my book.
ijw
A: 

Do you mean baseline in the typographic sense? (That is, each line of text is level with a corresponding line in the other column) If that's the case, the font sizes need to be multiples of each other -- for example, 12 and 18px (1:1.5).

If you mean the divs need to be the same height, there isn't an easy way to do this. You can manually set a height (height:100px;), or use javascript to adjust one as the other changes.

Or, you can fake the same height by enclosing the two divs in a container, and then applying a background style to the container that mimics the look of the columns, setting it to repeat vertically. That way, you get faux columns. For an in-depth look, see this classic A List Apart article.

Did you mean, you have two pieces of text, and both need to be at the bottom of the columns? (sorry, can't post an image yet)

One way you can do this is using the Faux Columns method above.

The other way is to set up the text in its own container inside the text. Then, position both absolutely at the bottom of the columns ... here's a long snippet:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html>
    <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     <title></title>
     <style type="text/css" media="screen">

     .col { width:200px; float:left;  }
     .short { height:200px; background:#eee; margin-bottom:20px; }
     .long { background:#ddd; margin-bottom:100px; /* margin equal to height of #big */  }

     #container { overflow:hidden; width:400px; margin:0px auto; position:relative; border:1px solid green;}


     #big, #small { position:absolute; bottom:0px; width:200px; }
     #big { height:100px; background:red; }
     #small { height:20px; background:green; right:0px; }



     </style>
    </head>
    <body>

    <div id="container">
     <div class="col long">
      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
     </div>

     <div class="col short">
      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
     </div>

     <div id="big" >BIG</div>

     <div id="small">small</div>

    </div>
    </body>
</html>
Matt Hampel
I have no idea what you meant to say, but 18 is not an integer multiple of 12 and, conversely, *anything* is a non-integer multiple of 12.
ijw
A: 

edit just re-read the questions and saw one box needs floating to the right... so the below doesn't work... but might be adaptable

First of all, you should be using spans rather than divs as the content is going to be inline to finish with. I don't know the ins and outs of why, but this means your elements will behave a bit friendlier across browsers.

Once you've done that, this works a treat, even in ie6 and 7:

#header {height:40px;line-height:40px;}
#left, #right {display:-moz-inline-stack;display:inline-block;vertical-align:baseline;width:auto;} /*double display property is fora  fix for ffx2 */
#left {font-size:30px;}
#right{font-size:20px;}

<div id="header">
  <span id="left">BIG</span>
  <span id="right">SMALL</span>
</div>
wheresrhys
A: 

You can do this using line-height but it only works on inline elements and if the text does not wrap.

<div id="header" style="overflow:hidden;">
    <span id="left" style="font-size:40px;">BIG</span>
    <span id="right" style="line-height:48px;">SMALL</span>
</div>

I changed the div to span. If you want to keep div just add display:inline to your style.

<div id="header" style="overflow:hidden;">
    <div id="left" style="font-size:40px;display:inline;">BIG</div>
    <div id="right" style="line-height:48px;display:inline;">SMALL</div>
</div>
Emily