CSS @supports directive and its JS twin. Ready to use!

Yesterday I have read the great article «@supports will change your life» by Charlotte Jackson. And finally I have found time to dive more into this old-new feature. Let’s have a quick overview of it.


Developers are lazy creatures. That’s why browsers forgive us a lot. They quietly correct many common HTML errors and makes life easy for us. If talking about CSS, browsers work a bit different. They don’t correct our errors, but ignore lines of code that they don’t understand. So, we can use new CSS features and browsers, which don’t support them, just won’t apply them. Sounds nice, but not always result will satisfy our needs. It’s a good practice to build modern stylish markup while ensuring it still looks nice in older browsers. Let’s consider you want to style your text with an initial letter — a form of decoration used at the beginning of a paragraph. The initial letter takes several lines deep and indents the body text:

There is a modern way to achieve that — CSS property initial-letter:

p::first-letter{
margin-right: 0.5em;

color: red;
font-size: 20px;

-webkit-initial-letter: 4;
initial-letter: 4; // how many lines of text letter will go deep
}

It is supported only by latest Safari. Let’s take a look to result:

You may check code at Codepen

On the left side we can see the screenshot of Safari browser, on the right — Opera/Chrome. Usual size red letter “L” with right offset doesn’t look good at all. In this case relying on browser forgiveness doesn’t work anymore. To prevent such unpleasant result, you will need to check if browser support particular feature.


CSS feature detection via JavaScript is a common client side practice (old good Modernizr). The same functionality hasn’t been available within CSS until @supports. And now we have it in every browser except IE11. So, let’s take a look to example:

@supports (display: flex) {
div { display: flex; }
}

@supports directive looks the same as @media query in your CSS code. It allows you to check style support in several different ways. The one above is a simplest one. You can also use not/or/and operators to create more complicated expressions consisting of several original ones, pretty the same as you do with @media queries. Check API and examples at MDN. Back to our initial letter, your code now may look like that:

@supports (initial-letter: 4) or (-webkit-initial-letter: 4) {
p::first-letter{
margin-right: 0.5em;

color: red;
font-size: 20px;

-webkit-initial-letter: 4;
initial-letter: 4;
}
}

So, no decoration by default, only for browsers, which support initial-letter property. Btw, I took this awesome example from a «Real Art Direction on the Web» talk by Jen Simmons. Check it, you wan’t regret.


The JavaScript twin of CSS @supports is window.CSS.supportsstatic method which returns a Boolean value indicating if the browser supports a given CSS feature, or not. There are two ways of calling it:

var result = CSS.supports("display", "flex");
// or
var result = CSS.supports("(display: flex)");

So, the difference is in a set of parameters. The first one allows to test the support of a pair property-value. The second one takes one parameter matching the condition of @supports. Browser support for this method is almost the same as for @supports directive — all modern browsers, except IE11, and partial support for Opera Mini (it uses old syntax window.supportsCSS). So, if you work with IE11 and lower don’t forget to do a check:

var supportsCSS = !!((window.CSS && window.CSS.supports) || window.supportsCSS || false);

That’s it! I do recommend you to check Charlotte Jackson’s article. It’s really great and will definitely convince you to start using this feature, if you still have doubts.


And don’t forget to support those you love ❤ «Anyone can show up when you’re happy. But the ones who stay by your side when your heart falls apart, they are your true friends» © Brigitte Nicole.


Thank you for staying with me until these words ❤ I like to chat, so looking forward to hearing from you. Have a nice day!