In Stone Age people used
align
attribute to center elements on their pages... never use those. With the arrival of CSS the old methods have been deprecated as CSS is able to offer more flexibility and easier maintenance with regards to centering.What is important to understand is that with CSS you don't just push the magic button and hope everything will work out for anything you want to center. You need to know what you want to center and what styles have been applied to that element in order to choose an appropriate method for centering.
In this tutorial I provide examples which demonstrate a particular centering method. Sometimes the effect may differ in Internet Explorer and standards compliant browsers. If you do not have Internet Explorer installed on your system you may want to use freely available tools such as NetRenderer or Total Validator.
Block-level and Inline-level Content
First step in centering with CSS is to find out what kind of element you are trying to center. Is it block-level or inline-level?Different methods are used for each type of content. Plain text, images,
, etc. are inline-level content, while elements such as
and are block-level content. Using the
are block-level content. Using the display
property, authors can change the way the element is displayed. For example, if you set img { display: block; }
your images will not be affected by text-align
property that affects only text and inline-level elements (unless you are talking about IE below 8 that is affected by Text-Align Bug).
Which elements are block-level and which are inline-level is beyond the scope of this document. There plenty of online resources available that describe everything in detail and I am not going to reinvent the wheel. Wikipedia has a list of inline-level elements as well as a list of block-level elements.
Lorem Ipsum Lorem Ipsum
Lorem Ipsum Lorem Ipsum
Lorem Ipsum Lorem Ipsum
Lorem Ipsum Lorem Ipsum
Lorem Ipsum Lorem Ipsum
Lorem Ipsum<br>
<img src="smiley.png"
alt="Lorem Ipsum" width="35" height="35">
</p>
</div>
</div>
<div class="outer2">
<div class="inner">
<p>
Lorem Ipsum!
Lorem Ipsum!<br>
<img src="smiley.png"
alt="Lorem Ipsum" width="35" height="35">
</p>
</div>
</div>
</div>
CSS code
#container
{
height: 200px;
position: relative;
overflow: hidden;
}
.outer, .outer2
{
position: absolute;
top: 0;
width: 200%;
left: -50%;
}
.outer2 { top: 85px; }
.inner
{
position: absolute;
left: 50%;
}
.inner p
{
position: relative;
left: -50%;
}
.outer2 p
{
background: #afa;
}
condcom code
The method is extremely similar to method of centering floats. However, there may seem to be some redundant or unexpected code,
.outer, .outer2 { width: 200%; }
in particular.First of all it's important to understand the difference on how
left
and right
properties affect absolutely and relatively positioned elements.When
position
property is set to value relative
, code left: 50%
will offset the entire element by 50% of the width of the parent container. However, when the position
property is set to absolute
and width
is set to auto
(the default width
value), left: 50%
will move the left margin edge of the element by 50% of the width of the container, i.e. resizing the element.So what problem does it create to us? If we would to try to center our absolutely positioned element the same way we centered floats subsequently changing
position: relative
to position: absolute
, our "shrink-wrapped" element would be able to expand only up to the half of its parent. If that's good enough for you, you can avoid the second wrapper
in the example above.
's left margin edge is in the center of
by half the
However, if your image is content level, and you are trying to center it, there is a trick. Images have intrinsic dimensions, meaning that browser knows image's height and width without you explicitly telling about it. Referring back to our centering block-level content with known width section we know that
"Wait a second", one may say, "images are inline-level content,
. The image is there. The image is centered. However, it is cut off. Yes, setting
Now let's take a look at our
When Internet Explorer is in quirks mode, it does not center block-level elements with
With obstacles addressed, let's begin breaking down the code and looking at what it does. Once again,
#container { position: relative; }
establishes containing block for our absolutely positioned elements. However, note the #container { overflow: hidden; }
it not there to contain any floats as one may think at first. It does exactly that, hides any overflow. Where is that overflow coming from? Take a guess, it's from .outer, .outer2 { width: 200%; }
that makes .outer
and .outer2
twice as wide as the parent, but #container { overflow: hidden; }
hides that extra half of width.Now, let's follow the "tree" of our
left
property values on all those container and see each step's purpose.Along with doubled width, our
.outer
also has left: -50%;
(note the minus sign). Since we did define width
, left
moves the entire element to the right (because we have used a negative value for left
), half the parent's width. Now the horizontal middle of .outer
is in the center of #container
with 25% of .outer
's width (remember, we doubled the width) sticking out of the #container
on each side. If you don't understand why 25% on each side, let me follow again on our dimensions. .outer
's width is double the parent's width, left: -50%
moved .outer
half of the parent's width which is exactly 25% of .outer
's width. Since originally .outer
's left edge was at the left edge of the #container
and we moved it 25% of .outer
's width the other 25% of .outer
's width will end up sticking out on the other side of #container
. What we basically did is create a centered container that is double the width of the #container
and if you were following the above paragraphs you know why we wanted this - our shrink wrapped element will expand only half the width of that parent, but since we have just doubled the width of the parent, the shrink wrapped element will be able to expand up to 100% of the #container
.Next step is absolutely positioned
.inner
with left: 50%
on it (note that this time it is a positive value). Since .inner
does not have any width
set (i.e. has width: auto
since that's the default), left: 50%
moves the left margin edge of .inner
to the center of .outer
consequently allowing the shrink-wrapped contents of .inner
to expand only up to the half of .outer
's width, but since we have doubled .outer
's width, this effect is exactly what we want.Final step is the actual element that we were trying to center in the first place, is our
, thus .inner p
. Note that it is relatively positioned (i.e. has position: relative
) and the reason is that we want left: -50%
(negative value again) to offset the element itself instead of only its margin edge. Now .inner
's left margin edge is in the center of .outer
(and of course the center of #container
) as well as .inner
is shrink wrapped around our
's left margin edge is in the center of
#container
. Offsetting
by half the
.inner
's width is the same thing as offsetting it by the half of its own width that will perfectly center it inside #container
, which is what we wanted.Special Note On Images and Content With Intrinsic Dimensions
I often see people being hard on themselves, trying to center some design related image using![]()
element. First of all, you should use ![]()
element only for content level imagery such as photographs, charts and maps, basically images which would not be changed if the website would be redesigned. For presentation level imagery such as borders, pretty design elements, rounded thingies etc. you should use the background
property.However, if your image is content level, and you are trying to center it, there is a trick. Images have intrinsic dimensions, meaning that browser knows image's height and width without you explicitly telling about it. Referring back to our centering block-level content with known width section we know that
margin: 0 auto
will center an element providing you have set width. Since elements with intrinsic dimensions already have that width, specifying just margin: 0 auto
will successfully center them."Wait a second", one may say, "images are inline-level content,
margin: 0 auto
will not center them". That's where the display
property joins the game. Setting display: block
on our ![]()
element makes it act like a block-level element.Example 7
Your browser must render images and support CSS in order to view this example.
Lorem Ipsum
Lorem Ipsum 
HTML Code
<div>
<p>Lorem Ipsum</p>
Lorem Ipsum
<img src="design.jpg" width="100" height="80" alt="design">
</div>
CSS code
div { text-align: left; }
p
{
width: 80%;
margin: 30px auto;
background: #fff url(design.jpg) no-repeat center;
color: #000;
}
img
{
display: block;
margin: 0 auto;
}
The example shows two methods that I've just mentioned. First, note that I've set
Take a close look at our div { text-align: left; }
. I did it only to assure you that we have not set text-align: center
anywhere since that's not how we are doing the centering in this example.
. The image is there. The image is centered. However, it is cut off. Yes, setting
background
does not affect the size of the element in any way, neither can you stretch or set dimensions on background images. The actual centering is done by the center
word in the value of background
property, which is a shorthand. The effect would be the same if we would have used background-position: center center
. The values that background-position
property accepts is beyond the scope of this tutorial.Now let's take a look at our
![]()
element and the text that is directly inside the
. I want to note that having plain text inside the
is not semantic, however I did not want to make my example too complicated. The
![]()
is centered, text is not. What's the magic? It's right there, img { display: block; margin: 0 auto; }
. As I've mentioned earlier, img { display: block; }
makes our image act like a block-level element. Since ![]()
is an element with intrinsic dimensions, setting img { margin: 0 auto; }
centers it, despite the fact that we haven't set width
on the image.Internet Explorer Bugs
There are two modes in IE: standards compliant mode (buggy) and quirks mode (super buggy). The modes are switched with the DOCTYPE which is known as Doctype Switching.When Internet Explorer is in quirks mode, it does not center block-level elements with
margin: 0 auto
. So how would you center it? First of all, you should not have your IE in quirks mode. I understand that under some circumstances changing the DOCTYPE could be impossible. However, there is another bug in Internet Explorer, which can be used to center block-level elements in quirks mode. Let's take a look at the example and I will explain what is going on.Example 8
I am not affected
Lorem Ipsum!

HTML Code
<div>
<p id="fixed">I am not affected</p>
<p id="broken">
Lorem Ipsum!<br>
<img src="smiley.png" alt="Lorem Ipsum"
width="35" height="35">
</p>
</div>
CSS code
div { text-align: center; }
p
{
margin: 1%;
width: 20%;
}
#fixed { float: left; }
#broken { clear: left; }
has
text-align: center
applied to it which, in standards compliant browsers does not center our block-level
s. Take a look in Internet Explorer however. What is going on? Apparently #broken
is centered with respect to the
it is contained in. But what's the difference between
As I have mentioned before, the expanding box model bug messes up virtually every centering method I have covered. It is out of scope of this tutorial, and I haven't found any usable solution for it. I will do more research on it, and hopefully will write a tutorial on how to fix it which will be hosted on hasLayout.net.
#fixed
and #broken
? The float
. In IE, text-align
affects block-level elements as is mentioned in my Text-Align Bug, it does so in both, standards compliant and quirks mode. It seems that the only way to fix that effect is to apply float: left
or float: right;
to the affected element.As I have mentioned before, the expanding box model bug messes up virtually every centering method I have covered. It is out of scope of this tutorial, and I haven't found any usable solution for it. I will do more research on it, and hopefully will write a tutorial on how to fix it which will be hosted on hasLayout.net.
No comments:
Post a Comment