Sunday, November 8, 2009

The letter-spacing Property

The letter-spacing property is used to adjust the space between letters. The letter-spacing property reduces or increases the width of the em boxes of letters. Note that this property does not change the distance between the em boxes, which is always zero.

The letter-spacing property can be applied to any element. It can take length values and the keywords normal and inherit. It is an inherited property. The initial values is normal. A length of 0 is equivalent to normal. Negative values are allowed; they reduce the width of em boxes.

Note 1: The em box is the box that a glyph occupies.

Note 2: The letter-spacing property does not take percentage values.

Note 3: When the letter-spacing property has a length value, the letter spacing of the text cannot be changed by the text-align property.

letter-spacing with px values

The number of px declared in the letter-spacing declaration is the number of extra pixels of width added to the em boxes it is applied to.

Example 1a): <p style="font-family:'Times New Roman';font-size: 35px"><span>t</span><span>h</span><span>e</span> <span>t</span> <span>h</span> <span>e</span> brown fox @&Acirc;</p>

 

In the above example, there is no letter-spacing declaration, therefore the em boxes are of default width. The default em box sizes for the letter is "t" is 10px, "h" is 18px, and "e" is 15px.

Example 1b): <p style="font-family:'Times New Roman';font-size: 35px;letter-spacing: 10px"><span>t</span><span>h</span><span>e</span> <span>t</span> <span>h</span> <span>e</span> brown fox @&Acirc;</p>


In the above example, the width of the em boxes of the <p> and its descendants have been increased by 10px. Therefore, the width of the em boxes are: "t" 20px, "h" 28px, and "e" 25px.

Example 2: <p style="font-family:'Times New Roman';font-size: 35px;letter-spacing: -3px">the <span>t</span> <span>h</span> <span>e</span> brown fox @&Acirc;</p>


In the above example, the letter-spacing value is negative. This results in the following em box widths: "t" 7px, "h" 15px, and "e" 12px.

letter-spacing with em values

When letter spacing is declared in em, the em value is multiplied with the font-size to give the number of pixels that are added to the width of the em boxes in the element.

Example 2: <p style="font-family:'Times New Roman';font-size: 35px;letter-spacing: 0.5em"><span>t</span><span>h</span><span>e</span> <span>t</span> <span>h</span> <span>e</span></p>


In the above example, the declared em value (0.5em) is multiplied with the font-size to give 17.5px (0.5 * 35). This is added to the width of the em box. This results in the following em box widths: "t" 28px, "h" 36px, and "e" 33px.

However, Internet Explorer 6 and Internet Explorer 7, calculate em letter-spacing declarations to a much smaller value due to a bug.

letter-spacing:normal

letter-spacing:normal restores the em box width to the default sizes. Since letter-spacing is an inherited property, the normal keyword can be used to restore the default letter spacing in an element that has inherited a modified letter spacing declaration.

letter-spacing:inherit

letter-spacing:inherit is used to override another letter-spacing declaration that has been applied to an element, and to restore the default behavior of inheriting the parent element's letter spacing.

Internet Explorer 6 and Internet Explorer 7 do not support letter-spacing:inherit, they ignore it.

Conclusion

For consistent results in all browsers, letter-spacing with em values should be avoided (Internet Explorer 6 and Internet Explorer 7 calculate them incorrectly).

letter-spacing:inherit should also be avoided because Internet Explorer 6 and Internet Explorer 7 do not support it.

letter-spacing declarations in px are supported in all browsers and is therefore the recommended way of using the property.

Friday, November 6, 2009

The word-spacing Property

The word-spacing property is used to modify the distance between words. In CSS, a word is considered to be a one or more (non-whitespace) glyphs with whitespace surrounding it. The word-spacing property does not specify the distance between words, it only specifies the amount of space to be added or removed from the default distance.

The word-spacing property can be applied to any element. It can take length values and the keywords normal and inherit. It is an inherited property. The initial values is normal. A length of 0 is equivalent to normal. Negative values are allowed; they reduce the space between the words.

Note: The word-spacing property does not take percentage values

The width of the space character depends on the font family and font size.

The word-spacing property affects each space (U+0020), non-breaking space (U+00A0), and ideographic space (U+3000) left in the text after the white space processing rules have been applied. Source: http://www.w3.org/TR/CSS21/text.html#spacing-props

According to the specification, therefore, other white space characters such as &ensp;, &emsp;, and &thinsp; are not affected by the word-spacing property. However, Internet Explorer 6 and Internet Explorer 7, modify the word spacing of these characters also. This is a bug. Firefox 3 and Firefox 3.5 do not modify the width of the non-breaking space character &nbsp;. This is a bug.

word-spacing with px values

The number of px declared in the word-spacing declaration is added to the normal width of the space character.

Example 1: <p style="font-family:'Times New Roman';font-size: 35px;word-spacing: 10px">the <span>quick</span> <span>brown</span></p>

In the above example, the default width of the space character is 9px. Therefore, the default space between words is 9px. However, since the word spacing is declared as 10px, 10px is added to the default spacing which results in word spacing of 19px.

Example 2: <p style="font-family:'Times New Roman';font-size: 35px;word-spacing: -20px">the <span>five quick</span> <span>boxing</span> wizards</p>

In the above example, the word-spacing value is negative. Since the default width of the space character is 9px, the final word spacing is 9px -20px = -11px. Therefore, the beginning and ends of words will overlap each other.

Firefox 3 and Firefox 3.5 do not reduce the word spacing between two inline elements (e.g. spans) to less than zero. This is a bug. Internet Explorer 8 does not reduce the word spacing to less than zero. This is a bug.

word-spacing with em values

When word spacing is declared in em, the em value is multiplied with the font-size to give the number of pixels that is added to the width of the space character in the element.

Example 2: <p style="font-family:'Times New Roman';font-size: 35px;word-spacing: 1.5em">the <span>fox</span> <span>on</span></p>


In the above example, the declared em value (1.5em) is multiplied with the font-size to give 52.5px (1.5 * 35). This is added to the width of the space character to give 61.5px which rounds off to 62px. However, Firefox 3 and Firefox 3.5, due to a rounding off error, increase the word spacing to only 61px. Internet Explorer 8 increases the word spacing to 62px. Internet Explorer 6 and Internet Explorer 7 increases the word spacing to only 33px. This is a bug.

word-spacing:normal restores the word spacing to the default width of the space character. Since word-spacing is an inherited property, the normal keyword can be used to restore the default word spacing in an element that has inherited a modified word spacing declaration.

word-spacing:inherit

word-spacing:inherit is used to override another word-spacing declaration that has been applied to an element, and to restore the default behavior of inheriting the parent element's word spacing.

Internet Explorer 6 and Internet Explorer 7 do not support word-spacing:inherit, they ignore it.

Conclusion

For consistent results in all browsers, word-spacing with em values should be avoided (Internet Explorer 6 and Internet Explorer 7 calculate them incorrectly).

word-spacing:inherit should also be avoided because Internet Explorer 6 and Internet Explorer 7 do not support it.

word-spacing declarations that result in negative word spacing should be avoided because they are not supported by Internet Explorer 8. Also, in Firefox 3 and Firefox 3.5, if an element with negative word spacing contains child inline elements, the word spacing between them is not reduced to less than zero. This is a bug.

Using the word-spacing declaration on elements that contain the character entities &ensp;, &emsp;, &thinsp;, and &nbsp; is not recommended because of bugs in Internet Explorer 6, Internet Explorer 7, Firefox 3 and Firefox 3.5 (as mentioned earlier).

Apart from the exceptions mentioned above, word-spacing declarations in px that result in positive word spacing are supported in all browsers and is therefore the recommended way of using the property.

Tuesday, November 3, 2009

The text-indent Property

Made minor corrections: Nov 04, 2009

The text-indent property is used to indent the first line of a block-level element. Adding or removing space from the beginning of a line is called indentation.

The text-indent property can be applied to block-level elements only. It can accept length values, percentage values and the keyword inherit. Percentage values refer to the width of the parent block-level element. Em values refer the font size of the element to which the text-indent property is applied. Negative values are allowed, these result in space being removed from the beginning of a line. The text-indent property is inherited by child block-level elements.

Note 1: When the text-indent declaration has a percentage value, the declared percentage value is inherited by child block elements. However, in Internet Explorer 6 and 7 and in Opera 10, the computed value is inherited.

Note 2: When the text-indent declaration has an em value, in Firefox 3, Firefox 3.5, Opera 10, Safari 4 and Chrome 3 the computed value is inherited by child block elements. However, Internet Explorer 6, 7, and 8, the declared em value is inherited by child block elements.

text-indent with px values

Example 1: <p style="font-size:35px;font-family:'Times New Roman';text-indent: 20px">The @&Acirc; The quick brown fox jumps over the lazy dog. The five boxing wizards jump quickly</p>

In the above example, the first line is indented by 20px. Subsequent lines are not indented.

Example 2: <p style="font-size:35px;font-family:'Times New Roman';text-indent:-20px">the quick brown @&Acirc; fox jumps over the lazy dog. The five boxing wizards jump quickly</p>

In the above example, the first line of the <p> has a negative indent. This is called a hanging indent. A negative value to text-indent causes the beginning of the line to hang out of the line box. Note that since the text is outside the line box, it does not have the background image of the <p> behind it. Also, unless the <p> has margin + padding to the left of it that is at least equal to the amount of negative indentation, some part of the text will fall out of the viewport and will not be visible.

text-indent with percentage values

When the text-indent property has a percentage value, the amount of indentation is calculated by multiplying the percentage with the width of the parent block element. Every block-level element that can be displayed has the body element as the ancestor. Therefore, if no other parent element exists, then the percentage is calculated with respect to the width of the body element. The width of the body element can be its CSS declared width or, if it has no width declared, the width of the browser window. When the amount of indentation is dependent on the width of the browser window, the indentation changes each time the user changes the width of the browser window.

Example 3: <div style="width:450px"><p style="font-size:35px;font-family:'Times New Roman';text-indent: 4.5%">The @&Acirc; The quick brown fox jumps over the lazy dog. The five boxing wizards jump quickly</p></div>

In the above example, the width of the parent block-level element is 450px. Therefore the amount of indentation is 20px (4.5% of 450px = 20.25px, rounded to 20px). Therefore, the line should look exactly like the one in Example 1. In Firefox 3, Firefox 3.5 and Internet Explorer 8, the line is indented 20px and looks exactly like the line in Example 1. However, in Internet Explorer 6 and in Internet Explorer 7, the line is indented 34px. Therefore, Internet Explorer 6's and Internet Explorer 7's implementation of text-indent with percentage values is buggy.

text-indent with em values

When the text-indent property has an em value, the amount of indentation is calculated by multiplying the em value with the font size of the element that the text-indent property has been applied to.

Example 4: <p style="font-size:35px;font-family:'Times New Roman';text-indent:0.57em">The @&Acirc; The quick brown fox jumps over the lazy dog. The five boxing wizards jump quickly</p>

In the above example, the font size of the <p> is 35px and the text-indent declaration has a value of 0.57em. This is computed to 20px (0.57 * 35 = 19.95px, rounded to 20px). Therefore, the above line will look exactly the same as the line in Example 1.

text-indent:inherit

text-indent:inherit is used to override another text-indent declaration that has been applied to an element. If an ancestor element has a percentage text-indent declaration, then in Firefox 3, Firefox 3.5 and Internet Explorer 8 the descendant element inherits the percentage value. If an ancestor element has an emtext-indent declaration, then in Firefox 3 and Firefox 3.5, the computed value is inherited by the descendant element. However, in Internet Explorer 8, the em value in inherited. If an ancestor element has a pxtext-indent declaration, then the px value is inherited by the descendant element in Firefox 3, Firefox 3.5, Internet Explorer 7 and Internet Explorer 8.

Note: Internet Explorer 6 sometimes ignores the text-indent:inherit declaration

Conclusion

Percentage values with text-indent must be avoided because Internet Explorer 6 and Internet Explorer 7 calculate them incorrectly, also in these browsers descendant elements inherit computed values whereas Firefox 3, Firefox 3.5 and Internet Explorer 8 inherit the percentage values. This may result in inconsistent rendering across different browsers.

em values with text-indent must be avoided because in Internet Explorer 6, Internet Explorer 7 and Internet Explorer 8, descendant elements inherit the declared em value whereas Firefox 3 and Firefox 3.5 inherit the computed values. This may result in inconsistent rendering across different browsers.

Therefore, for consistent results across browsers, text-indent with px values should be used.

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.

Saturday, August 8, 2009

The Font Matching Process

Font Matching is the process that a browser employs to find the font to be used to render an (X)HTML element. Usually, the process is straightforward, but becomes complicated when the font-family does not have a font for bold or italic or small caps (or for any combination of these), or if it does not contain the glyphs necessary to render the text.

Web browsers maintain a database of all the fonts that are available to a web page — operating system fonts, @font-face fonts and the browser's internal fonts (if any).

The Font Matching Process

  1. All the properties of the font that is required to display the element are determined.
  2. The value of the font-family property of the text will be the name of the first font family with which a match will be attempted.
  3. font-style is handled in this step:
    1. If the element's text does not have the property oblique or italic, the currently selected font is retained and the browser goes to step 4.
    2. If the element's text has the property oblique or italic, and the the font family contains an oblique or italic font, the font is chosen and then the browser goes to step 4.
    3. If the element's text has the property oblique or italic, and the font family does not contain an oblique or italic font, the normal font is slanted to simulate oblique/italic text and then the browser goes to step 4.
  4. font-variant is handled in this step:
    1. If the element's text does not have the property small-caps, the currently selected font is retained and the browser goes to step 5.
    2. If the element's text has the property small-caps, then the browser looks for a small caps version of the currently selected font. For example, if the currently selected font is Arial Italic, the browser looks for Arial Italic Small Caps. This leaves two possibilities:
      1. The font family does not contain a small caps version of the currently selected font — the browser then simulates small caps by down scaling capital letters of the currently selected font. The browser then goes to step 5.
      2. The font family contains a small caps version of the currently selected font — the browser then selects the small caps version of the currently selected font. The browser then goes to step 5.
  5. In this step, font-weight is checked:
    1. If the element's text has the font weight property set to normal, the currently selected font is retained and the browser goes to step 6.
    2. If the element's text has the font weight property set to anything other than normal, the browser looks for a matching weight in the font family. For example, if font-weight: 100; or if font-weight: bold;, the browser looks for a font in the font family of weight 100 or 700, respectively. Therefore, there are two possibilities:
      1. The element's text has the font weight set to lighter than normal ( 100,200, or 300) or 500:
        1. If the font family contains a version of the currently selected font of the required weight, the font is selected and the browser goes to step 6.
        2. If the font family does not contain a version of the currently selected font of the required weight, the browser chooses the normal version of the currently selected font and goes to step 6.
      2. The element's text has the font weight set to bold or 600, 700, 800 or 900:
        1. If the font family contains a version of the currently selected font of the required weight, the font is selected and the browser goes to step 6.
        2. If the font family does not contain a version of the currently selected font of the required weight, and if the font-family contains a bold version of the currently selected font, the browser chooses the bold version of the currently selected font and goes to step 6.
        3. If the font family does not contain a version of the currently selected font of the required weight, and if the font-family does not contains a bold version of the currently selected font, the browser simulates boldface by increasing the stroke width of the currently selected font and goes to step 6.
  6. In this step, the selected font is scaled to the required font size.
Note 1: If the element contains a glyph that is not found in the first font family, the browser chooses the next specified font family (if any) or the browser's default fallback font. The browser then goes through the entire font matching process for that glyph only. However, Internet Explorer 6 does not follow this process, it displays an empty "box" character when a glyph is not available.

For example, if Comic Sans MS does not contain a particular mathematical symbol, then, to display that symbol only, the browser will use the next specified font in the CSS declaration that does contain the symbol (say Times New Roman). Therefore, Comic Sans MS will be used for all the element's text except for the mathematical symbol, which will use Times New Roman.

Wednesday, August 5, 2009

The @font-face at-rule

The @font-face rule can be used for a number of things:

  1. Fonts that are not commonly provided by operating systems can be used on a webpage. The font files are downloaded by the browser when the page is loaded.
  2. Can be used to give simpler names to operating system fonts
  3. Operating system font-family names can be re-assigned to downloadable font files.
  4. Multiple font locations can be specified. Therefore, if a particular font is not provided by the viewer's operating system, only then will the browser download the font from the server.
  5. Complete font-families containing a boldface font, an oblique/italic font, and multiple weights can be created using @font-face.
  6. Special downoladable fonts such as light or oblique/italic can be specified for operating system font-families.
General Syntax

The general syntax of an @font-face rule is:
@font-face { descriptor: value }
Here is an example of an @font-face rule:
font-face {
font-family: Example;
src: url(http://www.example.com/example.ttf)
}

In the example, font-family and src are descriptors and Example and url(http:/www.example.com/example.ttf) are values. The descriptor, the colon and the value together are called font-descriptors.

The font-family Descriptor

Every @font-face rule must have the font-family descriptor. The font-family descriptor's value specifies the name of the font family for which the subsequent font descriptions apply. The value of font-family can also be the name of an operating system font family, in which case the font description will override the default properties of the font family.

Here is an example of the font-family descriptor:

font-family: "Example Modern";

The src Descriptor

The src descriptor indicates the location of the font file associated with the font family name and, optionally, a format hint of the font file. The location of the file can be indicated by a URL or, if the font is provided by the operating system, by the font family name. ; An @font-face rule can have only one src font-descriptor.

In an @font-face rule, the value of the src font descriptor can be a comma separated list of sources. If the font file cannot be found at the first location, the browser will try the second location.

Here is an example of the src font descriptor with only one location specified:
@font-face {
font-family: "Example Modern";
src: url(http://www.example.com/example.ttf) format("truetype")
}

The src descriptor can also point to a "local" font. A local font is the name of a font that is provided by the operating system.

Here is another example with two locations specified:
@font-face {
font-family: "Example 1";
src: local("Example 1"), url(http://www.example.com/example_1.otf)
}


Format Hints

The format hint consists of the word format followed by the font file format name in quotes, inside parentheses. The whole expression appears at the end of a url location in the src font-descriptor.
The format hint will tell the browser what format the font file specified in url is. Based on that information, the browser can avoid downloading unsupported font files.

Here is a table of currently defined format hints:

Format Hint Font Format File extensions
"truetype" TrueType .ttf
"opentype" OpenType .ttf, .otf
"truetype-aat" TrueType with Apple Advanced Typography extensions .ttf
"embedded-opentype" Embedded OpenType .eot
"svg" SVG Font .svg, .svgz

The format hints "truetype" and "opentype" are considered equivalent to each other.


Embedded OpenType (eot)

Internet Explorer 6, 7 and 8 only support embedding of fonts in Microsoft's Embedded OpenType (eot) format. Eot files are not supported by other browsers. Eot files can be created from font files that have the ttf extension. Therefore, eot files can be created only from TrueType font files and OpenType TT font files, not OpenType PS (.otf) files. The open source application fontforge can be used to convert otf fonts to ttf in order to convert them to eot.

Eot files are compressed and also allow restricted access — a root url is specified when creating the eot file and the browser will only load the eot file from html pages that are below the specified root url. An eot file can either contain all the glyphs contained in a font file or only the glyphs that were selected at the time of creation of the eot file (subsetting).

Eot files can be created using Microsoft's Web Embedding Fonts Tool (WEFT) or the open-source ttf2eot. While ttf2eot is much easier to use than WEFT, it can only convert a ttf file to eot — it does not support subsetting and domain restriction.

Here is an example of the CSS code to embed an eot font file:
@font-face {
font-family: "A Yummy Apology";
src: url(http://www.example.com/yummy.eot);
}

font-style with @font-face

The font-style descriptor can be used to specify the oblique or italic fonts of a font-family. All major browsers consider oblique and italic as equivalent. Therefore, it is not currently possible to specify both an oblique and an italic font in a font-family.

Here is an example of how @font-face can be used to specify both a normal and oblique/italic font for a downloadable font-family:
@font-face {
font-family: "Example 1";
src: url(http://www.example.com/example_reg.ttf) format("truetype");
}
@font-face {
font-family: "Example 1";
src: url(http://www.example.com/example_italic.ttf) format("truetype);
font-style: italic;
}

font-weight with @font-face

The font-weight descriptor can be used to specify fonts for different font weights of a font-family.

Example 1:
@font-face {
font-family: "Example 2";
src: url(http://www.example.com/example2_reg.ttf) format("truetype");
}
@font-face {
font-family: "Example 2";
src: url(http://www.example.com/example2_bld.ttf) format ("truetype");
font-weight: bold;
}

Example 2:
@font-face {
font-family: "Example";
src: url(http://www.example.com/example_reg.ttf) format("truetype");
}
@font-face {
font-family: "Example";
src: url(http://www.example.com/example_lig.ttf) format("truetype");
font-weight: 100;
}
@font-face {
font-family: "Example";
src: url(http://www.example.com/example_med.ttf) format("truetype");
font-weight: 200;
}

font-stretch with @font-face

The font-stretch descriptor can be used to specify the fonts to be used for different font widths within a font-family. However, the font-stretch property is currently not supported by any major browser.

Example:
@font-face {
font-family: "Example";
src: url(http://www.example.com/example_reg.ttf) format("truetype");
}
@font-face {
font-family: "Example";
src: url(http://www.example.com/example_cond.ttf) format("truetype");
font-stretch: condensed;
}
@font-face {
font-family: "Example";
src: url(http://www.example.com/example_expa.ttf) format("truetype");
font-stretch: expanded;
}

Browser Support

Firefox 3 and Opera 9.6

Firefox 3 and Opera 9.6 do not support @font-face. They completely ignore it.

Firefox 3.5, Safari 3.2.3 and Safari 4

Firefox 3.5, Safari 3.2.3 and Safari 4 fully support @font-face. However, there are some small differences between them in terms of feature implementation.
Firefox 3.5 only allows relative links in url specifications. Therefore, by default, the font files cannot be in another domain. This restriction can be relaxed using HTTP Access Controls. No other major browser implements such a restriction.
Safari 3.2.3 does not support number font-weights.
If a normal font is specified in an @font-face rule containing font-weight: bold or a font-weight of 600, 700, 800 or 900, Safari 3.2.3 and Safari 4 simulate bold face when rendering the text that the font is applied to. Firefox 3.5 does not.
Similarly, Safari 3.2.3 and Safari 4 simulate slanted text when using a normal font specifed by an @font-face rule for slanted/oblique text. However, Firefox 3.5 does not.
Eot files are not supported by any of these browsers.

Chrome 2

Chrome 2 partially supports @font-face — it does not support downloading of font files but supports all the features of @font-face with operating system (local) fonts.
If a normal font is specified in an @font-face rule containing font-weight: bold or a font-weight of 600, 700, 800 or 900, Chrome 2 simulates bold face when rendering the text that the font is applied to. Similarly, Chrome 2 also simulates slanted text when using a normal font specifed by an @font-face rule for slanted/oblique text.
Eot files are not supported by Chrome 2.

Internet Explorer 6, Internet Explorer 7 and Internet Explorer 8

Internet Explorer 6, Internet Explorer 7 and Internet Explorer 8 have basic support of @font-face with eot files. They do not support ttf and otf files. They only support simple @font-face rules that download eot files. They ignore the following:

  • @font-face rules that have format hints
  • @font-face rules with more than one location
  • @font-face with font-style
  • @font-face with font-width
  • @font-face with font-stretch

Firefox 3.5, Safari 3.2.3, Safari 4, Chrome 2, Internet Explorer 6, Internet Explorer 7 and Internet Explorer 8 do not support font-stretch in @font-face rules.

Tips

Internet Explorer 6, Internet Explorer 7 and Internet Explorer 8 download ttf and otf fonts specified in @font-face rules even though they do not support them. To prevent this, always use format hints when specifing ttf and otf fonts in @font-face rules.


When using a downloadable font in a web page, to ensure that both users of Internet Explorer and other browsers get to see the text in the correct font, one should have both a ttf/otf file and an eot file.

The @font-face rule for the eot file should appear before the @font-face rule for the ttf/otf file. This ensures that the appropriate file is loaded in Internet Explorer and other browsers.

Example:
@font-face{
font-family: example;
src: url(yummy.eot)
}
@font-face{
font-family: example;
src: url(yummy.ttf) format("truetype");
}


Both Microsoft's Web Embedding Fonts Tool (WEFT) and the open-source ttf2eot can only convert ttf fonts to eot. Therefore, it is necessary to first convert otf fonts to ttf in order to convert them to eot. The open source application fontforge can be used for this purpose.


The official w3.org specification of @font-face can be found here.