Images Retina automatiques pour les sites Web

104

Avec le nouvel Apple MacBook Pro avec écran Retina, si vous fournissez une image «standard» sur votre site Web, ce sera un peu flou. Vous devez donc fournir une image de la rétine.

Existe-t-il un moyen de basculer automatiquement vers les @2ximages, comme le fait iOS (avec Objective-C)? Ce que j'ai trouvé, c'est: CSS pour les images haute résolution sur les écrans mobiles et rétine , mais j'aimerais pouvoir trouver un processus automatique pour toutes mes images, sans CSS ni JavaScript .

C'est possible?

MISE À JOUR
Je voudrais souligner cet article intéressant suggéré par @Paul D. Waite et une discussion intéressante à ce sujet liée par Sebastian .

jan267
la source
6
retinajs.com
Stephan Bönnemann-Walenta
3
Vous pouvez le faire côté serveur avec PHP: retina-images.complexcompulsions.com
ReLeaf
2
@ michaelward82: pour les images photographiques, Daan Jobsis suggère que vous pouvez servir des images de la taille de la rétine à tout le monde sans que la taille de vos fichiers ne soit plus grande que les images sans rétine , en augmentant la quantité de compression JPG appliquée à l'image. Le fait que l'image soit affichée à l'échelle réduite ou sur un écran Retina signifie souvent que les artefacts de compression ne sont pas visibles.
Paul D.Waite
1
En fait, ce n'est pas faux , mais je me demandais s'il y avait une astuce à utiliser. Sous iOS, c'est automatique ... c'est pourquoi je le demande! :)
jan267
2
Notez que l'auteur de l '"article intéressant suggéré" a commis de grosses erreurs qui sont décrites ici: silev.org/test/Retina-resize.html - donc l'article doit être pris avec un gros grain de sel.
Sebastian

Réponses:

147

Il existe un nouvel attribut pour la balise img qui vous permet d'ajouter un attribut retina src, à savoir srcset. Aucun javascript ou CSS nécessaire, pas de double chargement d'images.

<img src="low-res.jpg" srcset="high-res.jpg 2x">

Prise en charge du navigateur: http://caniuse.com/#search=srcset

Autres ressources:

ebuat3989
la source
<img src = "LaunchAirportIcon.png" srcset = "[email protected] 2x">
malhal
7
Ce n'est plus seulement un kit Web, Edge & Firefox le prend également en charge. caniuse.com/#search=srcset - donc actuellement ~ 64% des utilisateurs dans le monde. Ensuite, tenez compte du fait que très peu d'utilisateurs hi-DPI seront sur les navigateurs non pris en charge (IE et ancien Android), et enfin qu'il est sécurisé - les utilisateurs sans support voient simplement une image DPI normale. Je pense vraiment qu'il est prêt à être utilisé.
andrewb
1
De plus, aucun double chargement n'est un énorme avantage. Cela signifie que vous ne gaspillez jamais la bande passante de qui que ce soit.
andrewb
IE échoue encore une fois. Mais malgré cela, je suis d'accord avec @andrewb. Pour construire sur son commentaire, je fournis le x2 à l'intérieur de srcdonc IE / Opera demandera toujours la version DPI supérieure.
Ricky Boyce
1
Cela devrait être la réponse acceptée. C'est de loin la solution la plus simple pour ce fil.
Julien Le Coupanec
14

Il existe différentes solutions, chacune avec ses avantages et ses inconvénients. Le choix qui vous convient le mieux dépend de divers facteurs, tels que la conception de votre site Web, le type de technologie que vos visiteurs habituels utilisent, etc. Notez que les écrans Retina ne se limitent pas au Macbook Pro Retina et aux iMac à venir, mais incluent également appareils mobiles, qui peuvent avoir leurs propres besoins.

Le problème est également étroitement lié aux images dans les conceptions réactives en général. En fait, il est probablement préférable d'utiliser des techniques de conception réactive génériques, au lieu de concevoir pour des appareils spécifiques. Après tout, la technologie continuera également à changer tout le temps à l'avenir.

Certaines des solutions / discussions que j'ai notées:

  • Des vecteurs dans la mesure du possible, y compris des techniques CSS (dégradés, coins arrondis, etc.), SVG et polices d'icônes.
  • Servir des images haute résolution ("retina"), mais les compresser davantage (qualité JPEG), comme suggéré par Yoav Weiss , ou laisser les réseaux mobiles les compresser quand on en a vraiment besoin (c'est-à-dire quand ils sont mobiles), comme suggéré par Paul Boag .
  • Adaptive Images , une solution (principalement) côté serveur. Il est basé sur un cookie stockant la résolution de l'écran, un serveur Web configuré pour servir des images à partir d'un script PHP, et un script nommé pour lire le cookie et servir l'image appropriée.
  • Un tas de possibilités bien décrites et discutées sur Smashing Magazine .
  • Servir des résolutions légèrement plus élevées pour lisser un peu la représentation de la rétine, comme suggéré dans une vidéo de Paul Boag .
  • La technique @ 1.5x sur A List Apart est fondamentalement la même idée.
  • Dans un futur proche, le <picture>tag pourrait devenir une solution soutenue par un groupe de travail du W3C et même Apple.
  • Une technique JavaScript proposée par Jake Archebald .
  • Une discussion approfondie des différentes techniques sur Smashing Magazine et du problème en général.

Comme le montrent les autres réponses, il existe encore plus de techniques - mais probablement aucune meilleure pratique pour le moment.

Une chose que je me demande, c'est comment tester et déboguer certaines de ces techniques, sans avoir le ou les périphériques respectifs disponibles ...

bhell
la source
11

Puisque personne n'a encore mentionné l'évidence, je vais le faire flotter là-bas: si possible, utilisez simplement SVG. Ils apparaissent à de belles résolutions de rétine sans aucun effort.

Le support est bon, IE8 étant le principal dinosaure dont il faut s'inquiéter. Les tailles de fichier gzippées sont souvent meilleures que les formats bitmap (png / jpg) et les images sont plus flexibles; vous pouvez les réutiliser à des résolutions différentes et les redéfinir si nécessaire, ce qui économise à la fois du temps de développement et de la bande passante de téléchargement.

svachalek
la source
J'aime ton indice! Le seul problème svgavec les anciens navigateurs.
jan267
15
Et les cas où vous avez des photos
Baumr
En effet, ils sont excellents à condition que vous ayez une version vectorielle de l'image que vous souhaitez utiliser, mais je ne pense pas que vous puissiez enregistrer des images raster normales au format SVG.
Chuck Le Butt
Il n'y a pas de "bon" moyen de convertir dans cette direction, donc le "si possible". Mais à l'exception des sites de photographie, etc., vous allez généralement créer vos ressources artistiques, je vous recommande donc de les faire sous forme de vecteurs, qui peuvent facilement être convertis en raster si vous le souhaitez, à n'importe quelle résolution.
svachalek
SVG ne fonctionne pas pour les captures d'écran (par exemple lors de la documentation des fonctionnalités de l'interface utilisateur).
Greg Brown
9

Voici le moins de mixin que j'utilise pour réaliser cela pour les images d'arrière-plan. retina.js ne fonctionne pas pour les images d'arrière-plan si vous utilisez dotLess, car il nécessite son propre mixin qui lui-même utilise une évaluation de script qui n'est pas prise en charge dans dotLess.

L'astuce avec tout cela est d'obtenir le support IE8. Il ne peut pas facilement faire la taille de l'arrière-plan, donc le cas de base (requête multimédia non mobile) doit être une icône simple et non mise à l'échelle. La requête multimédia gère alors le cas de la rétine et est libre d'utiliser la classe de taille d'arrière-plan puisque la rétine ne sera jamais utilisée sur IE8.

.retina-background-image( @path, @filename,@extension, @size )
{
     .background-size( cover );
     background-image: url( "@{path}@{filename}@{extension}" );
         @media only screen and ( -webkit-min-device-pixel-ratio: 2 ),
                only screen and ( -moz-min-device-pixel-ratio: 2 ),
                only screen and ( -o-min-device-pixel-ratio: 2/1 ),
                only screen and ( min-device-pixel-ratio: 2 )
         {
             background-image:url( "@{path}@{filename}@x2@{extension}" );
             background-size:@size @size;
         }
}

Échantillon d'utilisation:

.retina-background-image( "../references/Images/", "start_grey-97_12", ".png", 12px );

Cela nécessite que vous ayez deux fichiers:

Où le 2xfichier est en double résolution pour la rétine.

muzzamo
la source
8

Fournissez simplement des images de rétine à tout le monde et réduisez l'image à la moitié de sa taille native à l'intérieur de l'élément d'image. Comme disons que votre image est 400pxlarge et haute - spécifiez simplement la largeur de l'image 200pxpour la rendre nette comme ceci:

<img src="img.jpg" width="200px" height="200px" />

Si votre image est photographique, vous pouvez probablement augmenter la compression JPG dessus sans l'aggraver, car les artefacts de compression JPG ne seront probablement pas visibles lorsque l'image est affichée sur 2x: voir http://blog.netvlies.nl/ design-interactie / retina-revolution /

webdev
la source
1
Daan Jobsis suggère que pour les images photographiques, cela ne doit même pas entraîner des fichiers de plus grande taille: voir blog.netvlies.nl/design-interactie/retina-revolution
Paul D. Waite
Dans l'idéal, vous devez cependant spécifier une hauteur, afin que le navigateur puisse disposer la page avant que l'image ne soit téléchargée.
Paul D.Waite
8
Je ne pense pas que ce soit une bonne idée de fournir un fichier image plus grand et plus lourd si ce n'est nécessaire ...
jan267
1
@ PaulD.Waite intéressant pour la première chose et exactement pour la fin! :)
jan267
2
@ PaulD.Waite Notez que l'auteur de l'article lié a commis de grosses erreurs qui sont discutées ici: silev.org/test/Retina-resize.html - donc l'article doit être pris avec un gros grain de sel. Surtout le fait que "l'image non mise à l'échelle à droite" est en fait mise à l'échelle et ne peut donc pas vraiment être comparée à celle dont la résolution est doublée exactement (dites à votre navigateur d'afficher les bonnes images dans une nouvelle fenêtre et vous verrez ce que moi et l'auteur de cet autre article signifie)
Sebastian
1

si ses images d'arrière-plan, un moyen simple de le faire est:

    #image { background: url(image.png); }

@media only screen and (-webkit-min-device-pixel-ratio: 2),
       only screen and (-moz-min-device-pixel-ratio: 2),
       only screen and (-o-min-device-pixel-ratio: 2/1),
       only screen and (min-device-pixel-ratio: 2) {
           #image { background: url([email protected]); background-size: 50%; }
}

un autre moyen simple consiste à utiliser cette méthode:

Remplacez simplement:

<img src="image.jpg" alt="" width="200" height="100" />

avec

<img src="[email protected]" alt="" width="200" height="100" />
SonnyP
la source
1

J'ai trouvé cette manière intéressante de fournir des images à plusieurs résolutions.
Il utilise en fait CSS, ce que je voulais éviter, et ne fonctionne que dans Safari et Chrome.
Je parle de image-set.

Voici un exemple , fourni par Apple ( ici ):

header {
    background: -webkit-image-set( url(images/header.jpg)    1x,
                                   url(images/header_2x.jpg) 2x);
    height: 150px; /* height in CSS pixels */
    width: 800px; /* width in CSS pixels */
}

Je veux partager aussi ces deux liens:

jan267
la source
1

Avec JSF, vous pouvez créer une balise Facelets personnalisée pour éviter d'avoir à ajouter srcsetà chaque image.

Dans votre taglib.xmlvous pourriez avoir quelque chose comme:

<tag>
  <tag-name>img</tag-name>
  <source>tags/img.xhtml</source>
  <attribute>
    <name>src2x</name>
    <required>true</required>
    <type>java.lang.String</type>
  </attribute>
</tag>

Et votre tag pourrait ressembler à quelque chose comme:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:fn="http://xmlns.jcp.org/jsp/jstl/functions"
                xmlns:ui="http://xmlns.jcp.org/jsf/facelets">

  <img src="#{fn:replace(src2x, '@2x', '')}"
       srcset="#{src2x} 2x"/>

</ui:composition>

Qui pourrait être utilisé comme:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:myTag="http://your.com/namespace-of-taglib">
  <myTag:src2x="[email protected]"/>
</html>

Et rendra:

<img src="image.jpg"
     srcset="[email protected] 2x"/>
Jaspe de Vries
la source
0

Ce problème est particulièrement délicat avec les sites réactifs où l'image et la largeur peuvent varier en fonction de la taille du navigateur. De même, lorsque j'ai affaire à un CMS où plusieurs éditeurs téléchargent potentiellement des milliers d'images, il me semblait irréaliste de demander aux gens de télécharger des images spécialement compressées.

J'ai donc écrit un script qui prend cela en compte, il se déclenche en bas de page et à la fin du redimensionnement. A chaque fois en tenant compte de la densité de pixels et de la taille occupée par l'image.

http://caracaldigital.com/retina-handling-code/

Keegan 82
la source
0

Si vous n'êtes pas frustré par la peur d'utiliser java-script, voici un bon article http://www.highrobotics.com/articles/web/ready-for-retina.aspx . Il a une solution très simple.

Et l' exemple de JSFiddle vaut mille mots.

En utilisant:

<img onload="getImgSrc(this,'image_x1.png')" width="100" height="100" />

JS:

/* RETINA READY IMG SRC */
function getImgSrc(img, src) {
    var srcResult = src;
    // if high-res screen then change _x1 on _x2
    if (window.devicePixelRatio > 1 && 
        src.indexOf("_x1.")>=0) {
          srcResult = src.replace("_x1.", "_x2.");
    }
    img.onload = null; //protect from second rasing
    img.src = srcResult;    
}

$(document).ready(function(){
  // fire onload trigger on IMG tags that have empty SRC attribute
  var images = $('img:not([src=""])');
    images.each(function(i) {
        $(this).trigger('onload');            
    });
});
Artru
la source