A blog post from danboe.net

A standard MSN homepage, part III: consistently interpreted CSS

Posted Sep 9, 2004 at 12:00 AM

I ended the last post with a valid XHTML 1.0 Transitional document that points to a valid CSS file. Despite the validity, applying these styles to this document does not result in our intended visual experience. Even though the styles are now valid, they still reflect their origin: as rules which were authored and tested against quirks-mode rendering in IE 6. This post continues where we left off, identifying the problems in this stylesheet and solving the problems step-by-step. At the end, we’ll reach the desired visual experience without changing the markup. Instead, we’ll simply correct the stylesheet for standards-compliant rendering. Once we’re there, we’ll see that the exact same markup and style can be delivered to standards-compliant browsers with extremely predictable results.

Removing the quirks from our CSS

Correcting the fonts

The baseline CSS file defines a lot of font properties throughout the file. To clarify the discussion, I’ve copied all of the CSS rules related to font families, weights and sizes in the CSS here:

  1. body, div, span, p, ul, li, td, th, input, select, textarea, button
  2. {
  3. font-family: tahoma, sans-serif;
  4. }
  5.  
  6. .cm td, .cm td a, .nip a, .alr a, .hd, .nip .hilite
  7. {
  8. font-family: arial, sans-serif;
  9. }
  10.  
  11. td, th
  12. {
  13. font-size: 75%;
  14. }
  15.  
  16. .qlink, .txt, .txtad a, .promo a, .bt td a
  17. {
  18. font-size: 95%;
  19. }
  20.  
  21. h5
  22. {
  23. font-weight: bold;
  24. font-size: 0.9em;
  25. }
  26.  
  27. .terms .ct, .termsattr .ct
  28. {
  29. font-size: 80%;
  30. }
  31.  
  32. .second
  33. {
  34. font-size: 75%;
  35. }
  36.  
  37. .date a, .rf, .shop .il a
  38. {
  39. font-size: 75%;
  40. font-family: verdana, sans-serif;
  41. }
  42.  
  43. .srch, .bt td a, .txt .txtad, .promo a, .bbsw
  44. {
  45. font-family: tahoma, sans-serif;
  46. }
  47.  
  48. .help
  49. {
  50. font-size: 12px;
  51. }
  52.  
  53. .nip .dk
  54. {
  55. font-size: 90%;
  56. font-family: verdana, sans-serif;
  57. }
  58.  
  59. h4
  60. {
  61. font-size: 1.0em;
  62. }
  63.  
  64. .sm, .ql .md, .ql .md a
  65. {
  66. font-size: 75%;
  67. font-family: verdana, sans-serif;
  68. }
  69.  
  70. .sm
  71. {
  72. font-size: 0px;
  73. }
  74.  
  75. .sfl
  76. {
  77. font-size: 1px;
  78. }
  79.  
  80. .nip .adp
  81. {
  82. font-weight: bold;
  83. }
  84.  
  85. .bd
  86. {
  87. font-weight: 600;
  88. }
  89.  
  90. .srchcm th
  91. {
  92. font-weight: normal;
  93. font-size: 60%;
  94. }
  95.  
  96. .dot
  97. {
  98. font-size: 80%;
  99. }
  100.  
  101. .mon .lt
  102. {
  103. font-size: 85%;
  104. font-family: verdana, sans-serif;
  105. }
  106.  
  107. .mon .lt a
  108. {
  109. font-family: verdana, sans-serif;
  110. }
  111.  
  112. .mon .lt .hd
  113. {
  114. font-weight: 600;
  115. font-family: verdana, sans-serif;
  116. }
  117.  
  118. .qlink .adp
  119. {
  120. font-weight: bold;
  121. }
  122.  
  123. .promo .adp
  124. {
  125. font-weight: bold;
  126. }
  127.  
  128. .shop .il
  129. {
  130. font-weight: bold;
  131. }
  132.  
  133. .terms .ct, .termsattr .ct
  134. {
  135. font-size: 90%;
  136. }
  137.  
  138. .blowout .hd
  139. {
  140. font-size: 125%;
  141. }
  142.  
  143. .blowout .mn .hd
  144. {
  145. font-size: 175%;
  146. }
  147.  
  148. .blowout .mn .ct
  149. {
  150. font-size: 125%;
  151. }
  152.  
  153. .mhr a
  154. {
  155. font-weight: bold;
  156. font-size: 0.9em;
  157. }
  158. Download this code: /code/msn/part3_01.css

It’s pretty hard to work with in this manner, so to simplify things, the first thing I did was remove all of these from the CSS. It’s really better to start from nothing, and build from there.

I’ll start by defining the font-family properties, then move to font-size. I’ll keep font-weight as it exists in the baseline CSS.

A font-family reunion

When all is said and done, there are really just three font families that are used on the MSN.com home page, so I decided to be simple and define the styles in one place for all font-family properties. The new CSS now contains the following styles for font families:

  1. body
  2. {
  3. font-family: tahoma, sans-serif;
  4. }
  5.  
  6. .cm td, .cm td a, .nip a, .alr a, .hd, .nip .hilite
  7. {
  8. font-family: arial, sans-serif;
  9. }
  10.  
  11. .date a, .rf, .shop .il a, .nip .dk, .sm, .ql .md, .ql .md a, .mon .lt, .mon .lt a, .mon lt .hd
  12. {
  13. font-family: verdana, sans-serif;
  14. }
  15. Download this code: /code/msn/part3_02.css

This is obviously much easier to author, read and understand. It’s lighter, because we don’t have to repeat the property names and values for different rules. It’s also easier to manage, since we can just append rule selectors when we want to change the font for a region on the page.

Clear and flexible font sizes

The above approach for font-family worked so well that I decided to take the same approach with font-size too. So, the new CSS contains the following styles for font sizing:

  1. body
  2. {
  3. font-size: x-small; /* Windows IE 5 base size */
  4. voice-family: "\"}\"";
  5. voice-family: inherit;
  6. font-size: small; /* other browsers base size */
  7. }
  8.  
  9. html>body {
  10. font-size: small; /* Opera base size */
  11. }
  12.  
  13. h1, h2, h3, h4, h5, h6
  14. {
  15. font-size: 100%;
  16. }
  17.  
  18. .help, .chan, .ct, .hd, .nip .adp, .ccol h4, .rcol h4
  19. {
  20. font-size: 90%;
  21. }
  22.  
  23. .chan .hd, .chan .ct, .chan .adp, .help .ct, .mon .lt .ct a, .mon .lt .hd
  24. {
  25. font-size: 95%;
  26. }
  27.  
  28. .txtad, .txt, .bgl, .bgs, .bgr, .terms .ct, .termsattr .ct, .mhr
  29. {
  30. font-size: 85%;
  31. }
  32.  
  33. .date, .ql, .rf, .rcol .il
  34. {
  35. font-size: 75%;
  36. }
  37. Download this code: /code/msn/part3_03.css

Again, much easier to author, read, understand and manage. The cases are well defined, and all of them fit on the screen, which helps a lot during development. Oh, and the page now gets resizable fonts across browsers, too!

Note: this approach uses a combination of techniques to achieve the desired end result of resizable fonts while attempting to avoid cross-browser incompatibilities, the danger of pixels, or the risk of compounding ems or percentages in nested situations.

We start with a keyword-defined font-size that by definition does not compound. Because different browsers resolve the keyword to different actual sizes, we correct for that very specifically, as follows:

  • We use the @import directive in linking to the CSS to hide the styles from legacy browsers.
  • We use the box-model hack to set the font-size value to x-small for IE 5 on Windows, and to small for all other browsers.
  • We add a rule with greater specificity html>body to ensure that it gets a font-size of small as well. This is necessary since Opera has the same issue that IE 5 on Windows has, but does not recognize the box-model hack.

Once we have the base size defined appropriately, we use percentages against this base in all other places. That’s it.

The silver bullet of unordered lists

As an aggregator of links to various sites and content on the Microsoft Network and the Internet, it should be no surpise that the

MSN.com markup contains a lot of lists. The baseline CSS file styled these lists by using the following:

  1. ul
  2. {
  3. list-style-image: url(http://hp.msn.com/c/home/bullet.gif);
  4. list-style-position: outside;
  5. margin: 0px 0px 5px 10px;
  6. }
  7.  
  8. ol
  9. {
  10. list-style-position: outside;
  11. margin: -2px 0px 0px 23px;
  12. }
  13.  
  14. li
  15. {
  16. margin: 0px 0px 1px 1px;
  17. }
  18.  
  19. li a
  20. {
  21. margin: 0px 0px 0px -1px;
  22. }
  23.  
  24. .blowout li
  25. {
  26. list-style-image: url(http://hp.msn.com/c/home/bullets/ffffff.gif);
  27. }
  28. Download this code: /code/msn/part3_04.css

The problem with this approach for styling of lists is that the positioning of bullets and list-style-image images and the default margins and paddings associated with the ul, ol and li tags vary greatly between browsers. Additionally, if you were to examine the images that are used for bullets, you would notice that the position of the bullet within the image itself is also padded in a wierd way. Luckily, there’s a much better approach.

Here are the styles for lists as I’ve implemented them:

  1. ul
  2. {
  3. list-style-type: none;
  4. margin: 0;
  5. padding: 0;
  6. }
  7.  
  8. ol
  9. {
  10. margin: 0;
  11. }
  12.  
  13. ul li
  14. {
  15. background: url(000.gif) 3px 0.6em no-repeat;
  16. padding: 0 0 0 10px;
  17. }
  18.  
  19. .blowout li
  20. {
  21. background: url(fff.gif) 3px 0.6em no-repeat;
  22. }
  23. Download this code: /code/msn/part3_05.css

This works predictably across browsers, and uses simple, smaller images that do not have to include padding.

Small corrections

Now that the fonts and lists are rendering predictably, what’s left are smaller changes that need to be made.

Replacing the Fancy-Looking Search Box with a Predictable One

The Fancy Search Box on MSN.com

The baseline CSS file defines style to display a background image perfectly adjacent to the MSN Search textbox, a cosmetic treatment that creates an illusion of a fancy search box in ideal conditions. Unfortunately, the desired effect falls apart when the page is rendered outside of the latest version of IE, or by a user that has adjusted their default font size, because these cases modify the height of the text field, spoiling the illusion. While MSN.com today only does this for current versions of IE, we will remove it entirely, since we are attempting to walk entirely away from conditional, browser-specific CSS.

A Simpler Search Box

By removing these styles, we’re left with a fully functioning, though less striking search box. However, it’s clearly a text field for the entry of text, and by removing the decoration, it’s hard to mistake it for something else. We get here by removing the following styles from the new CSS file:

  1. .sfp
  2. {
  3. background-image: url(http://hp.msn.com/c/home/snb.gif);
  4. background-position: center;
  5. background-repeat: no-repeat;
  6. }
  7.  
  8. .srchd_inp
  9. {
  10. height: 22px;
  11. border-left: none;
  12. }
  13. Download this code: /code/msn/part3_06.css

The Curved Tab

Note: I should point out that the inflexibility of the fancy search box decoration also exists in the curved tab (or “fin”) background image appearing in the header. Fixing this issue for our standards-mode rendering is much more invasive of a change, due to the layout HTML employed in the MSN.com header. The background image for this curved tab is actually applied against a spacer image that resides in a cell that spans two rows. I’ll revisit this when we move to XHTML 1.0 Strict, but I will not attempt to make the changes to get the same appearance in our new Transitional document styled with standard CSS. Why not? Because it’s throw-away code, since the image and its implementation is designed from a fixed font size frame of mind that is inconsistent with the direction we’re taking. While it’s there, just consider it as a reminder of the old way of thinking.

Correcting small alignment bugs

Now we’re really getting close. The right column alignment needs to be corrected (the column should be left-aligned with centered ads), and the background image for the curve in the header does too. Therefore, I add the following to the new CSS:

  1. .sfc {
  2. background-position: top;
  3. }
  4.  
  5. .rcolb {
  6. text-align: left;
  7. }
  8.  
  9. .rcolb .adp {
  10. text-align: center;
  11. }
  12.  
  13. .mhr {
  14. text-align: center;
  15. }
  16. Download this code: /code/msn/part3_07.css

Final result: standards-compliant rendering!

The result of this journey is the final XHTML document that points to the final CSS file by using the @import directive in the directly linked CSS file. As you can see, it’s very close to the visual experience you get at the live MSN.com site, regardless of what standards-compliant browser you view the document with.

The road to Transitional: a recap

I thought it would be helpful to those of you who may be interested in actually getting the source of the files as they’ve evolved to present them together here.

Baseline MSN.com 8/27

HTML document and CSS file.

Part I: Valid XHTML 1.0 Transitional

HTML document and CSS file.

Part II: Valid CSS

HTML document and CSS file.

Part III: Standards-Compliant CSS

HTML document and CSS file linked via the import CSS file.

Next steps

In part IV, it’s time for us to leave our Transitional markup behind, throw our current CSS away, and move to Strict. You’ll be amazed at the results, I promise!


This post is closed to new comments.

About this page

This page contains a single post from Daniel Boerner's blog, of which Boot Camp + Windows Vista = no more Airport Extreme reboots is the latest post.

Are there more posts like this one?

Possibly. Within this blog, this post is categorized under work and webdev and it was posted on September 9, 2004. Those would be good places to start looking for related posts.

Next post (newer)

Previous post (older)