8 ms·
Media Queries are a Hack
- pkrein 14y agoThis 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 https://github.com/component/component
- acabal 14y agoI'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 14y agoA "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 14y agoCSS 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 14y agoAnd the first computers were humans (women) doing things like plotting missile trajectories for the military. Technologies drift.
- csallen 14y agoWe no longer use humans to do our computing, but we continue to use CSS to do our HTML styling.
- andybak 14y agoTo 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?
- talmand 14y agoEven then, if you plan things correctly and involve javascript for changes on the fly, it works quite well at positioning elements on the page, show results of interaction, performing transitions, and many of the other crazy things a view controller does.
- praxulus 14y agoMy interpretation was that a document is something simply consumed by the user, whereas a UI involves more "interaction" with the user.
- TazeTSchnitzel 14y agoIt largely refers to the complexity of the layout. HTML and CSS were made for styling pages of text with headings, images, perhaps a table here or there. But now people want to make application UIs with fluid layouts with them.
- arebop 14y agoAlso, transclusion never really took off, so traditional web pages are different to an app's page state, which might be initialized from computation by composed modules on the backend and a series of asynchronous updates in frontend. CSS has the cascade and @import and background-image links for example, but historically the document was typically one text file and some pictures; an app's UI is combined from many source files and subordinate resources. CSS works pretty well for declaratively styling a monolithic document, but it is not entirely satisfactory for styling the UI of complex app such as Facebook.
- crazygringo 14y agoWhat 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 14y agoI 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 https://github.com/slightlyoff/cassowary-js-refactor
- ihodes 14y agoThough obvious, FWIW: correct link to [1] https://github.com/slightlyoff/cassowary-js-refactor https://github.com/slightlyoff/cassowary-js-refactor
- ianstormtaylor 14y ago
- mistercow 14y agoIt 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 14y agoCurrently, 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).
- lnanek2 14y agoIn this case, showing testimonials isn't core to most pages anyway, so no big deal if they fade in a second late. Heck, the animation might bring more attention to them. It's kind of bizarre reading hundreds of words from this author about this problem when he could have solved it 3 lines of JavaScript, checking the width of the element and swapping a class value.
- mistercow 14y ago>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.
- jiaaro 14y agoWow. 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?
- masklinn 14y agoTFAA 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.
- russelluresti 14y agoI 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-round-bem-syntax/ http://csswizardry.com/2013/01/mindbemding-getting-your-head...). 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 14y agoI 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.
- websitescenes 14y agoYour 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 14y agoYou 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 14y agoYou 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 14y agoDo you have an example that would resolve the authors situation?
- tholex 14y agoyou 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; } } }
- deleted 14y ago[deleted]
- ianstormtaylor 14y agoThe problem is that you're triggering the media query off the window's width still, and not the parent element's width. So it runs into the same problem mentioned in the article.
- polemic 14y agoDuh, you're correct. Baleting and getting coffee.
- bzbarsky 14y agoRight, but the width of the parent element in general depends on the width of your component, and then things are just bad. The thing about the viewport width is that it's actually fixed no matter what things inside the viewport are doing, which means you _can_ base the behavior of things inside it on the width of the viewport. The only real alternative is to have invariants where your component's width/height is determined and it's somehow enforced that no matter how you lay out stuff inside it won't affect those numbers. Basically think the entirety of your component inside an iframe, but without the separate script global and baggage.
- ianstormtaylor 14y agoSorry, I actually meant just "element's width" not "parent". But you're right it definitely gets complicated, and you know way better than I do about which pieces are impossible and which aren't :) The viewport query is a lot easier from an implementors point of view for sure, but it's also a lot less useful from a developer's point of view. Would it be possible to have a way of only basing the element-specific query off of the state of the element before element-query-level styles had been applied? For example, take an element that who's height is less than 100px. And say it has a query for `height > 80px` that hid a child element, which then kicked the element's height down to 75px. Technically the query would be undone, but maybe since it is a query-specific change, it doesn't factor in. And it gets even more complicated when considering well what about a child's or parent's queries on top of that I'm sure. All I know is while I'm writing these styles, I have very defined things that I want to do, that can be expressed in words perfectly clearly, and if I were able to express them in code it would completely solve tons of headaches I have with managing CSS. Ideally we could figure out a syntax and implementation that can translate those kinds of thoughts into code that works.
- thatthatis 14y agoWhile 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 14y agoI 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.
- artificialidiot 14y agoSo, 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?
- paul9290 14y agoIs 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 14y agoThere'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 14y agoIn most cases you wouldn't want your mobile domain indexed by Google et al. so simply block all crawlers in robots.txt.
- r0s 14y agoSeperate subdomains seems like a monster pain to me. You can actually use media queries to link separate style sheets: http://www.w3.org/TR/css3-mediaqueries/#media0 http://www.w3.org/TR/css3-mediaqueries/#media0
- smoyer 14y agoThe 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 14y agoGWT 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 14y agoThere 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.
- folkelemaitre 14y agoWe 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 https://gist.github.com/folke/5314876
- bzalasky 14y agoI'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).
- yuchi 14y agoI 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.
- mgkimsal 14y agoOpen 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?
- LukeShu 14y agoI don't know much better than you, but here is the general understanding that I've picked up: HTML and HTML2 were developed by developers (via the IETF). HTML3->HTML4->XHTML and CSS1->CSS2 represent increasing control by academics in committees at W3C. HTML5 and CSS3 are the result of fed-up actual web developers stepping up. What gets implemented in browser-specific extensions is some combination of governing committees and developers actually willing to write the code.
- olalonde 14y ago> developing the CSS specs There's a long list here: http://www.w3.org/Style/CSS/members http://www.w3.org/Style/CSS/members. A quick look at LinkedIn profiles seems to indicate a lot of them are end users.
- rwhitman 14y agoThis 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 14y agoI 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.
- tholex 14y agoMedia 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.
- capisce 14y agoThe 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-definetypes.html http://qt-project.org/doc/qt-5.0/qtqml/qtqml-documents-defin...
- craftedpixelz 14y agoI 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 http://pxlz.me/44
- wubbfindel 14y agoI 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 14y agoOf 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 14y agoAll 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 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 14y agoPlus 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?
- aphexairlines 14y agoShadow DOM and web components probably give you the document root context you need for that example to work.
- barkgolgafrinch 14y agoExactly! 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-web-design-revisited/ http://barkgolgafrincham.wordpress.com/2012/10/04/responsive...
- gabrielfelipe 14y agoSomething i've been working on. It's pretty basic yet >.< https://github.com/gabriel-felipe/MagicHTML https://github.com/gabriel-felipe/MagicHTML
- barneycarroll 14y agoIE 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).aspx http://msdn.microsoft.com/en-us/library/ms537634(v=vs.85).as... [1] http://www.svendtofte.com/stylesheets/reflections-on-max-width/ http://www.svendtofte.com/stylesheets/reflections-on-max-wid...
- soparrissays 14y agoFrom 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.
- wmw 14y agohttps://github.com/wemakeweb/element-queries https://github.com/wemakeweb/element-queries