Google Ads

Questions for the Author?

Navigation

 ·   Wiki Home
 ·   Wiki Help
 ·   Categories
 ·   Title List
 ·   Uncategorized Pages
 ·   Random Page
 ·   File Upload
 ·   Uploaded Files
 ·   Recent Changes
 ·   RSS
 ·   Atom
 ·   What Links Here

Active Members:

Search:

 

Create or Find Page:

 

View CSS Notes

I'm writing some notes on CSS so I can get a better conceptual grasp of it. Consider these raw notes for me to unstupidify myself with regards to HTML/CSS.

So far, Leslie Franke's CSS Cheat Sheet is nice and compact. What I need, though, is something that's a little more best practice / philosophical. I'll use his cheat sheet as a jumping-off point.

For principles of avoiding CSS headaches, these compendium of techniques reinforces a lot of what I'm discovering in my notes and have wondered about.

Finding a Philosophical Approach to CSS-based Web Design

Hell if I know what the best way is. The CSS Box Model makes it more difficult to tweak the spacing and dimensions of nested box designs on the fly without forethought. Since CSS does not support constants either, which would have been incredibly useful, it means that creating a CSS-based layout is incredibly finicky compared to how a graphics programmer might have approached a flexible definition language. There must be some advantage

Some rules of thumb that I'm aware of:

  • Avoid the use of extraneous block-level elements, and use DIVs sparingly.

  • Create a clear cascade of elements, which helps specificity of applying styles broadly and individually.

  • Separate content from presentation. Presentational elements can be handled through CSS styling. Content elements are inline. Master the use of selectors.

  • Use HTML in a semantic manner. That means content-oriented, not presentation oriented, which allows the chunks of text and imagery to be properly scoped within the conventions of paragraphs, headers, sidebars, and so on. Also applies to using names for styles and classes.

  • While searching for "justifying the CSS Box Model", found this neat link off Dave Shea's site: CSS Cribsheet, which is a concise best practice checklist. Sweet.

  • Neat RESET code from Eric Meyer

  • A bunch of css frameworks to oggle!

It occurs to me that one thing that I've overlooked is that HTML, despite me thinking it's a kind of static layout language, is still highly order-dependent when it comes to writing markup. The concept of "in the document flow" and "out of the document flow" figures in heavily; since HTML is designed to flow endlessly in a document of undetermined width, each HTML element is designed to stand alone, not together. So the reason the element dimensions do not contain margin and padding within width is because the content is considered atomic; spacing is really considered as an optional attribute. It still seems a bit dumb to me because it makes flowing content predictably an act in constant arithmetic. This leads to making mistakes in addition, which leads to lots of tedious arithmetic bugs in coding, which I think is something preferably contained and should not be propagated.

Anyway, a visual designer is interested in combining elements so they seem to fit together, but this is not the prime concern of HTML. CSS is what was developed to tweak the flow into something, so the art of CSS design is less defining bins and boxes with self-contained elements than it is about artfully squirting content into boxes and hoping it all fits together neatly. However, there are real-world problems with browsers not quite working the same way, so this creates a world of pain if you want your page to look right. It's sort of like playing COMPETITION TETRIS, with each weirdly-shaped HTML element coming down the stream, and you hoping that you placed your previous blocks in a way that doesn't SCREW ya.

Which is why I have avoided HTML and CSS for so long and stuck with Flash. I tend to do screen-based stuff anyway. But it's inevitable that I need to define one bulletproof subset of HTML/CSS for just getting my stuff out there and looking relatively decent.

Rethinking the Flow

So one of the major clashes with my design sense and CSS is that I think in terms of screens, boxes, overlaid infographics, animation, event chains, and rasterops on framebuffers. This is an old-school computer graphic mindset. Now that I think about it, my video game screen architecture is a little underdeveloped in terms of content management.

  • The W3C Visual Formatting Model is the source of all. It suffers from introducing the concepts in an isolated piece-meal fashion. This is part of the overall CSS2 specification, which I guess I should read.

  • Essentially there are two kinds of boxes. The block boxes are full-width and stack on top of each other. The inline boxes stack left-to-right, unless you mess with that ordering and width with CSS properties.

  • Boxes can contain other boxes, providing context.

  • There are also boxes that are created on-the-fly by other tags. They inherit their properties from parent containing boxes.

Uncontrolled width is what screws up flow. Since width (and height) are sometimes not known until the element is fully rendered, this creates additional problems. So pre-calculating widths properly is important in defining tightly-controlled layouts. Also, the understanding of flow and out-of-flow elements is critical to create minimal CSS. There are also automatic calculations (e.g. 'auto') that help.

Width seems to be more constrained than height. The HTML doc is assumed to flow endlessly without length but with bounded width. This is important to know for attributes like overflow.

Essential Flow and Block Controlling Attributes

So what kind of properties do I care about in the layout?

  • Changing the type of box using display as block or inline or none to hide it. Here's a good article explaining the difference

  • Setting dimensions using width and height, keeping in mind that margin, border, and padding add to it.

    Boxes expand unless width is applied. If you use height then overflow becomes a consideration.

  • Floats applied to an element will tell content after it to flow around it. You can float: left or right. So order is important. And floats will pile up, as much as they can, relative to the containing box. Use clear: left, or right or all so the element will ignore it. Here's a pretty comprehensive article.

    The float properties can interact in weird ways. Need to know containing box, active floats before and after, and ensure width is set to predict it. Then there are the damn browser bugs...fortunately these seem to be diminishing with current browsers in use.

  • Positioning via the position: static, relative, absolute, which sets the type of positioning relative to document flow. Static is the normal behavior. Relative allows you to use left, top, bottom, right attributes to nudge it. However, this is more of an offset of the drawing code for that element; other elements are not shifted based on the position! Absolute is exactly where you want ON THE PAGE.

    To use relative positioning inside a containing box, set position: relative on the containing box and then position: absolute on the inner box.

  • Automatic values can be applied to margin-left:auto and margin-right:auto, which tells the browser to automatically calculate. Works only with width. Expressed usually as margin: 0 auto

Then there are those relative values

Can specify pixels as px, percentages as %, and ems as em suffixes. Percentages need to have a parent containing size to work. Ems are relative to the font-size property or its parent depending on use. So ems are useful for text-related matters, and pixels probably for more layout-related styling. % might be OK too for that too. Hmm.

Cross-browser consistency

One annoying thing about HTML and CSS is that the browsers themselves don't render entirely the same. Since HTML was invented primarily as a document description language, niceties such as consistent pixel rendering aren't important. And the original idea was that people could format their text in a way that was most convenient for their own viewing. CSS is the means by which to hack-on presentational control, but it's a fight between user advocates and designer control.

So the reality is that all the browsers start out with different default spacings, which Meyer's RESET code handles. There are other reset css in use, such as Yahoo's Font Reset, which is part of Yahoo's YUI Library.

Therefore, it's desirable to use this reset code to establish a nice baseline. I have my own preferred text styling, for example, so I can customize this code to conform to my expectations. An inspection of which elements are reset is instructive in knowing what the problem elements in the layout will be, and starting from a base will mean less finicking around later.

Note to self: that IE6 double-margin bug that apparently affects floated elements goes away when display: inline is added. Hmm!

There's a few websites where this annoying stuff is all cataloged:

Handling inline list heights

When you inline list elements, you'd think you could adjust their padding at the top and bottom so the background effect you're applying will be the right height. Nope! Certain properties are disabled for inline elements. A solution suggested is to retain the block-level but just float them left. See this article also.

Or set the line-height property and use background graphics for the highlighting...I'll have to try that next. Page 13 of Cederholm's "Web Standards Solutions"...

I'm becoming aware of some Internet Explorer 7 weirdnesses, like this idea of hasLayout, which is an rendering-specific flag that IE seems to set to trigger different behaviors, which is the indirect source of many IE7 rendering bugs. Pretty annoying.

I also am learning that I shouldn't work on CSS on my laptop, because I will go blind.

Grid Systems

Grid systems appeal to me. There are two aesthetic elements that come to mind when working with grids:

  • Given a page width, one needs to divide it into equal chunks so you can lay things out nicely and evenly. With print it's easy to do, but on a bitmapped display you need to think in pixels. Nathan Smith's 960gs system is a nice introduction to this idea. In that article is a nice link to Setting Type on the Web, which goes through the fun pixel-based calculations to get a nice vertical grid.

  • Once you have a grid system, one decides how much to let the columns breathe. This is kind of a whitespace-to-content-ratio decision. I tend to like compact groupings and whitespace that clarifies the boundaries between groups, but I don't have a layout principle. Maybe it's time to develop one.

The Glory of CSS Reset

As I've been farting around more with HTML/CSS, I'm coming to see how DOCTYPE + RESET are two of the main things that you should do right away. There's a really nice comparison of CSS reset approaches on Perishable Press, which itself has some beautiful web typography.

I've also read some arguments about whether CSS Reset code is good or bad practice. I like how the CSS Reset "fixes" browser inconsistencies in spacing, making it mandatory to rebuild them. Some argue that breaking down and then rebuilding spacing rules is wasteful of processing time and efficient coding. Some argue that it's lazy. Personally, I think it saves me time in an environment that is already notoriously awash in interpreted, weirdly-specified standards that shares little common sense with regards to the historical development of computer graphics systems. Complaining about resetting CSS is kind of like complaining about having a cup of water poured on you in a thunderstorm. But that's just what I think.

Expanding Those DIVs to contain their children

For a while I have been belaboring under the assumption that the overflow property had something to do with the way block elements expanded. NOPE! This article on Devito Design explains overflow and how to expand DIVs. The basics: overflow controls when scrollbars appears. That's it. It doesn't have anything to do with whether a DIV gets bigger. You can see how this works in this post that shows examples of overflow.

What I really want to do is have my DIVs expand to contain whatever content is in it. Seems like a reasonable request, right? The author on Devito Design says he spent hours researching this tip, and he is a good guy in my book for providing this solution (if it works...I'm about to try it):

div 
    height: auto;
    overflow: visible;

This worked in one situation, but not another.

It's that weird issue where the containing DIV doesn't seem to want to contain any floating elements...annoying! It's explained, with a nice "history of the solution" approach, on Quirksmode in this article describing the collapsing float workaround for Internet Explorer. And there's a good alternate description at CSS Tricks All About Floats, which quick solutions that work around IE. It all sounds maddening to me. So I fixed my problem by applying the time-tested `<div style="clear:both" > which fixes the height calculation...I guess the browser rendered suspends or is unable to calculate heights while everything is floating.

As for WHY OH WHY it works like this? Well, maybe it has to: a reasoned look at it

Pesky List Indentations

After you do a big margin:0 padding:0 reset on the UL, OL, and LI, you've got to build 'em back up. For just the regular bulleted lists, Eric Meyer notes that different browsers pad differently. The default behavior, with the bullets outside the left margin, is actually the traditionally correct way to do it. However, I prefer the indented margins myself...sorry. Anyway, here's the code I use (assume margins and padding are set to zero):

    UL 
        margin-left: 2em; margin-bottom: 1em;

Equal Height Columns

I'd forgotten how to fix the "columns are equal height" dilemma. There are two sources of info that I find promising: Dan Cederholm's Faux Columns approach and this pure CSS approach by Matthew James Taylor. What's nice about both these writeups is that they identify the working principle pretty clearly.

Cederholm's approach is probably the easiest with my fixed-width layouts. Taylor's approach requires extra DIVs to contain the background. The basic premise is that a floated parent DIV will stretch to the height of its largest child. You can set the background color of the parent, then. To make columns, you wrap the parent with MORE floated parents (each which will be the same height), then nudge all the divs into place so they lay on top of each other using relative positioning. A little tricky to grasp, but once you work out the math it makes sense. Each containing parent DIV also needs to be 100% width, otherwise the stacking doesn't seem to happen correctly.

Float Magic

Many of these positioning tricks appear to be based on activating the float or position properties of DIVs. Then, attributes such as width and height come into play. There is probably some kind of logic behind this. In some cases, the float property makes containers behave more the way we'd expect them to work:

  • A floated div contains in entirety everything that is inside of it. If it's not floated, the DIV does not contain everything and things are allowed to stick out of it. This article has a concise rundown of techniques.

  • On a similar note, a non-floated div that contains nothing but other divs is considered to have no content. That is why you stick a "br style=clear:both" just before the closing tag; this forces the div to have content, and then it has to stretch to contain the very bottom of any contained divs.

  • The "position:relative" property fixes some bugs with IE6-7 related to the overflow property. Snook has a quick note on this Good to know.

  • Using the position property on a div also disables the margin/padding collapsing "feature", if you're wondering where your extra padding and spacing has disappeared to, or if you're seeing mysterious gaps between DIVs. Andy Buddy explains this clearly (no pun intended).

  • The trick of using an outer div with "position:relative" in conjunction with an inner div with "position:absolute" opens up all kinds of easy static layouts.

  • Width and height calculations with the box model are pretty damn essential. It's an annoying model, to be sure, but it's what you have to deal with.

Self-Closing Tags and DIVs

I was trying to figure out why I couldn't do something like <div /> as opposed to <div></div> It turns out it's illegal in html 4.01 and xhtml 1.0. The discussion rages on Stackoverflow in this message thread; quickly, sticking to the following works (see the thread for a more complete list)

  • <br>
  • <img>
  • <hr>

A suggested rule of thumb is that if a tag is expected to have content as a tag pair, don't try self-closing it. <script>, for example, is reportedly problematic on some browsers if self-closed (see the Stackoverflow thread).

There's also some thought that it's because xhtml files are often served with the wrong MIME type. The MIME type is not the same as the DocType, and it's set by the web server, not your HTML document. That's a whole 'nother discussion!

CSS Shortcuts

I can never remember the order for them, so here's a quick cheatsheet for myself:

font: (weight) (font-size)/(line-height) (font-family);

background: (color) (background-image) (repeat-type) (position);

margin: (top) (right) (bottom) (left);
margin: (top and bottom) (left and right);

padding: (top) (right) (bottom) (left);
padding: (top and bottom) (left and right);

border: (thickness) (border-type) (color);

Centering Tricks

It's tough to vertically-center block-level elements to the current page unless you know the width and height of what you're going to center, then apply negative margins. In these modern times, we can do stuff like this or this. It's all overly complicated, and makes me just want to use TABLES to do it.

On a somewhat related note, when you have a block-level element with a fixed height and want to align an image to its background, you can do something like this (taken from Cederholm's Web Standards Solutions book):

background: url(imagefile.gif) no-repeat 0 50%;

Not quite the same as the first case, where you are trying to center content within its enclosing context.

It's worth mentioning too that vertically-centering inline elements is different than block elements, because not all properties (like width and height) apply to them. There's a nice article that describes the difference between block, inline, and "replaced" elements. If you grok this, then you'll avoid surprises.

Sticking a Footer at the bottom of the browser window

Surprisingly hard! The approach to do "position:absolute;bottom:0" didn't work as expected. There is this article that seems to be the current state-of-the-art. Will have to review this later. There's also Ryan Fait's Sticky Footer

The Mystery of Position: Fixed

I understand the position:fixed property to mean "fixed relative to the browser window". However, it seems to also be relative to its nearest containing parent with fixed, absolute, or relative positioning. The W3C explanation is not that much clearer. I have some code that looks like this:

div#wrap [ width: 600px; margin: 0 auto; ]
  div#page [ position:relative; width: 600px; ]
      a img#logo [ position:fixed; top:0px; ]
      div#sidenav [ position:fixed; top:150px; margin-left:24px]

And the inner block elements are happily floating fixed vertically but auto-centering within its containing div. Which is AWESOME, but freaking me out. I am wondering if it will break elsewhere. We'll see.

Chrome Redraw Problems

On my design.davidseah.com page, I was having trouble with page redraws. If I double-clicked a link to a page that did not have layout that went all the way to the bottom of the browser window, the bottom would not be drawn. It would be white. The problem would go away if I resized the window; it seemed like a repaint problem on a page that has a lot of overdraw composited effects.

I played with optimizing the background graphics to avoid colorspace conversions, reduced the size of the background repeating image, made the size larger so there would be fewer boundary wraps on vertical repeating, tried putting magic [br clear:all] after pages, played with removing floats...all to no avail. The problem existed only in Chrome, not Firefox or Internet Explorer.

One thing I did know: the problem only cropped up when I put tracking for Mint and Google Analytics in the head. I tried changing from the old tracking code for GA to the new asynchronous one. I didn't change the Mint one. Finally, I tried moving this code to the BOTTOM, just before [/BODY]. It seems to be working now...knocking wood. My guess is that the scripts are not executing in a way that allows Chrome's hopped-up Javascript engine to wait for layout, so under certain circumstances script exits before the layout is completely finished, and this interrupts the repaint somehow. That's a guess. We'll see. By sticking the code at the bottom, I'm hoping that the rest of the document has drawn, and so the deferred execution of the script triggers a redraw AFTER all the calculations have been made.

Drawing Order and Z-Index

You can set the z-index property to change the "stacking order"; that is, which block-level elements appear above or below. Negative is "into the screen", positive is "toward the viewer", and 0 is the "default rendering layer". However, z-index does not have an effect unless the block is positioned. Here's a pretty cool interactive stacking tutorial that allows you to type in values. There's a particular flow...the following is from this Mozilla DevCenter article

  • Background and borders of the root element
  • Descendant blocks in the normal flow, in order of appearance (in HTML)
  • Floating blocks
  • Inline descendants in the normal flow
  • Descendant positioned elements, in order of appearance (in HTML)