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.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
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
.outer, .outer2 { width: 200%; }
in particular.left
and right
properties affect absolutely and relatively positioned elements.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.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
#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.left
property values on all those container and see each step's purpose..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
..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..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
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;
}
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
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
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; }
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
#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.
0 comments:
Post a Comment