Jump to main navigation, main content

Archived entry | Matt Wilcox .net

Managing responsive designs is hard, so let's use our <head>

Here is what I believe is the best proposition yet for managing our responsive designs. This includes managing our CSS, JavaScript, and inline <img>’s.

<head>
  <meta name='case' data='breakpoint1' media='min-width:350px' />
  <meta name='case' data='breakpoint2' media='min-width:1000px' />
</head>

Deconstructing the case for breakpoint management in <head>

To re-cap our current problems with breakpoint management; we write our Media Query’s dozens of times in CSS files, we write the same tests in our JS files, and we will soon write them inside every <picture> element too. The same tests, in every case, but with a different “do something if true” instruction. That’s wasteful in terms of repetition, becomes very hard to manage, requires continuous re-processing of a test that never changes, and is future unfriendly. Read more detail here.

So why does that code up there solve all these issues?

At first glance, that code is going to cause many people a few frowns. We are not used to seeing this sort of thing - meta elements are supposed to describe a property of the URI aren’t they? Well, no. We already set meta elements that do not describe a property of the loaded URI - all of us do. Every time we set <meta name="robots" content=’index,follow’ /> or any associated instruction. Or when we tell Google Translate to not run on the page. Or when we tell IE not to use its picture menus. These are all examples of using a meta tag to control the behaviour of some software that’s consuming the URI’s HTML, and not to describe properties of the page itself.

What the code above does is set ‘case’ to equal a particular value, when a media query expression is matched. And if that’s done in the HTML <head> we know that absolutely everything else can rely on it - the <head> is the very first thing parsed by a browser, even before anything inside <body>. Anyone familiar with working on the ‘responsive images’ problem should at this point be getting very excited. It means that the browser can be aware of the need to adapt before any pre-fetch behaviours have been triggered by finding an <img /> element in the mark-up.

How would we use it?

In HTML

Addressing first how we might use it to control <img/> in our mark-up:

<body>
  <img src='/content/images/[case]/photo.jpg' alt='' />
</body>

What has this bought us?

Well, we have a single image element with no custom properties or other code, which will adapt to any number of breakpoints you want to declair, without ever adding another character to the image code.

We have something that is backward compatible right now: either create a directory called “[case]” so that a file exists there, or if you want to be cleverer about it, set your server to alias [case]’s path to an already existing path.

The image is cachable by proxies and CDNs because the source for each version of the image has a unique URI.

Are there any drawbacks?

None that I can see. Even with the current proposal, we should never change the alt attribute because all resources are supposed to have the same semantic meaning.

In CSS

Rather than writing endless clauses like this, where a test must be performed each time:

@media only screen and (min-width: 700px) { ... }

We could write this instead:

@media (case: breakpoint1) { ... }

What has this bought us?

We are abstracting the test itself away from the block of code that defines a response. This means if we decide to change the breakpoint condition, we do it once in the <head> and everything else works automatically.

We reduce the number of tests required of the browser. It’s not re-running a test, it’s instead checking the value of case - which has already been computed.

We have smaller code. Yeah, i know, it’s a tiny point but it’s a benefit non the less.

Are there any drawbacks?

Not that I can see, because you can still carry on using existing syntax if you like, this is just an additional capability we may want to take advantage of. It can also be used in all the same ways you use any existing media-query.

In the case of JavaScript

It’s largely the same as for CSS. Instead of doing its own tests, it can just use whatever value is stored in the ‘case’ node.

So why might this not work?

I’ve only analysed this from the perspective of an author. I do not know how much effort it might be for a browser vendor to actually implement, and whether they would be willing to do so. For me, this is the only potential downside to the whole idea - it needs the vendors to implement it. In terms of functionality and benefits of the approach, i can see no downsides to the idea itself.

This post is a follow up to a series of prior posts musing on the idea for something that can address our problems and replace Adaptive Images as my go-to solution.

Comments

skip to comment form
  1. Matt Wilcox posted 45min, 41sec after the entry and said:

    I think vendors may object initially to the idea of browsers having to do this:

    1) detect the existence of a specific meta tag
    2) if it exists scan all src="" properties for the variable string to replace with the variable value

    If no meta tag was there, it wouldn't have to do anything with the src strings.

  2. Yoav Weiss posted 6hrs, 10min, 48sec after the entry and said:

    I love the idea of a single break point (and proposed adding a media attribute to the base element in the past).

    My problems with the suggested solution:
    1. No fallback for older browsers
    2. It changes the meaning of URLs and may prevent inclusion of the '[' char from URLs. In any case, I think it will complicate HTML parsing significantly.

    I think that we should keep exploring the single breakpoint angle, looking for a better syntax.

  3. Matt Wilcox posted 6hrs, 16min, 21sec after the entry and said:

    @ Yoav

    1. There is a fallback for old browsers - as I've outlined in the main post. Just create a folder called [case] and it will be treated as a normal path. Or, alias that path on the server. This solution will work *right now* in your browser - as a fallback.

    2. No it doesn't. If the browser does not support the proposed property, it's just a regular path to a fallback image hosted at that location. If the browser *does* support it, then it will effectivly re-write the path to point to another resource. Nothing is broken, no semantics have changed.

    I do agree that the syntax of the variable needs to be considered to ensure it does not conflict with a genuine path. Perhaps it’d be useful to be able to declare the match pattern too.

  4. Yoav Weiss posted 6hrs, 46min, 27sec after the entry and said:

    OK, I missed the fallback part in your post. You're right. That would work.

    Regarding the HTML parsing part, I'm not sure that adding these templating capabilities is easy, even if they're limited to img URLs, but that's something for browser vendors to say.

  5. Joseph Mueller posted 54 days, 3hrs, 46mins after the entry and said:

    Hey Matt, I'm trying to implement your img replacement idea but I'm having a trouble getting the css to recognize the breakcases. Do I need to be running .php or javascript in order for the correct images to be loaded and case in my css to be called? Do you have a working demo somewhere?

    Thanks,
    Joe

  6. Joseph Mueller posted 54 days, 8hrs, 9mins after the entry and said:

    Nevermind.

  7. Jen Simmons posted 75 days, 2hrs, 44mins after the entry and said:

    You don't need to have browser vendors implement such a tool. You can use Sass and do this today. Mason Wendell has been encouraging people to do this: http://thecodingdesigner.com/journal/breakpoint-1 and he wrote a mixin for it: https://github.com/canarymason/breakpoint

    That said, I'm concerned that this technique encourages people to set variables like "iPhone" and "iPad" and to focus on devices, rather than thinking about the content, and making as many breakpoints as needed, in the moment / on the fly, at any number needed.

    Matt: I think you’ve missed the point of the post I’m afraid. This can not be done with server-side processing/pre-compiling such as SASS, and the idea that breakpoints may be misused is irrelevant. They can already be misused.

  8. marcel posted 75 days, 7hrs, 20mins after the entry and said:

    That's a very interesting approach, although I would prefer presentational details like breakpoints to reside in a separate stylesheet.

    The idea to manage them globally though makes a lot of sense to me. I'm curious what browser vendors will come up with in the future.

    Matt says: Yeah, that’s the thing though - breakpoints are not just presentational triggers. They’re also behavioural, and are needed to adapt the actual content (i.e., to supply a different semantically equal embedded image).

  9. Martijn Megens posted 92 days, 7hrs, 49mins after the entry and said:

    Or include a "point-of-entry" variable,
    in the meta-data, or as a seperate meta:
    1) :first (represents first directory)
    2) :last (represents last directory)
    2) :name (pad name left)
    2) :ext (pad name right/just before extension)

    meta name=”media” data=”/small:first” media=”min-width:350px”
    meta name=”media” data=”-large:ext” media=”min-width:1000px”
    or one-for-all
    meta name=”poe” data=”large-:name”

    img src=”/content/images/photo.jpg alt=”"
    becomes:
    img src=”/small/content/images/photo.jpg alt=”"
    img src=”/content/images/photo-large.jpg alt=”"
    or
    img src=”/content/images/large-photo.jpg alt=”"

    This way NOTHING changes for older browsers.

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.