Jump to main navigation, main content

Archived entry | Matt Wilcox .net

Responsive design: fixing our sensors and technology.

This is a follow up from my previous post where I talked about the problems with our current approaches with HTML/CSS/JS in order to enable building responsive websites. Please read that post to understand why our current approach is not future-friendly, and will cause us problems in the long run. Here I propose a solution to those problems; it’s this:

<head>
  <respond>
    <breakpoint case="one"   media="min-width:200px"/>
    <breakpoint case="two"   media="min-width:400px"/>
    <breakpoint case="three" media="min-width:600px"/>
  </respond>
</head>

<body>
  <picture alt="An alt tag for the image">
    <source src="mobile.jpg" match="one" />
    <source src="medium-res.jpg" match="two" />
    <source src="high-res.jpg" match="three" />
    <source src="very-high-res.jpg" media="min-width:800px" /><!-- special case not templated -->
    <img src="mobile.jpg" /><!-- fallback for old browsers -->
  </picture>
</body>

The idea behind this is to abstract the sensing from the asset negotiation. Because the sensing is so often the same, there’s no need to run the test on every single item we want to become responsive. The above pseudo code is a proposed method to template that solution. I should point out that another nice thing about taking this sort of approach (putting the sensing in the HTML head as a template) is that the CSS and the JS could all be made to inspect the breakpoint’s set in HEAD too, rather than having to re-declare the same tests in the CSS and JS files themselves. Meaning breakpoints are shared through the entire technology stack instead of being individually assigned, and the test is defined only once for the entire page.

The above approach would not stop us using existing methods to over-ride or expand on the templates either - if a particular use case does not fit with the defined template, do what we currently do and run a new test on that object itself.

Couple this approach with the likelihood of the media="” property being expanded to detect network speed and latency in the future, and this is a very flexible and DRY approach.

Note: I do not know whether this syntax is possible with HTML and whether or not it could be made possible if it isn’t now; it is merely an example to illustrait my thinking.

Comments

skip to comment form
  1. Phil Ricketts posted 22min, 11sec after the entry and said:

    You have my vote.

    Not wanting to get caught up on piddly little things like names, what you've suggest seems a great starting point for this discussion.

    My take, just for fun, as I'm not too sure about the term breakpoint (seems tied to debugging):
    I hope this conversation goes further, great idea Matt.

  2. Phil Ricketts posted 25min, 31sec after the entry and said:

    Ahh, HTML in comment fail.

    The code that was in above comment: http://pastebin.com/9F4q1K66

  3. Tim Harbour posted 36min, 34sec after the entry and said:

    Nice solution.
    This feels like the right way to do it.

    Moving the conditionals to the head allows us to get at that sensor information before the page is rendered without getting into http header latency problems.

    It would also mean that the browser could do any bandwidth detection as it downloads the content from the server…

    How about also extending it to allow us to conditionally include sensor specific files, css, js or even inline css or js

    like this :

    <breakpoint case="one” media="min-width:200px”>
    …conditionally include css, js files or inline code here
    </breakpoint>
    would that work?

  4. Aaron Gustafson posted 31 days, 1hrs, 4mins after the entry and said:

    I think this is a great idea. Personally, I think the “respond” tag name sounds a little trendy, but “breakpoints” would be a perfectly acceptable wrapper (and could allow subtags of “breakpoint”—as you suggest—or simply “break,” or “point”). One other piece I think we need though is access to the Network Information API from HTML.

  5. Matt Wilcox posted 31 days, 19hrs, 27mins after the entry and said:

    Thanks all smiley icon: smile

    Yeah, I completely agree with the Network API needing to be exposed in media-queries. Screen size is often a poor proxy for other data we're more interested in but can't expose; network speed, latency, etc.

    There are two groups of properties we actually care about with media queries, one set is about the device: screen size, processor speed, available RAM - all of these will effect how much we ought to be throwing at the device in order for it to perform well. The other set is about the connectivity between the device and our server; latency, bandwidth, cost (if it's billed per Mb). Those too will effect what's reasonable to shove down the pipe.

    We need to know both, and all we've got right now is "how big is your screen" and a lot of inferring from that. Much of the time it's reasonable inferring, but it is far from perfect - ask any iMac owner stuck in the countryside with a 0.5Mb connection…

  6. Brett Jankord posted 34 days, 13hrs, 59mins after the entry and said:

    I'm all for a native solution to keeping the picture element media queries DRY. For a DRY solution that works today, you could use PHP to set a variable for your different media queries.
    https://gist.github.com/1893129

    And then, if/when the respond/breakpoint element is, implemented start using that instead.

  7. Dominic P posted 51 days, 8hrs, 19mins after the entry and said:

    Just wanted to add a +1 to this idea. The current fragmentation of the media queries (CSS, JS, soon HTML) is starting to look like a maintenance nightmare. This idea is beautiful.

  8. Larry Garfield posted 58 days, 5hrs, 58mins after the entry and said:

    Coming here from http://www.w3.org/community/respimg/2012/05/11/respimg-proposal/#comment-653

    I'm luke-warm on the terminology and names of the elements, but we can debate that another time. I think the concept is quite solid and would love to see it developed further.

    The caveat is that it introduces a dependency between an element such as picture and the head of the page. That is going to make partial-page-builds (eg, pages built using ESI) more difficult. We're trying to vastly improve our support for that in Drupal right now, and one of the key challenges is that when you Ajax-load a portion of a page, you have to make sure that the JS and CSS that new snippet needs is already present. If not, then you have to implement your own transport layer to pull back the HTML fragment, and the extra CSS and JS that the fragment needs, then use Javascript to inject the CSS and JS into the page (hopefully avoiding any collisions or weird interactions), and then finally inject the new HTML. The code needed for that is really quite grotesque. smiley icon: smile

    My worry is that this approach will add one more dependency for us to worry about beyond just script and style/link tags. Now we also have to ensure that the breakpoint definitions we reference in the new HTML source exist in the page that the fragment is coming into, and have some way to modify it if not and pray that nothing breaks. Ungood.

    I am not sure how to resolve that, but it's something that would need to be resolved.

  9. Matt Wilcox posted 58 days, 6hrs, 7mins after the entry and said:

    I can see how that's a problem for you Larry - but drupal is a tiny part of the web and it is a special case problem. The generic idea is useful because it abstracts sensing from all three parts of the response languages: HTML, CSS, JS. Instead the sensing is done once in the head and everything else just inspects it. That is a bigger benefit by far than whether very niche methods of achieving certain types of AJAX loads are simple to do.

    In short, I think that's a Drupal problem, not a W3C tech problem.

  10. Brett Jankord posted 58 days, 6hrs, 16mins after the entry and said:

    Adam Bradley reminded me that a solution like this, "…only alleviates duplicating the media queries within one webpage." The only way to get it to work on other pages would be to add it to a PHP include. And if that’s the case, might as well just use PHP to create the media query variables. https://gist.github.com/1893129

    I've put together an example which would keep media queries in the CSS and allow us to alter the image file that gets loaded based on image-set() and URI templates:
    https://gist.github.com/2572749

  11. Matt Wilcox posted 58 days, 7hrs, 32mins after the entry and said:

    @Brett - Oh I agree, the reality is that the respond element would live in a server-side template.

    That doesn't fix the problems though - merely abstract them again so they're more managable - nor does server work negate the benefits of having this in the head. Or are you also wanting to pre-process all your CSS and JS too? Among other issues.

  12. Larry Garfield posted 58 days, 12hrs, 6mins after the entry and said:

    I think you missed my point entirely, Matt.

    first of all, Drupal currently powers 2% of the web. That makes it a very not-small target audience.

    That aside, the problem I describe is not unique to Drupal. It's a factor in any CMS-driven site. Wordpress would be affected, too. Basically *any* page that has content that is dynamically swapped out without doing a full page load is affected.

    "This CSS is only needed if this particular block is shown" is a universal problem for any modern site. "This block may be added to the page after the page is delivered to the browser" is going to be a universal problem for many many many sites. Think, ANY site using ESI and Varnish. That's, um, anyone running a high-end site who knows what they're doing. Think any modern web app.

    As I said, I like the idea of abstracting media queries to referenceable sets. That's a solid concept. But we need to think through how it applies to a page that changes structure client-side, which is an increasing number of them.

    I mention Drupal only as an example of where we have already run into this problem. It's a leading-edge case, and not leading by much.

  13. Matt Wilcox posted 58 days, 22hrs, 15mins after the entry and said:

    Yes Larry, however HTML is used on 99% of websites, so the issue of a small subset of site's having to work harder to properly load when using an advanced performance technique isn't really that big in comparison to the wider use case of HTML itself.

    I do agree that it'd be fantastic to come up with a method that makes that easy too; but I'd not want to see a MQ centralisation method being put off the cards just because of one comparatively niche use-case - which is not impossible to achieve, just harder than it currently is.

    I'd welcome any ideas for achieving this smiley icon: smile

  14. Matt Wilcox posted 58 days, 22hrs, 18mins after the entry and said:

    PS: the use case of injecting into another site is exactly why Scoped Selectors have been proposed & partially implemented - this is likely to be enough to solve that problem - unless I have missed something?

  15. Larry Garfield posted 64 days, 2hrs, 37mins after the entry and said:

    Matt, I think you're still missing my point. Drupal is 2% of the web. Dynamically generated pages are… what, 80%? 90%? I don't know, but dynamically generated pages are what any *useful* site is doing these days. The problem I'm pointing out is not niche by any definition in the world. And "pages that are build in pieces rather than from html tag to html tag all at once" are a rapidly increasing percentage of the market, and will become dominant (transparently to the user) within the next few years, I imagine. I mention Drupal purely as an example and case study of where this approach is problematic, not as the only place it is problematic.

    Again, I am *not opposed* to centralizing media queries. I *like* the idea. But without some way to address "pages that are built piecemeal" it is going to be stillborn. I do not want it to be sillborn.

    Consider your example from the top of the page. Now imagine you swap out the picture element for another, because a use clicked "next" on a slideshow. To save bandwidth (it's a big slideshow) you didn't download all images in the slideshow at once. You just download them on-demand when the user view's them.

    Now one of those images is of such a size that it needs another breakpoint target, we'll dub that "four", that applies at min-width 800px. Now what?

    This is a problem that anyone doing serious Ajax work has already run into: If you have an HTML fragment that depends on JS or CSS that is not already loaded, it's horribly fugly to hack around it and stuff can break easily. That's not a Drupal problem; that's *any* CMS (and CMSes in general are not a niche market by any definition) or app framework (ditto) that does partial page loading (which will be all of them with notable marketshare within 3 years).

    I don't know what the solution is. I'm saying we need to solve that problem in order to make what you're proposing really viable, which I want to see happen. I think I recall seeing a W3C brainstorming document at some point about partial page templates or something, but I don't recall exactly. That's where we need to focus energy first, before we make that situation worse.

From the archives

Other enteries filed under:

Web Development

Site information

Built with valid XHTML and CSS, designed with web standards and accessibility in mind. Best viewed in a modern browser [Firefox, Safari, Opera]

This domain and all content is a copy of my old website, for historical purposes only.