CSSOM, Vars, Mixins, etc.
Intro
I'm Tab Atkins, and I work on Chrome and CSS.
Hey! Slide decks aren designed for talks, not for reading
like a web page. I wrote a blog
post going over the same stuff, just with more talking and better organization.
Quick TOC
- Why the CSSOM sucks
- How we're fixing it
- CSS Variables!
- CSS Mixins!
- CSS Nesting!
- CSS Modules!
CSSOM
- The interface between javascript and CSS
- Totally string based
- Only virtue is that it exists
el.style.width = num + "px";
el.style.backgroundImage = "linear-gradient(" + color1 + "," + color2 + ")";
Why?
var w = parseFloat(el.style.width);
Better hope it's in px, not em or % or something more esoteric like vw!
The browser already knows how to convert between the values; why should you
have to do it again (probably with bugs)?
New CSSOM Values API
(Syntax not finalized.)
The browser deals with CSS as concrete values, not strings. We can expose
the same thing to you.
el.style.values.width.px += 100;
el.style.values.color.red = 255;
var emwidth = el.style.values.width.em;
var shadowColors =
el.style.values.textShadow.l.map(
function(s){ return s.color.cssText; }
);
JS development always features CSS manipulation heavily.
These should make it much easier/faster/less buggy.
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.
We're hoping enough agreement has crystalized that a strong experimental
implementation can crash through the barriers.
Var Example
@var header-color color #006;
@var main-color color #06c;
@var secondary-color color #c06;
a { color: var(main-color); }
a:visited { color: var(secondary-color); }
h1 {
color: var(header-color);
background: linear-gradient(left,var(main-color), transparent 25%);
}
Variables are typed. Every primitive value type, every property, and a few
extra convenience types exist.
This lets us expose the new CSSOM stuff on them:
document.styleSheets[0].vars['main-color'].alpha = .5;
Variables are global normally - any rule in the document can access it.
Local Variables can scope a var to a single declaration block, for use in
simplifying complex expressions:
.foo {
@local grad background-image radial-gradient(red, blue, green, ...);
background: url(foo.png), var(grad), blue;
}
CSS Mixins!
Mixins are blocks of rules that can be "mixed in" with normal blocks of rules.
They promote reusability when it's not appropriate to decorate the HTML
with extra classes.
CSS Preprocessors like LESS pioneered here.
Mixin Example
@mixin error {
background: #fdd;
color: red;
font-weight: bold;
}
div.error {
border: thick solid red;
padding: .5em;
@mixin error;
}
span.error {
text-decoration: underline;
@mixin error;
}
Mixins can also take parameters, which function like local variables:
@mixin rounded-corners(size length 8px) {
-moz-border-radius: var(size);
-webkit-border-radius: var(size);
border-radius: var(size);
}
.foo {
@mixin rounded-corners(1em);
}
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
Nesting Example
#main > header > h1 {
font-size: 2em;
background: blue;
color: white;
@this > a {
color: #ddf;
@this: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
CSS Modules!
Vars and Mixins are global by default
This is bad for widgets and similar, because they might clobber the author's
Vars and Mixins, or be clobbered themselves
Simple namespacing/modules/whatever to fix this
Module Example
@module foo {
@var bar color red;
@mixin baz { color: blue; }
}
.foo {
color: var(bar); // Doesn't work!
}
.bar {
@use foo;
color: var(bar); // Works!
}
.baz {
@mixin foo|baz; // Works!
}
Modules can be nested for further namespacing.
A single decl block can @use multiple modules.
So far, only vars, mixins, and more modules can be put in a module.
Great! ICANHAZNAO?!?
No, you cannot haz yet.
Only experimental, not in nightlies yet.
Spec will be produced this quarter.
Goal is experimental implementation in other browser before the end of the year.
Outro
Questions? Gimme your name and a random number first. I'll give out some
books based on them.