The Future of Responsive Design Standards Standards will evolve to better adapt to our users' needs and environments. November 5, 2014
The Future of ResponsiveDesign Standards
Standards will evolve to better adapt to our users'needs and environments.
November 5, 2014
How would you...include additional HTML at larger breakpoints?serve high resolution video based on a user's connection speed?increase text size based on a user's distance to the screen?adapt layouts and fonts based on a user's region?
User Agent Detection
if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i))) { $('body').addClass('mobile'); } else { $('body').addClass('desktop'); }
.desktop .button { height:1em; } .mobile .button { height:2em; }
Viewport CSS Classes
var $body = $('body'); $(window).resize(function(){ var width = $body.width() if (width < 480) { $body.addClass('mobile'); } else { $body.addClass('desktop'); } });
.desktop .button { height:1em; } .mobile .button { height:2em; }
Reduce JavaScriptManaging input deviceGeolocationRetrieving additional content and imagesInterfacing with SDKs and HTML5 Device APIs
Responsive ImagesAdaptive Images (.htaccess, PHP)Cookie-based solution (JS, PHP)Pure JavaScript Replacement
$('div.img').responsiveImages( {large:'1025px', medium:'481px'} );
<div class="img" data-src-lg="lg.jpg" data-src-md="md.jpg" data-src="def.jpg"></div> <noscript><img src="default.jpg" alt="SEO Alt Tag" /></noscript>
The <picture> Element
<picture> <source srcset="large.jpg" media="(min-width:1025px)"> <source srcset="medium.jpg" media="(min-width:481px)"> <source srcset="small.jpg"> <img src="fallback.jpg" alt="SEO Alt Tag"> </picture>
AJAX
var hasSidebar = false; var $body = $(body); var $window = $(window); function addSidebar() { if ($body.hasClass('desktop')) { hasSidebar = true; $window.off('resize.sidebar'); $.ajax({ url: 'sidebar.html', success: function(html) { $('#sidebar').append(html); } }); } } $window.on('resize.sidebar', addSidebar); addSidebar();
Link tags could work for HTML
<link href="sidebar.html" for="sidebar" rel="html" media="(min-width: 40em)"> <aside id="sidebar">...</aside>
A link tag plus media query could include an HTML fileSearch engines would be able to access it
Level 4 Media Queriesscripting: enabled, none, or intitial-onlyhover/any-hover: none, hover, or on-demandpointer/any-pointer: none, coarse or finelight-level: dim, normal or washed
<noscript>
<head> <noscript> <link href="noscript.css" rel="stylesheet" /> </noscript> </head> <body> <div class="js-content"> <!-- Some content injected via JavaScript --> </div> <noscript> Oops, no JavaScript for you. </noscript> </body>
Scripting Media Query
<!-- compliment a noscript tag here --> <link href="noscript.css" rel="stylesheet" media="not (scripting)"> <!-- or replace noscript tags --> <link href="noscript.html" for="sidebar" rel="html" media="not (scripting)"> <aside id="noscript">...</aside>
Has Touch?
if ('ontouchstart' in window) { $('body').addClass('has-touch'); } else { $('body').addClass('no-touch'); }
.no-touch { /* hover styles */ }
Pointer Media Query
@media only screen and not (any-pointer) { /* touch input styles */ } @media only screen and (pointer:coarse) { /* wii controller styles */ }
Ambient Light Events API
$(window).on('devicelight', function(e) { if (e.value < 50) { $('body').addClass('dim'); } else if (e.value < 10000) { $('body').addClass('normal'); } else { $('body').addClass('bright'); } });
body.bright { /* bright styles */ }
Device & Network APIsas Media Queries
connection-metered: none or connection-meteredconnection-bandwidth: measured in Mbsproximity: meters from sensoruser-media: none, audio, or videonetwork-discovery: none or network-discovery
Dirty Network Speed Check
// load a 2MB image and check the time diff var ts = new Date().getTime(); $('<img>').attr('src','test.jpg').on('load', function(){ var diff = (new Date().getTime()) - ts; if (diff < 1000) { // slow } else { // fast } });
Network Information API
var connection = (navigator.connection || navigator.mozConnection || navigator.webkitConnection); if (connection && !connection.metered && connection.bandwidth > 2) { $('body').addClass('hi-rez'); } else $('body').addClass('low-rez'); }
Connection Media Queries
@media screen and not connection-metered and (min-connection-bandwidth: 2Mbs) { /* hi-rez media */ }
Proximity Events API
$(window).on('deviceproximity', function(e) { if ( (e.value / 100) > 3 ) { $(body).addClass('distant'); } else { $(body).addClass('near'); } });
Get User Media API
if (navigator.getUserMedia) { navigator.getUserMedia ( { video:true, audio:true }, function(localMediaStream) { var video = document.querySelector('video'); video.src = window.URL.createObjectURL(localMediaStream); // Do something with the video here, e.g. video.play() }, function(err) { console.log("The following error occured: " + err); } ); } else { console.log("getUserMedia not supported"); }
User Media Media Query
<link href="video.css" rel="stylesheet" media="(user-media: video)"> <link href="audio.css" rel="stylesheet" media="(user-media: audio)">
Network Service Discovery API
function showServices( services ) { // Show a list of all the services provided for(var i = 0, l = services.length; i < l; i++) console.log( services[i].name + '(' + services[i].type + ')' ); } navigator.getNetworkServices([ 'zeroconf:_boxee-jsonrpc._tcp', 'upnp:urn:schemas-upnp-org:service:ContentDirectory:1' ]).then(showServices);
Network Discovery Media Query
.remote-control { display: none; } @media screen and (network-discovery) { .remote-control { display: block; } }
Evolving Media Queriesregion: country codesspeed: meters per secondsound-level: normal, loud, or headset
navigator.geolocation
if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(function (position) { console.log('Latitude: ' + position.coords.latitude); console.log('Longitude: ' + position.coords.longitude); // inject google maps... // call reverse geocode service to obtain country code... }); } else { console.log('No geolocation for you!); }
IP Detection Service
<script src="http://ip-detection.com/service.js"></script> ... var country = geoip_country_code(); if (country == 'RU') { $('head').append('<link href="russian.css" rel="stylesheet">'); }
Region Media Query
<!-- only include russian language styles --> <link href="russian.css" rel="stylesheet" media="(region: RU)">
Sound Level Media Query
@media screen and (sound-level: loud) { /* hide media or prompt user to plug in headphones */ }
Emotion Markup Language
@media screen and emotion and (emotion-level: happy) { /* rainbow and unicorn styles */ }