Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shouldn't "text-align: center;" applied to an absolutely positioned element, do nothing to its child elements?

I'll let you see the code first then tell you what my problem is:

Tinkerbin: http://tinkerbin.com/x8iGCFsZ

<style>
  div.container{
    height: 200px;
    width: 200px;
    background-color:red;
    margin-top: 10px;
  }

  div.subContainer{
    position: relative;
    text-align: center;
  }

  div.inner{
   position: absolute;
   background-color:yellow;
   width: 150px;
  }
</style>

<div class="container">
  <div class="subContainer">
    <div class="inner">bananas for breakfast</div>
  </div>
</div>

So, according to the textbook, text-align: center;, when applied to a parent element, only centers its child elements if they have display: inline;.

Therefore, and as you'd expect, since a <div> has by default display set to block (display:block;) the text-align: center; applied to the parent div.subContainer doesn't do anything to its child div.inner.

Everything fine so far. Nothing weird.

My problem arouses when I try using <span>, instead of <div> on the .inner element, and I position it absolutely (position: absolute;) — which, as you know force changes the display, from its default inline, to block.

Take a look:

<style>
  div.container{
    height: 200px;
    width: 200px;
    background-color:red;
    margin-top: 10px;
  }

  div.subContainer{
    position: relative;
    text-align: center;
  }

  span.inner{
   position: absolute;
   background-color:yellow;
   width: 150px;
  }
</style>

<div class="container">
  <div class="subContainer">
    <span class="inner">bananas for breakfast</span>
  </div>
</div>

What happens is weird. In spite of having the forced display value of block (thanks to the position: absolute;) the span is still centered. And even more, the centering is actually weird. It takes the left side of the block and aligns it with the center of the containing element, instead of, as usual, aligning both center.

The behavior is fixed — starts acting like a block — when I manually set the display on the span.inner to block.

span.inner{
   position: absolute;
   display: block;
   background-color:yellow;
   width: 150px;
}

So, what's happening here? Does the absolutely positioning not force change the display to block? Why is the centering weird?

like image 808
João Paulo Macedo Avatar asked Feb 09 '12 22:02

João Paulo Macedo


1 Answers

When you set it to position: absolute, it does become a block, but it gets removed from the flow of content at the point it would have originally appeared. Since you are not using top, left, bottom, and right, this is much more noticeable.

When using a <div>: A division, by default, is block-level and will take up the entire width possible. So it would, by default, start at the left side of the box and expand to the right. Positioning this absolutely would keep it at the top left corner where it originally appeared, the only noticeable difference being the width of the box.

result-with-div

When using a <span>: A span, by default, is an inline element which is affected by the text-align property of it's parent. The text cursor starts at the center of the element, and as text is entered, the characters are added and re-centered to adjust to the width of the text. When you remove the span from the flow, it starts at the point where the text would have started. The text cursor is at the very center (horizontally) of the element, since now there is no text in the actual parent.

result-with-span

You've already found the solution: adding display: block will force the element to actually be a block-level element. The thing is, just because position: absolute "forces" this property, it's not an actual property, only a computed value for the element. That being said, it only gets applied to the element's position when its explicitly set in its CSS definitions.

like image 192
animuson Avatar answered Sep 25 '22 02:09

animuson