christopher schmitt, "adaptive images for responsive web design"
DESCRIPTION
The open web doesn't stop at our desktop. Smart phones and tablets not only contain more computing power and better browsers than the computers that started the Internet economy, they have better displays. Presented at WebVisions Barcelona 2013.TRANSCRIPT
#WVBCN
ADAPTIVE IMAGESIN RESPONSIVE WEB DESIGN
CHRISTOPHER SCHMITT @teleject
#WVBCN
ADAPTIVE IMAGESIN RESPONSIVE WEB DESIGN
CHRISTOPHER SCHMITT @telejectWhat Bruce Said!
CHRISTOPHER SCHMITT@teleject
@teleject
http://nonbreakingspace.tv/
@teleject
http://dwmgbook.com/
@teleject
http://CSSsummit.com/
@teleject
http://cssdevconf.com/
y
x
alert("User-agent header sent: " + navigator.userAgent);
alert("User-agent header sent: " + navigator.userAgent);
Mozilla/1.0 (Win3.1)
http://www.useragentstring.com/
(cc) flic.kr/p/vUBHv
Mozilla/1.0 (Win3.1)Mozilla/1.22 (compatible; MSIE 2.0; Windows 95)
(cc) flic.kr/p/vUBHv
http://www.useragentstring.com/
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/534.55.3 (KHTML, like Gecko) Version/5.1.5 Safari/534.55.3
(cc) flic.kr/p/vUBHv
http://www.useragentstring.com/
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/534.55.3 (KHTML, like Gecko) Version/5.1.5 Safari/534.55.3http://webaim.org/blog/user-agent-string-history/
(cc) flic.kr/p/vUBHv
FEATURE TESTINGvs. BROWSER SNIFFING
1
2
3
FEATURE TESTINGvs. BROWSER SNIFFING
1 Browser width
2
3
A scripting approach var myWidth = 0, myHeight = 0; if( typeof( window.innerWidth ) == 'number' ) { //Non-IE myWidth = window.innerWidth; myHeight = window.innerHeight; } else if( document.documentElement &&
( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
//IE 6+ in 'standards compliant mode' myWidth = document.documentElement.clientWidth; myHeight = document.documentElement.clientHeight; }
http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
The jQuery approach
// returns width of browser viewport$(window).width(); // returns height of browser viewport$(window).height();
// returns width of HTML document $(document).width(); // returns height of HTML document$(document).height();
http://api.jquery.com/width/ & http://api.jquery.com/height/
CSS media queries
// default, mobile-1st CSS rules devices go here
@media screen and (min-width: 480px) { ... }
@media screen and (min-width: 600px) { ... }
@media screen and (min-width: 768px) { ... }
@media screen and (min-width: 910px) { ... }
(cc) flic.kr/p/8Lo5Gk
BROWSER WIDTHGIVES US FRAME, NOT THE CANVAS
FEATURE TESTINGvs. BROWSER SNIFFING
1 Browser width
2 Screen resolution
3
72 points-per-inch =72 pixels-per-inch
96PPIIF A WINDOWS USER
72 points-per-inch x [1+(1/3)] = 96 PPI
78μm
goo.gl/zpkFy 78μm
“RETINA” DISPLAYS300ppi at 12 inches from the eyes
[In 2013, Intel sees their product line] offer a higher resolution experience than a top-of-the-line 1080p HDTV.”
“
http://liliputing.com/2012/04/intel-retina-laptop-desktop-displays-coming-in-2013.html
72 PPI
240
240 PPI
240 PPI
72 PPI
RETINA DISPLAYS =LARGER IMAGES,LARGER FILE SIZES
FEATURE TESTINGvs. BROWSER SNIFFING
1 Browser width
2 Screen resolution
3 Bandwidth
(cc) flic.kr/p/4DziUN
SPEED TESTSHINDER SPEED,USER EXPERIENCE
Testing for speed of an internet connection is like stepping in front of a car to see how fast it is.”
“
(cc) flic.kr/p/4DziUN
Testing for speed of an internet connection is like stepping in front of a car to see how fast it is.”
“But, Christopher, you only have to test it once.”“
(cc) flic.kr/p/4DziUN
Speed test image
https://github.com/adamdbradley/foresight.js
Speed test image
+50k
https://github.com/adamdbradley/foresight.js
Native speed test
// @Modernizr's network-connection.jsconnection = navigator.connection || {
type: 0 }, // polyfill
isSlowConnection = connection.type == 3|| connection.type == 4
| /^[23]g$/.test(connection.type);
http://davidbcalhoun.com/2010/using-navigator-connection-android
FEATURE TESTINGvs. BROWSER SNIFFING
1 Browser width
2 Screen resolution
3 Bandwidth
IMGGIMME THAT OLD SCHOOL
1
2
3
1 .htaccess
2
3
IMGGIMME THAT OLD SCHOOL
Filament .htaccess# Responsive Images # Mobile-First images that scale responsively and responsibly# Copyright 2010, Scott Jehl, Filament Group, Inc # Dual licensed under the MIT or GPL Version 2 licenses. # //Start Responsive Images RewriteEngine On# direct image requests to tempRewriteCond %{QUERY_STRING} full=(.*)&?RewriteRule (.*)rwd-router/.*\.(jpe?g|png|gif|webp) $1%1 [L]# ignore trap for non-image requests, rewrite URL without trap segmentRewriteRule (.*)rwd-router/(.*)$ $1$2# //End Responsive Images
https://github.com/filamentgroup/Responsive-Images
Filament .htaccess
<script src="responsiveimgs.js"></script>
<img src="sample-content/running-sml.jpg?full=sample-content/running-lrg.jpg" />
8+4+
...the server has no way to know what resolution the client’s device is, so it can’t send the appropriately sized embeded images.”
“
http://mattwilcox.net/archive/entry/id/1053/
http://adaptive-images.com/
ADD .HTACCESS, JS,PHP 5, GD lib*, &THEN <IMG>
1 .htaccess
2 <picture> and/or srcset
3
GIMME THAT OLD SCHOOLIMG
media queries in HTML
<video controls> <source type="video/mp4" src="video/windowsill_small.mp4" media="all and (max-width: 480px), all and (max-device-width: 480px)"> <source type="video/webm" src="video/windowsill_small.webm" media="all and (max-width: 480px), all and (max-device-width: 480px)"> <source type="video/mp4" src="video/windowsill.mp4"> <source type="video/webm" src="video/windowsill.webm"> <!-- proper fallback content goes here --></video>
http://www.w3.org/community/respimg/2012/03/15/polyfilling-picture-without-the-overhead/
<picture> patch <picture alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia"> <!-- <source src="small.jpg"> --> <source src="small.jpg"> <!-- <source src="medium.jpg" media="(min-width: 400px)"> --> <source src="medium.jpg" media="(min-width: 400px)"> <!-- <source src="large.jpg" media="(min-width: 800px)"> --> <source src="large.jpg" media="(min-width: 800px)"> <!-- Fallback content for non-JS browsers. Same src as the initial source element. --> <noscript><img src="small.jpg" alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia"></noscript></picture>
http://www.w3.org/community/respimg/2012/03/15/polyfilling-picture-without-the-overhead/
ADD IF-ELSE HTML, JS, BORROW <VIDEO>, & THEN <IMG>
@srcset standard?
<h1><img alt="The Breakfast Combo" src="banner.jpeg" srcset="banner-HD.jpeg 2x,
banner-phone.jpeg 100w, banner-phone-HD.jpeg 100w 2x">
</h1>
http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-content-1.html#attr-img-srcset
1 .htaccess
2 <picture> and/or srcset
3 HiSRC
GIMME THAT OLD SCHOOLIMG
Set, forget it HiSRC
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script><script src="hisrc.js"></script><script>
$(document).ready(function(){$(".hisrc img").hisrc();
});</script>
https://github.com/teleject/hisrc
Set, forget it HiSRC
<div class="hisrc"><img src="halloween-mobile-1st.png"
data-1x="halloween-x1.png" data-2x="halloween-x2.jpg" alt="Celebrating Halloween in style" />
</div>
Set, forget it HiSRC
<div class="hisrc"><img src="halloween-mobile-1st.png"
data-1x="halloween-x1.png" data-2x="halloween-x2.jpg" alt="Celebrating Halloween in style" />
</div>
SERIES OF CHECKS TO FIND OUT RESPONSIVE PATH FOR IMAGES...
DO NATIVE SPEED TEST FOR MOBILE DEVICES FIRST...
http://davidbcalhoun.com/2010/using-navigator-connection-android
$.hisrc.devicePixelRatio = 1;if(window.devicePixelRatio !== undefined) {
$.hisrc.devicePixelRatio = window.devicePixelRatio
};
Check pixel density...
https://gist.github.com/2428356
+50k
https://github.com/adamdbradley/foresight.js
Force speed test
LESS THAN 4G MEANS MOBILE IMAGES LEFT IN PLACE
BETWEEN 4G &300 Kbps MEANS REGULAR DESKTOP IMAGES SWAPPED IN
FAST SPEED & HIGH DENSITY, RETINA IMAGES SWAPPED IN
https://github.com/crdeutsch/hisrc/tree/v2
2 TRICK PONY
CSS IS CORE.WE USE CSS MEDIA QUERIES FOR DESIGN
http://mediaqueri.es/
CSS media queries
// default, mobile-1st CSS rules devices go here
@media screen and (min-width: 480px) { ... }
@media screen and (min-width: 600px) { ... }
@media screen and (min-width: 768px) { ... }
@media screen and (min-width: 910px) { ... }
Single pixel GIF
Single pixel GIF
Single pixel GIF
Single pixel GIF
$.hisrc.defaults = { useTransparentGif: true,
http://www.w3.org/community/respimg/2012/04/06/responsive-content-images-using-a-spacer-png-and-background-image/
Single pixel GIF
$.hisrc.defaults = { useTransparentGif: true, transparentGifSrc: 'http://example.com/spg.gif',
6+5+9+ 11.6+17+
Single pixel GIF
$.hisrc.defaults = { useTransparentGif: true, transparentGifSrc: 'data:image/gif;base64,R0lGODlhAQABAIAAAMz/AAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
8+5+9+ 11.6+17+
Single pixel GIF
http://css-tricks.com/which-responsive-images-solution-
should-you-use/
24+http://css-tricks.com/which-responsive-images-solution-
should-you-use/
http://css-tricks.com/which-responsive-images-solution-
should-you-use/
ALL SOLUTIONS HAVE2x HTTP REQUESTS+ JAVASCRIPT
WORKAROUNDS TRICKS in CONTEXT
1
2
3
&
(cc) flic.kr/p/64fGf6
WORKAROUNDS TRICKS
1 background-size: 100%
2
3
&
(cc) flic.kr/p/64fGf6
http://fittextjs.com/
background-size: 100%<a href="example.com/link">Download on Github</a>
.download a { padding: .095em .8em;background: url(../img/arrow.png) no-repeat;background-size: 100%;margin-left: .4em;-webkit-transition: margin 0.15s ease-out;-moz-transition: margin 0.15s ease-out;text-decoration: none;
}
9+5+9+ 11.6+17+
WORKAROUNDS TRICKS in CONTEXT
1 background-size: auto
2 SVG
3
&
(cc) flic.kr/p/64fGf6
SVG
Native SVG
http://caniuse.com/#search=SVG%20in%20HTML%20img%20element
PNG 16kbSVG 7kb
9+5+9+ 11.6+17+
http://petercollingridge.appspot.com/svg-optimiser
Modernizr checkif(!Modernizr.svg){ var images = document.getElementsByTagName("img"); for(var i = 0; i < images.length; i++){ var src = images[i].src.split("."); images[i].src = src[0] + ".png"; }}
http://stackoverflow.com/questions/12846852/svg-png-extension-switch
WORKAROUNDS TRICKS in CONTEXT
1 background-size: auto
2 SVG (Clown Car)
3
&
(cc) flic.kr/p/64fGf6
WORKAROUNDS TRICKS in CONTEXT
1 background-size: auto
2 SVG
3 font-based solutions
&
(cc) flic.kr/p/64fGf6
...if you use <meta charset="utf-8"> (you should be for HTML5), you’re adding common Unicode characters like ♫ and ✆, and you don’t need a specific font’s version... just copy and paste them into your HTML.”
“
Font-based RWD
http://ilovetypography.com/2012/04/11/designing-type-systems/
Font-based RWD
http://ilovetypography.com/2012/04/11/designing-type-systems/
avg file size 40kb/per font
http://css-tricks.com/examples/IconFont/
http://fontello.com/
http://icomoon.io
Font-based icons
<style> [data-icon]:before { font-family: 'icon-font'; content: attr(data-icon); }</style>
<a href="http://example.com/cloud/save/"> <span data-icon="C" aria-hidden="true"></span> Save to Cloud</a>
WORKAROUNDS TRICKS in CONTEXT
1 background-size: 100%
2 SVG
3 font-based solutions
&
(cc) flic.kr/p/64fGf64 compressed JPEGs
iCloud iOS 5 OSX Lion iPad 2 iPhone
OSThe world’s most advanced desktop operating system advances even further.With over 250 new features including Multi-Touch gestures, Mission Control, full-screen apps, and Launchpad, OS X Lion takes the Mac further than ever.
Learn More
X Lion
iCloud iOS 5 OSX Lion iPad 2 iPhone
OSThe world’s most advanced desktop operating system advances even further.With over 250 new features including Multi-Touch gestures, Mission Control, full-screen apps, and Launchpad, OS X Lion takes the Mac further than ever.
Learn More
X Lion!
" ←↑
iCloud iOS 5 OSX Lion iPad 2 iPhone
OSThe world’s most advanced desktop operating system advances even further.With over 250 new features including Multi-Touch gestures, Mission Control, full-screen apps, and Launchpad, OS X Lion takes the Mac further than ever.
Learn More
X Lion! ↙
" ← ←↗ ↑ ↖
↑ ↖
iCloud iOS 5 OSX Lion iPad 2 iPhone
OSThe world’s most advanced desktop operating system advances even further.With over 250 new features including Multi-Touch gestures, Mission Control, full-screen apps, and Launchpad, OS X Lion takes the Mac further than ever.
Learn More
X Lion↑ ↗
← " "↙ ! ↘
! ↘
Size Type Dimensions Display Px Density File Size
Extreme 2276x1400 1x & 2x 446kb
Extra Large
1024x1536 2x 1,745kbExtra Large 512x768 1x 503kb
Large640x960 2x 746kb
Large320x480 1x 223kb
Medium500x750 2x 485kb
Medium250x375 1x 145kb
Size Type Dimensions Display Px Density File Size
Extreme 2276x1400 1x & 2x 446kb
Extra Large
1024x1536 2x 1,745kbExtra Large 512x768 1x 503kb
Large640x960 2x 746kb
Large320x480 1x 223kb
Medium500x750 2x 485kb
Medium250x375 1x 145kb
<picture> Patch <picture alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia"> <!-- <source src="small.jpg"> --> <source src="small.jpg"> <!-- <source src="medium.jpg" media="(min-width: 400px)"> --> <source src="medium.jpg" media="(min-width: 400px)"> <!-- <source src="large.jpg" media="(min-width: 800px)"> --> <source src="large.jpg" media="(min-width: 800px)"> <!-- Fallback content for non-JS browsers. Same src as the initial source element. --> <noscript><img src="small.jpg" alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia"></noscript></picture>
http://www.w3.org/community/respimg/2012/03/15/polyfilling-picture-without-the-overhead/
<img src="rock-climber.jpg" alt="" />
One Image, One IMG
Clown Car SVG<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 329" preserveAspectRatio="xMidYMid meet"> <title>Clown Car Technique</title> <style> svg { background-size: 100% 100%; background-repeat: no-repeat; } @media screen and (max-width: 400px) { svg {background-image: url(images/small.png");} } @media screen and (min-width: 401px) and (max-width: 700px) { svg {background-image: url(images/medium.png);} } @media screen and (min-width: 701px) and (max-width: 1000px) { svg {background-image: url(images/big.png);} } @media screen and (min-width: 1001px) { svg {background-image: url(images/huge.png);} } </style></svg>
https://github.com/estelle/clowncar
Clown Car SVG<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 329" preserveAspectRatio="xMidYMid meet"> <title>Clown Car Technique</title> <style> svg { background-size: 100% 100%; background-repeat: no-repeat; } @media screen and (max-width: 400px) { svg {background-image: url(images/small.png");} } @media screen and (min-width: 401px) and (max-width: 700px) { svg {background-image: url(images/medium.png);} } @media screen and (min-width: 701px) and (max-width: 1000px) { svg {background-image: url(images/big.png);} } @media screen and (min-width: 1001px) { svg {background-image: url(images/huge.png);} } </style></svg>
https://github.com/estelle/clowncar
http://coding.smashingmagazine.com/2013/06/02/clown-car-technique-solving-for-adaptive-images-in-responsive-
web-design/
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 375 231" preserveAspectRatio="xMidYMid meet" tabindex="-1" aria-label="the aria label is being read" role="img" title="the title attribute of the SVG is being read"> <title>Clown Car Technique</title> <style> </style></svg>
http://codepen.io/teleject/pen/KlzBe
Combo Move: SVG
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 375 231" preserveAspectRatio="xMidYMid meet" tabindex="-1" aria-label="the aria label is being read" role="img" title="the title attribute of the SVG is being read"> <title>Clown Car Technique</title> <style> </style> <foreignObject> <!--[if lte IE 8]> <img src="../images/mobile-first.png" width="375" height="231" alt="put alt attribute text here"/> <![endif]--> </foreignObject></svg>
http://codepen.io/teleject/pen/KlzBe
svg { background-size: 100% 100%; background-repeat: no-repeat; }
http://codepen.io/teleject/pen/KlzBe
Combo Move: SVG
svg { background-size: 100% 100%; background-repeat: no-repeat; } @media screen and (max-width: 400px) { svg { background-image: url("http://s.cdpn.io/168/[email protected]"); outline: green solid 5px; } }
http://codepen.io/teleject/pen/KlzBe
Combo Move: SVG
@media screen and (min-width: 401px), screen and (max-width: 800px) and (-webkit-min-device-pixel-ratio: 1.75) { svg { background-image: url("http://s.cdpn.io/168/pic-Extreme-2276x1400-72ppi.jpg"); outline: red solid 5px; } }
http://codepen.io/teleject/pen/KlzBe
Combo Move: Compressed JPEG
@media screen and (max-width: 400px) { svg { width: 375px; height: 231px; } }@media screen and (min-width: 401px) { svg { width: 750px; height: 462px; } }svg { outline: 5px solid black; }
http://codepen.io/teleject/pen/KlzBe
Combo Move: CSS
http://codepen.io/teleject/pen/KlzBe
http://codepen.io/teleject/pen/KlzBe
http://codepen.io/teleject/pen/KlzBe
COMBO MOVEDON’T BLAME THE PLAYER
1
2
3
No additional HTTP request1
Min. # of images = 2
No JavaScript
http://codepen.io/teleject/pen/KlzBe
IMGGIMME THAT NEW SCHOOL
1
2
3
IMGGIMME THAT NEW SCHOOL
1
2
3
simple design for users
#rwdimg
1
IMGGIMME THAT NEW SCHOOL
1
2
3
simple design for users
browser, server handshake
#rwdimg
2
IMGGIMME THAT NEW SCHOOL
1
2
3
simple design for users
browser, server handshake
same, several formats
#rwdimg
3
#rwdimg
#rwdimg
#rwdimg
#rwdimg
#rwdimg
#rwdimg
#rwdimg
#rwdimg
<link rel="shortcut icon" href="/assets/favicon.ico" />
Favicon
#rwdimg
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="apple-touch-icon-144x144-precomposed.png" />
<link rel="apple-touch-icon-precomposed" sizes="114x114"href="apple-touch-icon-114x114-precomposed.png" />
<link rel="apple-touch-icon-precomposed" sizes="72x72"href="apple-touch-icon-72x72-precomposed.png" />
<link rel="apple-touch-icon-precomposed" href="apple-touch-icon-precomposed.png" />
Mobile iOS Bookmarks
#rwdimg
THANK YOU!CHRISTOPHER SCHMITT @teleject
The Non Breaking Space Podcast - http://nonbreakingspace.tv/