
Media Queries are a Hack - ianstormtaylor
http://ianstormtaylor.com/media-queries-are-a-hack/
======
russelluresti
I feel you're approaching the problem in the wrong mindset. You're imagining
that you have one module and that's all you ever have. Instead, think of a the
CSS module (your .testimonial module) as an interface - a blueprint to
implement different types of .testimonial module variations.

The BEM architecture calls these "Modifiers"
([http://csswizardry.com/2013/01/mindbemding-getting-your-
head...](http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-
bem-syntax/)).

When I look at your example, I don't think of a .testimonial object in two
different contexts (one vertical in the sidebar of the signup page while one
horizontal on the pricing page). Instead, I think of two different variations
of the .testimonial object. So while your .testimonial class may define
certain global styles, you change what you need by variations like
.testimonial.vertical or .testimonial.horizontal (though I wouldn't actually
use those names, but you get the idea).

This requires making a decision on when to apply what classes, but that's
okay. You shouldn't be trying to abstract away actual UI decision-making to an
automated tool or process. You seem to think that settings rules and logic to
be executed based on those rules (when x, execute y; when y, execute z; etc.)
will mean you always end up with a usable interface. However, this is not the
case.

Ultimately, UI is not "write-once, use anywhere", and that's okay.

~~~
condiment
I agree with this. Media queries are a tool that eliminates the need to
maintain separate HTML templates for mobile- or tablet-specific versions of a
website. They work well at this task.

Element queries as described by the author address an entirely different set
of concerns, which is that modular components of HTML might be re-used in
varying situations, and depending on the implementation you might want to
style them differently. Media queries are the wrong tool to solve this
problem.

The problem is that when we want to use this:

    
    
      .testimonial (max-width:27em) {font-size: 0.8em;}
    

We have to use a context-specific style definition instead:

    
    
      .testimonial {font-size: 1em;}
      .signup .testimonial {font-size: 0.8em;}
    

Or, better (from the parent):

    
    
      .testimonial.vertical {font-size: 0.8em;}
      .testimonial.horizontal {font-size: 1em;}
    

You might still have to revisit each of these styles in a media query to apply
changes depending on the global presentation. So while the proposed element
query might eliminate the need to chain selectors, I do not believe that it
simplifies media queries in any meaningful way.

~~~
Wintamute
No, the problem is with your class names

    
    
        .testimonial.vertical
        .testimonial.horizontal
    

By including those classes in the actual markup you're hard-coding semantics
about the presentation of those two elements that may cease to be relevant
when the screen changes width. What if when the screen gets sufficiently
narrow you want the horizontal layout to actually change to vertical? The
breakpoint at which that happens is more closely linked to the size of the
element than the global size of the whole screen (which media queries relate
to).

So the point is that with element queries you're defining modular breakpoints
that directly relate to your CSS modules, not the global size of the screen,
and you're not polluting/complicating markup with CSS class names that could
become non-semantic in drastically differing viewport dimensions.

------
acabal
I've been thinking about adding a mobile version to Scribophile lately but
reading about the craziness of media queries and browser support is kind of
scaring me away.

I think the core of the problem is that CSS was designed to style documents
(because the web long ago was more or less a collection of text documents),
but as the web evolved, it became necessary to use CSS for styling _UIs_ \--an
entirely different beast from documents.

This twisting has led to the state we're in now, where CSS _creates_ the
problem it tried to _solve_ : updating a style on a medium-complexity web site
requires digging through a minefield of complex and interconnected CSS. Yes
things like SASS or LESS can help but they're not an ultimate solution, nor
are they a web standard, so tying your horse to one of those carts can limit
you in the future.

Maybe in CSS5 they can add proper object-oriented syntax and element queries
to help increase modularity and reuse and decrease cascading and media query
complexity.

~~~
wavefunction
A "document" is one of the many possible "ui"s for the underlying model of
information that gets displayed. I must be missing some nuance in the
distinction you're trying to draw between a "document" vs a "ui." Are you
talking about static vs. dynamic content?

~~~
tsunamifury
CSS was made to style and place text on a page, not position buttons or define
interactions or transitions or platform delineation or any of the other crazy
things a view controller does in a compiled language.

Its an add-on to a markup language also built mostly only to display text.

~~~
jm3
And the first computers were humans (women) doing things like plotting missile
trajectories for the military. Technologies drift.

~~~
csallen
We no longer use humans to do our computing, but we continue to use CSS to do
our HTML styling.

~~~
andybak
To the authors of the comments beneath this one:

A more constructive angle to this debate would be to compare HTML/CSS to other
declarative UI frameworks such as those in QT and iOS and discuss what
features need to be added or removed to make HTML/CSS more maintainable and
less painful.

We all know the history of HTML and we're aware of the path it's evolution has
taken.

Are you arguing that it's inherently unfixable and needs to be scrapped? I
think you'd have a tough time arguing that point so why not move the debate
forward instead of playing the curmudgeon?

------
mgkimsal
Open question - who is really involved in developing the CSS specs and
specific implementations for specific browser? Is it people who would also end
up being end users, or people with a more theoretical/academic background?

I ask not to be snarky, but ... I've _never_ really been satisfied with CSS.
CSS proponents have shouted me down (figuratively) for being a 'tables'
holdout, but it felt to me like we traded super-nested tables with ALIGN and
CELLPADDING attributes for box-model hacks and numerous interpretations of the
word "may" and "should" from years-old spec docs; it didn't feel like that
much of an improvement in many cases.

Do browser makers consult 'regular' web developers before coding in new
browser-specific CSS extensions?

~~~
olalonde
> developing the CSS specs

There's a long list here: <http://www.w3.org/Style/CSS/members>. A quick look
at LinkedIn profiles seems to indicate a lot of them are end users.

------
mistercow
It seems like this would be a great thing to implement "shim-first". Create a
solid spec that defines the way it should behave, then write a JS library that
makes the spec work in current browsers. Then you have a set up where browsers
can implement it natively and only improve performance without changing
behavior.

~~~
BHSPitMonkey
Currently, we generally use preprocessors such as LESS or Sass to compile from
some more improved syntax into usable CSS2/CSS3 before serving (a la
CoffeScript->JavaScript). A shim is generally meant to be there just in case
some feature (present in some modern browsers) isn't available in the current
browser; For this use case, that would be ALL browsers, and you'd just be
adding page load time across the board (and further delaying when the page
gets styled during rendering).

~~~
mistercow
>Currently, we generally use preprocessors such as LESS or Sass to compile
from some more improved syntax into usable CSS2/CSS3 before serving (a la
CoffeScript->JavaScript).

Unfortunately, even for static CSS, that's not going to be practical for
element queries. You could do it in theory, but in practice, you'd end up
generating tons and tons of CSS for even very simple sites.

>A shim is generally meant to be there just in case some feature (present in
some modern browsers) isn't available in the current browser;

That's why I put "shim-first" in quotes.

------
crazygringo
What I think we're starting to need is a separation between CSS for visual
styling (font-size, border-radius, background-color, etc.) and CSS for layout
(float, margin-left, etc.).

The first can only be done by CSS in the browser. But the second can be
accomplished via CSS, _or_ by JavaScript.

As the web evolves, CSS for layout is increasingly not keeping pace. But it's
not unreasonable to think that we could do away with it altogether.

Is there anything preventing someone from creating totally new layout models,
based on new formats, that are parsed in JavaScript, and essentially turn
everything into div's with position:absolute? And get recalculated upon window
resize etc.?

This would completely free us from existing layout limitations of CSS, to do
the exact kind of things like element queries, or whatever else we might think
of.

I'm just not really sure what the performance implications would be like.

~~~
ux-app
I agree with you 100% about the need to separate styling from layout. CSS for
layout just plain sucks. Layouts that _should_ be simple turn out to require
hack upon hack to achieve.

In regard to your layout in JS question. There is an excellent port of the
Cassowary constraint solver in JS [1]. It allows you to specify complex
relationships between containers along with weights, which allow you to
specify layouts in a sane manner. Performance is very good, especially since
it takes advantage of web workers where available.

What I hate most about layout in CSS is that it takes something that should be
brain-dead simple and turns it into something that requires memorization of
edge cases and browser hacks with some added voodoo magic. It's such a waste
of brain cycles.

To top it all off constraint based solvers have been around for over 20
years... and yet in 2013 we're still dealing with this mess.

[1] <https://github.com/slightlyoff/cassowary-js-refactor>

~~~
ianstormtaylor
Very cool repo and articles that he links to. Lots of the layout constraints
(not type-size, colors, etc.) should be solved when Flexbox support lands in
the other major browsers. For example a 20% wide container, that gets no wider
than 800px and no skinnier than 200px can be solved with Flexbox pretty
easily.

Not having adequate Flexbox support after it being discussed for soooo long is
my other big problem with CSS.

~~~
ux-app
flexbox is great, but it only solves a narrow set of layout issues. There's so
much more that a constraint based system brings to the table. A layout system
should make it _extremely_ simple to anchor edges between arbitrary containers
regardless of their position in the DOM.

While we're at it lets scrap the DOM too. It's really painful to see how much
it is being contorted to suit the application paradigm.

------
jiaaro
Wow. In retrospect, when we needed general conditionals in CSS, we got just
one, very specialized one, and the rest was swept under the rug.

How did I miss that until now?

------
artificialidiot
So, until we have a full blown prolog interpreter for CSS layout calculation,
someone will always complain CSS is not sufficient. What a surprise...

Maybe we should update CSS to include object oriented features too. Then we
can have abstract factory methods for our reusable components. Throw in an
optional type checker for good measure while we are at it.

Please people, CSS and HTML only ever have had a single layout algorithm.
Maybe it is not terribly flexible but it is good for limited width and
unlimited unknown height presentation of a single stream of content. If your
content genuinely calls for a different layout, please consider using
something else other than CSS and HTML.

While I appreciate the endless efforts to workaround and improve the layout
capabilities of CSS, may I suggest embracing the limited nature of this stack
and design accordingly?

Maybe, if we admit the "content" arrive, is rendered and consumed
sequentially, we would relieve ourselves the burden of beating CSS into
submission whenever we want to diverge; with the added benefit of making life
easier for those who can't see.

You wouldn't shy away from a little bit of challenge of learning something
more suitable for you purposes, right?

------
masklinn
TFAA apparently decided on an eye-grabbing headline rather than one which
matched his article. It probably works, but it's sad: his actual thesis is
that media queries are insufficient or the wrong tool.

As acabal notes, the core issue is that CSS was originally for styling
documents, and media-queries work in that framework: they're about laying out
or formatting a document, not a component within the document.

Which is of course the wrong approach if you're creating
distributable/reusable components and blocks. Media queries are not a hack and
are probably necessary: the final author will use them to lay out his
site/page responsively.

But they're not _sufficient_ , because the inner layout of a sub-element is
impacted more by the element's size than the viewport's (the sub-element's
positioning and size on the other hand are affected by the viewport).

All in all, the article is a good note of a real problem. But its headline
stinks for the usual reasons.

------
websitescenes
Your not using media queries correctly if your having these issues. If you
want widgets to be responsive to a parent element then make them fluid. The
fluid technique has been around since the beginning and doesn't require media
queries. I keep seeing people talking about crazy new units and grid systems,
etc, etc. Just learn how to use media queries correctly... Sounds like you are
using too many breakpoints. General breakpoints with percentage widths can do
anything.

~~~
ianstormtaylor
You can't hide an inner element, or completely change the way it acts just by
making something "fluid". Making things fluid and using that to make
bulletproof modules is a good first step, but it doesn't do everything we need
it to do.

~~~
websitescenes
You can with LESS. I use LESS on all responsive projects and have done this
many times. Obviously it is not vanilla CSS you write in but it is compiled
into standard CSS. I really recommend trying it out before you reinvent the
wheel.

~~~
wvenable
Do you have an example that would resolve the authors situation?

~~~
tholex
you still have to base it off either the parent (.signup-page .testimonial) or
a conditional that's only used on a particular page (.testimonial.compact).
The media queries are sub-optimal but it's contained within .testimonial.
Here's how it can look:

    
    
      .testimonial {
        media screen and (max-width: 900px) {
          font-size: 0.8em;
        }
        &.compact {
          media screen and (max-width: 1200px) {
            font-size: 0.8em;
          }
        }
      }

~~~
lotyrin
So... no.

What if this thing shows up in 18 places, some of those change sizes on
mobile, some of them in turn being reused in several places and then somebody
changes something that affects the size (and therefore desired styles) of some
but not other of those contexts, and adds 6 more contexts in which the size
matters?

I want to say "When displaying a user profile, If there's more than X units of
horizontal space, use the large profile image. If there's more than Y units of
vertical space show their bio, trimmed to length but avoiding widow sentences
and followed by ellipsis. If there's very little room at all, just show their
user name."

I know what I want and I can describe it simply and in a way that a machine
could implement, but using today's tools it will take significant developer
(human) effort (which typically isn't within my client's priorities and
ultimately gets neglected).

~~~
tholex
By all means, I would love to have element queries. They would definitely help
in many cases. You would have to limit their use to just those areas of markup
where container widths are explicit.

If it shows up in 18 places I bet you there will be two different contexts
with the same container size, but different looks, and element queries won't
help you at this point. You'll still need to tailor your CSS classes for
different contexts.

~~~
lotyrin
Obviously if I want styles to vary by context of their container, I'll need to
create those rules. The desire for and utility of being able to do that is not
at all in question. I don't see how having such rules is in any way mutually
exclusive with element queries.

------
rwhitman
This is such an excellent point. Media Queries have been bugging the hell out
of me lately for a reason I couldn't put my finger on, and I think you just
nailed it

~~~
talmand
I didn't see it that way. Media queries do what their intended quite well, for
the most part. What is described in the article should not be addressed by
media queries at all. That's why I thought the idea was being described as
element queries, which makes more sense in that context then calling them
media queries.

Don't think of it as an improvement or replacement, but as an addition.

------
bzalasky
I've encountered one scenario where element queries would be incredibly
useful: web app designs that include sidebar navigation that toggles open and
collapses. This design pattern makes responsive design a little bit more
difficult. The main challenge is that the width of the main content pane
changes depending on the state of the sidebar. Your media query to scale down
an element or rearrange a layout, often has to default to happening at a
greater window width than otherwise necessary (if the sidebar is collapsed),
because of the potential for the sidebar being open. There are some gross ways
to work around this with JS, but I don't think it's worth it. An element query
would make it easy to watch the width of the main content pane, independent of
the sidebar pane's state.

If you create an account at Stipple.com and log in, you'll see an example of
what I'm talking about (disclosure: I'm an engineer at Stipple).

------
wubbfindel
I wonder if a javascript/jquery helper could be used as a fill for now?

You could set up size points for an Element like this (mobile first approach)
:

$(".testimonials").when-min-width(400px, "medium").when-min-width(800px,
"large");

Then you're CSS could look like this :

.testimonials{ // do basic stuff, and small display stuff }

.testimonials.medium{ // do medium display stuff }

.testimonials.large{ // do large display stuff }

Hmm. Maybe I'll build it.

~~~
nkozyra
Of course you could, but in addition to mobile devices, the point of media
queries is to handle anything that might make a standard HTTP request. This
includes televisions, older phones, gaming consoles, you name it. Javascript
is relatively unreliable on many of those devices; what's worse, you don't
want to force a jquery call _just_ to do something that's actively supported
by CSS3.

~~~
wubbfindel
All good points. But I did think if them before posting.

 _"Javascript is relatively unreliable on many of those devices"_

AFAIK it's reasonable to argue that just as Javscript can be unreliable, even
non-existent, on many devices, so can CSS media queries. I think it's fair to
say that media queries are still a "modern" browser feature.
<http://caniuse.com/css-mediaqueries>

_"what's worse, you don't want to force a jquery call just to do..."_

Agreed - jquery is too large just for this. That's why I said
"javascript/jquery". The jquery like syntax used was for simplicity. But in
truth any simple selector engine would do the job. Sizzle for example, or even
a home-grown one.

 _"...something that's actively supported by CSS3"_

But that's the point OP was making isn't it? AFAIK, CSS3 @media queries _do
not_ support element level querying.

~~~
talmand
Plus if the desired result is supported in CSS3 then you can use javascript to
just trigger the change via CSS instead of performing the task through the
script.

An obvious example of this is transitions. If you have CSS3 transitions you
can trigger them with a class name change instead of using jquery's animation
code. When you can do that you don't need jquery or other library at all.
Unless you have simply awful HTML that requires an advanced selector engine,
such as Sizzle as you state.

But as you point out, if the devices listed have unreliable support of
javascript then chances are it has unreliable support of CSS3.

I don't understand the argument against building a shim as a proof of concept
though. What's wrong with building the example to see if it becomes popular in
traditional uses of CSS before pushing it as a standard? Don't bother since it
might not work on TVs because of lack of proper javascript support?

------
tholex
Media queries are still necessary to lay out the page you've described. The
primary containers of your pages all need to move around based on the size of
the top-level container.

If you could only rely on your parent, that would also be problematic - the
size of a component would be dependent on its chain of parents. If you were
reusing the same component within further containers, say 3 different pages,
you might want two to look the same despite a size difference, and element
queries don't help you anymore. You just need a .testimonial.compact class,
have slitghtly different media targeting, and now you have two types of
testimonials that you can use on further pages.

Element queries could also easily create strange loops that cause the
threshold to be crossed recursively, if the parent bases its width on the
child. This is the case with inline-block elements and the property-which-
must-not-be-named.

------
pkrein
This all makes more sense in the context of TJ Holowaychuck's new Component
package management tool (first link in the article). Component gives a sane
structure to building small, modular js+css+html+assets components.
<https://github.com/component/component>

------
barneycarroll
IE used to have dynamic CSS properties [0], which were most often used in the
wild to achieve max-width in IE [1] (at huge cost — in the linked article the
author warns against using the very performance-expensive technique).

But the way that technique is implemented is actually very similar to what
you're describing: the CSS causes the selected element to examine some of its
DOM properties and conditionally apply styles on a per-property basis.

Maybe this is another great old IE quirk that needs some W3 loving?

[0] [http://msdn.microsoft.com/en-
us/library/ms537634(v=vs.85).as...](http://msdn.microsoft.com/en-
us/library/ms537634\(v=vs.85\).aspx) [1]
[http://www.svendtofte.com/stylesheets/reflections-on-max-
wid...](http://www.svendtofte.com/stylesheets/reflections-on-max-width/)

------
thatthatis
While we're complaining about the faults of media queries, allow me to add my
largest perturbation with them: As a user, I sometimes want the "full" site
when I'm on my phone/tablet.

With media queries, it's essentially impossible to let users choose their
format experience.

~~~
MRSallee
I only ever want a full site when the mobile layout is lacking something I
know should be there. Which is then a fault of the mobile layout, not the
method it's delivered.

------
folkelemaitre
We has a similar issue to solve. One part of our app is comparable to the
inbox of an email client (list of messages). We launched a new dashboard view,
where people could add all sorts of charts and also lists of messages. We used
the same code / css for that, but here as well we wanted to hide / unhide
certain things in the message depending on the width of the widget. We finally
added some very simple (and highly restrictive) js code to make it happen in
some way. Check this gist to see what we did:
<https://gist.github.com/folke/5314876>

------
soparrissays
From what I've read the way to approach media queries is to shrink your page
width to a point where the page breaks and then add in some code to fix it.

Element queries would be nice, but aren't we essentially doing that if we take
the idea of the previous approach and apply to more high level elements?

If we create media queries on a per element basis we are essentially achieving
the same thing. In that sense media queries are a superset of your proposed
solution. It would make for a nice short hand though.

------
yuchi
I had that same idea more than once, to propose a local per-element media
query.

In fact the concept itself of querying the whole window to understand the
dimension a portion of it will occupy... well it's strange.

At the same time, have you considered the implications of such a structure? A
local media query could change the queried properties. Dangerously recursive.

In fact you COULD reach what you want using seamless iframes. I tinkered my
head with such an option sometimes.

------
barkgolgafrinch
Exactly! This is part of a more fundamental problem with the whole concept of
responsive web design... It can't be just about media queries. I blogged about
this some time ago, and plan to amend with links to this article. Well done.
Here's my post --
[http://barkgolgafrincham.wordpress.com/2012/10/04/responsive...](http://barkgolgafrincham.wordpress.com/2012/10/04/responsive-
web-design-revisited/)

------
smoyer
The ability to compile Java to Javascript is only one of GWT's benefits ...
the ability to package the associated HTML and CSS into "modules" and later
import the modules you need makes web pages the collection of components the
author desires.

I can create similar self contained components in JSF and several other
languages (frameworks), so I'm wondering if the problem is the author's
development technique.

~~~
tholex
GWT is definitely not going to help the problem the author is talking about.
GWT's "packaged" components still end up as the same markup and CSS. In most
backend frameworks I'm talking about the Helpers, in GWT this would be some
"View", or whatever isn't the presenter.

You would still need to use different CSS in the two cases mentioned, so it
would be two different packaged components in GWT, two different Views. Maybe
interiting from one another, but certainly far FAR more lines of code than a
conditional / "modifier" CSS class. .testimonial.compact vs just a normal
.testimonial, for instance.

------
ipetepete
There are some good points made in the article. The responsive or one-for-all
approach is still in its infancy. There will be issues, but I see an evolution
in this that will ultimately lead to very succinct reusable widgets as
described by the OP.

This is definitely one to grow on.

------
capisce
The web should take a cue from QML when it comes to creating self-contained
and reusable components: [http://qt-project.org/doc/qt-5.0/qtqml/qtqml-
documents-defin...](http://qt-project.org/doc/qt-5.0/qtqml/qtqml-documents-
definetypes.html)

------
paul9290
Is there any SEO benefit of using media queries over pointing to a subdomain
with a separate stylesheet. I.E. m.domain.com ?

Personally, for reviewing Google Analytics I just prefer making my web apps &
sites responsive. Though responsive can take quite of bit of time.

~~~
seriocomic
There's no direct SEO benefit per se, just the mitigation of duplicate content
that can be introduced when an m.dot sub-domain (for the same content) is
incorrectly implemented (i.e. not using rel=canonical/rel=alternate and other
indexation directives). There's also the 'crawl once, show everywhere' benefit
if you have a single front-end representation of the code. Introducing an
m.dot version of your site requires Google et.al. to consider whether to use
their separate mobile crawlers to crawl the content that has been created for
the mobile experience.

~~~
gav
In most cases you wouldn't want your mobile domain indexed by Google et al. so
simply block all crawlers in robots.txt.

------
gabrielfelipe
Something i've been working on. It's pretty basic yet >.<
<https://github.com/gabriel-felipe/MagicHTML>

------
craftedpixelz
I think this is currently the main issue still holding RWD back right now.

I blogged about the same issue not long ago: <http://pxlz.me/44>

------
wmw
<https://github.com/wemakeweb/element-queries>

------
aphexairlines
Shadow DOM and web components probably give you the document root context you
need for that example to work.

