tags:

views:

410

answers:

5

In the following, I'd like to alter the CSS such that the right-sibling is truly centered in the container div. (Edit: without using absolute positioning).

<html>
  <head>
    <style type='text/css'>
      #container {
        width: 500px;
      }
      #left-sibling {
        float: left;
      }
      #right-sibling {
        text-align: center;
      }
    </style>
  </head>
  <body>
    <div id='container'>
      <div id='left-sibling'>Spam</div>
      <div id='right-sibling'>Eggs</div>
    </div>
  </body>
</html>

In its current implementation, the right sibling's centering is affected by the left sibling -- you can see this by adding display: none to the left-sibling's style.

(Note: I'd like to avoid modifying the HTML structure because, as I understand it, the whole point of CSS is to decouple the tag structure from the presentation logic, and this doesn't seem like a really crazy request for CSS to handle.)

TIA.

A: 

You can change the float: left; on #left-sibling to position: absolute;. This will take it out of the normal flow, so it won't affect right-sibling any more.

Of course, this could have other side-effects with your design.

Greg
Good point -- I'll edit to question to specify I'd like to avoid absolute positioning.
cdleary
A: 

You should always set a width on floated elements, otherwise things get weird :)

If you put a

border: solid 1px #000;

rule on both divs you will see what's happening - the #right-sibling div is filling the entire width of the parent div (#container), so although the text is actually aligned to the centre, it looks like it isn't!

Mark B
No, this isn't correct. Although #right-sibling does fill the entire width, the #left-sibling affects the text alignment calculation. Like I say in the question, if you add `display: none` to the style for #left-sibling the position of "Eggs" changes.
cdleary
It is correct - although the DIV is full-width, that's not how text-align works - it can only align the text within the available space.Add Eggs<br />Eggs<br />Eggs<br /> after the text in #right-sibling and you'll see that the lines *below* the left-sibling div are aligned as you want.
Mark B
Yeah, I meant that "the text **is** actually aligned to the centre" wasn't a correct statement, because the left sibling was affecting the centering calculation.
cdleary
A: 

The text-align attribute controls the alignment of the contents in the container where the attribute is applied. By adding the following styles it is easy to see:

#left-sibling { float: left; width:100px; border:1px Solid Blue; }
#right-sibling { text-align: center; width:100px; border:1px Solid Red; }

I would suggest adding a doctype to the document to avoid quirksmode

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;

and the following styles:

#container { width: 500px; position:relative; border:1px Solid Black; }
#left-sibling { float:left; position:absolute; top:0px; left:0px; width:100px; border:1px Solid Blue; }
#right-sibling { width:100px; position:relative; margin-left:auto; margin-right:auto; border:1px Solid Red; }

You would of course want to adjust the size of the siblings to fit your needs. The borders does a nice job showing what's really happening.

MadViking
You're using absolute positioning -- not sure if you saw that I amended the question after @RoBorg commented on it.
cdleary
A: 

Try setting a width to the left-sibling and an equal padding-right: to the right-sibling

like so

<html>
  <head>
    <style type='text/css'>
      #container {
        width: 500px;
      }
      #left-sibling {
        float: left;
     width:50px;
      }
      #right-sibling {
        text-align: center;
     padding-right:50px;
      }
    </style>
  </head>
  <body>
    <div id='container'>
      <div id='left-sibling'>Spam</div>
      <div id='right-sibling'>Eggs</div>
    </div>
  </body>
</html>
adam
+2  A: 

A trick I just used to get this to work is to have padding on the left of the container and we can encourage the left-sibling to sit inside this space by giving it an equal but negative margin.

To complete the picture we also put padding on the right of the container of an equal size to the width of the left-sibling.

<html>
  <head>
   <style type='text/css'>      
  #container {
   width: 500px;
   padding-left:50px;
   padding-right:50px;     
   }      
  #left-sibling {
   border: solid 1px #000;
   float: left;
   width:50px;
   margin-left:-50px;  
  }      
  #right-sibling {
   border: solid 1px #000;
   text-align: center;

  }
  #container2 {
   width: 500px;   
   }  
</style>
  </head>
 <body>
  <div id='container'>      
   <div id='left-sibling'>Spam</div>
   <div id='right-sibling'>Eggs<br />Eggs<br />Eggs<br /></div>
  </div>
  <div id='container'> 
   <div id='left-sibling' style="display:none;">Spam</div>    
   <div id='right-sibling'>Eggs<br />Eggs<br />Eggs<br /></div>
  </div>
  <div id='container2'> 
   <div id='right-sibling'>Eggs<br />Eggs<br />Eggs<br /></div>
  </div>
   </body>
</html>
rohancragg
Awesome! This is exactly what I needed. :) On a side note, you should only have an 'id' applied to one element on each HTML document. For more than 1 use a 'class' identifier. Thanks again for the great solution.
Mike Grace