Do you ever feel weird when everyone around you is doing something you would ordinarily think is wrong [or not quite ideal at the very least], but somehow no one seems to want to say anything for one reason or another? It’s a very strange feeling to see everyone doing their best impression of a hapless observer. It kind of reminds of me of that old fable, “The Emperor’s New Clothes.”
I’ve kind of always felt that way about CSS media queries. Why is everyone just so accepting of a technology that just doesn’t seem to be getting the job done? Why haven’t we as a community come together and improved it in a real and meaningful way? Why haven’t we come up with something better?
Today, CSS media queries just happens to be the functional cornerstone of responsive web design. But, it was never designed for what everyone’s using it for today, and the proof is in the practice. I still often stumble on websites when using a tablet device that at-first seem well-designed, but just happen to look and feel downright wonky when you put them through their paces.
There’s something fundamentally wrong with this approach to responsive web design that we just have not properly addressed yet, and I’d like to be one of the few voices to call the emperor out for his nakedness on this one. Thankfully though, in this day and age, I’m glad there’s almost zero chance of being burned at the stake for having this alternative viewpoint.
What’s Wrong With CSS Media Queries
CSS media queries were designed for something, but that thing isn’t responsive web design. Based on my experience, here are seven (7) big issues I’ve run into when trying to use them for working with websites:
1. Not intuitive:
“CSS media queries are intuitive”, said no web designer ever. The way you define a media query is pretty straightforward, but it’s not always exactly clear how things will play out on real browsers, on real devices, and in a myriad of scenarios.
@media only screen and (min-width: 320px) and (max-width: 480px) { /** CSS rules go here **/ }
The code above applies to the viewport when it is between 320 and 480 pixels. However, it’s not exactly definitive [or intuitive] when you want to do something more specific, like apply a style rule when the device is a tablet in landscape operation. It’s not impossible to [sort of] set a media query up to do this, but it’s definitely not intuitive – or definitive.
2. Limited conditionality:
CSS media queries are dynamic and enable you to define conditional statements in your CSS. For example, if the viewport is between this and that, then do the other. However, you are limited to viewport considerations mostly, and there are many more conditional scenarios that would make sense in modern web design.
Say you’re building a progressive web-app. There are times when it would be useful to style certain UI elements differently based on the OS. For example, it is customary to have the tab-bar at the bottom for iOS devices, while for Android the reverse is the case. So, how exactly would you get this to work with CSS media queries?
You can’t, because CSS media queries are not built with any feature that would let you. Besides this, there happen to be numerous other customizations that you may need to be made via CSS, but media queries isn’t an option when you need varying degrees of simple to advanced conditionality.
3. Not natively extensible:
CSS media queries are functionality that is baked into the browser. This means that it is not natively extensible. In other words, you can’t add extra and enhanced capabilities to CSS media queries natively via the CSS interface.
Even if new CSS media query features are approved by the [long-suffering] web standards process, it still takes time before these features become usable on account of ubiquity. In addition, not every feature that is added may be useful to you, so you are left to figure out some other way to solve your specific challenge if you don’t get what you want.
Of course, there is a way to extend CSS, but you have to know JavaScript really, really well, and it’s not a process that is practical for most web designers.
4. Not suited for retrofit:
Some might find this hard to believe, but before mobile devices showed up, there were actually a lot of websites out there, and none of them were mobile-friendly. As a result, these desktop-era websites needed to be upgraded.
Unfortunately, CSS media queries are not a very good option for this task. Because these websites were built before mobile devices were relevant, a lot of them have design elements that don’t lend themselves to responsive web design e.g. sidebars, table-based layouts, tabbed content, etc. Also, a sizable proportion of these websites are built on a content management system (CMS) like WordPress, Drupal, Magento, etc., and integrating CSS media queries [front-end] effectively from the back-end is extremely difficult to near impossible to coordinate.
I’ve had to retrofit websites powered by Magento Enterprise, WordPress, and one that used a custom CMS based on Coldfusion, and all projects would have been downright impossible using CSS media queries [which is what all my clients tried prior to using our alternative approach].
5. Not code efficient:
Using CSS media queries to make a web page responsive requires code multiplication on a significant scale. Because of the way these directives work [with your breakpoints], you have to define individual style rules in each and every media query block.
section {width: 960px;} /* Portrait */ @media only screen and (min-device-width: 320px) and (max-device-width: 480px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: portrait) { section {width: 100%} } /* Landscape */ @media only screen and (min-device-width: 320px) and (max-device-width: 480px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: landscape) { section {width: 100%;} }
When writing the code above, my original intention was to make the <section>
elements on my page fluid [width of 100%] in all mobile devices. However, since I don’t have native device-detection capability, I have to compromise and define a style rule in each and every mobile-oriented CSS media query block to make sure that the new property will apply in all relevant scenarios.
This means that the functional efficiency of the stylesheet cascade, and the good development principles of Do-not-Repeat-Yourself, have to take a back seat.
6. Increases workflow complexity:
CSS media queries handle only a very specific aspect of responsive web design that is almost entirely focused on layout resizing. Ergo, to do anything more than that, you have to rely on JavaScript to make up the difference. This introduces additional learning requirements for code and tools.
In addition, the non-definitive way it [media queries] handles breakpoints means that you have to spend more time [and money] testing your web pages in numerous virtual and/or physical devices to make sure that things work the way you originally intended. And, you need to retest everything again when you make any significant changes to your layout.
By the simple and purposeful action of using CSS media queries, you significantly increase the number of steps required to build a modern web page.
7. Worsens performance:
On account of the way CSS media queries work, you will end up needing a lot more CSS code than otherwise to make your website responsive/mobile-friendly. According to data from HTTPArchive.org, CSS file sizes have increased by 114% over the last five years. The increase in HTML file sizes peaked at about 53% over the same period.
This peculiar situation has performance implications for your website as it is bound to be slower after implementing CSS media queries [in a responsive web design context] than it ever was before, especially for mobile devices using less-than-ideal mobile broadband networks.
And, asides from the issue of increased file sizes, there is no internal mechanism within CSS media queries to actually improve the performance of your web page. For that, you’re going to have to leverage advanced JavaScript techniques to enable these enhancements.
Why are we still using this?
If I asked you what percentage of websites were using CSS media queries, what would your answer be? With all the stress web designers have had to endure over the years, you’d think we’d have probably gotten over the adoption hump by now, but you’d be very wrong.
The percentage of websites using CSS media queries across the entire web is about 0.2%. Contrast that with the percentage of websites using jQuery at 18%. What that means is that you are 90 times more likely to come across a website that is powered by jQuery than you are a responsive website [not including those that happen to be both].
Why would a toolkit based on a core technology [JavaScript] that certain folks seem to think is complicated and superfluous be so far ahead of one that is seemingly less complex [CSS] and meant to address an arguably more important problem [mobile-friendliness]? Obviously, there’s something seriously wrong here that is hindering adoption, and it needs to be addressed.
CSS media queries found it’s way into web browsers to handle a specific challenge, but it was then drafted to carry the whole weight of responsive web design on its shoulders. It’s kind of like practicing for a 3rd-grade recorder recital, only to be magically transported to Royal Albert Hall to render a trombone solo of Handel’s Messiah; No fair!
With all the challenges of modern web design, it’s extremely surprising that we’re still on this media query business. It doesn’t go far enough to deal with some important legacy issues, in addition to some new ones in new fields like progressive web-app design. As such, I think it’s time we came up with an alternative. But, what would that be exactly?
What is the Solution?
The solution to all this is really very simple: JavaScript. Now, before you pick up that pitchfork, give me a chance to explain.
JavaScript is the only component of the HTML5 trinity where extensibility is not a dirty word. You can’t extend HTML markup using more HTML, and you sure as heck can’t extend CSS natively with CSS. However, you can extend JavaScript natively using JavaScript, and you can even do the same for CSS.
Manipulating CSS with JavaScript is extensively discussed in the W3C’s Web Standards Curriculum. The document.stylesheets
DOM interface enables us to access the stylesheets applied to a web page, including all the external stylesheets referenced using HTML’s <link>
tag. It’s not an easy thing to do, but it’s possible.
So I should expand on the initial answer: it’s not simply JavaScript, it’s JavaScript-assisted CSS. JavaScript is an awesome platform with functionality like you wouldn’t believe, but CSS is where most web designers work. If we could somehow create some kind of functional bridge between these two where a web designer could write a CSS ruleset to leverage JavaScript functionality, that would be somewhat of a game-changer for web design.
Show me some code
For the last two years or so, I’ve been working on a new JavaScript-assisted CSS toolkit called rKit. The whole idea was to build a designer-friendly tool to not just replace CSS media queries for responsive web design, but to address some of the known [and unknown] challenges web designers/developers face when building modern websites and webapps.
There’s a lot to the concept, but here’s a quick code snippet of CSS to explain:
#my-element[rk="if @viewport.width between 320 and 480"]{background-color: #0000ff;}
With rKit, the CSS rules look like modified attribute-value selectors. You can then define an expression within the value section. The syntax of this expression is designed to be simple and intuitive.
Note: rk
is a constant attribute identifier.
The code above is functionally equivalent to the CSS media query below:
@media only screen and (min-device-width: 320px) and (max-device-width: 480px) { #my-element {background-color:#0000ff;} }
However, there’s a lot more you can do with rKit. Here’s another quick example:
#my-element[rk="if @self.width between 320 and 480"]{background-color: #00ff00;}
By simply changing the entity reference from @viewport
to @self
, we’ve essentially setup what is commonly referred to as an element query. So what now happens is that when the width of #my-element
is between 320 and 480 pixels, the given declaration [background-color: #00ff00
] will apply.
You can also use classes instead of pure declarations:
#my-element[rk="if @self.width between 320 and 480 then addClass(c_mobile_320)"]{} .c_mobile_320 {background-color: #00ff00;}
This is just the tip of the iceberg though. With rKit, you can do some pretty awesome things like event management, mutation observation, quantity queries, routing, data-binding [up to 7-way], and a host of other cool stuff, all using pure CSS code, and without writing a single line of JavaScript.
rKit will be free and open-source when it’s launched. And, it will also sport a special performance pack that you can install in a way that guarantees zero render-blocking, so the web page loads like a rocket on rails.
It’s taken quite a while to put this together, but it’ll be here soon [definitely before Godot], and I’m really interested to see just what web designers [and developers] are able to do with it.
Conclusion
I hope you don’t come away from this post thinking I’m bashing CSS media queries just because. I’m not. That would be like bashing a tomato for ending up in a fruit salad. Like I said earlier, CSS media queries were never designed for responsive web design. It was co-opted on account of expediency, and we all made the misstep of trying to use it to solve all the problems.
Sadly, we as a web community never really got around to correcting that initial mistake by improving it in a significant way, or coming out with a better alternative. But alas, shows must go on, websites must be built, and progress must prevail. It’s time for a change.
rKit is merely one option and one answer. It’s not the first, and it definitely won’t be the last. But, at the very least it is a right step in the right direction. An opportunity to fix some problems of the past, and then iterate to fix those in the now and into the future. It would be interesting to see how it matches up against the status quo.
All tolled, making a mistake is not an end in itself; it should be a learning experience. With any luck, we’ll learn how to use the right tool for the right job next time. I mean, just because you can ride a bicycle on a paved road doesn’t mean you should bring one to the Nürburgring. Bring a Porsche!
Related Topics
Top