Sunday, November 1, 2009

The vertical-align property

The CSS property vertical-align is used to alter the vertical position of inline and replaced elements (it has no effect on block elements). With this property, various parts of inline and replaced elements can be aligned to various parts of the line box. For example, the top of an image can be aligned to the top of the parent element's content box.

The vertical-align property's values can either be keywords, percentages or length values. It is not an inherited property. It has the initial value baseline.

Note: The ascent is the distance between the baseline and the top of the content box. The descent is the distance between the baseline and the bottom of the content box. The size of the leading of a text line box can be obtained by subtracting the height of the line box from the height of the content box. The leading can be either positive (extra space above and below the content box) or negative (the line box cuts off some space from the top and bottom of the content box). The top half-leading and the bottom half-leading is the amount of space (added or removed) above and below the content box, respectively.

Keywords

These are the keywords that can be used with the vertical-align property: baseline, top, text-top, bottom, text-bottom, middle,super, sub and inherit.

vertical-align:baseline

This is the initial, default value of vertical-align. Therefore vertical-align:baseline is only used to override another vertical-align declaration that was applied to an element.

Example: <p>the quick brown <em class="raised" style="vertical-align:baseline">fox</em></p>

vertical-align:top

The declaration vertical-align:top aligns the top of an element's line box to the top of its parent element's line box.

Example 1a: <p style="font-size:35px;font-family:'Times New Roman'">the @Â<span style="line-height: 59px">@Â five</span></p>

In the above example, the line box of the span has a height of 59px and the line box of the <p> expands to accommodate the span line box. However, without the span, the <p> line box would have a height of only 40px.

Example 1b: <p style="font-size:35px;font-family:'Times New Roman'">the @Â<span style="vertical-align:top;line-height: 59px">@Â five</span></p>

In the above example, the vertical-align:top declaration causes the top of the span line box to be aligned to the top of the <p> line box. However, in Internet Explorer 6 and Internet Explorer 7 the vertical-align:top declaration has no effect. This is a bug.

Example 2: <p style="font-size:35px;font-family:'Times New Roman'">the @Â<img style="vertical-align:top" src="20x50.jpg" alt="20x50 image" /></p>

In the above example, the vertical-align:top declaration causes the top of the image to be aligned to the top of the <p> line box.

The vertical-align:top declaration has an effect only in the following cases:

  • vertical-align:top on an inline non-replaced element whose ascent + top half-leading is different from its parent's. The ascent + top half-leading of the inline non-replaced element could be different from the parent element's because
    • a line-height declaration on it, or an inherited raw number line-height declaration, caused it to have a top half-leading that is not equal its parent (with all other CSS text and line box properties being the same as the parent's)
    • it is of different font size (with all other CSS text and line box properties being the same as the parent's)
    • it uses a different font whose ascent is different from its parent's (with all other CSS text and line box properties being the same as the parent's)
    • it contains an element (replaced or non-replaced) that has increased the top half-leading (with all other CSS text and line box properties being the same as the parent's)
  • vertical-align:top on an inline non-replaced element whose parent contains an element (replaced or non-replaced) which increased the top half leading of its (the parent's) line box (with all other CSS text and line box properties being the same)
  • vertical-align:top on an inline replaced element (e.g. an image) whose height is not equal to the ascent of the text of the element it is contained in (with all other CSS text and line box properties being the same as the parent's)
    Note: A line height declaration on an image has no effect on its line box

In all other cases, the top of an element's line box is already aligned with the top of its parent's line box and so, vertical-align:top has no effect.

Note 1: For the parent element, the ascent + top half-leading value that is considered is the one measured when it does not contain the inline element to which the vertical-align declaration is applied.

Note 2: The ascent + top half-leading is measured from the baseline to the top of an element's line box.

vertical-align:bottom

The declaration vertical-align:bottom aligns the bottom of an element's line box to the bottom of its parent element's line box.

Example 3: <p style="font-size: 35px;font-family:'Times New Roman'">the @Â<span style="vertical-align:bottom;line-height: 21px">@Â five</span></p>

In the above example, the span's descent + bottom half-leading is reduced. Therefore, its bottom is not aligned to the bottom of the <p>'s line box which is of normal line height. The vertical-align:bottom declaration on the span causes its line box to be lowered so that its bottom is aligned to the bottom of the <p> line box.

However, in Internet Explorer 6 and Internet Explorer 7, the vertical-align:bottom declaration on the span in the example does not have any effect. This is a bug.

On replaced elements, vertical-align:bottom, causes the bottom of the replaced element's box to align with the bottom of the parent element's line box.

The vertical-align:bottom declaration has an effect only in the following cases:

  • vertical-align:bottom on an inline non-replaced element whose descent + bottom half-leading is different from its parent's. The descent + bottom half-leading of the inline non-replaced element could be different from its parent's because:
    • a line-height declaration on it, or an inherited raw number line-height declaration, caused it to have a bottom half-leading that is not equal to its parent (with all other CSS text and line box properties being the same as the parent's)
    • it is of different font size (with all other CSS text and line box properties being the same as the parent's)
    • it uses a different font whose descent is different from its parent's (with all other CSS text and line box properties being the same as the parent's)
    • it contains an element (replaced or non-replaced) that has increased bottom half-leading (with all other CSS text and line box properties being the same as the parent's)
  • vertical-align:bottom on an inline non-replaced element whose parent contains an element (replaced or non-replaced) which increased the bottom half-leading of its (the parent's) line box (with all other CSS text and line box properties being the same)
  • vertical-align:bottom on an inline replaced element (e.g. an image) (with all other CSS text and line box properties being the same as the parent's)
    Note: A line height declaration on an image has no effect on its line box.

In all other cases, the bottom of an element's line box is already aligned with the bottom of its parent's line box and so, vertical-align:bottom has no effect.

Note 1: For the parent element, the descent + bottom half-leading that is considered is the one measured when it does not contain the inline element to which the vertical-align declaration is applied.

Note 2: The descent + bottom half-leading is measured from the baseline to the bottom of the element's line box.

vertical-align:text-top

The vertical-align:text-top declaration aligns the top of an element's line box to the top of its parent element's content box.

The top of an element's content box is also the top of the text and is therefore known as the text-top.

Example 4: <p style="font-size:35px;font-family:'Times New Roman';line-height:60px">the @Â<span style="vertical-align:text-top">@Â five</span></p>

In the above example, the declared line height on the <p> is 60px. The inline span inherits this line height. The top of the span's line box is by default aligned to the top of the <p> line box. Therefore, the vertical-align: text-top declaration on the span causes the line box to move down 10px so that its top is aligned to the the text-top of the <p>.

Since the span line box has moved down 10px and its height is 60px, the <p>'s line box height has to be increased to 70px to accommodate it.

Note 1: In the above example, in Internet Explorer 6, Internet Explorer 7 and Internet Explorer 8, the vertical-align: text-top declaration on the span has no effect. This is a bug.

Note 2: In the above example, if the line height of the <p> had been decreased, then the span line box would have moved up. This is because the span line box's height is reduced (invisibly) and the text-top of the <p> falls out of the line box.

When vertical-align:text-top is applied to a replaced element (e.g. an image), the top of the image gets aligned to the text-top of its parent.

When an inline non-replaced element and its parent have the same CSS text and line box properties and normal line height, the top of the inline element's line box coincides with the text-top of its parent element's line box. In such a case, vertical-align:text-top has no effect.

The vertical-align:text-top declaration has an effect only in the following cases:

  • When the top of the line box of an inline element is not in alignment with the top of the content box of its parent. This occurs in the following cases:
    • When the line height of the inline element is increased or decreased (with all other CSS text and line box properties being the same as the parent's).
      Note that the line height of an inline element can be increased or decreased either directly (by a line-height declaration that matches the inline element) or indirectly (inherited from its parent)
    • When the inline element is of different font size (with all other CSS text and line box properties being the same as the parent's)
    • When the inline element uses a different font whose ascent is not equal to the parent element's ascent (with all other CSS text and line box properties being the same as the parent's)
    • When the inline element contains an element (replaced or non-replaced) that has increased the top half-leading such that the inline element's ascent + top half-leading is not equal to the parent element's ascent (with all other CSS text and line box properties being the same)
  • vertical-align:text-top on an inline replaced element (e.g. an image) whose height is not equal to its parent's ascent (with all other CSS text and line box properties being the same as the parent's)
    Note: A line height declaration on an image has no effect on its line box.

In all other cases, the top of an element's line box is already aligned with the text-top of its parent and so, vertical-align:text-top has no effect.

vertical-align:text-bottom

The vertical-align:text-bottom declaration aligns the bottom of an element's line box to the bottom of its parent element's content box.

The bottom of an element's content box is also the bottom of the text and is therefore known as the text-bottom.

Example 5: <p style="font-size:35px;font-family:'Times New Roman'">the @Â<span style="vertical-align:text-bottom;line-height: 59px">@Â five</span></p>

In the above example, the declared line height on the span is 59px. Therefore the span's line box height is increased to 59px. The height of the content box of the span is 40px. In Firefox 3.5, the top half-leading is 9px and the bottom half-leading is 10px. This gives the line box a height of 59px.

Since the bottom half-leading is 10px, this is the gap between the bottom of the span's line box and the text-bottom of the <p>. Therefore the vertical-align:text-bottom declaration moves the span line box up by 10px (with respect to the <p>) so that the span line box bottom is aligned with the text-bottom of the <p>.

Note 1: In the above example, in Internet Explorer 6, Internet Explorer 7 and Internet Explorer 8, the vertical-align:text-bottom declaration on the span has no effect. This is a bug.

Note 2: In the above example if the line height of the span had been decreased, then the span line box would have moved down. This is because the span line box's height is reduced invisibly causing the bottom of the line box to be within the content box.

When vertical-align:text-bottom is applied to a replaced element (e.g. an image), the bottom of the image gets aligned to the text-bottom of its parent.

When an inline non-replaced element and its parent have the same CSS text and line box properties and normal line height, the bottom of the inline element's line box coincides with the text-bottom of its parent element's line box. In such a case, vertical-align:text-bottom has no effect.

The vertical-align:text-bottom declaration has an effect only in the following cases:

  • When the bottom of the line box of an inline element is not in alignment with the bottom of the content box of its parent. This occurs in the following cases:
    • When the line height of the inline element is increased or decreased (with all other CSS text and line box properties being the same as the parent's).
      Note that the line height of an inline element can be increased or decreased either directly (by a line-height declaration that matches the inline element) or indirectly (inherited from its parent)
    • When the inline element is of different font size (with all other CSS text and line box properties being the same as the parent's)
    • When the inline element uses a different font whose descent is not equal to the parent element's descent (with all other CSS text and line box properties being the same as the parent's)
    • When the inline element contains an element (replaced or non-replaced) that has increased the bottom half-leading such that the inline element's descent + bottom half-leading is not equal to the parent element's descent (with all other CSS text and line box properties being the same)
  • vertical-align:text-bottom on an inline replaced element (e.g. an image)(with all other CSS text and line box properties being the same as the parent's)
    Note: A line height declaration on an image has no effect on its line box.

In all other cases, the bottom of an element's line box is already aligned with the text-bottom of its parent and so, vertical-align:text-bottom has no effect.

vertical-align:middle

The vertical-align:middle declaration aligns the vertical middle of an element's line box to the height of the parent's baseline (the descent) plus 0.5ex (of the parent).

Example 6: <p style="font-size:35px;font-family:'Times New Roman'">the @Â<img style="vertical-align:middle" src="20x50.jpg" alt="20x50 image" /></p>

In the above example, the <p> content box x-height is 16px, therefore 0.5ex is 8px. The baseline height is 8px. The image's height is 50px, therefore the vertical middle of the image will be at 25px (measuring from the bottom). The vertical-align:middle declaration on the image will therefore align the 25px point on the image to the 32px (16px + 8px) mark. This is true for Firefox 3, Firefox 3.5, Internet Explorer 8, Safari 4 and Chrome 3.

Opera 10 calculates 1ex as 0.5em. In the above example, font size is 35px = 1em, 1ex = 17.5px, 0.5ex = 8.75px. Therefore, the 24px point on the image is aligned to the 17px mark on the <p> content box.

Internet Explorer 6 and 7 also calculate 0.5ex as 8.75px in the above example. In these browsers, the 24px point on the image is aligned to the 19px point on the <p> content box.

vertical-align:super

The vertical-align:super declaration raises the position of the line box of an inline (replaced or non-replaced) element to give it the appearance of a superscript. It does not change the font size or any other property.

The official CSS specification does not specify by how much vertical-align:super should raise an inline element. Because of this, depending on the browser, the number of pixels by which vertical-align:super raises an inline element varies.

In a particular browser, the number of pixels that vertical-align:super raises an inline element depends on the font size of the parent element. It is not affected by the line height of the parent element or any properties of the inline element. The number of pixels the inline element is raised by is measured from the baseline of the content box of the parent element.

Example 7: <p style="font-size:35px;font-family:'Times New Roman'">the @Â<span style="vertical-align:super">@Â five</span></p>

In the above example, the span line box is raised by 16px in Firefox 3, Firefox 3.5, Interenet Explorer 8 and Opera 10. Internet Explorer 6 and 7 raise it by 20px. Safari and Chrome 3 raise it by 12px. The <p> line box expands to accommodate the raised line box.

vertical-align:sub

The vertical-align:sub declaration lowers the position of the line box of an inline (replaced or non-replaced) element to give it the appearance of a subscript. It does not change the font size or any other property.

The official CSS specification does not specify by how much vertical-align:sub should lower an inline element. Because of this, depending on the browser, the number of pixels by which vertical-align:sub lowers an inline element varies.

In a particular browser, the number of pixels that vertical-align:sub lowers an inline element depends on the font size of the parent element. It is not affected by the line height of the parent element or any properties of the inline element. The number of pixels the inline element is lowered by is measured from the baseline of the content box of the parent element.

Example 8: <p style="font-size:35px;font-family:'Times New Roman'">the @Â<span style="vertical-align:sub">@Â five</span></p>

In the above example, the span line box is lowered by 5px in Firefox 3 and Firefox 3.5, by 4px in Interent Explorer 8, by 16px in Opera 10, by 20px in Internet Explorer 6 and Internet Explorer 7 and by 8px in Safari 4 and Chrome 3.

vertical-align:inherit

vertical-align is not an inherited property. However, an element can be made to inherit its parent element's vertical-align value using the declaration vertical-align:inherit. This declaration causes an element to inherit the computed value of vertical-align of its parent element.

Example 12: <p class="test">the @&Acirc;<span style="vertical-align:0.5em">@&Acirc; five<span style="vertical-align:inherit;font-size:20px">@&Acirc; boxing</span></span></p>

In the above example, the child span (to the <p>) is raised by 18px (35px * 0.5 = 17.5px, rounded to 18px). The grand child span has a 3px gap between the bottom of its line box and the bottom of the parent span line box.

When vertical-align:inherit is applied to the grand child span, it inherits the computed value of vertical-align from its parent (17.5px). Therefore, the grand child span's line box's bottom will be 21px (17.5px + 3px = 20.5px, rounded to 21px) above the bottom of its parent's line box. In other words, the grand child span's line box will be raised by 18px.

In Firefox 3 and Firefox 3.5, the grand child span is raised by 17px. This is due to a rounding off bug. In Opera 10 the grand child span is raised by 18px. In Internet Explorer 6, Internet Explorer, 7 and Internet Explorer 8 the grand child span is raised by 15px. This is a bug. In Safari 4 and Chrome 3, it raised by 23px. This is a bug.

Percentage Values with vertical-align

When vertical-align has a percentage value, the distance that the inline element is to be raised or lowered is calculated by multiplying the percentage with the line height of the inline element. The line height may be inherited or declared using CSS. The percentage can be positive or negative. A positive value raises the inline element, a negative value lowers it.

Example 9: <p style="font-size:35px;font-family:'Times New Roman'">the @Â<span style="">@Â five</span></p>

In the above example, the default line height of the <p> is 40px. Therefore vertical-align:75% should raise the span by 0.75 * 40 = 30px.

Firefox 3 and Firefox 3.5 raise the span line box by 31px; Internet Explorer 8, Safari 4, Chrome 3 and Opera 10 by 30px. Internet Explorer 6 and Internet Explorer 7 raise the span line box by 26px. This is a bug.

Length Values - px and em with vertical-align

The distance that an inline element is raised or lowered by the vertical-align property can be specified in px or em. A positive value raises the inline element, a negative value lowers it.

When specified in em, to find the distance that the element is moved in px, the em value is mulitplied with the font size of the inline element that the vertical-align declaration is applied to. The font size may be inherited or declared directly with CSS. Note that even though the font-size declaration does not affect the rendering of images, it is used by the browser to convert em values to pixels when an image has a vertical-align declaration in em.

Example 10: <p class="test">the @Â<img style="vertical-align:16px" src="20x50.jpg" alt="20x50 image" /></p>

Example 11: <p class="test">the @Â<img style="vertical-align:0.45em" src="20x50.jpg" alt="20x50 image" /></p>

Browser Bugs

Internet Explore 6's and Internet Explorer 7's implementation of vertical-align is extremely buggy. These browsers produce unexpected results when vertical-align is used on an inline element of reduced or increased line height (inherited or directly declared) and on replaced elements whose parents are of reduced or increased line height. They also compute lower than expected values for vertical-align percentage declarations.

Firefox 3 displays incorrect rendering when vertical-align:top is used on a span containing an image that is taller than the ascent. Firefox 3 and Firefox 3.5 compute higher than expected values for vertical-align percentage declarations.

Opera 10 displays incorrect rendering when vertical-align:bottom is used on an image that is taller than the ascent on a <p> of increased line height. Opera 10's implementation of vertical-align:text-bottom is buggy.

Safari 4 and Chrome 3 incorrectly renders the positioning of an image with vertical-align:bottom on a <p> of decreased line height. These browsers also incorrectly compute a much larger value than expected for vertical-align percentage declarations.

A bug in Internet Explorer 8, vertical-align:text-bottom and vertical-align:text-top produce no effect on a span of increased or decreased line height. The line height on the span can be inherited or directly declared.

The major browsers differ in the distance that they raise or lower elements with vertical-align:sub and vertical-align:super.

Conclusion

The vertical-align property does not produce consistent results across browsers except when used with px values. Therefore, for consistent rendering across browsers, vertical-align with keywords, percentages and em values should be avoided.

No comments: