How to Use CSS Feature Queries

How to Use CSS Feature Queries

The world of web design is ever-changing and it’s exciting to keep up with new design trends in CSS. If you are an early CSS adopter, you may already be looking forward to using things like CSS Grid Layouts, CSS Blend Modes, or something with typographic flexibility that allows an easy way to create drop caps with CSS.

With so many new advances in CSS, it’s exciting to know that new ways of designing websites are in the realm of possibility. Traditionally, designers would have to wait to build sites with these new techniques because of the browser support problem. You don’t want to build your clients a site that most browsers can’t support, right? This can often be disappointing for those who are “designing ahead,” but not all hope is lost. More often than not, there is a way to create a good experience for all users, no matter what browser they are using. There’s not much we can do to force the desired browser support of our clients, but there are ways we can bring our designs to life, even with limitations. That’s where CSS Feature Queries come in.

How to Account for Uneven Browser Support in Web Design

Do the terms “graceful degradation” and “progressive enhancement” ring a bell? They are probably two terms that you use regularly when discussing ways to help with the limitations of older browsers. Even if you do not call these approaches by name, you’ve probably most certainly put the concepts of these into action.

Before diving into CSS Feature Queries, it’s important to understand common ways of addressing browser inconsistency. These two approaches have been around much longer and offer two different ways of design thinking.

Graceful Degradation

Aside from sounding like a band name from the 90s, graceful degradation uses the idea of providing all the bells and whistles in more modern browsers, but will “degrade gracefully” to a lower level of functionality in older browsers.

It is tempting to go for the “wow” factor all the time by using all the new shiny CSS attributes that you can, but it’s important not to lose focus on what’s most important, which is the actual site content. That is why your visitors are there; they need to be able to easily view and interact with the site content. In the older browsers, the experience may not be as nice, but it will provide your users with an adequate basic functionality so they can still view the content of the site without having things appear broken or missing on the page.

Progressive Enhancement

Basically, progressive enhancement is just like graceful degradation, except backwards. The approach is similar, but it does things the other way around. A basic user experience is planned out for all browsers so there is consistency with how things are rendered at a basic level, to ensure content can adequately be viewed and the user can perform any needed tasks with what is provided. More advanced functionality is then built in and will be available to the browsers that can render it.
A good way to think about it is that graceful degradation starts complex with a goal of providing a simple experience when needed. Progressive enhancements starts simple and then adds on to that with the desired feature-rich experience.

Modernizer

Modernizer is the most widely adopted tool in a progressive enhancement. Modernizr is a JavaScript library that checks if a browser supports next generation web technologies. I won’t get into all the technical details here, but basically Modernizer checks if a feature is available in the browser and returns true or false. This allows developers to test for some of the new technologies and provide fallbacks for browsers that do not support them. It becomes necessary to note when polyfills are needed.

It’s a good solution, but Modernizer requires JavaScript, which is small in size but yet still slower than only using CSS. And although it isn’t common, what happens if JavaScript doesn’t execute? That kind of defeats the purpose, which makes Feature Queries a pretty attractive option for handling browser inconsistencies.

CSS Feature Queries

CSS Feature Queries are a way to perform a browser-native method of feature detection. These queries analyze whether or not a browser has properly implemented a CSS property. Essentially, the browser “reports” on whether or not a certain CSS property or value is supported. The result determines whether or not to apply a block of CSS or not.

When using CSS Feature Queries, being in either the graceful degradation or progressive enhancement mindset is helpful. Designers can take a graceful degradation approach when certain features are not supported. Stylesheets will use the new features when available but will degrade gracefully when those features are not supported by the browser.

For the most part, there is pretty good browser support for CSS Feature Queries. Keep in mind that they are currently not supported in all browsers, particularly older versions of Internet Explorer. Be sure to reference Can I Use to get current information. Don’t be discouraged with the lack of IE support for Feature Queries. When doing your site planning, think of the overall CSS plan and what will not have support and go from there.

Feature Query Examples

To fully understand CSS Feature Queries, it is helpful to see them in action by writing small tests in your CSS to see whether or not a particular feature is supported. This will help you write and apply CSS based on what is (or isn’t) supported by a browser and optimize your page for the available set of features.

CSS Grid Layouts

Let’s take CSS Grid Layouts for example. They’ve been a hot topic in the web design community, but because they are not mainstream yet, we can use Feature Queries to test them. We will be using the @supports rule and targeting the browsers with grid support. You might notice the syntax of a Feature Query (the @ symbol) is a lot like a Media Query, so that makes them easy to write and remember.

If the browser understands display: grid, in the CSS Feature Query declaration, the styles inside the brackets will be applied. If not, it will be skipped over to our fallback.

// fallback code for older browsers (and those that do not support Feature Queries)
.content {
height: 400px;
background-color: purple;
color: white;
}
// start grid CSS

@supports (display: grid) {
.content {
grid-column-start: 3;
grid-column-end: 4;
grid-row-start: 3;
grid-row-end: 4;
background: #f5c531;
height: 400px;
}
}

As you can see, there are different styles specified, depending on if the browser supports grid layouts or not. Only experimental browsers understand display: grid currently, so they will display the following:

Example of an experimental browser display grid
How a browser that supports CSS grid layouts would render the code.

As for older browsers, they will display the fallback, which has a purple background:

How a browser that does not support CSS grid layouts would render the code.
How a browser that does not support CSS grid layouts would render the code.

Text customization with drop caps

Drop caps are a pretty nifty CSS capability that give an extra elegance to typography. This property tells the browser to letter bigger, like how drop caps are typically designed. For example, the first letter in the first word of a paragraph could be the size of five lines of text. The letter could be bold, with a small margin on the right side.

However, they are not universally supported, so it’s best to come up with a fallback that is styled similar to what a supported browser would show. In this example, we’ll use the same color, bold style, and serif font for the design. We can account for the initial-letter limited support by creating this default style as the fallback.

Let’s look at an example to create a drop cap with a different approach rather than using initial-letter. (This will be your fallback code.)

a drop cap with a different approach rather than using initial-letter. (This will be your fallback code.)
p::first-letter {
float: left;
font-size: 5em;
line-height: 1;
font-weight: bold;
margin-right: .2em;
color: #00FFFF;
font-family: serif;
}

That works, but you can create drop caps more efficiently by utilizing CSS Feature Queries and using the full potential of CSS with initial-letter. Here’s what that would look like:

@supports (initial-letter: 5) or (-webkit-initial-letter: 5) {
p::first-letter {
-webkit-initial-letter: 5;
initial-letter: 5;
color: #00FFFF;
font-weight: bold;
margin-right: 0.5em;
font-family: serif;
}
}

Notice something a little different here? We have some logic in our Feature Query with or. Currently, initial-letter is only supported in Safari 9, so this requires a -webkit prefix. It’s also a good idea to include the unprefixed version (browser support will increase in the future). Keep in mind when you’re experimenting, you can use or, and, and not in your Feature Queries.

Here is what is rendered from a browser that supports the initial-letter property:

Screenshot of what rendered from a browser that supports the initial-letter property

New image effects

There are so many new image effects that can be done with CSS. Browser support varies of course, but some of these new effects are pretty cool. Who would have thought overlays weren’t just a Photoshop layer anymore? Let’s take a look at mix-blend-modes and how they can be applied to images, when supported.

Other than determining whether or not a browser supports a specific feature, Feature Queries are a tool for bundling together CSS declarations so that they’ll run as a group. The following example looks complex, but once it is broken down, it will make more sense.

Here is a simple HTML snippet that has a class applied on the <article> tag.

&amp;amp;amp;lt;article class=&amp;amp;quot;feature-img&amp;amp;quot;&amp;amp;amp;gt;
&amp;amp;amp;lt;img src=&amp;amp;quot;example-img.jpg&amp;amp;quot; /&amp;amp;amp;gt;
&amp;amp;amp;lt;/article&amp;amp;amp;gt;

The CSS:

@supports (mix-blend-mode: overlay) and ((background: linear-gradient(rgb(166, 80, 80), rgb(139, 0, 0))) or (background: -webkit-linear-gradient(rgb(166, 80, 80), rgb(139, 0, 0)))) {

.feature-img {
background: -webkit-linear-gradient(rgb(166, 80, 80), rgb(139, 0, 0));
background: linear-gradient(rgb(166, 80, 80), rgb(139, 0, 0));
}
.feature-img img {
mix-blend-mode: overlay;
}
}

As you already know, the condition must include both a property and a value. In the example above, you’re checking for the mix-blend-mode property and the overlay value for that property. Some older Android browsers require the -webkit- prefix for linear gradients, so this has been included in the @supports block. Keep in mind that when you group a number of conditions together, the correct use of parentheses is necessary.

Specifically, this block is looking for browsers that allow the for the mix-blend-mode of overlay and the ability to render a linear-gradient. If that is supported, the image will have an overlay with a gradient applied to it, giving it a red color.

The original image is shown on the left. When a browser has support for mix-blend-mode: overlay it applies a red overlay to the image with a gradient.
The original image is shown on the left. When a browser has support for mix-blend-mode: overlay it applies a red overlay to the image with a gradient.

For browsers that don’t have mix-blend-mode support, you would use this syntax with not. There would be some styles applied, but very limited in comparison to those in the query above.

@supports not(mix-blend-mode: overlay) {
.feature-img img {
opacity: 0.5;
filter: alpha(opacity=50);
}
}
The original image is shown on the left, which has no CSS applied to it. The image on the right is what browsers that do not support mix-blend-mode: overlay will show.
The original image is shown on the left, which has no CSS applied to it. The image on the right is what browsers that do not support mix-blend-mode: overlay will show.

If you have not used CSS Feature Queries before, this is a good introduction to the possibilities of taking this approach. There are so many cool new things happening with CSS, and CSS Feature Queries allow for a way to utilize some of the new capabilities that are not yet fully supported.

Get started

Build faster, protect your brand, and grow your business with a WordPress platform built to power remarkable online experiences.