I'm Tab Atkins

and I work at Google.

@tabatkins

xanthir.com/+

xanthir.com

xanthir.com/talks/2015-07-08

The (Far) Future of CSS

The Problem With CSS

CSS has 400+ properties, and keeps growing.

Cycle time from "notice there's a problem/lack" to "solution usable in all browsers" is way too long.

(Read Guy Steele, Java designer, on "Growing A Language")

What is Houdini?

CSS is the biggest "black box" remaining on the web, impossible to reach into.

Houdini Task Force lets you "escape the box".

Lets JS interact with as many parts of CSS as possible.

http://drafts.css-houdini.org/

(Many of the drafts are just placeholders for now.)

Custom Properties

:root {
  --header-color: #006;
  --main-color: #06c;
  --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), #0000);
}

Custom Properties

They look like variables, but IT'S A TRAP

Trojan horse for first "customizable CSS".

You can put anything in a custom property, and process it with JS.

Custom Properties

Currently, custom properties are optimized for variables.

Custom Props Level 2 will introduce more control over properties (inheritance, initial value, animation, etc)

Allow processing of custom values within existing properties.

Better API for responding to properties being set/changed/etc.

Current draft at http://drafts.css-houdini.org/css-properties-values-api/

Custom Properties Example

document.registerProperty({
  name: "--rotate",
  initial: "0deg",
  type: ""
  inherits: false
});
...
this.registerApplyHook({
    apply: function(el) {
      el.outputStyle.transform =
      	'translate('
      	+ el.style.get('--translate-x')
      	+ ...
      	+ el.style.get('transform');
    },
    inputProperties: ["--translate-*", "--scale-*", "--rotate", "transform"],
    outputProperties: ["transform"]
});

Custom Properties Example

#myElement {
    --translate-x: 5px;
    --translate-y: 10px;
    --rotate: 10deg;
    --scale-x: 25;
    --scale-y: 25;
}

.foobar {
    --rotate: 20deg;
}

Where else can we go?

Now that we've got our foot in the door, what else can we do?

Easy to find a few more CSS constructs that can be made extensible.

Custom Media Queries

Declarative form is easy:

@custom-media --small-screen (max-width: 600px);
@custom-media --medium-screen (min-width: 600.01px) and (max-width: 1000px);
@custom-media --large-screen (min-width: 1000.01px);
...
@media (--small-screen) { ... }

Custom Media Queries

Imperative form shouldn't be too difficult either:

CSS.customMedia.set("--bar", true);
CSS.customMedia.set("--baz", 500);
CSS.customMedia.set("--qux",
     new MediaQueryList("(width >= 500px)"));
@media (--bar) { ... }
@media (--baz >= 600) { ... }
@media (--qux) { ... }

And further...

Custom at-rule example

@--svg my-image {
	@defs {
		@linear-gradient id="fade" {...}
	}
	@rect x="5" y="5" width="100" height="200" fill="url(#fade)";
}
.foo {
	background-image: --svg(my-image);
}

Aside - Container/Element Queries?

Browsers are planning to add resize listeners to all elements (currently only works on windows and iframes).

That, + custom at-rules, gives you everything you need to do a 95% correct implementation of container queries in JS.

This is good, because that last 5% (which a browser implementation would need to do) is hard, but usually unnecessary.

Faster iteration, yay!

Custom Layout

Flexbox and Grid took so long, but we're so hungry for better layout, they're still useful.

Turnover cycle on layout is way too long.

Layout is a hard problem.

Layout "below"

Existing layout modes are responsive to "natural" size of children.

This is hard to measure today.

Hacks include using an off-screen iframe to measure the laid-out size of elements without disturbing the current page.

(Read the Flexbox Layout Algorithm for examples.)

Layout "above"

Existing layout modes know how to tell their parents about their own "natural" sizes, which enables auto-sizing, used everywhere.

Impossible to do well today without hacky/slow resize handlers.

(Read the CSS Sizing spec for details.)

Layout is hard

Layout is heavily optimized today, and switching between browser and JS repeatedly is expensive.

Looks like solution is "layout worker" - separate, dedicated scripting context with no outside-world contact.

Custom Paint

Let JS hook into the CSS painting process, and generate images on the fly.

First stage is the paint() function, which calls back to JS.

Current draft at http://drafts.css-houdini.org/css-paint-api/

Also likely going to use a "paint worker".

Custom Paint Example

No code yet, because API is up in the air, but...

Have you seen Lea Verou's conic-gradient() polyfill?

Her approach is smart, but has inherent limitations. Custom Paint can make it work right.

Custom Scroll

Another non-obvious extension point.

Layout effects responding to scroll properly is hard. (Think position:fixed, or parallax, or pull-to-refresh, or large headers shrinking+sticking when you scroll down.)

Exact form of control/responsiveness still being debated. Maybe "scroll worker"?

The End

Ask Me Anything - I Am A Spec Writer

@tabatkins

xanthir.com/+

xanthir.com

http://xanthir.com/talks/2015-07-08