LearningCSS

From HerzbubeWiki
Jump to navigation Jump to search

On this page I keep notes about Cascading Style Sheets, or CSS. I taught myself the basics sometime in the 1990ies, and have been slightly in touch on and off again. I'm starting this page now that I plan to get an education in web programming.

The next learning page after this one is LearningJavaScript. The previous page is LearningHTML.

Note to self: CSS was designed to work with all XML languages, not just HTML!


References


Glossary

Baseline
The baseline of a line of text is the imaginary line upon which the bottoms of characters sit. Some letters (e.g. "y") extend below the baseline.
CSS
Cascading Style Sheets. Wikipedia link. From CSS 3 onwards, CSS has been split into modules that are developed independently. Although there is no longer a unified CSS specification, the W3C periodically publishes a snapshot of the current work in progress. W3C snapshot link.
CSS 1
Version 1 of CSS was published in 1996.
CSS 2
Version 2 of CSS was published in 1998. The bugfix version 2.1 was finally published in 2011, after many years of going back and forth between Working Draft and Candidate Recommendation status. Wikipedia has the full story.
CSS 3
Version 3 of CSS is no single specification, rather it was decided to split up CSS into separate "modules" which could then be worked on and released independently.
CSS 4
Work on some CSS 4 modules has started, but as of writing this none of the modules has been formally published.
Font stack
A list of fonts that all have a similar style. The list typically contains fallback fonts for all major operating systems and one generic font family, so that the website will look similar on all systems.
Hanging indent
A line of text is said to have a hanging indent if it "hangs out" to the left of the other lines of text in the block.
Leading
Extra spacing between lines.
Line length
The line length is the number of words or characters in a line. Resaonable (or even optimal) values are about 10-12 words or 60-75 characters.
Replaced element
The canonical example of a replaced element is the img element. As for the formal definition of the term, the HTML specs say that the term is defined by the CSS spec. So far I have found this definition in the CSS 2.1 specs:

An element whose content is outside the scope of the CSS formatting model, such as an image, embedded document, or applet. [...]

Rule
A CSS standard rule consists of 1-n selectors and 1 declaration block that contains 1-n declarations. A declaration consists of a property and its value. Besides the standard rule there are other rules that begin with @<keyword>" ... and are formatted according to the CSS specification for that keyword. For instance, a media query rule looks like this: @media ....
RWD
Responsive web design.
Specificity
A term to express the fact that more specific selectors have more weight when it comes to handling style conflicts. The nitty-gritty details are, of course, to be found in the W3C specs. More accessible articles can be found by searching the web. A one-glance overview is available from cssspecificity.com.
Style
Probably the same as a rule.
Style sheet
A collection of rules.
The book
Learning Web Design, 4th edition. See the references section.
Viewport
The portion of the browser window that displays the HTML document's content. Mobile browsers typically set the viewport width to an imaginary high value so a web page is rendered as if it were displayed by a desktop browser. The resulting image is then scaled down to the actual screen size. This behaviour can be countered by using the meta element. See the section on "Responsive web design" for details.


Syntax

General syntax

This is the general syntax of a single rule:

selector1, selector2, [...]
{
  property1: value1;
  property2: value2;
  [...]
}

Notes:

  • I use the Allman style for braces because I am used to that and prefer it over all the other bracing styles. The default CSS style, though, is to place the brace on the same line as the selectors.
  • For measurement values, the unit must immediately follow the number, i.e. no space is allowed between the two. Example: 2em.


Selector types

The first and most basic selector type is the element type selector. It selects an element by its name. In the following example the rule selects h1 elements:

h1 { color: red; }


A child selector selects the direct child elements of a given parent element. The element names are separated by a greater-than (>) character. Example:

p > em { color: red; }

A descendant selector selects the descendant elements of a given parent element. The element names are separated by a space character. Example:

li em { color: red; }

An adjacent sibling selector selects the direct sibling element of a given preceding element. The element names are separated by a plus (+) character. Example:

h1 + p { color: red; }

A general sibling selector selects any sibling elements of a given preceding element. The element names are separated by a tilde (~) character. This selector type is new in CSS 3. Example:

h1 ~ p { color: red; }

Note: Child, descendant, adjacent sibling and general sibling selectors are summarily called contextual selectors.


An ID selector selects the single element with a given id attribute value. The element name and the ID value are separated by a hash (#) character. The element name can be omitted because by definition only one element in an HTML document can have any given ID. An ID selector can be combined with contextual selectors. Examples:

p#foo { color: red; }
#foo { color: red; }
#foo li { color: red; }

A class selector selects all elements with a given class attribute value. The element name and the class value are separated by a period (.) character. The element name can be omitted, in which case the selector selects all elements of a given class regardless of their element type. A class selector can be combined with contextual selectors. Examples:

p.foo { color: red; }
.foo { color: red; }
.links li { color: red; }

A universal selector selects all elements. The selector consists of an asterisk (*) character. The universal selector can be combined with contextual selectors. Apparently the universal selector can cause problems with form controls in some browsers, so its use must be well tested. Examples:

* { color: red; }
#foo * { color: red; }


Finally, a grouped selector lists two or more of the above selectors to assign the same declaration to the whole group of elements. The individual selectors are separated by a comma (,) character. Examples:

h1, h2, h3, h4, h5, h6, p { color: red; }
p > em, li > em { color: red; }
h1 em, h2 em, h3 em { color: red; }
h1 + p, h2 + p { color: red; }
h1 ~ p, h2 ~ p { color: red; }
#foo, #bar { color: red; }
#links li { color: red; }
.foo, .bar { color: red; }


Pseudo-class selectors 1

The selector types shown in the previous section are all based on the markup found in the HTML document. CSS also has a number of so-called "pseudo-class" selectors which are based on user interactions or the state that an element is in. This section explains the 5 most used pseudo-class selectors.


The element name and the pseudo-class selector are separated by a colon (:) character. Example:

a:foo { ... }


Link pseudo-classes:

:link
Selects all types of links.
:visited
Selects visited links only.


User action pseudo-classes:

:focus
Selects elements that are selected and ready for input. This is typically used to style form controls and links. A user that uses the keyboard to tab through the links of an HTML document sets the focus on every link.
:hover
Selects elements when the mouse pointer hovers over them. Some touch screen devices attempt to simulate the hover state, for instance on Android when the user single-taps an element it goes into hover state. The user must tap a second time to conclude the interaction (e.g. follow a link).
:active
Selects elements (typically links and buttons) that are in the process of being clicked (or tapped)


Note: If selectors for all five pseudo-classes are in a style sheet, they must appear in a certain order to prevent conflicts. The order is LVFHA, or :link, :visited, :focus, :hover and :active.


Pseudo-class selectors 2

This section lists the remaining number of pseudo-class selectors, which generally are used less frequently.


Structural pseudo-classes are those that select an element depending on where in the DOM tree it resides. Here's a quick list, the meaning of each pseudo-class is obvious if you know your DOM:

:root
:empty
:first-child
:last-child
:only-child
:first-of-type
:last-of-type
:only-of-type
:nth-child()
:nth-last-child()
:nth-of-type()
:nth-last-of-type()


Pseudo-classes that apply to states that are typical for form widgets:

:enabled
:disabled
:checked


And a few more exotic pseudo-classes:

:target
Selects elements targeted by a fragment identifier in a URL. TODO: Example.
:lang()
Selects based on a two-character language code. TODO: Example.
:not()
Selects every element except what is listed in the parentheses. TODO: Example.


Pseudo-element selectors

In CSS 3, the element name and the pseudo-element selector are separated by double colon (::) characters. In CSS 2, however, the separator is only a single colon (:) character. The book (p. 279) recommends using a single colon charachter for backwards compatibility. Example:

/* CSS 2 */
a:foo { ... }

/* CSS 3 */
a::foo { ... }


Here is a list of the four pseudo-element selectors:

:first-line
Selects the first line of text. Only the following properties can be used: color, font, background, word-spacing, letter-spacing, text-decoration, vertical-align, text-transform and line-height.
:first-letter
Selects the first character in the text. Only the following properties can be used: color, font, background, word-spacing, letter-spacing, text-decoration, vertical-align, text-transform, line-height, padding, margin, border, and float.
:before
Dynamically adds text before the actual text as it appears in the markup of the HTML document. The property content specifies the text to add.
:after
Dynamically adds text after the actual text as it appears in the markup of the HTML document. The property content specifies the text to add.


Pseudo-class and pseudo-element selectors

In a selector that combines both pseudo-class and pseudo-element, the pseudo-class must appear before the pseudo-element.

Example:

a:hover::before { ... }   /* Use double-colon for CSS 3 */
a:hover:before { ... }   /* Use single-colon for CSS 2 in case legacy browsers must be supported */

Important: In case of user-action pseudo-classes such as :hover, if the style is supposed to be applied only when the user interacts with the pseudo-element and not the actual element, this is impossible to achieve (or only with some black magic trickery). At least that was the state of things in 2013 when this StackOverflow answer was written.


Attribute selectors

Attribute selectors select elements based on the presence and/or specific value of an attribute.


Here is a list of all attribute selectors from CSS 2:

element[attribute]
Selects elements that have the given attribute, regardless of the attribute value. This is the simple attribute selector.
element[attribute="value"]
Selects elements that have the given attribute and the given value. This is the exact attribute value selector.
element[attribute~="value"]
Selects elements that have the given attribute, and the attribute value contains the given string. This is the partial attribute value selector.
element[attribute|="value"]
Selects elements that have the given attribute, and the attribute value is hyphen-separated and the first part of the attribute value is the given string. This is the hyphen-separated attribute value selector.


Here is a list of all attribute selectors from CSS 3:

element[attribute^="value"]
Selects elements that have the given attribute and the beginning of the attribute value matches the given string. This is the beginning substring attribute value selector.
element[attribute$="value"]
Selects elements that have the given attribute and the end of the attribute value matches the given string. This is the ending substring attribute value selector.
element[attribute*="value"]
Selects elements that have the given attribute and the attribute value contains the given string. This is the arbitrary substring attribute value selector.


TODO: What about case sensitivity of values? TODO: How is the CSS 2 "partial attribute value selector" different from the CSS 3 "arbitrary substring attribute value selector"?


Comments

CSS comments don't use the same style as HTML comments. They are written using the C/C++ syntax:

/* This is a comment */

As in C/C++, the comment may span multiple lines. In fact, after the initial /* everything counts as a comment until the closing */ is found.


Important declarations

A declaration may be flagged as "important" to give it precedence over declarations that otherwise would have a higher priority. The "important" flag is specified like this:

selector { property1: value1 !important; }

Example:

p { color: red !important; }


Colors

Colors can be specified in one of three modes:

  • A color name
  • An RGB (red-green-blue) value, optionally with transparency (alpha) added to it. There are several variants how the three numbers can be specified. See the examples below.
  • A HSL (hue-saturation-lightness) value, optionally with transparency (alpha) added to it.. The three values in this color model are always specified as 1) a number for the hue value, 2) a percentage for the saturation, 3) a percentage for the lightness. See the examples below.


Examples for all three of those:

/* Color name */
color: red;

/* RGB values */
color: #FF0000;
color: #F00;              /* expands to #FF0000 */
color: #FF000080;         /* with transparency 0.5 */
color: rgb(255, 0, 0);
color: rgb(100%, 0%, 0%);
color: rgba(255, 0, 0, 0.5);
color: rgba(255, 0, 0, 50%);

/* HSL values */
color: hsl(265, 23%, 90%);
color: hsla(265, 23%, 90%, 0.5);
color: hsla(265, 23%, 90%, 50%);

Notes:

  • Transparency or alpha 0% is fully transparent, transparency or alpha 100% is fully opaque.
  • Internet Explorer 8 and older does not support colors with transparency, for those browsers you need a workaround such as a transparent .png


Gradients

In CSS 3 it became possible to specify a gradient wherever hitherto only an image URL was possible. Notably these properties are affected:

  • background-image
  • border-image
  • list-style-image


There are two types of gradients:

  • Linear gradients: Changes colors along a line, from one edge of an element to the other.
  • Radial gradients: Changes colors along a radius, from a center point towards the edge of a circular or elliptical shape.


Linear gradient examples:

/* 0 degrees points upwards, positive angles go around clockwise */
linear-gradient(180deg, yellow, green)
/*
  Keywords can be used for 90° angles: to top, to right,
  to bottom, to left
*/
linear-gradient(to bottom, yellow, green)
/*
  Any number of color stops can be specified. The position on the line is
  specified as a percentage. The 0% and 100% percentages can be omitted.
*/
linear-gradient(90deg, yellow, orange 25%, blue)
/* As usual colors can also be specified with RGB values */
linear-gradient(to bottom, #e2e2e2 0%, #dbdbdb 50%, #d1d1d1 51%, #fefefe 100%)


Radial gradient examples:

/*
  The circle shape is the default and can be omitted.
  The position of the center of the gradient is specified in the same way as background-position.
  The radius length in this example is specified with a keyword. TODO: Find out more about the keywords.
*/
radial-gradient(circle top left contain yellow green);
/*
  Here we use an elliptical shape. The radius is specified with a
  length value. TODO: How do we specify two size values to form
  an actual ellipse?
*/
radial-gradient(ellipse top left 20px yellow green);

/* TODO: Add more examples */


Media queries

Rules can be wrapped in media queries (a CSS 3 feature) so that they apply only if the conditions specified in the media query apply. The syntax is this:

@media [not|only] <target-media-type1> and (<expression1>) [and (<expression2>) ...]
       [, [not|only] <target-media-type2> and (<expression3>) [and (<expression4>) ...]]
       ...
{
  ...
}

Notes:

  • The rule can have several media queries separated by a comma (,). The rule evaluates to true if any one of the queries evaluates to true (logical-or).
  • A media query can have several expressions separated by the keyword "and". The media query evaluates to true only if all expressions evaluate to true (logical-and).
  • The keyword "not" in front of a media query negates its result (logical-not)
  • The keyword "only" is used to "[...] hide style sheets from older user agents. User agents must process media queries starting with ‘only’ as if the ‘only’ keyword was not present." TODO: What does this mean, exactly? The quote is from the CSS media queries specification.
  • An expression is always enclosed by parentheses and consists of a media feature plus value pair, separated by a colon (:) character. The syntax is this: (<media feature>: value)
  • An expression that contains an error of some sort evaluates to false. Gross syntax errors (e.g. missing parenthesis) usually lead to the media query or even the entire rule to evaluate to false.
  • Media queries can also be placed in the HTML document or appended to an @import CSS rule for when an external style sheet is referenced. For details see the "Integration" section further down.


CSS 3 defines the media types in the following list. CSS 2 had more media types but they are now deprecated.

  • all (the default)
  • print
  • screen
  • speech


CSS 3 defines the media features in the following list. Unless noted, the media-feature can be tested with a min- and max- prefix for a minimum/maximum value.

  • width: The width of the display area (viewport).
  • height: The height of the display area (viewport).
  • device-width: The width of the devices rendering surface (the whole screen).
  • device-height: The height of the devices rendering surface (the whole screen).
  • orientation: Whether the device is in portrait or landscape orientation. (Does not accept min-/max- prefixes.)
  • aspect-ratio: Ratio of the viewport’s width divided by height (width/height).
  • device-aspect-ratio: Ratio of the whole screen’s (rendering surface) width to height.
  • color: The bit depth of the display; for example, color: 8 tests for whether the device has at least 8-bit color.
  • color-index: The number of colors in the color lookup table.
  • monochrome: The number of bits per pixel in a monochrome device.
  • resolution: The density of pixels in the device. This is increasingly relevant for detecting high-resolution displays.
  • scan: Whether a tv media type uses progressive or interlace scanning. (Does not accept min-/max- prefixes.)
  • grid: Whether the device uses a grid-based display, such as a fixed-width font. (Does not accept min-/max- prefixes.)


An example of an actual expression:

/* Declarations apply for browser window widths 520-699px /*
@media screen and (min-width: 520px) and (max-width: 699px) { ... }


Integration of CSS rules into HTML documents

Summary

There are five ways how CSS rules can be integrated into an HTML document:

  • Inline styles: Specify the declaration part of a rule directly in the style attribute of the desired HTML element.
  • Embedded style sheet: Specify a set of rules in the style element within the document's head part.
  • External style sheet 1: Specify a reference to an external CSS style sheet from the HTML document.
  • External style sheet 2: Specify a reference to an external CSS style sheet from another CSS style sheet.
  • Browser style sheet: A browser's style sheet may also apply to an HTML document.


Inline styles

The style attribute can be used to declare an inline style whose declarations apply to exactly one element of an HTML document. Example:

<p style="color: green; font-size: small;">This is a paragraph with green text color and small font size.</p>

Note that in this form we don't need a selector because the declaration is attached directly to a very specific HTML element.


Embedded style sheets

The style element within an HTML document's head part can be used to declare an entire CSS style sheet that is embedded right inside the HTML document. The style sheet's rules apply only to elements within that document. Example:

<head>
  [...]
  <style>
    p
    {
      color: green;
      font-size: small;
    }
  </style>
</head>

Notes:

  • In HTML 4.x and XHTML 1.x the style element needs an additional attribute type. It looks like this: type="text/css".


External style sheets 1

The link element within an HTML document's head part can be used to declare a reference to an external CSS style sheet. The style sheet's rules apply to elements within that HTML document, but also to any other HTML documents that have a reference to the same style sheet.

Example:

<head>
  [...]
  <link rel="stylesheet" href="foo.css" />
  <link rel="stylesheet" href="bar.css" />
  <link rel="stylesheet" href="baz.css" media="screen and (min-width: 780px)" />
  [...]

Notes:

  • The rel attribute defines the type, or better the relation of the external resource to the HTML document. With CSS style sheets, the attribute value is always "stylesheet".
  • The href attribute defines the location of the CSS style sheet. It is customary to use the filename extension .css.
  • The media attribute defines a media query which, if it evaluates to false, causes the style sheet to be ignored
  • In HTML 4.x and XHTML 1.x the link element needs an additional attribute type. It looks like this: type="text/css".
  • Multiple CSS style sheets can be referenced. In case of conflict, the last one wins.


External style sheets 2

The @import rule within a CSS style sheet can be used to declare a reference to another CSS style sheet. Example:

@import url("foo.css");
@import url("bar.css");
@import url("baz.css") screen and (min-width: 780px);
[...]

Notes:

  • Any @import rules must appear before any other CSS rule
  • Multiple CSS style sheets can be referenced. In case of conflict, the last one wins.
  • A media query can be appended to the rule which, if it evaluates to false, prevents the style sheet from being imported


Inheritance

Basic inheritance rule

Some - but not all - CSS properties are said to inherit. If an HTML element is styled with a CSS property that inherits, then the HTML element passes down that property to all of its descendants in the DOM tree. Descendants include not only direct children, but also indirect ones further down the tree structure.

Or, seen from the other way round: An HTML element inherits all inheritable CSS properties from its ancestors in the DOM tree. Ancestors include not only the direct parent, but also indirect ones further up the tree structure.


Overriding

If an HTML element inherits a property, the inherited value can be overridden for that element. All of the descendants of that element now inherit the new overriding value.


Conflicts

It is possible that several sources of style information set the same property on the same HTML element to a different value. If such is the case, the following order of precedence applies:

  1. The browser style sheet (aka the user agent style sheet) has the lowest priority
  2. The user's individual style sheet (if there is one) overrides the browser style sheet
  3. The HTML document's author style sheet has the highest priority. Here there is a sub-ordering:
    1. External style sheets have the lowest priority. Another sub-ordering:
      1. External style sheets added with the link element have lower priority
      2. External style sheets added with the @import rule have higher priority
    2. Embedded style sheets override external style sheets
    3. An inline style has the highest priority because it is closest to the HTML element that is being styled


Once the applicable style sheet has been chosen, if any two rules in that style sheet conflict, the type of selector is used to determine the winner. Generally, the more specific a selector the higher its priority - this is called specificity. The following list is ordered from lowest to highest specificity. Note: This list should be sufficient to understand most cases, but the specs have more details.

  1. Element type selectors are the least specific
  2. All contextual selectors are slightly more specific
  3. Class selectors are even more specific
  4. ID selectors are the most specific


Importance:

  • A property:value declaration can be marked as "important". This makes sure that in case of a conflict the declaration that uses the "important" flag takes precedence over declarations that normally would have a higher priority
  1. If the user's individual style sheet contains "important" declarations, these declarations get top priority over all other conflicting declarations. The idea is that a visually impaired user always has the last say in how things appear.


Finally, the general rule in every case of same-level or same-importance or same-priority conflict is: Last one wins!


Which properties inherit?

In general, properties related to the styling of text—font size, color, style, etc.—are passed down. Properties such as borders, margins, backgrounds, and so on, that affect the boxed area around the element tend not to be passed down.

TODO: Do we have some specifics?


The inherit keyword

Properties that inherit support the keyword inherit as one of their possible values. From the book:

The inherit value allows you to explicitly force an element to inherit a style property value from its parent. This may come in handy to override other styles applied to that element and to guarantee that the element always matches its parent.

Example:

p { font-size: inherit; }


Units

Absolute units

px
pixel, defined as an absolute measurement equal to 1/96 of an inch in CSS3
pt
points (1/72 inch in CSS2.1)
pc
picas (1 pica = 12 points)
mm
millimeters
cm
centimeters
in
inches

Note: If an HTML document is to be printed, absolute units are probably fine. However, do not use absolute units if the HTML document should be displayed on a computer screen. The reason: Computer screens come in all sorts of sizes and pixel densities, so an HTML document styled with absolute units will display wrong on most computer screens.


Relative units

Relative units are based on the size of something else, such as the default text size or the size of the parent element.

em
A unit of measurement equal to the current font size. In traditional typography, em is based on the width of the capital letter M - thus the name "em". In the CSS specification, an em is calculated as the distance between the baseline of two lines when the font is set without any extra space between the lines (i.e. without any "leading").
ex
x-height, approximately the height of a lowercase “x” in the font
px
pixel, considered relative in CSS2.1 because it varies with display resolution


The following units are new in CSS3:

ch
zero width, equal to the width of a zero (0) in the current font and size
rem
root em, equal to the em size of the root element (html)
vw
viewport width unit, equal to 1/100 of the current viewport (browser window) width
vh
viewport height unit, equal to 1/100 of the current viewport height
vmin
viewport minimum unit, equal to the value of vw or vh, whichever is smaller
vmax
viewport maximum unit, equal to the value of vw or vh, whichever is larger


Best practices

  • The preferred values for font sizes are em values and percentage values (or a combination of the two)
  • The most popular solution for making em values display consistently is to set the size of the body element to 100% (keeping it at the default or user’s preference), then use em values to size the text elements thereafter. This preserves the user's preferred text viewing size, yet ensures text elements are sized proportionally.
  • It may be tricky to specify the correct values in relative units if the current context is some levels deep into the DOM tree and there have been several relative unit specifications for ancestors of the current element. A useful unit in such a case might be rem.


The box model

Overview

The browser sees every HTML element (both block and inline) as a rectangular box. The following schematic shows the elements of such a box:

+--- Outer edge ---------------------------+
|                                          |
|  Margin area                             |
|                                          |
|    +--- Border ---------------------+    |
|    |                                |    |
|    |  Padding area                  |    |
|    |                                |    |
|    |    +--- Inner edge -------+    |    |
|    |    |                      |    |    |
|    |    |  Content area        |    |    |
|    |    |                      |    |    |
|    |    +----------------------+    |    |
|    |                                |    |
|    |                                |    |
|    |                                |    |
|    +--------------------------------+    |
|                                          |
|                                          |
|                                          |
+------------------------------------------+

Notes

  • The inner edge and outer edge are imaginary boundaries, they have no visible representation
  • The border, on the other hand, can be made visible
  • Padding, border and margin are all optional


Sizing

Two properties control the size of an element's box:

  • width
  • height


The property box-sizing, which was introduced in CSS 3, can be used to specify the area that should be sized. Possible values are:

  • content-box (the default): The width and height properties refer to the size of the element's content area.
  • border-box: The width and height properties refer to the size of the element's border area (including the border itself).

Important: The border-box model is very important for responsive designs because the model avoids messing around with additional paddings and borders. Margins are still a problem, though.


CSS 2 introduced a few additional properties that are useful to put limits on boxes instead of specifying an exact box size. These properties are also affected by the box-sizing property's value.

  • max-width
  • max-height
  • min-width
  • min-height

Note: The book recommends avoiding these properties when box-sizing is set to "border box", because "they are known to cause browser problems."


Padding

You can specify an individual padding for each of the four sides of the box. By default thre is no padding.


Border

There is a large number of properties for styling borders:

  • The basic border line style
  • Border width
  • Border color
  • Rounded corners
  • Border image

All of these properties can be specified individually for each of the four sides (or corners) of the box. By default there is no border.


Margin

You can specify an individual margin for each of the four sides of the box. By default the browser style sheet adds some margins around various block elements.


Collapsing margins:

  • Usually the top and bottom margin of two adjacent block elements collapse, i.e. the two margins don't add up, instead the larger of the two margins is used.
  • The exception to the rule: Top/bottom margins do not collapse for floated and absolutely positioned elements. See the "Floating and positioning" section for details.
  • Left and right margins never collapse.


Margins around non-replaced inline elements (e.g. em):

  • Top/bottom margins can be specified but have no effect
  • Left/right margins have the desired effect, but being inline elements they are added only to the left of the first line and to the right of the last line.


Margins around replaced inline elements (e.g. img):

  • Margins have the desired effect on all four sides of the box


Negative margins can be used to achieve interesting and/or stupid effects, such as overlapping text.


Fonts

Font families

CSS distinguishes between:

  • Actual fonts. Examples: Arial, Courier.
  • Generic font families. Examples: monospace, sans-serif


CSS specifies 5 generic font families:

  • serif
  • sans-serif
  • monospace
  • cursive (cursive fonts emulate a script or handwritten appearance)
  • fantasy (purely decorative)


Font names

Names of actual fonts must obey these rules:

  • They must be capitalized, i.e. the first letter of each word must be in uppercase. Example: Arial (instead of arial).
  • If the font name has a space in it, it must be specified within quotation marks. Example: "Duru Sans".

Names of generic font families must appear exactly as they are defined by the CSS specification (also see the previous section).


Font sizes

The font-size property is used to specify a font size. The following values can be specified:

  • A percentage value (e.g. 150%). The percentage is relative to the HTML element's default/inherited font size.
  • One of the two relative keywords larger or smaller. These also increase/decrease the font size relative to the HTML element's default/inherited font size.
  • One of the following absolute keywords. Note that the keywords do not specify an absolute size, rather the different sizes are scaled in a consistent manner in relation to each other.
    • xx-small
    • x-small
    • small
    • medium (this is usually the browser's default size)
    • large
    • x-large
    • xx-large
  • One of the many CSS length units (e.g. 1.5em). The unit that is used determines whether the specified size is relative or absolute.


Note: The default font size of browsers generally is 16 pixels - unless you have people with visual impairment, or people with very large monitors. Blatantly assuming 16 pixels provides a useful baseline for calculating relative font size values.


Boldness

The font-weight property is used to specify the "boldness" of a font. The following values can be specified:

  • normal (the default)
  • bold
  • bolder
  • lighter
  • 100, 200, 300 [...] 900


Note: The problem with the numeric values is that most fonts do not support so many different weights. Also, different browser may interpret numeric values in different ways. In general, numeric settings of 600 and higher result in bold text


Italics

The font-style property is used to specify the "posture" of a font, i.e. whether the letter shapes appear vertical or slanted. The following values can be specified:

  • normal (the default)
  • italic
  • oblique


Note: The difference between italic and oblique is that italic really uses a separate typeface design, whereas oblique uses the normal typeface design and just slants it. In most browsers, however, the two will look the same, unless the font's italic design is truly different.


Small caps

The font-variant property is used to specify whether a separate font design called "small caps" should be used. The following values can be specified:

  • normal (the default)
  • small-caps


Note: Most fonts do not have a dedicated "small caps" design, so browsers usually simulate the effect by scaling down uppercase letters from the normal font design.


Line height

The line height can only be specified via the font shorthand property. See the next section for details.


The font shorthand property

The font property is a shorthand to specify all the above font properties in one fell swoop. The property's values have to appear in a given order, which is this:

font: font-style font-weight font-variant font-size/line-height font-family;

Notes:

  • Size and family are required
  • Style, weight and variant can appear in any order
  • Style, weight and variant can also be omitted, in which case they default to normal
  • The line height value does exactly what it says. It is used to add extra spacing between lines.
  • Family can reference web fonts declared by the @font-face rule


Floating, positioning, flexbox

Introduction

An HTML document has a default layout flow that is good enough to display simple structured text. CSS provides the means to break elements out of the default flow and position them at more or less arbitrary positions to create nicely layouted documents.


The normal flow

The normal layout flow is this:

  • Text elements are laid out from top to bottom and from left to right in the order in which they appear in the HTML source document
  • Block elements stack up on top of one another (i.e. each block element starts a new line) and fill the available width of the browser window or other containing element.
  • Inline elements and text characters line up next to one another to fill the block elements.
  • When the window or containing element is resized, the block elements expand or contract to the new width, and the inline content reflows to fit.


Floating

The float property is used to remove an element from the normal flow and to turn it into a floating element. This has the following effects:

  • The element moves as far as possible to the left or to the right
  • The following content wraps around the floating element
  • The floated element stays in the content area of the containing element
    • This blanket statement comes from the book (p. 344). It seems to be true for inline elements only, because block elements are hanging out of their container element, which goes as far as the container element not displaying anymore if all of its content is floated.
  • Not surprisingly the entire box of the element moves, i.e. including margins


Special behaviour of floating inline elements:

  • An inline text element (e.g. span) that is floated requires that you specify a width. If the width is omitted the content area of the inline text element will horizontally expand to its widest possible width. This is almost certainly not what you want, because it defeats the purpose of floating, which is to let other content flow around it.
  • Although images are also inline elements, they do not require a width because images have an intrinsic width.
  • An inline element that is floated starts to behave like a block element. One of the effects is that the element's top and bottom margin will be rendered (for inline elements in the normal flow, top and bottom margins have no effect).
  • Top/bottom margins of floating inline elements do not collapse!


Special behaviour of floating block elements:

  • A block element (e.g. p) that is floated requires that you specify a width. If the width is omitted it retains its default value "auto" which causes the block element to use the entire available width of the browser window or the containing element. This is almost certainly not what you want, because it defeats the purpose of floating, which is to let other content flow around it.
  • A floating block element stays below any block element that precedes it in the flow


Multiple floats is best explained with an example schematic:

+-----------------------------------------------------+
| P1 (non-float)                                      |
+-----------------------------------------------------+
+---------+  +---------+  +---------+  +--------------+
| P2      |  | P3      |  | P4      |  | P8           |
| (float) |  | (float) |  | (float) |  | (non-float)  |
|         |  +---------+  |         |  +--------------+
|         |               |         |  +--------------+
|         |               +---------+  | P9           |
|         |  +---------+  +---------+  | (non-float)  |
|         |  | P5      |  | P6      |  |              |
+---------+  | (float) |  | (float) |  |              |
             +---------+  |         |  |              |
                          |         |  |              |
                          +---------+  +--------------+
+---------+  +----------------------------------------+
| P7      |  | P10 (non-float)                        |
| (float) |  +----------------------------------------+
|         |  +----------------------------------------+
|         |  | P11 (non-float)                        |
+---------+  +----------------------------------------+
+-----------------------------------------------------+
| P12 (non-float)                                     |
+-----------------------------------------------------+

Notes:

  • The first three floats (P2-P4) start stacking up from the left edge
  • When there isn't enough room for the fourth (P5), it moves down and to the left until it bumps into something - because the float P2 is very long it bumps into that
  • The fifth float (P6) again stacks up from the left
  • Again there isn't enough room for the sixth float (P7), so it moves down and to the left until it bumps into something - in this case, it's the edge of the browser window because P2 is no longer in the way


Containers of floating block elements:

  • A floating block element hangs out of its container element
  • If all of the content of a container is floating, then the container element will become empty and not render at all
  • Solution 1: Float the container as well and set its width to 100%. float: left; width: 100%
  • Solution 2: Set the container's overflow property to auto and its width to 100%. overflow: auto; width: 100%


Positioning

An alternative to floating, which depends on where an element occurs in the HTML document's markup, is the so-called "positioning" mechanism. The property is position and the possible values are these:

static
The default. The element is positioned according to the normal layout flow.
relative
The element is positioned with an offset that is relative to its original position in the flow. The space occupied by the element in its original position is preserved as empty space.
absolute
The element is removed from the document flow entirely and positioned with respect to the browser window or a containing element. Unlike relatively positioned elements, the space that the element would have occupied is made available to other elements. An absolutely positioned element always behaves like a block element, even if it originally was an inline element.
fixed
The element is removed from the document flow entirely and and positioned relative to the viewport. The element stays in its fixed position even when the user scrolls the document.


Once a positioning method other than "static" has been established, the actual position must be specified:

  • There are four offset properties that can be used for this: top, right, bottom and left.
  • Each of the four properties establishes the position of one of the four edges of the positioned element. For instance, the top property establishes the position of the top edge of the positioned element (well, duh!).
  • Less obviously, because the properties specify offset values, there must be a reference frame that the offsets are based on. This is called the positioning context.
  • Like the positioned element, the positioning context is a box that also has 4 edges. The value of each of the four properties specifies the distance from the corresponding edge of the positioning context towards the center of the positioning context. For instance, "top: 20px" specifies that the top edge of the positioned element is 20 pixels away from the top edge of the positioning context.
  • A negative offset value reverses the direction to away from the center of the positioning context.


The positioning context depends on the positioning method:

  • Positioning method "relative": The positioning context is the original position of the element.
  • Positioning method "absolute": The positioning context is the nearest ancestor element (aka "containing block") that has a positioning method other than "static". If no such ancestor element exists, the positioning context is the root element html (aka "initial containing block").
    • If an ancestor exists that is a block element, the positioning context is the padding area
    • If an ancestor exists that is an inline element, the positioning context is the content area
    • TODO: Are these two statements true even if borders and margins are defined?
    • TODO: And what about when no ancestor exists?
  • Positioning method "fixed": The positioning context is the viewport. The result is that elements with positioning method "fixed" don't move when the user scrolls the document.


Additional notes:

  • An inline element that is absolutely positioned starts to behave like a block element. One of the effects is that the element's top and bottom margin will be rendered (for inline elements in the normal flow, top and bottom margins have no effect).
  • TODO: What about collapsing margins? Cf. floating elements where margins do not collapse.
  • Positioned elements can overlap with other content.


Conflicting specifications:

  • If all four offset properties are specified, the size of the positioned element has also been implicitly specified
  • If width/height of the positioned element are also specified, it is easily possible that the two size specifications are not the same
  • CSS apparently has many rules what happens in such a case, but the book does not specify them. Instead the recommendation is not to over-specify things - a width and one or two offset values are usually sufficient.


Possible offset values:

  • auto (the default)
  • Percentage values
  • Unit values


flexbox

A third alternative to floating and position is the so-called "Flexible Box", or flexbox for short, layouting model. The main purpose is to provide a way to layout elements/items when their size is unknown and/or dynamic.

When flexbox is used, there is always a flex container and the flex items that it contains. With flexbox the container has the ability to alter its items’ width/height (and order) to best fill the available space. A container expands its items to fill available free space, or shrinks them to prevent overflow.

Here is a diagram that shows the main concept of the flexbox layouting model:

+--------------------------------------------------------------------------------> main axis
|
|           <--------------- main size ---------------------->
|  
|  ^        +-- flex container ------------------------------+  <-- cross start
|  |        |                                                |
|  | cross  |  +-------------+   +------------------------+  |
|  | size   |  | flex item 1 |   | flex item 2            |  |
|  |        |  +-------------+   +------------------------+  |
|  |        |                                                |
|  v        +------------------------------------------------+  <-- cross end
|
|           ^                                                ^
|           |                                                |
|           main start                                main end
v
cross axis

Notes:

  • The main axis can be horizontal or vertical. The CSS property is flex-direction.
  • The cross axis is automatically defined as being perpendicular to the main axis.
  • Items are placed into the container starting either at "main start" or at "main end".
  • Flex lines are placed into the container always starting at "cross start" and going toward "cross end".
  • The main size of an item is the item's size in the direction of the main axis. The cross size is the the item's size in the direction of the cross axis.


Properties for the container:

  • display: Values are "flex" or "inline-flex". Enables the flexbox layouting model.
  • flex-direction: Values are "row" (left to right, the default), "row-reverse" (right to left), "column" (top to bottom), "column-reverse" (bottom to top).
  • flex-wrap: Values are "nowrap" (all flex items will be on one line, the default), "wrap" (flex items will wrap onto multiple lines, top to bottom), "wrap-reverse" (same as "wrap", but bottom to top).
  • flex-flow: Shorthand for flex-direction and flex-wrap. The default value is "row nowrap".
  • justify-content: Defines the alignment along the main axis. Values are "flex-start" (the default), "flex-end", "center", "space-between", "space-around" and "space-evenly". For details see below.
  • align-items: Defines how items are laid out along the cross axis on the current line. Values are "stretch" (the default), "flex-start", "flex-end", "center" and "baseline". For details see below.
  • align-content: Defines how lines are laid out within the container when there is extra space in the cross axis - similar to how justify-content aligns items within the main axis. Has no effect if it's a single line container, i.e. flex-wrap is set to "no-wrap". Values are "normal" (the default), "flex-start", "start", "flex-end", "end", "center", "space-between", "space-around", "space-evenly" "stretch". For details see below.
  • writing-mode: TODO
  • gap, row-gap, column-gap: TODO

Properties for the items:

  • order: Numerical value (can be negative, default is 0). Specifies the order in which items are laid out, instead of just following the order in which the items appear in the source. Items with the same value are ordered as they appear in the source.
  • flex-grow: Numerical value (no negative numbers, default is 0). Allows the item to grow. The value is a proportion. Remaining space in the container is distributed among growing items according to the specified proportions.
  • flex-shrink: Numerical value (no negative numbers, default is 0). Allows the item to shrink. TODO: Figure out how this works (may be the same concept as flex-grow).
  • flex-basis: Defines the default size of the item before the remaining space is distributed. Values are "auto" (look at my width or height property), "content" (size the item based on the item's content; this option may not be well supported), "0" (TODO), any length value such as "20%", "5rem" etc.
  • flex: Shorthand for flex-grow, flex-shrink and flex-basis. The default value is "0 1 auto". The second and third values are optional. It is recommended to use this shorthand because it sets the other values intelligently.
  • align-self: Allows the default alignment, or the alignment specified by align-items, to be overridden for an individual flex item. See align-items for details.


The value for justify-content defines the alignment along the main axis. It helps distribute extra free space leftover when either all the flex items on a line are inflexible, or are flexible but have reached their maximum size. It also exerts some control over the alignment of items when they overflow the line.

flex-start                                          flex-end
+--------------------------------------------+      +--------------------------------------------+
|+-----------++---++------+                  |      |                  +-----------++---++------+|
||           ||   ||      |                  |      |                  |           ||   ||      ||
|+-----------++---++------+                  |      |                  +-----------++---++------+|
+--------------------------------------------+      +--------------------------------------------+
Pack items at start of flex-direction               Pack items at end of flex-direction

center
+--------------------------------------------+
|         +-----------++---++------+         |
|         |           ||   ||      |         |
|         +-----------++---++------+         |
+--------------------------------------------+
Pack items centered along the line

space-between
+--------------------------------------------+
|+-----------+         +---+         +------+|
||           |         |   |         |      ||
|+-----------+         +---+         +------+|
+--------------------------------------------+
Evenly distribute items, first/last item is on the start/end line

space-around
+--------------------------------------------+
|  +-----------+       +---+       +------+  |
|  |           |       |   |       |      |  |
|  +-----------+       +---+       +------+  |
+--------------------------------------------+
Evenly distribute items with equal space AROUND them on both sides
1 unit of space to the left/right of first/last item
2 units of space between items 1/2 and 2/3

space-evenly
+--------------------------------------------+
|    +-----------+     +---+     +------+    |
|    |           |     |   |     |      |    |
|    +-----------+     +---+     +------+    |
+--------------------------------------------+
Evenly distribute items with equal space on both sides of all items (including at the edges)


align-items defines the default behavior for how flex items are laid out along the cross axis on the current line. This is similar to justify-content but for the cross axis (perpendicular to the main axis).

flex-start
+-----------------------+          +-----------------------+
|  +---+  +---+  +---+  |          |                       |
|  |   |  |   |  |   |  |          |         +---+         |
|  |   |  |   |  +---+  |          |         |   |         |
|  |   |  |   |         |          |  +---+  |   |         |
|  +---+  |   |         |          |  |   |  |   |         |
|         |   |         |          |  |   |  |   |  +---+  |
|         +---+         |          |  |   |  |   |  |   |  |
|                       |          |  |   |  |   |  |   |  |
|                       |          |  +---+  +---+  +---+  |
+-----------------------+          +-----------------------+
items are placed at start          items are placed at end
of cross axis                      of cross axis


center                             stretch (default)
+-----------------------+          +-----------------------+
|                       |          |  +---+  +---+  +---+  |
|         +---+         |          |  |   |  |   |  |   |  |
|  +---+  |   |         |          |  |   |  |   |  |   |  |
|  |   |  |   |  +---+  |          |  |   |  |   |  |   |  |
|  |   |  |   |  |   |  |          |  |   |  |   |  |   |  |
|  |   |  |   |  +---+  |          |  |   |  |   |  |   |  |
|  +---+  |   |         |          |  |   |  |   |  |   |  |
|         +---+         |          |  |   |  |   |  |   |  |
|                       |          |  +---+  +---+  +---+  |
+-----------------------+          +-----------------------+
items are centered in the          items are stretched to fill
cross axis                         the container along the cross axis
                                   (respecting min-width/max-width)


baseline
+-----------------------+
|        +---+          |
|  +---+ |   |          |
|  |   | |   | +---+    |
|  |foo| |BAR| |BaZ|    |
|  |   | |   | |   |    |
|  +---+ |   | |   |    |
|        |   | +---+    |
|        +---+          |
|                       |
+-----------------------+
items are aligned so that
their baselines align


align-content aligns the lines within the flex container when there is extra space in the cross axis, similar to how justify-content aligns individual items within the main axis.

TODO


Transitions, Transforms, Animations

Transitions

A transition tells the browser to change the value of a CSS property over a period of time. Optionally the transition can be delayed, and the transition style can be changed. A transition must have a trigger.


A simple example serves as the basis for discussion:

a
{
  background-color: mediumblue;
  transition-property: background-color, color, letter-spacing;
  transition-duration: 0.3s, 2s, 0.3s;
  transition-timing-function: ease-out, ease-in, ease-out;
  transition-delay: 0.2s;
}

a.smooth:hover, a.smooth:focus
{
  background-color: red;
}

Discussion:

  • The trigger for the transition in this example simply exists in the form of a different CSS rule that specifies a new value for a CSS property. Obviously, the trigger could also be a JavaScript snippet that changes the value of a CSS property.
  • The transition-property property names the CSS properties. Not all CSS properties are capable of transitions, but a lot of them are - too many to list here.
  • The transition-duration property specifies the duration of each transition either in seconds (unit "s") or milliseconds (unit "ms").
  • The optional transition-timing-function property defines the style of each transition. The names that can be specified here come from a list of pre-defined timing functions. The default timing function is "ease", which starts slowly, accelerates quickly, then slows down at the end.
  • The optional transition-delay property specifies the delay of each transition in seconds (unit "s") or milliseconds (unit "ms") before the transition starts.
  • Multiple transitions are specified by separating the value of each transition with a comma (",").
  • The values in the different transition-* properties are matched according to their position in the list.
  • If one list has fewer values than the others, the browser repeats the values in the list, starting over at the beginning.


The shorthand property transition combines all of the individual transition properties into one:

transition: property1 duration1 timing-function1 delay1, property2 duration2 timing-function2 delay2, [...];


Transforms (2D)

A transform changes the geometry of an element in some way. The box of the element is not affected by the transform, though, which is to say that the page layout does not change due to a transform. The following elements can be transformed:

  • Elements with replaced content, such as img, canvas, form input elements, and embedded media
  • Elements with display: block
  • Elements with display: inline-block
  • Elements with display: inline-table (or any of the table-* display types)


The following transform types exist:

Translate
This simple transform changes an element's position on the page, either by moving it along the x-axis or the y-axis, or both.
Rotate
This slightly more complicated transform rotates an element for a specified amount of degrees around a center point.
Scale
This transform makes an element smaller or larger by scaling it either along the x-axis or the y-axis, or both.
Skew
This difficult to understand transform changes the slant of an element, either along the x-axis (changing the element's width) or the y-axis (changing the element's height), or both.
Matrix
This allows you to specify your own custom transform matrix.


There are two transform properties:

  • transform: function(value) function(value), [...]: Specifies one or more transform functions, each function separated by a space character. Transforms are applied in the order in which they appear. This is important because, for instance, a translate followed by a rotate is not the same as the same rotate followed by the same translate.
  • transform-origin: horizontal-offset vertical-offset: Specifies the center, or origin, of all transforms. The two offsets are specified either as a keyword (left, center, right, top, bottom), a percentage, or a length value using one of the usual CSS units (px, em, etc.). If only one value is specified it will be used for both offsets. The default is 50% 50%.


Translate:

transform: translateX(50px);
transform: translateY(-2em);
transform: translate(5%, -7%);

Notes:

  • Length values can be specified in any of the usual CSS units, or as a percentage
  • Percentages are calculated on the width of the bounding box (which includes the border, i.e. from border-edge to border-edge)
  • Both positive and negative values are possible
  • If only one value is specified for the shorthand translate function, it is assumed to be the x-axis value


Rotate:

transform: rotate(-10deg);
transform: rotate(30deg);

Notes:

  • A full circle is 360 degrees
  • Both positive and negative values are possible
  • TODO: Are other units than "deg" possible?


Scale:

transform: scaleX(1.5);
transform: scaleY(0.75);
transform: scale(2, .5);

Notes:

  • The value is unitless because it specifies a size ratio. You can also think of it is a percentage.
  • Values above 1 make the element larger, values below 1 make the element smaller
  • If only one value is specified for the shorthand scale function, it is used for scaling in both directions


Skew:

transform: skewX(15deg);
transform: skewY(-30deg);
transform: skew(15deg, -30deg);

Notes:

  • A full circle is 360 degrees
  • Both positive and negative values are possible
  • If only one value is specified for the shorthand skew function, it is assumed to be the x-axis value
  • TODO: Are other units than "deg" possible?


Transforms (3D)

This section only has some barebones information.


The following 3 properties establish a 3-dimensional space to work with:

  • The perspective property adds, well, perspective to the element to which it applies. The child elements now start to "behave" as though they are in 3-D space. The value of the perspective property is some integer larger than zero that specifies a distance from the element's origin on the z-axis. The lower the value, the more extreme the perspective.
  • The perspective-origin property describes the position of the user's eyes relative to the transformed items. The values are a horizontal position (left, center, right, or a length or percentage) and a vertical position (top, bottom, center, or a length or percentage value). The default is centered vertically and horizontally (perspective-origin: 50% 50%).
  • The backface-visibility property specifies whether the reverse side of the element is visible when it spins around.


As with 2D, the 3D transform functions are specified using the transform property. The new 3D transform functions are:

  • translate3d
  • translateZ
  • scale3d
  • scaleZ
  • rotate3d
  • rotateX
  • rotateY
  • rotateZ
  • matrix3d


Keyframe animations

This section only has some barebones information.


Keyframe animations are broken down into 2-n segments. Each segment is delimited by a so-called keyframe. Transitions are simple animations with merely two keyframes: A start and an end keyframe. More complex animations require many keyframes to control property changes in the sequence.


Specifying a keyframe animation consists of two parts:

  1. Establish the keyframes with a @keyframes rule
  2. Add properties to the keyframes that will be animated


Here's a simple example:

@keyframes colors
{
    0% { background-color: red; }
   20% { background-color: orange; }
   40% { background-color: yellow; }
   60% { background-color: green; }
   80% { background-color: blue; }
  100% { background-color: purple; }
}

Notes:

  • The animation has a name, "colors" in this example
  • The animation runs along a time axis that goes from 0% (the beginning of the animation) to 100% (the end of the animation)
  • TODO: Is it possible to specify something else than percentage values?


Once a keyframe animation has been specified, it can be applied to any number of elements. Here's an example:

a
{
  animation-name: colors;
  animation-duration: 5s;
  animation-timing-function: linear;
  animation-delay: 0.2s;
  animation-iteration-count: infinite;
  animation-direction: alternate;
  /*
    The play state by default is "running". Here we pause the animation when the
    link is in its normal state. Because of that we need to set it to "running"
    further down when the link is in its hover state.
  */
  animation-play-state: paused;
}

a:hover
{
  animation-play-state: running;
}


As usual there is a shorthand property that can be used to specify all the animation properties in one go:

animation: colors 5s linear 0.2s infinite alternate;


To make things move around, combine an animation with the top, right, bottom or left properties, or use one or more transforms.


FWIW, When the browser has to automatically determine property values to fill in between keyframes, this apparently is called "tweening".


Multi-column layouts

The CSS module "Multi-column Layout" defines properties that are used to specify how an element's content should be rendered in columns. This obviates the need to create ponderous and fragile structures in the HTML source code to achieve a columnar layout. Overall support for multi-column layouts is good in modern browsers, even IE (IE 10 fully supports it).


The main properties are:

column-count
Specifies the maximum number of columns to use to render the text. The browser may create less columns than this upper limit if not enough space is available.
column-width
Specifies a minimum column width. The browser may create columns that are wider than this if it has surplus space to fill.
column-gap
The distance between columns. The convention is that this is 1 em.


The actual algorithm used by the browser to determine the number of columns and their widths probably is quite complicated, but I imagine it works roughly like this:

  • The browser determines the actual number of columns that it creates by examining the available width, how many columns it can fit in there according to column-width and column-gap. Additionally, the browser tries to create columns of approximately the same length.
  • The browser then reduces the resulting number if it exceeds the maximum specified by column-count.
  • After it has determined the number of columns, the browser then calculates the actual column width by evenly distributing the available space (taking column-gap into consideration).


For more details see the MDN docs.


Tables

Some notes about tables, directly from the CSS2 spec:

  • The table model specifies that internally the table is divided into grid cells. Grid cells are not equivalent to table cells because table cells may span several rows and/or columns.
  • Internal table elements generate rectangular boxes with content and borders. Cells have padding as well. Internal table elements do not have margins.
    • An internal table element is one that produces a row, row group, column, column group, or cell.
    • Specifically, a table cell is an internal table element, but from the previous sentence one must deduce that there are other internal table elements as well.
  • Cell boxes that are smaller than the height of the row receive extra top or bottom padding.
  • A cell's width (and possibly it's height as well) extends to the inner edge of the cell's border. The width does not include the border and/or the border spacing (in case any is defined). This is not specified in the text, but can be seen in a figure in the section for the border-spacing property.

TODO: This section is incomplete and unstructured. Write more!


Properties

Box model properties

None of the properties in this section inherit.

width, height, min-width, min-height, max-width, max-height
These properties specify various widths and heights of either the content area or the border area of an element. The value of the box-sizing properties controls which area it is. Possible values are: auto (the default), percentage values and unit values.
box-sizing
Specifies the area that sizing properties should refer to. Possible values are: content-box (the default) and border-box. This is a CSS 3 property.
overflow
Specifies what should happen when an element's content area is too small for the content. Possible values are: visible (the default), hidden, scroll and auto.
padding-top, padding-right, padding-bottom, padding-left
These properties specify the amount of padding between the content area and the border. Possible values are: Percentage values and unit values. The default is zero padding. Percentages refer to the width of the parent element!
padding
Specifies several paddings in one declaration. Four values = top, right, bottom, left (clockwise, starting at the top). When you omit some values, they are not set to their default (zero), instead the previous value from the corresponding "other" side is substituded. For instance, when you omit the last value for the left side, the same value that was used for the right side is substituted. To sum it up: Three values = Top, left + right, bottom. Two values = Top + bottom, left + right. One value = All sides.
border-top-style, border-right-style, border-bottom-style, border-left-style, border-style
These properties specify the border style. The default if no style is specified is that the border does not exist and all other border properties are ignored. For the border-style shorthand property the same rules apply as for the padding shorthand property. Possible values are: none (the default), dotted, dashed, solid, double, groove, ridge, inset and outset.
border-top-width, border-right-width, border-bottom-width, border-left-width, border-width
These properties specify the border thickness. For the border-width shorthand property the same rules apply as for the padding shorthand property. Possible values are: thin, medium (the default), thick and unit values.
border-top-color, border-right-color, border-bottom-color, border-left-color, border-color
These properties specify the border color. The default if no color is specified is to use the element's foreground color (specified by the color property). For the border-color shorthand property the same rules apply as for the padding shorthand property. Possible values are: transparent, color names and RGB values.
border-top, border-right, border-bottom, border-left, border
These are shorthand properties that specify border style, border width and border color in one go. Values can appear in any order. Values are optional (but no border will be rendered if border style is omitted).
border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-radius
These properties specify how border corners are rounded. The default if these properties are not used is to have sharp 90° corners. For the border-radius shorthand property the same rules apply as for the padding shorthand property. Possible values are: Percentage values and unit values. If only one value is specified, the corner will be the section of a circle. If two values are specified, the corner will be the section of an ellipse. The first value is for the horizontal radius, the second value is for the vertical radius. For the border-radius shorthand property, two values must be separated by a slash (/) character - horizontal radius values appear before the slash, vertical radius values after the slash.
border-image
Specifies the URL of an image to use for the border. This is a CSS 3 property. TODO Find out more about this property.
margin-top, margin-right, margin-bottom, margin-left, margin
These properties specify the amount of margin outside the border. Possible values are: auto (the default), percentage values and unit values. Percentages refer to the width of the parent element! For the margin shorthand property the same rules apply as for the padding shorthand property.
box-shadow
Specifies one or more box shadows (aka "drop shadow") to use. All shadows are drawn behind the background and border. The shadows are drawn around the box that includes the border, i.e. the margin is excluded. The shadows are drawn in layers in reverse order in which they are specified, with the result that the first shadow is on top. Possible values are: none and a list of values in the format horizontal-offset1 vertical-offset1 blur-distance1 spread-distance1 color1 inset, horizontal-offset2 vertical-offset2 blur-distance2 spread-distance2 color2 inset, [...]. Color, blur and spread distance and the inset keyword are optional. The offsets move the shadow to the right and down - negative values move the shadow to the left and up. A blur distance of 0 is no blur, the higher the blur distance goes the softer the blur at the shadow edge. The spread distance increases (positive values) or decreases (negative values) the size of the shadow. The keyword inset causes the shadow to be drawn on the inside of the box.


Font-related properties

All properties in this section inherit.

The Fonts section further up on this page has more details.

font-family
Specifies one or more font names. The default value depends on the browser. Font names are separated by a comma. Earlier font names have precedence over later font names. Names of actual fonts must be capitalized and, if they contain space characters, must be specified within quotation marks. Instead of actual fonts the following 5 generic font families can also be used: serif, sans-serif, monospace, cursive (emulate script or handwritten appearance), and fantasy (purely decorative). Web fonts declared by the @font-face rule can also be referenced here.
font-size
Specifies the font size (duh!). Typical values use em units or percentages.
font-weight
Specifies boldness. Universally supported and therefore typically used values are normal and bold.
font-style
Specifies italics. Typical values are normal and italic.
font-variant
Specifies small caps. Typical values are normal and small-caps.
font
Specifies all of the above. Size and family are required, the other ones are optional; if omitted they default to normal. The order in which values appear is font-style font-weight font-variant font-size/line-height font-family, although style, weight and variant can appear in any order.


Text properties

All properties in this section inherit, except text-decoration.

line-height
Specifies the minimum distance from baseline to baseline of two adjacent lines of text. Most browsers split extra space above and below the text, thus making the text vertically centered in the overall line height. The line-height value is minimal because if an inline element such as an image also appears on the line, the line height will expand to accomodate the inline element.
text-indent
Specifies the indentation of the first line of text. Applies only to block elements, table cells and inline blocks. Possible values are units and percentages. A unit value can be negative to produce a hanging indent (in which case a margin should also be specified to make sure that the text hanging out to the left remains visible). A percentage value is calculated based on the width of the parent element.
text-align
Specifies the horizontal alignment of text. Applies only to block elements, table cells and inline blocks. Possible values are: left, right, center and justify (i.e. align both left and right).
text-align-last
Specifies the horizontal alignment of the last line of text. This is a CSS 3 property that may not be well supported by browsers. TODO: Find out more about this property.
text-justify
This is a CSS 3 property that may not be well supported by browsers. TODO: Find out more about this property.
text-decoration
Specifies various text decorations. Possible values are: none, underline, overline, line-through and blink (yikes!). CSS 3 allows even more decorations. This property notably can be used to remove the underlines from links.
text-transform
Specifies capitalization of text. Possible values are: none, capitalize, lowercase and uppercase.
letter-spacing, word-spacing
Specifies spacing between individual letters or words. Possible values are: normal and unit values. An em value passed down to descendants remains the same even if the descendants use a different font size.
text-shadow
Specifies one or more text shadows (aka "drop shadow") to use. All shadows are drawn in front of the background and border. The shadows are drawn in layers in reverse order in which they are specified, with the result that the first shadow is on top. Possible values are: none and a list of values in the format horizontal-offset1 vertical-offset1 blur-radius1 color1, horizontal-offset2 vertical-offset2 blur-radius2 color2, [...]. Color and blur radius are optional. The offsets move the shadow to the right and down - negative values move the shadow to the left and up. A blur radius of 0 is no blur, the higher the blur radius goes the softer the blur.
vertical-align
Specifies the vertical alignment of an inline element's baseline relative to the baseline of the surrounding text. Also specifies the vertical alignment of content in a table cell. Possible values are: baseline, sub, super, top, text-top, middle, textbottom, bottom, a percentage value and a unit value.
white-space
Specifies how whitespace is handled. Possible values are: normal, pre, nowrap, pre-wrap and pre-line.
visibility
Specifies whether the element is visible or not. Possible values are: visible, hidden and collapse. Hidden elements still occupy space.


Color properties

None of the properties in this section inherit, except color which does.

color
Specifies the foreground color of an element. Usually this affects the text color, but if the element also has a border and there is no specific border color, then the border will be rendered in the foreground color.
background-color
Specifies the background color of an element. This fills the canvas behind the element, up to the edges of the element's border. This does not fill the element's margin. Possible values are: transparent and color values. The default value is transparent.
opacity
Specifies the opacity (or transparency) of an element. Both foreground and background are affected by this. Values range from 0 (transparent) to 1 (opaque).


List properties

All properties in this section inherit. All properties in this section apply only to ul, ol and li elements, or elements whose display attribute value is list-item.

list-style-type
Specifies the type of marker that appears in front of each list item. Possible values are: none, disc, circle, square, decimal, decimal-leading-zero, lower-alpha, upper-alpha, lower-latin, upper-latin, lower-roman, upper-roman and lower-greek.
list-style-position
Specifies whether the marker that appears in front of each list item is inside or outside the list's content area. Possible values are: inside and outside. The default is outside.
list-style-image
Specifies an image that should be used as the marker that appears in front of each list item. Possible values are: none and url(/path/to/image.png). A gradient can be specified instead of an image URL.
list-style
Specifies all of the above. Values are separated by space. Values can appear in any order. Example: url(/path/to/image.png) circle outside.


Table properties

All properties in this section inherit. All properties in this section apply only to table and inline-table elements.

border-collapse
Specifies whether adjacent cells in a table have separate borders with some spacing in between the cells, or share borders. Possible values are: separate (the default) and collapse.
border-spacing
For tables that use the separate border model, this specifies the horizontal and vertical spacing between cells. Possible values are: Unit values. If only one value is specified it defines both horizontal and vertical spacing. If two values are specified the first is for horizontal, the second for vertical spacing. The default is zero spacing. Even with zero spacing, browsers usually display some space between cells because of a non-zero default value for the cellspacing attribute.
empty-cells
Specifies whether empty cells are shown or hidden. Unsurprisingly, the possible values are show and hide. A cell is considered empty if it only contains carriage returns or space characters (not including the non-breaking space character).
table-layout
TODO Find out more about this property


Some notes on the collapsing border model:

  • Borders are rendered so that the two adjacent cells each receive 1/2 of the border. Borders with an even numbered width are no problem, for borders with an odd numbered width the browser decides which cell receives the extra pixel.
  • If adjacent cells have different border styles then the following rules apply in the listed order to find the winner:
    1. If the border-style property is set to "hidden" for either of the cells, then no border is displayed.
    2. Wider borders take precedence over narrower ones.
    3. The values of the border-style property are weighted as follows, from most to least precedence: double, solid, dashed, dotted, ridge, outset, groove, and (the lowest) inset.


Background image properties

None of the properties in this section inherit.

Note: In CSS 2 only a single background image could be specified. In CSS 3, multiple background images can be specified by separating the url() values of the background-image property with a comma (,). Example: background-image: url(foo.png), url(bar.png);. For all the other background properties, their values can also be repeated by adding a comma separator. Example: background-position: left top, bottom right;.


background-image
Specifies the URL of a background image for the element. Possible values are: none and url(/path/to/image.png). The base of a relative URL is the location of the CSS rule that contains the background-image property. If both a background color and a background image are present, the image is rendered on top of the color. It is recommended to always provide a background color that matches the primary color of the background image, in case the image fails to display for some reason (e.g. a user might disable all images). A gradient can be specified instead of an image URL.
background-repeat
Specifies the tiling of a background images. Possible values are: repeat (the default), repeat-x, repeat-y and no-repeat. The background image fills the canvas behind the element. The origin image is placed inside the border, but tiled images extend under the border to its outer edge. Background images never fill the element's margin.
background-position
Specifies where the origin image is rendered before tiling begins. If tiling is enabled, the image is tiled along the entire x-axis and/or y-axis regardless of where the origin image is placed on the respective axis. For instance, if horizontal tiling is enabled and the origin image is placed at the horizontal center, tiling occurs both to the left and to the right of the origin image. Possible values are: left, center, right, top, bottom, percentage values and unit values. The origin is defined by a horizontal and a vertical value. If both values are specified they are separated by a space character (e.g. "top left"). If only one value is specified the other defaults to the center position of the respective axis. With keywords the order in which the keywords appear is not important. With percentage or unit values the horizontal value comes first. Percentages: 0% ist top/left, 100% is bottom/right. Percentage values apply to both the background area and the image itself. For instance, 50% specifies that the center of the image is aligned with the center of the background area.
background-attachment
Specifies how the background image is attached. Possible values are: scroll (the default), fixed and local. The local value is CSS 3 only. When scroll is specified...
  • The background image is attached to the element content
  • The background image is visible whenever the element content is visible and scrolls together with the element content.
When fixed is specified...
  • The background image is attached to the viewport!
  • The background-position property no longer refers to the element's content area but instead refers to the viewport. For instance, a center position now refers to the center of the viewport, not the center of the element's content area.
  • The background image becomes visible only while the element's content area intersects with the area in the viewport occupied by the image.
  • As a consequence, if there is no intersection between the two areas, a background image may not be visible even though the element's content area is well within the viewport.
background
Specifies all of the above, plus the background-color property listed in the "Color properties" section. Values are separated by space. Values can appear in any order, except for background-position where the horizontal value must come first and the vertical value must appear immediately afterwards. Values are optional, however if a value is omitted a default value will be used instead. Example: white url(arlo.png) no-repeat right top fixed;.


Properties that are new to CSS 3:

background-clip
TODO: Find out more about this.
background-size
TODO: Find out more about this.
background-origin
TODO: Find out more about this.


Floating properties

None of the properties in this section inherit.

float
Specifies that an element (can be inline or block) no longer participates in the normal layouting flow and instead "floats" to the left or right as far as possible. Possible values are: left, right and none (the default). Floated elemented (both inline and block) are also required to have a width in order to behave as expected.
clear
Specifies that a block element should stop wrapping around a preceding floating element. This property applies to block elements only. The block element will start on a new line below the floating element. Possible values are: left, right, both and none. The values allow to specifically let the block element start on a new line below any left-floated or right-floated elements only.


Positioning properties

None of the properties in this section inherit.

position
Specifies that an element (can be inline or block) no longer participates in the normal layouting flow and instead is positioned in some special way. Possible values are: static (the default), relative, absolute and fixed.
top, right, bottom, left
These properties specify the offset, or distance, of one of the edges of a positioned element from the same edge of the position context. Possible values are: auto (the default), percentage values and unit values. Positive values specify the distance towards the center of the positioning context, negative value specify the distance away from the center of the positioning context.
z-index
Specifies the position of an element on the z-axis. This is important in case positioned elements overlap. Overlapping elements form a stack. An elements position in the stack is determined by its z-index and, for same z-indexes, by the elements position in the HTML document source. Higher z-index values place an element further up in the stack. Elements that occur later in the HTML document source appear further up in the stack.


Transition properties

None of the properties in this section inherit.

Notes:

  • Transitions can be applied to all normal elements, but also to the :before and :after pseudo-elements.
  • Multiple transitions can be specified by separating the value of each transition with a comma (",").
  • If you don't use the shorthand transition property, the values in the different transition-* properties are matched according to their position in the list. If one list has fewer values than the others, the browser repeats the values in the list, starting over at the beginning.


transition-property
Specifies the properties to which each transition applies. Possible values are all (which is the default), none, or the name of any CSS property that is capable of transitions. There are too many CSS properties to list here - check out this list on MDN.
transition-duration
Specifies the duration of each transition either in seconds (unit "s") or milliseconds (unit "ms"). The default is 0s (zero seconds). 0.2s seems to be a popular transition time.
transition-timing-function
Defines the style, or timing function, of each transition. Possible values are:
  • ease (the default) : Starts slowly, accelerates quickly, then slows down at the end.
  • linear : Speed stays consistent from the transition’s beginning to end.
  • ease-in : Starts slowly, then speeds up.
  • ease-out : Starts out fast, then slows down.
  • ease-in-out : Starts slowly, speeds up, then slows down again at the very end. Similar to ease, but with less pronounced acceleration in the middle.
  • cubic-bezier(#, #, #, #) : A function for defining a Bezier curve that describes the transition acceleration. TODO: Add more details.
  • steps(#, start | end) : Divides the transition into a number of steps as defined by a stepping function. The first value is the number of steps, and the start and end keywords define whether the change in state happens at the beginning (start) or end of each step. TODO: Add more details.
  • step-start : This is the same as specifying steps(1, start). This changes states in one step, at the beginning of the duration time. The result is a sudden state change, the same as if no transition had been applied at all.
  • step-end : This is the same as specifying steps(1, end). This changes states in one step, at the end of the duration time.
transition-delay
Specifies the delay of each transition in seconds (unit "s") or milliseconds (unit "ms") before the transition starts. The default is 0s (zero seconds).
transition
Specifies all of the above. Property and duration are required, the timing function and delay are optional; if omitted their default value applies. The order in which values appear is property duration timing-function delay. Blocks of values for several transitions are separated by a comma (",").


Transform properties

None of the properties in this section inherit.

transform
Specifies one or more transform functions. The format of the value is this: function(value), function(value), [...]. Each function is separated by a comma (","). Transforms are applied in the order in which they appear. The default value is none. Possible transform functions:
  • transform: translateX(x-value), transform: translateY(y-value), transform: translate(x-value, y-value) : Values are either one of the usual CSS units or a percentage. Percentages are calculated on the width of the bounding box (which includes the border, i.e. from border-edge to border-edge). Values can be positive or negative. If only one value is specified for the shorthand translate function, it is assumed to be the x-axis value.
  • transform: rotate(NNNdeg) : "NNN" is a numeric value, "deg" is the unit. Both positive and negative values are possible. A full circle is 360 degrees.
  • transform: scaleX(x-value), transform: scaleY(y-value), transform: scale(x-value, y-value) : The value is a unitless number that specifies a size ratio. Value 1 = size ratio 100%, values < 1 make element smaller, values > 1 make element larger. If only one value is specified for the shorthand scale function, it is used for scaling in both directions
  • transform: skewX(NNNdeg), transform: skewY(NNNdeg), transform: skew(NNNdeg, NNNdeg) : "NNN" is a numeric value, "deg" is the unit. Both positive and negative values are possible. A full circle is 360 degrees. If only one value is specified for the shorthand skew function, it is assumed to be the x-axis value.
transform-origin
Specifies the center, or origin, of all transforms. The format of the value is this: horizontal-offset vertical-offset. The two offsets are specified either as a keyword (left, center, right, top, bottom), a percentage, or a length value using one of the usual CSS units (px, em, etc.). If only one value is specified it will be used for both offsets. The default is 50% 50%.


Other properties

display
Specifies the type of element box an element generates in the layout. Possible values are: inline, block, list-item, inline-block, flex, table, inline-table, table-row-group, table-header-group, table-footer-group, table-row, table-column-group, table-column, table-cell, table-caption and none.


Rules

selectors { declarations; }
The standard CSS rule type.
@font-face
Declares a web font that can then be referenced by a font-family property.
@import
Reference to another style sheet file. Syntax: @import url("bar.css");.
@counter-style
CSS 3 rule to specify bullet shapes for list items. TODO: Find out more about this.
@media
CSS 3 rule that is called a "media query". See the "Media queries" section further up on this page for all the details.


Recipes

Drop shadows

Use the text-shadow property to create drop shadows.

  • Zero offsets give the text a "glow" effect. Example: text-shadow: 0 0 .7em purple;.
  • To achieve a "raised" look, position a light shadow above and a dark shadow below the text, using tiny offsets. Example:
    body { background-color: thistle; } h1 { color: #ba9eba; text-shadow: -.05em -.05em .05em white, .03em .03em .05em purple; }.
  • To achieve an "embossed" look, the ligh shadow goes below and the dark shadow goes above. Example:
    body { background-color: thistle; } h1 { color: #ba9eba; text-shadow: -.05em -.05em .05em purple, .03em .03em .05em white; }.


Bottom border instead of underline for links

By default links (a elements) are displayed as underlined text. A useful technique to create more nicely designed links while still conforming to the ingrained expectation of links being underlined is to use a border on the bottom of a elements.


Changing the display role

Change list items into inline elements to turn a list into a horizontal navigation bar.

ul.navigation li { display: inline; }

Change links into block elements in order to be able to give them a specific width and height.

ul.navigation li a { display: block; }

Prevent a paragraph from creating a line break (inline) but let it stay a block so that we can change certain CSS properties which only apply to block elements. This is an essential technique if we want to assign a width to an element, as we do in this example, because only block elements can have a width.

p#foo
{
  display: inline-block;
  width: 25%;
}

Entirely remove content from the flow of displayed elements:

p#foo { display: none; }


CSS reset

A CSS reset clears all styles from the browser's default style sheet and prepares an empty table for your own styles. The intention is that you don't get any surprises because of unexpected styles interfering with your own, and also that you get a more consistent look across different browsers.

Although this is supposed to be a recipe, the amount of CSS code is too much to reproduce here. Search the web with the keywords CSS Reset to find a solution.


Image replacement of text

Sometimes you want a fancyful logo or other image in place of plain text. Instead of replacing the text in the markup of the document source, you keep the text in the document to be found and indexed by search engines, and also for non-visual user agents. You then use CSS rules to add the image as a background image and move the text out of the way into a non-visible area.

A very simple technique uses the text-indent property. Apparently this is called the "Kellum Technique" because it was invented by Scott Kellum.

<h1 id="logo">Jenware</h1>

h1#logo {
  width: 450px;
  height: 80px
  background: url(logo.png) no-repeat;
  text-indent: 100%;
  white-space: no-wrap;
  overflow: hidden;
}

A simpler solution, in terms of the amount of CSS properties you have to write, uses an extremely low negative or high positive pixel value for text-indent, to make sure that the text is moved outside of the viewport. The drawback is that the browser might still draw the text box even though in the end it won't be rendered. The solution above makes it crystal clear to the browser that it won't have to draw the text, so it is more efficient because it increases performance.


CSS sprites

CSS sprites are large images that are a combination of many smaller images, such as icons or logos. The idea is that you then use the same sprite image over and over as the background image of many different HTML elements (e.g. a link list), while shifting the visible portion of the sprite image with the background-position property so that for every HTML element only its unique icon or logo is visible. The reason for this technique is to drastically reduce the number of HTTP requests the browser has to make - instead of requesting 15 small images the browser only requests 1 larger image and then performs some image juggling locally. The overall result is to improve the website performance on the client side, reduce the load on the server, and decrease the overall network traffic.

Here is a bit of code to illustrate the principle:

<ul>
  <li><a href="" class="hide twitter">Twitter</a></li>
  <li><a href="" class="hide fb">Facebook</a></li>
  [...]
</ul>

/* This is the image replacement technique discussed in the previous section */
.hide {
  text-indent: 100%;
  white-space: nowrap;
  overflow: hidden;
}

li a {
  display: block;
  width: 29px;
  height: 18px;
  background-image: url(sprite-image.png);
}

li a.twitter { background-position: 0 0;}
li a.fb { background-position: 0 -20px;}
[...]


Search the web for the keywords CSS sprite generator to find useful tools that generate a CSS sprite image for you, including the CSS rules.


Embedding (image) data

Anywhere where an URL can be specified it is possible to specify a so-called "data URI" (Wikipedia link) to embed the data directly into the style sheet instead of referencing an external data source. This is typically used for small images so that there are less HTTP queries to be made.

See the Wikipedia page linked in the previous paragraph for the full details of how a data URI can look like. Here's a short example (taken from the Wikipedia page) to demonstrate the principle:

ul.checklist li.complete {
    padding-left: 20px;
    background:white  url('data:image/png;base64,iVB\
ORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEU\
AAAD///+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8\
yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAEl\
FTkSuQmCC') no-repeat scroll left top;
}

Note: Whitespace is illegal in a data URI, but here the backslash escaping the newline is a feature of CSS.


Styling forms

TODO. See p.434f in the book.


Page layout

General layout strategies

Fixed layouts
A fixed layout stays put at a specific pixel width regardless of the size of the browser window or text size. This is usually achieved by specifying widths and margins with pixel values. A popular width is 960px because that fits into the ubiquitous 1024 x 960 monitors.
Fluid (or liquid) layouts
A fluid/liquid layout resizes proportionally when the browser window resizes. This is usually achieved by specifying widths and margins with percentage values so that elements resize proportionally. Fluid/liquid layouts are the cornerstone of what is generally known as "responsive" design.
Elastic layouts
An elastic layout resizes proportionally based on the size of the text. In this type of layout, a line of text always remains the same - the proportions of the page are tied to the typographic content. This is is usually achieved by using em units to specify things, because em is in relation to the font size. An example is this CSS Zen Garden design.
Hybrid layouts
A hybrid layout combines fixed and scalable areas.
Adaptive layouts
A combination of several fixed layouts, each of which takes effect only when the browser meets certain criteria. For instance, fixed layout 1 is used for desktop browsers, fixed layout 2 is used for tablet devices with medium-sized screens, fixed layout 3 is used for small screens such as mobile phones. This not a fluid layout because it does not constantly change when the browser is resized, instead it changes only in an abrupt manner at certain thresholds.


Concrete layout techniques

Multiple columns:

  • Use floats
  • Fluid or fixed layouts can also used with positioning
  • A wrapper div around the column divs is useful to horizontally center a fixed-width layout: Specify auto for the wrapper's left and right margin.


Responsive web design

The first thing to do is, make sure that the browser uses the actual screen width as the viewport width. This counters the behaviour of mobile browsers which set the viewport width to an imaginary high value to emulate a desktop browser.

<meta name="viewport" content="width=device-width, initial-scale=1" />


Images can be scaled down with this rule

img { max-width: 100% }

but this is not an ideal solution. First, requesting an image that is larger than it needs to be wastes network bandwidth. Second, a scaled-down image may start to look bad if the difference to the original size becomes too large - finer details of a logo may be lost, etc. So all in all it is better to serve an image that is as close as possible to the size that is actually needed. One way to achieve this is to use media queries. Also search the web for the keywords Responsive Images for more information on the topic.


A best practice for responsive web design is to adopt a "mobile first" mindset: Design styles for the smallest and least capable device first, and then begin overriding these styles to adapt to larger screens and more capable devices. "Mobile first" media queries tend to begin with the min- prefix, adding the overriding styles only when the width is at least the specified width or larger.


Using pixels as unit for media queries can make the choice for thresholds (aka "breakpoints") difficult because there are so many different devices out there. An alternative therefore might be the em unit which bases thresholds on the content.