Conditional Resources

So you wanna conditionally load assets for your web app? Do you load them based on @media queries (device size, screen width, pixel density etc.) or based on touch events? Are we detecting “touch device” or are we asking “supports touch events”? Which touch events are we looking for? With so many different capabilities across the device spectrum, and with the advancement of touch capabilities ( or lack thereof ), touch will no longer mean “mobile.” For instance, the new version of Windows 8 will now incorporate a touch interface so it’s now more disastrous than ever before to assume “touch” means “mobile” or “no touch” means “desktop.”

A first look at the new “Windows 8” user interface. Read more at http://bit.ly/iCTxY6. Developers: Learn how to take advantage of the future of Windows at the Build Conference: http://www.buildwindows.com

When I originally set out to do some experimenting, I was reading Progressive Enhancement by those smarty pants over at the Filament Group and tooling around with EnhanceJS. Adorned in its best Easter Sunday clothes, EnhanceJS sets out to achieve, but falls short of what Modernizr helps us front–end devs do so well (of course EnhanceJS came before Modernizr). The downside of EnhanceJS that I have discovered is that it strictly uses @media detection to load assets (css,js), but with Modernizr we are using feature detection to test for the capabilities over just one feature; screen size.

Device Width and Orientation

As we all know (and if you don’t, you do now) some devices detect touch events and some don’t. Take the Windows phone for example, Modernizr.touch == false. Eek! What’s a front–end web developer to do? Run for the hills? I say face it with great strength as we do when facing our fears. In example 1 we use Modernizr to load resources based on max-device-width: 1024px and orientation: landscape. I will also soon mention where this idea falls short. View Example 1

<script>
// MODERNIZR
Modernizr.load([{
        test : Modernizr.mq('screen and (max-device-width: 1024px) and (orientation: landscape)'),
        yep  : 'js/mobile-plugin.js',
        nope : 'js/desktop-plugin.js'
}]);//end Modernizr.load
</script>
(Example 1) Modernizr.mq to detect device-width with orientation

If you’ve tested like the good little front-end dev you are, you’ll find device-width doesn’t change when the device is rotated. On an iPhone for example, the device width is 320px and the device height is 480px regardless of its rotation. What this means is that orientation testing for resource loading isn’t the best approach so be sure to use it all the time. Another valid point is that orientation testing isn’t even needed (it only tests the initial orientation, because it isn’t binded to a rotation or resize event). Since the example above also includes totally different plugins, there is an implied switch from a mobile design to a desktop design based on one feature.

window.Screen.width

<script>
Modernizr.load([{
	test : 1025 > window.screen.width,
	yep  : "js/mobile-plugin.js",
	nope : "js/desktop-plugin.js" 
}]);
</script>
(Example 2) fast and reliable loading of assets based on screen.width

View Example 2. As of this writing, Windows 8 tablet with IE10 ( 1366w x 768h ) supports touch events in both its tablet mode and in IE10 desktop mode. So if you use screen.width it’s a desktop, but if you use Modernizr.touch it’s a tablet, even when running in desktop mode (docked for example) and has a mouse/keyboard connected. We just can’t guesstimate whether something is mobile because there’s lots of devices out there in the wild with varying capabilities (solidifying even more that the web is one but I digress). If testing screen.width for plugins is a must for you, then using Modernizr to test window.screen.width is a better choice over device-width and orientation.

Down the Rabbit Hole

Now that we have a little more knowledge about the cause and effects of these examples we can start to narrow down the scope of our objectives. What we’re essentially looking for in our detection is;

  1. Event Model Detection : where authors can fork their Javascript event binding code to do the right thing
  2. Touch Device Detection : so authors can optimize layout and interaction for those fatty fingers and interfaces.

@media queries tackle the second item on our list, but we’d still need to detect and render clickable controls vs swipeable ones. So, for the current breed of Windows Phones “touch” –being true– is valid in that the input method is a touch one so you’ll need bigger manipulation controllers, but for Windows 8 on Desktop that means the same either way. This leads me to wonder how in the hell can we the web authors decide what the $#@* to do.

My Two Cents

With the following detection method, we’re loading our assets/resources based on whether the device is touch capable and if so, giving our app the finger fatty styles it deserves. If touch is not supported then let the controls be styled as normal as if the touch interface wasn’t there in the first place. View Example 3

<script>
Modernizr.load([{
	test: Modernizr.touch,
	yep:  ["css/touch-controls.css", "js/touch-events.js"],
	nope: ["css/no-touch-controls.css", "js/no-touch-events.js"] 
}]);
</script>
(Example 3) Modernizr.touch to load assets/resources for those supporting touch events and styling the interface accordingly

The problem encountered with this method is that we’re assuming once again about the device and its capabilities –and you know what happens when we assume right? Over on the IE blog they discuss some ways of handling Multi–touch and Mouse Input in All Browsers so feel free to give it a read through. Also be warned that there is no discussion into what we are to do as authors in order to style those inputs once the detection has been indicated.

Alright, So Now What?

As I said previously in my ramblings, Internet Explorer 10 for Windows 8 will now support touch events and interfaces so we must be prepared more than ever for the changing landscape of interface interactions. IE10 will introduce a new concept coined pointer events so authors won’t have to create code that handles each type of input separately.

“Internet Explorer 10 and Metro style apps using Javascript for Windows 8 introduce support in the web platform for handling touch and pen input. Rather than requiring developers to create code that handles each type of input separately, Internet Explorer 10 introduces the concept of a pointer.”

“A pointer is any point of contact on the screen: it can be a mouse, finger, or pen. Developers can now easily provide a consistent experience across input hardware and form factors by writing to a single set of pointer events that encapsulate input from mouse, touch, and pen.”

–Microsoft Internet Explorer 10 Guide for Developers DOM Pointer and gesture events

I certainly don’t claim to be an expert on anything I’ve said previously and by all means certainly challenge or even update me on your own research with this matter. Of course this is only a glimpse into what I’ve found in my research. I’d love to hear what you’ve discovered so we can all gain more insight into this tricky little devil known as “conditional resource loading.”

Mucho Thanks

A special thanks to Scott Jehl, Todd Parker, Patty Toland, Maggie Costello Wachs along with Technical Editor James Craig of W3C WAI-ARI for a wonderful book helping to seed the new methods being created and widely implemented (Modernizr, yepnope) to solve these issues. My research could not have been possible without the combination of these huge brains on the Modernizr issues threading via Github (and a little push from this dude).

Updates

  • April 10th, 2012

    http://blog.jquery.com/2012/04/10/getting-touchy-about-patents
    jQuery publicly calls upon Microsoft to submit a proposal to the W3C for Pointer Events and encourages the community to experiment with Touch and MSPointer. Send your feedback directly to the W3C public-webevents mailing list.

  • May 29th, 2012

    Media Queries Level 4 Editor’s Draft introduces a pointer query @media(pointer:coarse)

    Typical examples of a ‘fine’ pointing system are a mouse, a track-pad or a stylus–based touch screen. Finger–based touch screens would qualify as ‘coarse’.

    Media Queries Level 4 Editor’s Draft introduces the ability to query your style sheets for :hover interactions using the query @media(hover)

    The value of ‘hover’ media query should for example be 0 on a touch screen device that can also be controlled via an optional mouse. Authors should therefore be careful not to assume that the ‘:hover’ pseudo class will never match on device where ‘hover:0’ is true, but they should design layouts that do not depend on hovering to be fully usable.

  • June 19th, 2012

    Filament Group announces a new workflow titled SouthStreet : A workflow for Progressive Enhancement. The projects in SouthStreet focus on two key themes to help reduce overhead and improve performance in responsive designs

Conditional Resource Links

Dennis Gaebel

Design Technologist passionate for Open Source, SVG, Typography, Web Animation, Interaction Development & Pattern Based Design. http://droidpinkman.io.
  1. Thanks for taking the time to write this up. Maybe I misunderstood, but I don’t think screen.width is the most reliable method. See James Pearce’s research: http://tripleodeon.com/2011/12/first-understand-your-screen/

    1. Well Yo (If that is your real name)…
      Definitely screen.width is not the best approach. My current status is to consider everything touch and base my content container sizes on what the actual content is calling for; basically so text doesn’t extend into infinity. Windows 8 also presents ’tiling’ in an interesting way for user interaction and visual display. Great read by James! Highly suggested

  2. I’ve been debating how to fork my code and UI based on device context as well. Especially considering that tablets are similar to desktop in screen size, but the interaction context is entirely different.

    I recently ported Categoriz to JavaScript to experiment with this idea. It currently works standalone or with ender. Could be used with yepnope. I’m looking into integrating it with modernizr and express.js.

    I’d love to hear your thoughts on it. github.com/Skookum/categorizr.js and a demo at Skookum.github.com/categorizr.js

    The demo doesn’t fork js at all, just a bare bones demo using the device type class on the HTML element (think modernizr style forking).

    1. @iamdustan
      I really have a problem with the User-Agent sniffing. I mean you would have to update the User Agent String every time a new device is released. Correct me if I’m wrong, but it seems a little tedious and against our “best practices.”

      1. I was extremely skeptical at first before reading up on WURFL and facebook’s use of it (http://www.facebook.com/note.php?note_id=441195668919). I don’t see this as a replacement to tools like modernizr and doing feature-detection, but knowing the device-type goes a long way in knowing the user’s browsing context.

        The idea is that there is a very small and known amount of desktop browsers and that number changes very little over time. Then there’s mobile which is blowing up so we default to that. We do our best with tablets and update as need be. It’s not perfect, but it’s explicit.

        I may abandon this idea after trying it out on one project, but until it’s in production there is no way to know how effective or ineffective it is.

  3. Very well written post. This is exactly what I was looking for. I’ve been using Modernizr and wondering how to target various resolutions properly.

    1. Thanks for the kind words @Devin. Targeting devices is certainly a chore to say the least. One thing I’m finding is that window.screen.width will cut laptop users off at the knees.

      ~Happy coding!

  4. […] Conditional Resources | Gray Ghost Visuals Press Ladda in bilder/scripts osv beroende på vilken media-query som gäller just nu på sidan mha Modernizr. […]

  5. […] keyboard interactions —something that is on the mind of many, many, many, many, many people and something I’ve written about before. So what’s the best way to deal with touch at the moment? Modernizr? Well, detecting for […]

Leave a Reply

Your email address will not be published. Required fields are marked *

show formatting examples
<pre class="language-[markup | sass | css | php | javascript | ruby | clike | bash]"><code>
…code example goes here…
</code></pre>

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Comment Preview

  1. John Doe shouted this comment preview:
    2012/05/15