When I look at new modules in the CSS spec, it makes me feel like singing the chorus from a popular Radiohead song from the ’90s:
But I’m a creep.
I’m a weirdo.
I don’t belong here.
If web standards could talk, I think a lot of them would be humming that regularly.
But hey, let’s be fair and not leave “weirdos” out of CSS3 discussions. So in this post, I’ll run through a bunch of things from the CSS specifications that you might not have heard of yet. None of this is even close to ready to use (unless it degrades really gracefully), but it will serve to get you familiar with some of the rounded corners and drop shadows of the future.
toggle() Values
According to the spec, the toggle() expression (formerly called cycle()
) “allows descendant elements to cycle over a list of values instead of inheriting the same value.”
That’s probably not the most clear explanation, so I’ll try to make it easier to understand. The example I like in the spec is the one applied to unordered lists:
ul { list-style-type: disc; } ul ul { list-style-type: toggle(disc, circle, square, box); }
With this code, the parent list will use “disc” while nested lists will cycle through “circle”, “square”, and “box”, respectively. So a list that is four levels deep will use “box”, and a 5th-level nested list will start back at the beginning of the cycle, using “disc”.
Variables (finally)
CSS variables have been talked about for a long time. Of course, if you’re preprocessing, then you couldn’t care less about this in the spec, because preprocessors add this feature out-of-the-box. But now the spec has what seems to be a more definite future mapped out for CSS variables.
Here’s some simple syntax to show you how they work:
:root { var-global-color: navajowhite; } .element { color: $global-color; font-family: var($global-font, 'Helvetica, sans-serif'); }
Custom variables are created using the “var-” prefix, then a custom name of your choosing. When you apply the variable to a property, you prefix it with the dollar sign (like in PHP). Alternatively, you have the option to use the var()
expression/function. With var()
, you’re able to provide a default value as a second argument, which will be used if the supplied variable (the first argument) is not defined.
So in the example above, the font stack would be “Helvetica, sans-serif” because $global-font
is not defined. But the color of the text (represented by $global-color
) will be navajowhite
(yes, that’s a valid color name), because we’ve defined it on the :root
element.
Box Alignment Module
The Box Alignment Module is an attempt to separate simpler alignment issues into a universal set of features that will be available in all other layout modules (flexbox, grid layout, etc).
According to the description, it “attempts to create a cohesive and common box alignment model to share among all of CSS” and defines six new properties, specifically:
justify-self
align-self
justify-content
align-content
justify-items
align-items
This new module attempts to address a couple of things:
First, these features allow for simple ways to align elements and content that mimic more powerful alignment features in other layout modules like flexbox. This means you can finally do something simple like vertically centering text in a block, without having to resort to all the code overhead of using something larger like flexbox.
Second, these new properties are intentionally generic so that they can be used across all layout modules, which is going to be a great benefit to learning the syntax for all the different layout modules.
I have to give credit and thanks to Tab Atkins for clarifying this particular module for me on IRC.
@viewport (Device Adaptation)
This one seems pretty exciting and looks to be a nice complement to media queries. From my brief look at the specification, it is intended as a replacement for the viewport meta tag.
Here’s an example from the spec:
@viewport { width: device-width; } @media screen and (min-width: 400px) { div { color: red; } } @media screen and (max-width: 400px) { div { color: green; } }
In the example above, we’re defining the viewport using the @viewport
at-rule, then defining some media queries. So if the actual width of the device was 320px, and the size of the window was 960px, then the second media query would be the only one of the two to take effect.
If not for the @viewport
rule, the reverse would happen — the first media query would apply but the second would not.
Line Grid Module
The Line Grid Module describes features “to align lines and blocks to invisible grids in the document.”
Some of the potential benefits of this module include improvements in readability through vertical rhythm, better multi-column layouts, improving the vertical rhythm of text before and after images, and enhancing paged media.
The spec also points out that this will help the vertical rhythm in East Asian layouts which require this more often than other scripts.
Compositing and Blending
The ability to combine elements with their backgrounds using various effects is nothing new to most web designers.
Some of the blending effects described in this module include:
multiply
screen
overlay
darken
lighten
color-dodge
color-burn
saturation
luminosity
Look familiar? The features introduced here are very similar to what you find in the layers panel in Photoshop, so when this module starts to get widespread browser support, it will be an easy thing for many designers to incorporate into their toolkit.
Conditional Rules with @supports and @document
This one looks super-cool, and again it looks to be in the very early stages and likely not even close to being ready for use. This module adds two new at-rules that can be used in a manner similar to how we use conditional classes or Modernizr’s helper classes.
For example, you can fork some CSS that will only be rendered if the browser supports a specific feature:
@supports ( display: flexbox ) { .example { background: blue; border: solid 1px white; } }
Additionally, you can use the @document
at-rule to apply CSS rules to certain pages, like this:
@document domain("impressivewebs.com") { body { font-size: 16px; } }
This targets the body element as long as it exists on a page on the specified domain. In addition to domain()
, you can use url()
, url-prefix()
, and regexp()
.
Final Warning
As already mentioned, these features are absolutely not ready to use, and in most cases might not be ready for some time. I believe the only one above that has any browser support is CSS Variables, which works in WebKit Nightlies. (Update: See comment from Bruce Lawson where he explains support for @viewport
in Opera Mini and Mobile). Most of the modules mentioned above have numerous red “issue” boxes, demonstrating problems that are still being worked out in the syntax and how browsers should implement them.
Of course, if we could abolish old browsers, then these types of cutting-edge features would be much closer to being used fearlessly by more developers.
If you have any further info on the statuses of any of these modules or have any corrections to any of the above, please comment. If you want more summaries and code examples on new CSS3 features, check out my CSS3 Click Chart resource which has recently been updated to include some of the above and more.
Or you can browse the CSSWG’s dev channel folder for links to all sorts of “creeps” and “weirdos” in the spec.
Is toggle() actually in the W3 spec? Or is it just a dev proposal
Also which browsers currently support the toggle() CSS expression.
Thanks.
Toggle is in the spec under its old name, cycle:
http://www.w3.org/TR/css3-values/#cycle
I’m not sure about support, but if the new name sticks, then support for cycle will be moot.
@viewport (Device Adaptation) is available now. As it was originally an Opera spec (disclosure: I work for Opera), you can use it with an -o- prefix (so @-o-viewport) in Opera Mobile, Opera Mini and Opera Mobile Emulator (the latter is the Opera Mobile codebase, packaged as a Win/ Lin/ Mac installable for ease of testing mobile layouts on a desktop).
It’s also partially implemented in IE10 with an -ms- prefix, so @-ms-viewport.
Usual story applies; do
@-webkit-viewport,
@-moz-viewport,
@-ms-viewport,
@-o-viewport,
@viewport
in the assumption that webkit and Firefox will catch up, and the unprefixed version for future-proofing.
Cool, thanks Bruce.
That works? It was my understanding @ rules can’t be delimited like that, so you’ll just have to duplicate the prefixed viewport rules.
Haven’t tested the -o- and -ms- combo yet though..
It won’t work as the whole “I don’t understand this at-rule throw out the whole declaration block” css parsers have been doing forever.
I’d imagine Bruce meant each rule on their own e.g.