Chris Knight
Chris Knight

Reputation: 25074

How can I avoid hard coding line height while vertically centering element in a div?

I have a checkbox next to 3 lines of text. I wish to center the checkbox vertically against these lines of text:

   A
[] B
   C

I'm attempting to do this via div containers while resisting the immense temptation to revert to tables. Here's my code so far:

<div style="overflow:auto;">
   <div style="height:57px; float:left;margin-right:15px;">
      <input style="vertical-align:middle;height:100%" type="checkbox" 
             name="theCheckbox" id="checkboxId">
   </div>
   <div style="float:left;">
       A<br/>
       B<br/>
       C
   </div>
</div>

JSFiddle

While the above 'works', I'm not happy about the hard coded height. Changing 57px to 100% makes the checkbox disappear (computed height becomes 0). Removing the height style from the div alltogether also results in a disappearing checkbox. Can anyone suggest improvments or alternative solutions to achieve my goal?

EDIT: I have to support IE7+ amongst other browsers.

Upvotes: 0

Views: 731

Answers (3)

Marc Audet
Marc Audet

Reputation: 46785

You can position the checkbox vertically using absolute positioning.

For your HTML, you can simplify it as follows:

<div class="wrap">
    <input class="control" type="checkbox" name="theCheckbox" id="checkboxId">
    <div class="label">A
        <br/>B
        <br/>C
        <br/>D</div>
</div>

and apply the following CSS:

.wrap {
    border: 1px dotted gray;
    position: relative;
    overflow: auto; /* triggers hasLayout in IE7 */
}
.control {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    margin: auto;
}
.label {
    margin-left: 20px;
}

Demo Fiddle: http://jsfiddle.net/audetwebdesign/N23qr/

The tradeoff here is that you need to hard code a value for margin-left on the .label container, which is less restrictive than specifying a height value.

Note About IE7

To get position: relative to work correctly for .wrap, you need to make sure that IE7 invokes the hasLayout property, which can be effected by applying overflow: auto. For more details, see: IE7 relative/absolute positioning bug with dynamically modified page content and specifically, http://www.satzansatz.de/cssd/onhavinglayout.html#rp

Upvotes: 1

geekchic
geekchic

Reputation: 2431

How about this?

HTML:

<input type="checkbox" name="theCheckbox" id="checkboxId"/>

<div id ="try">
   A<br/>
   B<br/>
   C
</div>

CSS:

#checkboxId{
position:relative;
vertical-align:middle; 
}

#try{  
position:relative;
display:inline-block;    
vertical-align:middle; 
}

Here is the JSFiddle

Upvotes: 2

CaribouCode
CaribouCode

Reputation: 14398

You could treat the elements as a table (without actually using a table) like this:

HTML

<div id="container">
   <div class="tableCell">
     <input type="checkbox" name="theCheckbox" id="checkboxId">
   </div>
  <div class="tableCell">A<br/>B<br/>C</div>
</div>

CSS

#container { display: table; }

.tableCell { 
    display: table-cell;
    vertical-align: middle; }

See the fiddle here: http://jsfiddle.net/QpnkV/2/

For backwards compatibility think about using scripts in your dochead like this:

<!--[if lt IE 8]><script src="http://ie7-js.googlecode.com/svn/version/2.1(beta4)/IE9.js"></script><![endif]-->

<!--[if IE 8]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->

Upvotes: 2

Related Questions