I'm Tab Atkins

and I work at Google.




The Future of CSS

...or at least, some of it.

Image Values

Gradients have changed over time...

Use an element as an image!

The image() function

Basically a souped-up url()

A few other bits

Specify the resolution of the image, so you can use high-res images (for printing) that are sized properly.
Rotate an image by 90deg increments. This affects layout, unlike rotate() transforms.
object-fit, object-position
Size and position an image within its content box.


Revival of an old 2003 spec

Defines the ::marker pseudo-element

Defining your own list-style

@counter-style leaves {
	type: repeating;
	glyphs: url(leaf1.jpg) url(leaf2.jpg) url(leaf3.jpg);

@counter-style binary {
	type: numeric;
	glyphs: "0" "1";

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


Basically, display:block for applications.

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

Is nearly done being rewritten right now, and is currently being re-implemented in Chrome (other browsers should follow shortly).

Basic Example

Thousands of household uses!

Combining an input and a button

<div style="display: flexbox;">
	<input style="width: flex(); display: block;">

Thousands of household uses!

Horizontal navigation bar

	ul { display: flexbox; }
	li { width: flex(); }

Thousands of household uses!


	.accordion {
		display: flexbox;
		flex-flow: column;
		flex-pack: start;
	.accordion > section {
		height: 0;
		overflow: hidden;
	.accordion > section.active {
		height: flex(1);
<section class=accordion>
	<h1>First section</h1>
	<section>Cool stuff to show in this section</section>

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.


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

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

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

rem is the em from the root element

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

The calc() function

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

calc(50% + 20px)

calc(100% / 7)

The attr(), cycle() 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 as px, 100px);

cycle() takes several values, and "cycles" between them with each nested use

em { font-style: cycle(italic, normal); }

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.

td:col(col.foo) 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; }

The End?

Questions and Answers




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 very rough agreement on the solution, and are starting experimental implementations.

Var Example

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

CSS Nesting!

Stylesheets often have tons of repetition in the selectors.

"#main > header > h1", "#main > header > h1 > a", "#main > header > h1 > a:visited", etc.

Verbose, hard to read, prone to hard-to-see errors

Old and Busted

#main > header > h1 {
  font-size: 2em;
  background: blue;
  color: white;
#main > header > h1 > a {
  color: #ddf;
#main > header > h1 > a:visited {
	color: #fdf;

Nesting Example

#main > header > h1 {
  font-size: 2em;
  background: blue;
  color: white;
  & > a {
    color: #ddf;
    &:visited {
      color: #fdf;

Just syntax sugar for the long-form stuff.

Again, CSS preprocessors led the way.

Shorter stylesheets, better organization mean faster app development.

Explicitly indicates scoping opportunities, which might be useful for browser perf

The End

Questions and Answers