I'm Tab Atkins

and I work at Google.





The Future of CSS

...or at least, some of it.

Image Values

Defines several useful image-related features.

It's in CR, and features are showing up and unprefixing as we speak.



Gradients have changed over time…

Gradients have changed over time…

Corner-to-corner gradients are now "magic".

Old behavior of to top right: Image of a color gradient
New behavior: Image of a color gradient

The image() function

Basically a souped-up url()

Images 4!

Now that Image Values level 3 is in CR, I've started work on level 4.


The element() function

Use an element as an image!

MozHacks article

Conical Gradients!

conic-gradient(red, yellow, lime, cyan, blue, magenta, red)
repeating-conic-gradient(20% 20%, white 0deg 20deg, transparent 20deg 40deg)

Improvements to color-stop syntax

Color and position can be in either order.

"white 20%" === "20% white"

A color-stop can have two positions, defining a "stripe"

"red 33%, white 33%, white 67%, blue 67%"
"red 33%, white 33% 67%, blue 67%"

Improvements to color-stop syntax

Omit the color and have it automatically computed for you, for making non-linear transition curves

"black, #333 5%, #666 10%, #999 15%, #ccc 20%, white"
"black, 5%, 10%, 15%, 20%, white"

cross-fade() function

Smoothly fade between two images. Already works in WebKit (with an older syntax), and is used by CSS animations!

cross-fade( ?  [,  |  ]? )

image-set() function!

image-set("normal.png" 1x, "high-res.png" 2x, "print.png" 500dpi)

Lets you specify multiple resolutions of an image, and the browser will automatically choose which one to download, based on the screen's resolution and the current network speed.


Provides hints to the browser about how it should scale images.


Revival of an old 2003 spec


Counter Styles!

Split off from Lists this year


Defining your own list-style

@counter-style stars {
  type: repeating;
  glyphs: url(star1.jpg) url(star2.jpg);
  suffix: '';
✩  One
✪  Two
✩  Three
✪  Four
✩  Five
@counter-style binary {
  type: numeric;
  glyphs: 0 1;
1.    One
10.   Two
11.   Three
100.  Four
101.  Five

Defining your own list-style

@counter-style dice {
  type: additive;
  additive-glyphs: 6 ⚅, 5 ⚄, 4 ⚃, 3 ⚂, 2 ⚁, 1 ⚀;
  suffix: ’‘;
⚀    One
⚁    Two
⚂    Three
⚅⚄   Eleven
⚅⚅   Twelve
⚅⚅⚀  Thirteen


Phase 1 of making CSS actually handle layout

Dumps much of the text-related complication in favor of simpler, more useful abilities.

Been in CR for a few months, and unprefixed implementations are emerging as we speak.


Four distinct improvements

  1. Layout direction with flex-flow
  2. Source-order independence with order
  3. Vertical and horizontal alignment (centering!) with the justify-* and align-* properties
  4. Flexiblity with flex

Grid Alignment!

Finally, a layout system designed for pages.

Slice the page into cells, and position elements into those cells.

No extraneous markup, no source-order dependence, fully flexible.


Grid Alignment!

grid-template: "a c"
               "b c"
               "d d"
               "e e";
#title { grid-cell: a }

Grid Alignment!

grid-template: "a d"
               "c d"
               "b e";
#title { grid-cell: a }

Values & Units


This spec defines all the basic value types that CSS uses across its specs

Also defines the syntax used in property descriptions, if you ever wondered what the hell "&&" meant in a spec.

Some useful new units

rem is the em from the root element

ex is relative to the font's x-height, similar to the em

ch is the width of the "0" (an 'average character')

vw, vh, vmin, vmax units are relative to the size of the window

The calc() function

Lets you do math in CSS, combining things that are comparable

calc(20px + 3em + 40%)

calc(100% / 7)

linear-gradient(to right, white, silver calc(50% - 10px), silver calc(50% + 10px), white);

The attr(), toggle() functions

attr() lets you pull values from attributes on the element

Useful for implementing the UA stylesheet, or for styling based on data-* attributes

width: attr(data-size px, 100px);

toggle() takes several values, and "toggles" between them with each nested use

New Selectors!


The first module to hit level 4!

Selectors are getting pretty powerful now

Column pseudos

In HTML, the column of a cell is indicated implicitly, rather than directlly through nesting. This makes it impossible to style an element based on its column, except for the 4 properties that the spec allows <col> to have.

col.foo || td selects the cells within the column that matches "col.foo"

td:nth-col(n) and td:nth-last-col(n) work in the expected way

Link pseudos

:any-link is :link done right - matches both visited and unvisited links

:local-link matches links to elsewhere in the same page

:local-link(n) matches based on subsets of the path - :local-link(0) looks only at the domain, :local-link(1) looks at the domain and the first segment of the path, etc.

Time pseudos

Only useful for presentation formats that are time-based, like karaoke captions in an HTML <video> or a screen reader

:current matches the current active element

:past and :future matches elements that have already been passed, or haven't been hit yet, respectively

video::cue(:past) { color: red; }
video::cue(:future) { color: white; }
/* Bouncing ball left as an exercise for the reader */

The Reference Combinator

Lets you follow IDREF attributes in the selector, like <label for=foo>

label:hover /for/ input { outline: thick dotted red; }

:nth-match() - selector indexing

li.foo:nth-child(even) doesn't do what you want...

li:nth-match(even of .foo) does!

CSS Variables!

Variables! In CSS! OMG!

A common request for literally over a decade.


Why so long?

Previously, discussion was paralyzed by indecision and argument.

Now we have agreement on the solution, and are finishing experimental implementations - both FF and WebKit are nearly ready to ship!

Var Example

:root {
	var-header-color: #006;
	var-main-color: #06c;
	var-accent-color: #c06;
a { color: var(main-color); }
a:visited { color: var(accent-color); }
h1 { 
  color: var(header-color);
  background: linear-gradient(var(main-color), transparent 25%);

The End

Questions and Answers