Avoiding Hacks

From CSS Discuss

Jump to: navigation, search

Although valid Css Hacks are invaluable, I'm pretty sure everyone agrees that it's better to avoid them if you can (for future compatibility of new implementations). I wanted to share some techniques that help me avoid overuse of hacks.


Margin instead of padding

Use margin on child elements instead of padding on parent elements.

The differences in the box model (see BoxModelHack) are well-documented, and mostly revolve around padding and border-width, right? (Win IE pushes those inward, while spec-compliant browsers push them outward.) While you could use hacks to define and redefine those values, why not just use another method to get the same effect without a hack? Specify the width of your containing element with no padding, then add margins to the known child elements of this container. div.main {

 width: 70%;
 padding: 0;

.main p, .main h1, .main h2, .main h3 {

 margin: 0.5em 1em 1.5em 1em;

Comment: Would .main * work too? It would be easier to maintain and extend using the UniversalSelector. Response: Using this would also add margins to sub-elements of .main * like .main p strong which may not be what you want. If IE correctly recognized .main>* then it would be the preferred solution.

Comment 2: Note that using the above code to define the child margins, a header will have a bigger margin than, say, a paragraph. This is because a header (h2, h3, etc) has a bigger default font-size than a paragraph (p), and the unit used (em) to define the margins is relative to font-size. To work around this, use either a percentage or pixel value.

Let font-size inherit from the root element

Scalable font sizes are the other bane to Win IE5's CSS implementation. I haven't figured out a way to get around the hack completely, but you can implement one hack for the body element and let that inherit all the way down. For example: let's implement our hacks to set the body at a keyword size (WinIE5 is one step larger than the other browsers, so we'll set it small there, and medium on everything else). body {

 font-size: small;
 voice-family: "\"}\"",inherit;
 font-size: medium;

html>body { font-size: medium; }

Note: If you are confused by the "voice-family" selector, go back and read about the Box Model Hack (see BoxModelHack). Specifically, the section on The Tantek Hack.

Feel free to correct if I've left something out, but the idea remains the same. Now all elements will inherit the same size (almost) and the text will remain scalable. Any child element of that root can now modify its default size with a unit like UsingEms or percentages (%) without having to hack it back and forth again for each browser. p { font-size: 0.8em; } td, th { font-size: 0.7em; } h1 { font-size: 200%; } h2 { font-size: 170%; } h3 { font-size: 140%; } h4 { font-size: 120%; } Be careful though, when setting the size of elements within elements. A size of small inside small is still small, but 50% inside 50% is 25%. In the above example, if you had a p(0.8em) within a td(0.7em), the font-size would end up being 0.56em (probably not what you intended). This example assumes you would always be using td for tabular data, not layout, however, if you did need a paragraph inside a table cell, you could reset it via the cascade. td p { font-size: 1em; }

Suggestions from Apple

I found the Best Practices page at Apple's Developer web site to have some helpful hints. There's some Internet Explorer bashing, but only where deserved.

Other Ideas?

Does anyone else employ similar techniques to avoid hacks?

I use Owen Briggs' Sane CSS Sizes method for uniformly sizing fonts across browsers. It also works by inheriting font size from the root element, but sets it as a percentage (76%) based on extensive cross-browser testing (264+ screenshots available for reference).

Personal tools