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