The Future of CSS


CSS used to be kinda boring. You would apply some fixed style to a sector and pretty much just hope that the user's browser supports it. Doing things this way is a bit slow, difficult to maintain, and mostly relies on JavaScript for feature detection.

How much has this changed? Well, obviously that depends a lot on the browser, but as far as CSS itself goes things are very different.

Fixed style/units

This is pretty old news, but worth at least a quick mention - CSS has new relative units. Sure, we've had em and % for quite a while now, but they are often an inadequate solution. Their effects are relative to their parent element's value, which isn't always what we would want. Often, what we really want is to have them relative to some “master size” because that is much easier to follow and keep track of. Also, this allows changing the font size in a single place to change all other sizes.

Well, I'm glad to say that such a unit does exist and is called the “rem”. It's pretty easy to use - just set the font size on :root and that defines the size of 1rem. Afterwards, you can use 0.75rem anywhere and it will result in a size three-quarters of that.

That's great, but it still ultimately results in “fixed style” because everything ends up being some scaled version of a fixed size. This might be true... If you set the “master size” in any of the old units. Fortunately, CSS now also has viewport units, which are relative to the size of the screen.

Viewport units come as a few new units that are relative to the size of the viewport (visible area in a browser window). Here's a quick list of what each is

  • vw: 100vw is equal to the full-width of the viewport
  • vh: 100vh is eaual to the full height of the viewport
  • vmin (vm in IE 9): Same as vw or vh, but it represents the lesser of the two
  • vmax: Same as vmin, except the greater instead of lesser

You can now set the font size on the root element to any of these units (probably vw or vmin) and all rem units will be relative to the viewport. Combine this with @media and you'd be well on your way to a fully responsive site. And, as an added bonus, if most or all of your sizes are rem you can change the sizes of an entire layout by changing a single value!

Difficult to maintain

“Responsive units make it possible to change the size of everything in a single place, but what about everything else?”

CSS has long been a declarative language. It has been a language where you declare a value for a property and tell it where to apply that rule (not in that order, of course). It hasn't been able to use any functions or variables, requiring instead to have everything explicitly defined. This too is changing.

Did you know that CSS can now do mathematical operations (basic arithmetic)? Yep, it's true. CSS now has a calc() function! It is now possible to adjust an element's position according to its size, assuming you know both. This has always been possible if you use static or similar units (px), of course, it's just a lot easier now, and it's also now possible to do this using a mixture units. You can now do something similar to the following:

#someId {
   width: 10vw;
   position: relative;
   left: calc(100% - 5vw);
}

You may not realize how useful this is until you actually need to use it. Being able to set size or position based on a mixing or relative units was not possible before, as their values would not be known until run in a browser. You can never know what 80% - 15px was, but now you are able to let the browser make these calculations.

And now for the big one - one that we have long been waiting for. Variables!

That's right, CSS now supports variables and this opens up an entire world of possibilities. We've had LESS and SASS for a while now, but being able to use them directly in a browser while updating the style for a website in good ol’ CSS cannot be beat!

The color pallete used on a site is usually pretty simple, consisting of a small number of colors that are used again and again. Backgrounds and borders, and sometimes font colors are usually set by a few basic colors. A designer might use the same color for a border in one place and the same color for a shadow somewhere else. As a result, any given stylesheet is likely to reuse the same color in numerous places. In a text editor, the can be easily updated using a search-and-replace, but this is not really a practical solution, and being able to see the changes as you make them is less frustrating and will immediately make a designer aware if what they're doing will work with the design or not.

There are an infinite number of uses for variables in CSS, but I think that setting a color pallete is the best example of how useful they can be. You can use them for pretty much anything you want to. To get the most convenience out of them, I would suggest setting all of them near the top of your stylesheet (in html or :root) and making use of a small number of variables as often as possible. My default stylesheet for this site contains three colors that I use to create borders, backgrounds, shadows, etc. My recent redesign of the site involved modifying these three variables and changing the background, and that changed almost the entire look of everything.

To use CSS variables, you just define it using --some-var and use it wherever as var(--some-var). Anywhere you use a variable, it must be preceded by --. Pretty simple, though I do wish that the -- wasn't required when retrieving a value, as it seems unnecessary since it already requires var().

Feature Detection

Any developer who has ever worked on anything intended to be viewed by the public should be well aware of the need for feature detection. It is an unfortunate fact of life that not all browsers are equal, and there are times where you'll want to do something in your CSS that will improve the experience of a user in a modern browser but might also ruin it for someone using an outdated browser. For example, one thing you might want to do is to have outlined text using text shadows to make light colored text against a white background easy to read. While this might look cool, it makes it extremely difficult to read for those using browsers that don't support shadows. What you would want to do is apply the style you want to browsers that support the required features, but offer a fallback to browsers that don't.

Until recently, detecting whether or not a feature was supported required JavaScript such as Modernizr. The basic idea was that you create classes for features on some element such as html, and then use those classes as part of selectors in CSS. This works well enough, and it is something you absolutely should do for now, but CSS has given us a better solution in the form of @supports.

Unlike the JavaScript version of feature detection, the CSS solution allows multiple selectors and rules to be grouped together according to whether or not a feature is supported. Also, since it is the browser that determines whether or not it supports a given feature, it is less likely that you will get false positives or negatives. Unfortunately and somewhat ironically, there is no way of checking for support of @supports itself in CSS, meaning it's probably best to apply a default style and only use CSS's feature detection method as progressive enhancement. This feature, above all others, I wish was added to CSS long ago. It is supported in more recent versions of Firefox, Chrome, and Opera only - no IE or Safari.

Using these today and the future of CSS

Zero of these features are supported in IE8, which is sadly still a very common headache. Even in modern browsers, support is fairly limited (variables being only supported in the most recent version of Firefox). Solving this issue is the goal of Myth, but even then it cannot add support for anything that happens in the browser. So, unless you're willing to write-off browsers that are used by a very significant percentage of users, you should be careful about implementing any of these features. Myth does a pretty decent job at handling variables by outputting a stylesheet where all variables are replaced by their values, its support for calc() applies only to similar units, which makes it essentially useless (we can calculate 80% - 5% fairly easily, and it won't be able to do calc(80vw - 15px)).

The future that CSS is showing is, however, is very promising. Perhaps a decade from now, variables will be supported as well as padding is today. And when that day finally comes, there will be new features with very limited support, but at least we will be able to easily check for support of the cutting-edge features of next decade.

Until then, here is something that we have to look forward to.

Often, a developer might make multiple variations of a site by making variations to a color pallete, for example, but the rest of the CSS will be exactly the same. You could have the style for each site contained in a single stylesheet and use @import to import a set of variables to theme that particular site. If you want to load all of your CSS in a single request, you could instead apply those variables according to domain using @document. Either way makes updating the style of multiple websites quite a bit easier.

All-in-all, CSS is offering us the ability to style a page based on factors such as size, location, feature support, and a variety of media types. And those are just the ways that style can adapt to certain conditions, the features it offers that actually apply style are far more numerous and are exciting on their own.