Responsive Images
MobileTech Conference, Berlin 04.09.2013
Sven Wolfermann | maddesigns
MobileTech Conference, Berlin 04.09.2013
Sven Wolfermann | maddesigns
Twitter: @maddesigns
Web: http://maddesigns.de

keine statische Breitenangaben
img, embed, object, video {
max-width: 100%;
}
Für Medien muss im CSS eine flexible Breite gesetzt werden, die Höhe soll sich automatisch in Relation anpassen.
img, embed, object, video {
max-width: 100%; /* max. width original px */
height: auto;
/* width: auto; */
}
Statistik von cartoonized.net




Tests des Ladeverhalten mobiler Browser
Beispiel: Test CSS-Hintergrundbilder
<div class="test5"></div>
@media all and (min-width: 601px) {
.test5 {
background-image: url("img/test5-desktop.png");
}
}
@media all and (max-width: 600px) {
.test5 {
background-image: url("img/test5-mobile.png");
}
}

nur das passende Bild wird geladen, gut!
Eine einfache und gute Lösung meiner Meinung nach, ist die <noscript>-Lösung mit HTML5 data-Attributen
<noscript data-large="Koala-large.jpg"
data-small="Koala-small.jpg"
data-alt="Koala">
<img src="Koala-small.jpg" alt="Koala" />
</noscript>
Vorteil: Assets die im <noscript>-Tag eingebunden sind, werden nicht vom Browser in den DOM eingefügt (und nicht geladen), wenn JavaScript aktiviert ist.
+ Ressourcen werden nicht doppelt geladen
− JavaScript notwendig
jQuery Snippet
$('noscript[data-large][data-small]').each(function(){
var $this = $(this);
var src = screen.width >= 500 ?
$this.data('large') : $this.data('small');
$('<img src="' + src + '" alt="' + $this
.data('alt') + '" />')
.insertAfter($this);
});
<!-- small screen DOM --> <noscript ... > <img src="Koala-small.jpg" alt="Koala" /> </noscript> <img src="Koala-small.jpg" alt="Koala">

Cookie-Snippet so früh wie möglich im <head>
<head> <script> document.cookie='resolution='+Math.max(screen.width,screen.height)+'; path=/'; </script> … </head>
PHP-Script anpassen (global Breakpoints)
$resolutions = array(1382, 992, 768, 480, 320);
<IfModule mod_rewrite.c>
#Enable URL rewriting
RewriteEngine On
Options +FollowSymlinks
#Adaptive Images
#don't apply the AI behaviour to images inside AI's cache folder:
RewriteCond %{REQUEST_URI} !ai-cache
#further directories that shouldn't use AI
RewriteCond %{REQUEST_URI} !cssimages
#Send any GIF, JPG, or PNG request that IS NOT stored inside one of the above directories
RewriteRule ^.*\.(jpg|jpeg|png|gif)$ adaptive-images.php [L]
. . .
</IfModule>


Aktuelle W3C-Diskussion – <picture> Element
Aufbau wie <video> Element
<picture width="500" height="500"> <source src="large.jpg" media="(min-width: 45em)"> <source src="middle.jpg" media="(min-width: 18em)"> <img src="small.jpg" alt=""> <p>Accessible text</p> </picture>
Polyfill für den <picture> Ansatz
<span data-picture data-alt="Alttext">
<span data-src="small.jpg"></span>
<span data-src="medium.jpg" data-media="(min-width: 400px)"></span>
<span data-src="large.jpg" data-media="(min-width: 800px)"></span>
<span data-src="xlarge.jpg" data-media="(min-width: 1000px)"></span>
<!-- Fallback content for non-JS browsers. Same img src as
the initial, unqualified source element. -->
<noscript>
<img src="small.jpg" alt="Alt">
</noscript>
</span>
Markup wie <picture> Ansatz
$(function(){
$('picture').picture();
});
oder <figure>
<figure class="responsive" alt="A Half Brained Idea"
data-media="assets/images/small.png"
data-media440="assets/images/medium.png"
data-media600="assets/images/large.png">
<noscript>
<img src="assets/images/large.png" alt="A Half Brained Idea">
</noscript>
</figure>
<img> durch ein neues Attribut erweitern, das mehrere Bildpfade und -qualitäten enthält
<img alt="The Breakfast Combo"
src="banner.jpeg"
srcset="banner-HD.jpeg 2x,
banner-phone.jpeg 100w,
banner-phone-HD.jpeg 100w 2x">
Das beste aus beiden Vorschlägen
<picture width="500" height="500">
<source media="(min-width: 45em)"
srcset="large-1.jpg 1x, large-2.jpg 2x">
<source media="(min-width: 18em)"
srcset="med-1.jpg 1x, med-2.jpg 2x">
<source srcset="small-1.jpg 1x, small-2.jpg 2x">
<img src="small-1.jpg" alt="">
<p>Accessible text</p>
</picture>
wird mit den Browserherstellern diskutiert, aktuell scheint die Integration vom "srcset"-Attribut voran getrieben zu werden
Support für background-images in Safari 6, Chrome 21
background-image: -webkit-image-set( url(cloud-sd.png) 1x, url(cloud-hd.png) 2x);
<img src="normal-image.jpg" srcset="better-image.jpg 2x">
-› Retina-Support für iOS
Media Queries innerhalb SVG

<img src="file.svg" alt="image">
Vorteil:
+ gut für Bild im Text
Nachteil:
− SVG erst ab Android 4, IE9
− Bild das erscheint, ist nicht das was man herunterladen kann
− Seitenverhältnis bleibt gleich
file.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>

BBC News Technik um Bilder dynamisch und responsive zu laden
<div class="delayed-image-load"
data-src="http://placehold.it/340"
data-width="340"></div>
RESTful Image URL:
http://your-image-service.com/horse/100/

doppelte Pixeldichte, iPhone = 326ppi
Rumor: Apple to double 'iPhone 5S' Retina resolution to 1.5M pixels

Samsung Android Screen Sizes:
2.8, 3.14, 3.2, 3.4, 3.5, 3.6, 3.65, 3.7, 3.97, 4, 4.2, 4.27, 4.3, 4.5, 4.52, 4.65, 4.8, 5, 5.3, 5.5, 5.8, 6.3, 7, 7.7, 8, 10, 10.1 (Tweet von @dkdsgn)
Pixel-Matching auf unterschiedlichen Android-Screens
![]()
kann visuelle „Fehler“ hervorrufen
Problem: hochgezogene Pixel
![]()
mehrere optimierte Grafiken müssen bereit gestellt werden
background-image: -webkit-image-set(
url(cloud-sd.png) 1x, url(cloud-hd.png) 2x);
CSS abhängig von der Pixeldichte
@media only screen and (-webkit-max-device-pixel-ratio: 0.75),
only screen and (max-resolution: 90dpi) {
/* LowDPI CSS */
}
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
only screen and (min-resolution: 144dpi) {
/* HiDPI CSS */
}
@media only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and (min-resolution: 192dpi) {
/* Retina specific CSS */
}
Bildgröße: 400x400px
Qualität: 60
Größe: 49.161 Byte
Bildgröße: 800x800px
Qualität: 15
Größe: 51.289 Byte
<img width="400" src="normal.jpg" alt="">
<img width="400" src="retina.jpg" alt="">
optimal für Logos & Icons
<img src="img/SVG-logo.svg" width="100" alt=""> <img src="img/SVG-logo.svg" width="200" alt=""> <img src="img/SVG-logo.svg" width="300" alt="">Safari 5 Bug: Höhe (height="") muss angegeben werden
|
|
|
|
SVG |
7,57 KB |
51,50 KB |
4,50 KB |
PNG 200px |
6,50 KB |
11,10 KB |
4,18 KB |
PNG 400px |
11,80 KB |
27,60 KB |
8,32 KB |
PNG 800px |
18,50 KB |
72,70 KB |
14,80 KB |
fett = PNG kleiner als SVG
die Datenmenge für kleine PNG-Bilder ist häufig geringer als eine SVG-Grafik
funktionieren wie normale Image-Sprites
.svg .cloud {
background: url(img/SVG_sprites.svg);
}
.no-svg .cloud {
background: url(img/SVG_sprites.png);
}
.cloud {
background-position: 0px 0px;
}
.cloud-active {
background-position: -64px 0px;
}
iconizr.com – SVG-Sprite-Service mit PNG-Fallback-Generierung

Vorteil:
kostenloser Service icomoon.io

HTML
<img src="logo-maddesigns.png" alt="Logo maddesigns"> <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhE...">
CSS
<style>
.logo { background-image: url("logo-maddesigns.png") }
</style>
<style>
.logo { background-image: url("data:image/png;base64,iVBORw...")}
</style>

Beispiel:
Amazon Web Service (AWS) – jedes gesparte Byte kann helfen Kosten zu sparen
das richtige Bildformat je Bildinhalt verwenden!
Online-Tool


kleinere Bilddaten bei vergleichbarer Qualität
nur Chrome (und Opera)
Problematisch: Facebook testete WebP-Bilder, User waren unzufrieden


Apache Modul „Expires Header“ zum Caching verwenden
<IfModule mod_expires.c> ExpiresActive On ExpiresByType text/css "access plus 1 week" ExpiresByType application/javascript "access plus 1 month" ExpiresByType application/x-javascript "access plus 1 month" ExpiresByType image/gif "access plus 1 month" ExpiresByType image/jpeg "access plus 1 month" ExpiresByType image/png "access plus 1 month" </IfModule>
8 Guidelines and 1 Rule for Responsive Images
Sensible jumps in responsive image file sizes
Responsive Images for Ruby on Rails
Riloadr – cross-browser framework-independent responsive images loader
Sven Wolfermann | maddesigns