responsive & responsible: implementing responsive design at scale
DESCRIPTION
Presentation given at Breaking Development Conference, September 2011.TRANSCRIPT
Responsible
Responsive&
filament groupScott Jehl
filament groupWe design engaging sites and
applications that are simple to
use and accessible to all.
Mitch Hedberg
“An escalator can never break: it can only become stairs. ”
A natural subset of Progressive Enhancement.
Responsive Design
Delightful and inclusive.
Responsible
Inclusive Delightful
It works in my browser.
It feels intuitive.
It allows me to complete my task
It’s fun to use!
It’s damned fast!
...and work especially well in newer browsers!
Make it workeverywhere.
to skin an app.
There are, in fact,
Many ways
“it depends.”- Every speaker at this conference.
Should it be responsive?
• Commonality across experiences
• Developer Skillset
• Time up-front vs. maintenance
• Interest in a challenge
Make no mistake!
PE, done right, is hard.
can be rich, without being exclusive.
A proposition:
A layered approach
Talk = cheap.
Let’s tear it apart, shall we?
We built something.
A One-Web Case Study
Design-velopment Team
@beep
@upstatement
@filamentgroup
@mirandamulligan
But is it responsible?
Responsive.
Areas of Responsibility
Accessibility Performance
Usability Sustainability
Responsive... ble baseline
• “Content” first
• Mobile-first images
• Mobile-friendly layout
Asset Baseline
• Basic CSS file
• Basic JS file
• Qualified Enhanced CSS file
Defensive Development = Qualified Upgrades
Experience Divisions
Basic CSS
“Basic” = safe defaults
• Tweaks to browser typography
• Horizontal rules
• Text alignment
• Display: Inline / Block
• No complex layout or positioning
“Basic”
Enhanced Experience
The @media qualifier
Ethan Marcotte
“If you’re awesome, or you’re Internet Explorer,you get enhanced.”
@media-fortified design.
<link href="enhanced.css" media="only all">
<link rel=...” href=”basic.css” id=”basic”>
<!--[if gte IE 6]><link href="enhanced.css" rel="stylesheet"><![endif]-->
<!--[if !IE]><!--><link href="enhanced.css" media="only all"><!--<![endif]-->
<script src=”basic.js”></script>
All in your <head>
The Concatenator
Server-side Concatenation
<link href=”css/file1.css,file2.css,file3.css” ..>
Minify + Gzip
Enhanced CSS
/* styles for everyone go here.. */
@media all and (min-width: 500px){ .. }
@media all and (min-width: 620px){ .. }
@media all and (min-width: 950px){ .. }
Inheritance Prevention
@media all and (min-width: 500px)
and (max-width: 700px){
/* styles constrained to 500-700px */
}
Left
Right
Left
Display: table + table-cell
Ems all the way down.
Ems allow for components to adapt differently in different containers
• ResponsiveImages.js
• Respond.js
• Modernizr / extensions / HTML5 Shim
• The Boston Globe JS Framework
Basic.js: “just enough”
Also.
Responsive Images
<img
src=”foo.r.jpg”
data-fullsrc=”foo.lrg.jpg”
/>
Edge Cases
Edge Cases
Respond.js
https://github.com/scottjehl/Respond
Now available as part of
Also: matchMedia polyfill
window.matchMedia( “only all” );
github.com/paulirish/matchMedia.js
Globe JS Framework
The globe, um... global.
globe = {};
Feature flags from Modernizr
globe.support.touch
globe.support.applicationcache
respond.mediaQueriesSupported
Internet Explorer Flags
<!--[if lt IE 7 ]> <html lang="en" class="ie ie6"> <![endif]-->
globe.browser.ie6 = document.documentElement .className.indexOf( “ie6” ) >= 0;
Again, with the @media
globe.enhanced =
respond.mediaQueriesSupported
|| globe.browser.ie6
|| globe.browser.ie7
|| globe.browser.ie8;
Conditional-comment driven
JS Experience Divideif( !globe.enhanced ){
//last stop for old browsers!
return;
}
else{
//remove Basic CSS
//bring on the enhancements
}
great browser, too slow.
And one caveat...
No Enhanced JS for BB5
No JS? That’s okay.
On removing Basic.css...
head.removeChild( basicCSS );
• Convenient when basic.css does not easily cascade.
• A convenience that can’t be guaranteed.
Enhancing Further
Loading Assets
Different for every browser. Highly optimized.
Enhanced page weight
~ hand-crafted delivery ~
The assets you receive depend on
width, section, features
Defining Assets to Load
//Arrays of JS and CSS files
globe.jsToLoad = [ “jquery.js” ];
globe.cssToLoad = [];
jQuery is dynamically-loaded too!
Feature-based Loading
if( globe.support.touch ){
jsToLoad.push( “touchEvents.js” );
}
Section-specific Loading
if( globe.hasClass( “gallery”, body ) ){
jsToLoad.push( “galleries.js” );
}
Device Size Decisions
if( window.screen.width > 500 ){
cssToLoad.push( “fonts.css” );
}screen, not window
Our width usage rule of thumb:
screen for assetswindow for design
Why Screen, not viewport?
• Fixed per device
• Assets delivered to device’s potential, not just current state.
• Orientation-change makes resize relevant again.
Pack & Load
globe.load.script(
jsToLoad.join(",")
);
globe.load.style(
cssToLoad.join(",")
);
Again, concat.
“js/file1.js,file2.js,file3.js”
Minify + Gzip
Responsive Behavior
Collapsible Sections
We value all input...
On the desktop...
photo: flickrich
...and on the device
Touch & Mouse Events
Mouse Events
Normalized Events
• vclick
• vmousedown
• vmouseover
• vmouseup
• vmousecancel
Click - or - Gesture
http://filamentgroup.com/lab/jquery_mobile_pagination_plugin/
Drag pagination
#!hashbang
Less JS execution, faster page loads
Single-Page Apps
Degrees of #!%$hashbang
<a href=”#foo.html”>Foo</a> <a href=”foo.html”>Foo</a>
http://example.com/#!foo.html
Not great: Less... not great:
Great:history.replaceState
http://example.com/#!foo.html
http://example.com/foo.html
...in code.
window.addEventListener( “hashchange”, function(){
history.replaceState( {}, document.title, location.hash.replace("#!","" ) );
}, false );
Many ways to “Save”
Hidden Touch Interface
Even save without JS
Simple Form
Extends the ability for a site to meet you where you are
PE + offline is possible!
Accessibilityenhancements
Keep it accessible
Keys + WAI ARIA
pairs with mobile, resolution-independent
audible interface
One-Web Challenges
Content Negotiation
What if we treat them like navigation?
Landing pages are heavy
Anchor-Include Pattern
<a href=”path/to/weather.html”data-after=”path/to/weather-fragment.html”>T</a>
https://gist.github.com/983328
Ideal Delivery
In page source
Delivered via Ajax
Ads.
Ads are not awesome.
• Third-party, potential for conflicts
• They block content loading
• Potentially overtake page
• Pixel dimensions, contractually
• Filled with document.write
Best. Line. Ever.
document.write( “...<noscript>..” );
Dynamically injected, naturally.
How we “solve” ads:
<iframe>
Resize + Hide + Append
Where to append?CSS:
@media all and (min-width: 500px){ .a .ad { display: none; }}
JavaScript:
//on window resize:if( !$( “.ad” ).is( “:visible” ) ){ $( “.ad” ).appendTo( “.b” );}
Not an edge-case.
Edge Caching
In conclusion...
to build sites that are rich without being exclusive.
We have the tools
What about “apps?”
FlipPics
http://bit.ly/pBJciO
@scottjehl
thanks everyone.