CSS notes
From Helpful
| For more webdev-related articles, see the webdev category. Among the more interesting are general webdev notes, Javascript related notes, CSS notes, browser peculiarities, jQuery |
| These are primarily notes This is probably not going to be complete in any real sense, and exists to contain bits of useful information. |
Note that when most anyone or anything (including most browsers) mention CSS 2, they usually mean CSS 2.1 (CSS Level 2 Revision 1). This is not an insignificant detail, as 2.1's behaviour description includes corrections, and is current.
Contents
|
Interesting links
W3:
- Jigsaw CSS validator
- http://www.w3.org/TR/CSS21/
- Selectors (from the standard)
Other:
Impossibilities
Vertical layouting
It seems to be nearly impossible to do vertical layouting and nesting; 'relative to screen sizes' exists, but 'relative to containing element' only exists in absolute measurements.
This means accurately imitating the ability of framesetss to divide the screen is very hard, and nearly impossible to do neatly. It is not possible to scroll nested things when needed (overflow:auto style) that are not absolutely sized, while relative sizing will almost as a rule break layouting as percentage refers to page size, not container size. This can in some cases be worked around using - ironically - tables.
There is one exception: 100% height at all levels does work. (probably using percentages at all levels does(verify)). Depending on context, this may be doable enough or just impractical.
Things that can save a headache
CSS reset
| This article/section is a stub — probably a pile of half-sorted notes and assertions some of which may well be wrong, and not verified as a whole. Feel free to add or refine. |
Browsers have some mildly varying default margins, padding, etc. Particularly when going for pixel-tight control, it helps to settle all of these at zero by default so that they are only non-zero when you yourself set them. (Note: border-collapsing tables also help here)
It can also make sense to have a not-so-zero-looking CSS re-reset (particularly in some styles)
Additionally, it is useful to explicitly have default/fallback styles for a site, e.g
- specifying site-wide background color and font
- having border-collapsing tables by default
- getting consistent form input styling (borders, padding, aligning, etc)
Avoiding anonymous descendant selectors
| This article/section is a stub — probably a pile of half-sorted notes and assertions some of which may well be wrong, and not verified as a whole. Feel free to add or refine. |
For example:
.details div { padding: .5em }
is problematic in that if you nest divs, each of them inherits their own .5em, and it can be a pain to remove all of those, and that in turn can mean you're going to avoid structing (with divs in this structure).
(This is also one argument against div overkill, but a stronger ones against anonymous CSS selectors)
One possible reason is to have used the anonymous-div in the first place is that IE6 did not support the CSS standard's child selector at all (.details>div) - that would have used structure and the div wouldn't have been so anonymous.
One of the cleaner ways of handling this is to also give your major divs a class, so that you can do something like the following:
.details div.section { padding: .5em }
...and generally rely on nested divs inherit a default (quite possibly 0px from your CSS reset).
pseudo-namespaces on your classes
Class names like header are asking for trouble when merging things. Even when your site is too monolithic to be used modularly elsewhere, javascript plugins may create elements with such classes. One of the two will have to use names that are much less likely to collide, such as _appname_header.
Scrollbars
Firefox will only show a scrollbar on your page when necessary, which means that if the page changes its contents, the scrollbars may be added later, which means a relayout which makes the page jump. If you figure the scrollbars will likely be necessary later in the view of a page, you can force them with:
html { overflow:-moz-scrollbars-vertical; }
Tricks
Tables
| This article/section is a stub — probably a pile of half-sorted notes and assertions some of which may well be wrong, and not verified as a whole. Feel free to add or refine. |
CSS versions of the cellspacing="something" attribute
To remove cell spacing, i.e.:
cellspacing="0"
Use:
border-collapse: collapse
For non-zero values, you would likely use the separated borders model, for example replacing cellspacing="1" with:
border-collapse:separate; /* which is the default */ border-spacing:1px
See also
Column styling
Exploiting the properties of the CSS + operator, you can e.g. style the first column differently than the rest like:
td { background:red } /* applies to all */
td+td { background:blue } /* applies to second and later */
Given a constant/limited number of columns, you can effectively style each separately, for example a six-column table, like:
td { text-align:left; white-space:nowrap }
td+td { text-align:left; white-space:normal }
td+td+td { text-align:left; white-space:nowrap }
td+td+td+td { text-align:center; white-space:normal }
td+td+td+td+td { text-align:left; white-space:normal; background: #fafafa}
(this example controls wrapping and whitespace treatment in a statistics table)
See also
- Support:
- http://www.quirksmode.org/css/tables.html
- Summary: Everyone supports it, but IE7's support of newer features is partial (~2008).
Font size and relative units
| This article/section is a stub — probably a pile of half-sorted notes and assertions some of which may well be wrong, and not verified as a whole. Feel free to add or refine. |
It is often useful to use em instead of pixel sizes (which are a bad idea in general). It serves as a resolution-independent spacer (and has the added bonus of making sure that your layout makes sense when people resize the font).
1.0em is the font size (height), but scales with client-based font resizing Note this is different from e.g. TeX's definition
1.0ex is the height of a lowercase x, and varies per font (although not that much between most common web fonts). It's probably not as useful as em.
(The other units, aside from %, (in other words: pt,pc,mm,cm,in) are all physical and should depend only on screen size and resolution.)
See also:
Lowering inline images
Inline images like icons often look a little too high. A class like like:
.imglower { vertical-align: -15%; }
...often goes a long way.
Paragraph indenting
text-indent applies to only the first line, so to indent only the first line:
text-indent:2em;To indent everything except the first line (note that you can use lists to do the same thing), try something like:
text-indent:-1.5em; margin-left:1.5em;
overflow
The overflow (also separated into overflow-x and overflow-y) has four possible values:
- visible: (default) content is not clipped
- hidden: content is clipped
- scroll: scrollbars are always added
- auto: scrollbars are added only when there there is overflowing content (UAs have some choice, but that is the common behaviour)
See also W3/CSS2: Overflow and clipping
fixed-size containers with scrollbars:
Fixed-size views that crop
Crop meaning text/content beyond a point (determined by layouting) just doesn't get displayed (like last.fm's track name labels). This can be useful to view up to a fixed size of something but not have it disturb layouting. One use is avoiding that long URLs (inherently non-line-breakable) break your layour widthwise.
It can be done in a few different ways that all involveYou would often set a width. You can set a height to, e.g. about 1.2em to display a single line, and you probably want to use line-height to increase the spacing between lines, to make sure you won't get stray ascenders from the line below.
white-space: pre-like behaviour
To get more literal whitespace treatment (newlines, spaces), set white-space:pre .
You may also want to know about white-space:nowrap; it acts something like overflow:hidden.
Centering block elements
It seems the proper way is to set margin:auto - specifically the left and right margins - but note this only works when you set an explicit (and absolute(verify)) width.
Apparently you can also abuse misinterpretation of text-alignment: set text-align: center; on the parent of the block element (and text-align: left; on the block element itself to have its contents behave normally. This may behave somewhat differently in different browsers(verify).
Decorating a link
The following looks like the image is added as content:
.link-https { padding-right: 16px; background: url(lock_icon.gif) center right no-repeat; }
(a mediawiki trick, seen e.g. on wikipedia)
Outlines
Use outlines instead of borders when you want lines that don't take up space in terms of layouting, so this is useful for highlighting - though note they are less configurable than borders.
It will also easily run into your content (if you don't have margins), so keep them subtle.
Browsers often use outlines to show widget focus. You can change this using, for example:
:focus { outline: thick solid black }
:active { outline: thick solid red }
Browsers also regularly use outlines to mark links, link images and/or image buttons when they are clicked, as subtle feedback. It is also applied when users use keyboard navigation, to signal the current position.
On creatively styled links such as image links and tabs, the outline may look annoying, particularly when padding, margin, text-indent and other such tricks are used. You may want:
a:active {
outline:none
/* and perhaps use some of your own subtle feedback styling*/
}
This seems to work out as removing the outline on mouse clicks - but not keyboard navigation(verify).
Per-page CSS in a single file
Sending CSS inline in a page each time can be a convenient way to control the scope at which that CSS applies, meaning you don't have to worry about collisions between short classnames.
However, centralizing CSS is useful, as you save some bandwidth if you avoid sending the CSS in each and every copy of the page. If you put it in a site's monolithic CSS file it will likely be cached too, meaning the CSS will load and apply faster.
A simple way to work around scoping problems is to manually create a scope per page by putting an id on each page's body. For example, a site's result.html could contain:
<body id="reshtml">
And the site css something like
#reshtml .header { }
#reshtml .results .row { }
#reshtml .results .row .name { }
/* ...etc */
Unsorted
- 'Ten CSS tricks you may not know' (some basic, some interesting)
CSS3 in current browsers
There is a subset of CSS3 attribute tests that has worked for on browsers for a while now::
^= means starts with $= means ends with *= means 'contains
For example:
a[href ^= "ftp:"] a[href $= ".edu"] a[href $= ".mp3"]
text typesetting
text-align
text-align:
- left
- right
- center
- justify (often called 'justified' or 'full')
- inherit
CSS3 will have a more detailed text-justify
line-height
Takes:
- normal
- inherit
- a number, e.g. 2 for double-spacing or 1.5 for something less. (May be <1, but not <0)
- a percentage (relative to font size(verify))
- a specific length (e.g. in px or em)
word-spacing
letter-spacing
Cursor
- auto (browser chooses)
- default (non-special cursor; usually the arrow)
- wait (often an hourglass)
- text (select/edit I-bar, which is often the default on text)
- pointer (often a hand)
- help (often a questionmark)
- crosshair
For interfaces:
- move
- e-resize, ne-resize, nw-resize, n-resize, se-resize, sw-resize, s-resize, w-resize
Non-standard (introduced in IE), not necessary supported:
- progress (usually hourglass besides arrow)
- all-scroll
- col-resize, row-resize (think frame resizing)
- no-drop, not-allowed (usually a circle with a bar through it)
- url: an arbitrary image (one of the less supported ones, and there are varying extra browser-specific requirements)
- vertical-text (rotated I-bar)
Quirksmode has a detailed list of what browsers support what cursor styles.
positioning
| This article/section is a stub — probably a pile of half-sorted notes and assertions some of which may well be wrong, and not verified as a whole. Feel free to add or refine. |
The things you should know about in the area of positioning/layouting:
- Normal flow refers to regular layouting of block, inline, run-in boxes, which interact with each other and with their parent in terms of sequence, line wrapping, positioning, size, and such. Exact interaction behaviour depends on box types.
- Floats: When you float elements, they are first formatted in normal flow, then taken out of that flow and shifted left or right. Floats interact with normal flow in that content at the same scope wraps around it, and shifted only so far so they do not overlap with other floats (you can, for example, use this to make a space-adaptive grid, but there are height/ inline layouting details to doing so)
- Absolute positioning: position is relative to the 'containing block' (see notes on meaning below), box is taken out of normal flow, and width may be set.
The three CSS properties most relevant to this layouting are:
- position,
- float, and also
- display, which controls the box type (and can also take things out of layouting and being displayed with value 'none')
As to position's values:
- static: (default): content is in normal flow. (top/left/right/bottom do not apply)
- absolute: (top/bottom and/or left/right set position)
- fixed: relative to browser window. Fairly rare, usually used e.g. to put a logo in a corner, to have it look like a header/menu is fixed while you scroll through content, etc, to put a progress bar on the bottom no matter thhe window size, etc. (top/bottom and/or left/right anchor such elements and set the distance to such an anchor)
- relative: relative positioning applies after an element has been positioned (normal flow or floating). Relative positioning allows you to do some final shifting using the top or bottom, but unlike normal flow and floating, this does not affect layouting.
See also CSS2/Positioning schemes and the sections after it, and CSS2/Comparison of normal flow, floats, and absolute positioning
Some more details
Mixing relative and absolute can have interesting results, both in the sense of potentially useful features and of peculiarity.
There are various types of boxes:
- block boxes: div, p, etc.
- inline boxes: span, em, etc.
- run-in boxes
When display:none, no box is generated. (See also CSS2/Controlling box generation)
I believe all values of display imply one of the three main box types, plus some extra behaviour sensible for each(verify).
Containing block: (verify)
- for relative/static-positioned blocks: nearest block-level, table cell or inline-block ancestor
- for absolute-positioned blocks: nearest ancestor that is absolute, relative, or fixed (with some text directionality details)
- for fixed-positioned blocks: the same viewport it works in (window, frame, etc.)
See also CSS2/Definition of "containing block".
z-index orders elements that use position:absolute (regular elements are simply on top of their parents). Higher number is in front. See also:
- http://developer.mozilla.org/en/docs/Understanding_CSS_z-index
- http://css-discuss.incutio.com/?page=OverlappingAndZIndex
display versus visibility
At face value, both display and visibility can be used to hide things. However, they have different implications, which are useful to know for site designers.
visibility affects whether an element is rendered and reacts to events. It does not affect DOM visibility or the page layout.
- visible means just that
- hidden means it can't be seen and doesn't play in event handling, but is still present in the layout
- collapse: mostly the same as hidden, except in tables, in which collapse hides rows/columns and makes the space available for other rows/columns, but affects only the table layout and not the page layout.
display controls the flow characteristic (the box type). Setting display to none not only affects rendering, it also takes the element out of layouting.
This is a little more bothersome in terms of scripting. While it is easy to set display to none, it is not as easy to show it again, since it is not directly obvious what the value of display was before you none'd it. For this reason, it is common to temporarily add a CSS class that temporarily overrides/inherits none while it it on the element, than to set display:none directly on the element.
See also:
- W3, CSS2 standard: "Visibility: the 'visibility' property"
- http://www.w3.org/TR/CSS21/tables.html#dynamic-effects W3, CSS2 standard: "Dynamic row and column effects"]
- http://www.w3.org/TR/CSS21/visuren.html#display-prop W3, CSS2 standard: "The 'display' property"]
tables
| This article/section is a stub — probably a pile of half-sorted notes and assertions some of which may well be wrong, and not verified as a whole. Feel free to add or refine. |
- empty-cells: show (default), hide, or inherit
- table-layout: auto (default), fixed, or inherit
Media
CSS-capable browsers will usually take:
- CSS that applies to all media (all), which seems the default
- CSS that applies when rendering to specific media (like screen, print, projection, handheld, braille, tv, and a few others.
Note browsers may not support more than a few. Normal browsers seem to do print and screen.
Generally, for-media styling is either done by putting most of your styling in the omniscient all stylesheet and exceptions in each specific media stylesheet, or sometimes by making (or auto-generating) full stylesheets for each medium.
Printing
'print version'
While the below is handy to strip things you don't want in print, most people are not aware of such CSS details and will expect a print to look like the screen.
For this reason, it is generally clearer to offer a 'print version' link, whatever it actually does (remove styling from the current document, pop up a reduced version, etc).
different sheets
One solution is to add a print CSS file with exceptions that overrule the all sheet.
<link type="text/css" rel="stylesheet" href="print.css" media="print" />...probably below your other links and <style> tags, since you're overriding.(verify)
If the CSS contains mostly overrides, the printed page will get styled the same way it normally would, except for the added rules, often stripping fancy/colored/imaged styling by generally setting, for example, color:black and background:none, border-color:black, and border-width:1px.
You could even do layouting differently in the printed version, which can handy if you want to print just the main content. Often enough it is easy enough to do this by hiding elements, though, which you probably want to do anyway.
It is also useful to hide things in printed versions of a webpage, like header images, various interactivity and navigation links (...that is not useful as context).
You could also do the opposite - making a class that doesn't get shown on screen, but does get printed - this can be handy for semi-important things you would, on screen, handle in noticable tooltips.
other media-specific specification
You can import a particular stylesheet to apply to a specific medium:
@import url("fancyfonts.css") screen;You can also specify rules for specific media in inline css, such as
@media print { body { font-size: 10pt } }
@media screen { body { font-size: 13px } }
@media screen, print { body { line-height: 1.2 } }
You can't do it on elements, though; the best you can do is using a class.
Browser quirks
IE:
It looks like many of IE's layouting problems stem from the fact that before IE7, its layouting was implemented by independently rendered nested windows. Many things (particularly problems with negative padding/margins and such) can be explained by the hacks they would have had to patch on. It was simply a bad model to implement CSS, and the necessary rewrite seems to have gotten postponed for years. IE7 uses a new engine and fixes most related bugs.
There are enough problems not related to that problem, though. For example, !important is buggy in IE6.
Selector problems
Of CSS3 (and CSS3 features in otherwise CSS2-support browsers), and a few CSS2 details:
IE (pre-7-beta-1) offers no or buggy support for for:
- the direct-child selector, >(CSS2)
- the adjacent-preceding selector, +(CSS2)
- the any-preceding d selector, ~(CSS3)
- not()
- various attribute tests (mostly/all(verify) CSS3)
- various CSS pseudo-elements
- various CSS pseudo-classes
- namespaces
While IE allows multiple classes being set, it does not support multiple-class selectors like:
.listitem.hover { background:blue }
nor id-and-class selectors like #foo.bar (verify)
IE is quirky when you use * as a leading selector(verify)
Min-width workaround
IE does not support the min-width property, but you can fake it by having an element with a fixed width, e.g. a 1-by-1 transparent gif css-stretched to 130-by-1 (and possibly floated, depending on use).
Another way seems to be to use an expression() for width(verify).
Minimum height
It seems IE makes divs have a font-size-dependent minimal height, meaning you cannot easily make small text-less pixel-exact boxes.
It seems to apply even if there is no text node in the div, and the minimum size seems to be on the scale of about half a dozen pixels (perhaps actually an ex?).
To remove this minimum, add something like font-size:0px;.
Ironically, min-height also isn't supported in IE. A hack similar to the min-width one will work, see:
Various layouting details
Pages on CSS positioning/floating:
- http://www.brainjar.com/css/positioning/
- http://www.barelyfitz.com/screencast/html-training/css/positioning/
- http://www.smashingmagazine.com/2007/05/01/css-float-theory-things-you-should-know/
- http://www.fu2k.org/alex/css/layouts/3Col_NN4_FMFM.mhtml (3 column layouts)
Semi-sorted
Strict mode, quirks mode
Note: Strict mode is applied when you specify a doctype, quirks mode when you do not. This mainly exists for backwards compatibility, to have old web documents (which rarely have a doctype) still work without changes.
Quirks mode / strict mode differences:
- http://en.wikipedia.org/wiki/Quirks_mode (Controlling quirks mode)
- http://www.quirksmode.org/css/quirksmode.html
- http://developer.mozilla.org/en/docs/Mozilla_Quirks_Mode_Behavior
box model
Refers to the way box sizes are calculated/rendered; see e.g. [1].
IE for a long time did not fully comply to those specs (they basically couldn't in the initial implementation of their rendering engine), and (for backwards compatibility) still does not do so in quirks mode.
Box model:
- http://www.quirksmode.org/css/box.html
- http://tantek.com/CSS/Examples/boxmodelhack.html
- http://en.wikipedia.org/wiki/Internet_Explorer_box_model_bug
Pseudos
| This article/section is a stub — probably a pile of half-sorted notes and assertions some of which may well be wrong, and not verified as a whole. Feel free to add or refine. |
(Note that much of this was non-standard or did not exist before CSS/CSS2)
Conditional comments
Specifically, HTML comments that contain conditions that only IE on windows will use(verify), and are implicitly ignored by everything else, as they are actually inside delimited comments.
It is usually used to include an IE-specific stylesheet without having to implement browser detection via scripting.
Since this relies on features rather than bugs (unlike CSS syntax hacks and such), this is a robust way to include CSS that works around bugs in IE, and other IE-specific things.
For example, IE-in-general:
<!--[if IE]> <link rel="stylesheet" type="text/css" href="ie_workarounds.css" /> <![endif]-->
Specific versions (or many, e.g. <!--[if lte IE 6]>) of IE, for example those present in IE6 (and fixed in IE7).
<!--[if IE 6]> <link rel="stylesheet" type="text/css" href="ie6_workarounds.css" /> <![endif]-->
See also:
Pseudo-classes
- :hover (note that IE before 7 doesn't support this on non-links)
- :active (note that this is not always supported on everything. Be careful when applying it on elements other than A, INPUT, BUTTON, and similar things)
- :focus
Images
CSS sprites
| This article/section is a stub — probably a pile of half-sorted notes and assertions some of which may well be wrong, and not verified as a whole. Feel free to add or refine. |
CSS sprites refer to using an image file to contain more than one logical image. Think, for example, of having an image store the normal, rollover, and clicked state for a starring system, button, or similar.
The largest upside is that you can store many buttons/states in a single file, reducing the amount of images that will have to be loaded for a web page, and thereby the load time through lag, apparent response time, and avoid things like late-loading hover states (although pre-loading images is not very hard either).
In the case of CSS, you include the same file repeatedly, an use styling (width, height, ) to create viewports of sorts so that each use actually shows the sub-image you want. This is usually done by exploiting the background property, specifically for background-position [2].
Preloading images
| This article/section is a stub — probably a pile of half-sorted notes and assertions some of which may well be wrong, and not verified as a whole. Feel free to add or refine. |
Image preload means that page items aren't randomly visually fast and slow to respond.
Common methods:
- One common way is to pre-load images by using <img> tags that are not displayed. There are various ways of doing this, such as:
- display:none on the images, or on a div around a few images, etc.
- position a div containing img tags outside the window, and overflow:hidden on the containing element to avoid scrollbars
- use background: with the transparent color, the image, no-repeat, and a position that means the image will not be visible.
- Alternatively, you can use javascript. Preloading scripts often do the invisible DOM element thing, but can choose to delay it until after the page has loaded, to avoid slowing down the initial load. A downside is that it means that the paranoid script-disabling crowd will get no preload.
You usually want to stick pre-loading on the end of your page (elements at the end of the body, or onload scripting), since you probably want to minimize the effect on the initial load time. You're likely loading images that are only necessary for later interaction, and have enough imagery for the initial load anyway.

