Bert Bos | CSS, une petite selection

CSS, une petite selection

mini-tutoriel CSS 3

Cascading Style Sheets

Bert Bos (W3C) <bert@‌w3.org>

Blend Web Mix
Lyon, France
1 octobre 2013

Today's topics

Generic Print focus GUI focus
Stable Selectors 3,
Values and units
Multi-column layout Flexible box layout,
Conditional rules
Development Text GCPM Transitions,

Designed for typography, but also used for apps

Used by nearly all Web pages, most e-books, most printed books

Complex specification: 60+ modules, many still in development

CSS structure

CSS structure

CSS structure – features

CSS has many features. “Feature” isn't a technical term, but it has to do with things that can be tested: each keyword, each kind of selector, each type of value for a property, but also syntax features such as cascading and inheritance. The set of features is still growing, we don't know yet what CSS will eventually consist of.

CSS structure – levels

Originally we didn't intent CSS to be very big. It was to be a simple language that just about everybody could learn, that delivered good typography, but not necessarily complex layouts.

The current level 2 is close in size to what CSS was supposed to be. That was still much too big for the browsers around 1996, so we split it in two levels.

But in 1998 we had to leave things out of level 2, too. E.g., we replaced template-based grid layout (see css3-layout) by absolute positioning, left out vertical text and some properties related to pagination and books, and decided to postpone the handling of mathematics.

At the same time the implementers and users wanted more (although at a slower speed) and so we decided to take it slowly until 2000 and then add a level 3.

CSS structure – modules

CSS became very popular and professional users wanted us to extend it, rather than design a complementary language. (We did make XSLT and XSL-FO, and they are very successful with book publishers, but not with Web designers.) And so CSS level 3 soon became so big that we couldn't write it all in one specification. It would be too big and take too long.

So we decided to split CSS in modules. Eventually the whole of CSS should be defined by modules and the old level 1 and level 2 specifications will be obsolete, because all of their features are described in some module of level 3.

After some modules were finished, we found that people wanted their features to be extended even more, and we decided that it was best to add a level 4, so that we didn't have to make even more modules, but could keep the same name. Thus, e.g., we have started a Backgrounds & Borders level 4 and a Selectors level 4.

But there are very many modules and in the Working Group we keep splitting and rearranging modules whenever some features take more times than others. Modules are primarily for the benefit of the Working Group itself. They are difficult to explain to users.

We decided that users needed something easier. We don't really have the resources to do much for authors (we hope other people will write documentation for them, e.g., on W3C's new WebPlatform.org), but we can do something for one class of users, viz., implementers. We decided to publish a “Snapshot” every once in a while to document the features that were ready to be implemented.

In principle, implementers can implement everything that is a Recommendation or a Candidate Recommendation, but for extra safety our snapshot includes only Candidate Recommendations with which we already had some experience, so that we know they are really stable.

CSS structure – 2010

So far we published two snapshots. Their names aren't very attractive, we know. We just called them after the years we wrote them: 2007 and 2010. Maybe we'll come up with something more catchy for the next one…

The 2010 snapshot differs from the 2007 one only by the inclusion of the Media Queries specification. Of the many drafts we published between 2007 and 2010, only that one was stable enough to be added.

The next snapshot may include one or more of the new Values and Units, Backgrounds and Borders, Multi-column, Image Values and Speech, depending on how we evaluate their stability. We haven't decided that yet.

Unfortunately, the demand for new features has been such that we have mostly been writing new, unstable modules and haven't had time to finish the stable ones. So, instead of making a snapshot for 2013 that is hardly bigger than the one for 2010, we might wait until next year…



Selectors – principles

For CSS, a document is always a tree with two kinds of ordered nodes:

Elements have

In HTML, SVG, etc., the classes are carried by one of the attributes.

Inside and outside the tree

CSS has a handful of pseudo-elements, because typographically interesting components do not always correspond exactly to an element in the document: ::first-line for the first line of a paragraph, :first-letter for the first letter letter or letter combination, ::before for a piece of text that doesn't occur in the document but is implied by the mark-up, etc.

De semantics of hyperlinks will maybe be expressed in CSS some day. Hyperlinks are on the edge of semantics and style and it is difficult in this case to keep them separate. In princip;le, the fact that something is a link is semantics, but whether to present the link as a hyperlink, a transclusion, or something else is style…

XLink and HLink have been attempts to capture the semantics in XML, so that other technologies, such as CSS, could build on it. But they haven't been very successful. Opera has proposed CSS properties ('-o-link').

New in level 3

Sibling elements

E ~ F
an element F that has elder sibling E

  <h1 id=french>French...</h1>
  <h1 id=english>English...</h1>
#french ~ p {
  font-weight: bold;
  color: #077;
  font-size: 1.4em;
  padding-left :1em;

Negation selectors

an element E that doesn't match s

img:not([alt]) {
  border: 10px rgb(147,103,94) solid;
  border-radius: 10px;

':First-child' is in level 2. In level 3 we generalized the pseudo-class to select the n'th child, or the first n children, or every n'th child starting with the m'th.

More about ':nth-child()' below.

Last element of a certain type

an element that is the last element of type E in its parent

  border-bottom:2px solid red

The n'th child / every n'th child (1/2)

every second child starting with the 4th (i.e., children 4, 6, 8, 10, etc.)

td:nth-child(2n + 4) {
  background:rgba(29, 53, 91, .3);

Note: no space between the “2” and the “n”!

The n'th child / every n'th child (2/2)

The n in an + b stands for all whole numbers ≥ 0 (i.e., 0, 1, 2,…)

If a or b is 0, you can omit that part:

Negative numbers are allowed (and sometimes useful):

Empty elements

an empty element (no text, no children)

th:empty, td:empty{
  background:rgba(253,143,149, .5);

The target of the current URL

the element that is pointed at by the current URL, e.g..:


From the demo:

:target { border:4px gold solid }

If you follow a link to somewhere in the middle of another document, then you can give the element that you jumped to a special style by means of ':target'.

Of course, you can also jump within the same document, e.g., from the table of contents to a section. Some tricks rely on jumping within a document to change the style of the document with every click, such as showing and hiding tabbed cards. (But hopefully one day we'll have ways to do such style changes directly, without the limitations of this trick.)

Selectors exercise

How would you make a document that allows you to switch which of two texts is visible?

Hint: you can do this with :target and ~, or with :checked and ~ (What is the advantage of :checked over :target in this case?)


Multi-column layout

Multi-column layout

Two ways to use columns

Two ways to use columns:

And if the element is narrower than the desired width of one column, there will be only one column and it will be narrower than what 'columns' specified.

Unbalanced columns

If an element has a fixed height, columns can be filled in two ways:

In both cases it is possible that there is too much text. In that case, extra columns are added on the right side, outside the element's box. Whether they are visible depends on the value of overflow.

Text that spans columns

From the demo:


<P>Lorem ipsum dolor...
<P>Nulla sagittis, odi...
<P>Lorem ipsum dolor...
<P>Nulla sagittis, odi...


body {columns: 18em}
h2 {column-span: all}

Numbers (column-span:3) may come in CSS level 4




Lets style changes, such as for :hover or :focus happen slowly

li#transition {
  transition: 1s;

(transition is actually a shorthand property)

May 2013: Firefox ok, Opera ok, Safari with prefix, Chrome ok, IE ok

Transition property

Step 1: Specify which properties should transition slowly

transition-property: all;
transition-property: none;
transition-property: background-color;
transition-property: background-color,
  height, width;

(Normally not necessary, because default = all)


Step 2: Specify how long the transition should take

transition-duration: 2s;
transition-duration: 4000ms;
transition-duration: 4000ms, 8000ms;

Note: usuallly transition-duration on its own is sufficient, because the default for transition-property is all

In practice a transition duration of less than half a second is enough. Sufficient to draw attention but not so long to slow as the user down.


Step 3: Speed at every moment of the transition

ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier(<number>, <number>, <number>, <number>)

transition-timing-function: ease;
transition-timing-function: ease, linear;
  cubic-bezier(0.6, 0.1, 0.15, 0.8);

Default: ease

Cubic bezier

ease is the same as cubic-bezier(0.25, 0.1, 0.25, 1.0)
linear is the same as cubic-bezier(0.0, 0.0, 1.0, 1.0)

Timing function

cubic-bezier(0.6, 0.1, 0.2, 0.7)

Cubic bezier

Define your own timing function

:nth-child(1):hover {
   cubic-bezier(0.3, -0.3, 0.7, 1.3) }


Transforms for hover and focus

blur menu
polaroid table

Conditional rules

Conditional rules

Conditional rules

The module defines:

Syntax 1

Test for a supported property and value

@supports ( display: flex ) {
  body, #navigation, #content { display: flex }
  #navigation { color: gray }

The rules are only applied by a UA that knows the property display and the value flex

UAs that do not know @supports itself will of course skip the whole at-rule…


From the demo:

@supports (display: flex) {
  .supports.flex {display: block}

Values and units

Values and units

Values and units – contents

cm, mm, in en pt are unfortunately no longer useful on screen media. So far there is no replacement.

Expressions: calc()

For calculations ( + - * / ) that depend on the current rendering

From the demo:

p.framed {
  border: 10px solid gold;
  padding: calc(2em - 10px) }
p.unframed {
  padding: 2em }

The two boxes have the same width

Calc() syntax

„+” and „-” must have spaces on both sides

Only values of the same type can be added: calc(1em + 2s) is wrong

Division (/) only by numbers: calc(100% / 10em) is wrong

Division by 0 is evidently not possible

(May 2013: FF ok, IE ok, Opera no, Safari 5 no, Safari 6 with prefix, Chrome ok)

Values out of range

The -1em is ignored here and the result is 2em:

div {
 padding: 2em;
 padding: -1em  /* ignored, must ≥ 0 */ }

but not here:

div {
 padding: 2em;
 padding: calc(0px - 1em) /* accepted */ }

(-1em is still impossible, the nearest valid value, 0, is used)

The '-1em' is caught as an error when the syntax is checked and the line is simply ignored. But calc() values can only be checked for the correct type (length, number, time…). The value depends, in general, on the element it is used on, and thus no attempt is made to check it except for division by 0. (Division by zero can be checked, because it only involves numbers, never units.)

The end



To Lead the Web to its full potential

To Anticipate the Trends

To Increase your company value

Join W3C


or contact: Bernard Gidon <bgidon@w3.org>


Pour Développer le potentiel du Web

Pour Anticiper les évolutions technologiques

Pour Augmenter la valeur et visibilité de votre organisation

Rejoigner le W3C


ou contacter : Bernard Gidon <bgidon@w3.org>

Bert Bos <bert@w3.org>
GPG fingerprint: 7744 0204 52A5 14D9 147D
2A13 2D7A E420 184B 5BA4