Comment masquer une image cassée en utilisant uniquement CSS / HTML?

194

Comment puis-je masquer l'icône d'image cassée? Exemple : Exemple

J'ai une image avec l'erreur src:

<img src="Error.src"/>

La solution doit fonctionner dans tous les navigateurs.

Geray Suinov
la source
1
J'ai essayé de définir alt = "", et de définir sur img teg background throw CSS live: {background: url (src), width: ...; hauteur: ..} mais ce n'est pas vrai. Ma balise img doit se cacher puis src est cassé.
Geray Suinov le
Voir une solution possible ici - stackoverflow.com/questions/18484753/... mais nécessite cependant JS. Vous ne pouvez pas faire cela avec CSS seul.
JohanVdR
Voir l' attribut « onerror » w3schools.com/jsref/event_onerror.asp
Amy.js

Réponses:

274

Il n'y a aucun moyen pour CSS / HTML de savoir si l'image est un lien cassé, vous devrez donc utiliser JavaScript quoi qu'il arrive

Mais voici une méthode minimale pour masquer l'image ou remplacer la source par une sauvegarde.

<img src="Error.src" onerror="this.style.display='none'"/>

ou

<img src="Error.src" onerror="this.src='fallback-img.jpg'"/>

Mettre à jour

Vous pouvez appliquer cette logique à plusieurs images à la fois en faisant quelque chose comme ceci:

document.addEventListener("DOMContentLoaded", function(event) {
   document.querySelectorAll('img').forEach(function(img){
  	img.onerror = function(){this.style.display='none';};
   })
});
<img src="error.src">
<img src="error.src">
<img src="error.src">
<img src="error.src">

Mise à jour 2

Pour une option CSS, voir la réponse de michalzuber ci-dessous. Vous ne pouvez pas masquer l'image entière, mais vous modifiez l'apparence de l'icône cassée.

Kevin Jantzer
la source
3
Vous pouvez le faire avec HTML uniquement en utilisant la balise object car elle peut être utilisée pour afficher des images comme la balise img, et n'affiche pas un lien cassé si l'image n'existe pas, cela fonctionne dans tous les navigateurs et aussi loin en arrière comme IE8 tout seul, vous pouvez même utiliser des images par défaut avec cette méthode, j'ai posté une réponse avec des détails ci-dessous.
Nick Steele
1
Cela a fonctionné pour moi au lieu de l'approche <object> car j'avais besoin que l'image ait une marge déclarée, mais seulement si une image valide était trouvée, sinon j'avais besoin qu'elle prenne zéro espace. <object> n'a pas l'événement onerror, donc ce n'était pas une option ici. Une règle de style pour supprimer la marge, à l'aide d'une pseudo-classe: empty, n'a jamais été déclenchée sur l'objet.
John Hatton
J'ai une question. est-il possible de donner le script commun à appliquer pour chaque balise d'image sur la page au lieu de donner cette ligne particulière de script dans chaque balise d'image. merci @Kevin jantzer
Lemdor
1
@Lemdor - oui, vous auriez besoin de trouver des images lors du chargement et d'attacher la fonction commune à chacune. Vous pouvez utiliser jQuery ou vanilla JS pour accomplir cela (j'ai mis à jour ma réponse avec un exemple)
Kevin Jantzer
Dans reactJs, il est très facile de faire cela, le même principe s'applique là-bas. Vous avez trouvé ce tutoriel ici - youtu.be/90P1_xCaim4 . L'ajout d'un préchargeur ( youtu.be/GBHBjv6xfY4 ) pour l'image masque la transition et contribue à fournir une bonne UX.
Prem
143

Malgré ce que les gens disent ici, vous n'avez pas du tout besoin de JavaScript, vous n'avez même pas besoin de CSS !!

C'est en fait très faisable et simple avec HTML uniquement. Vous pouvez même afficher une image par défaut si une image ne se charge pas . Voici comment...

Cela fonctionne également sur tous les navigateurs, même aussi loin que IE8 (sur plus de 250000 visiteurs de sites que j'ai hébergés en septembre 2015, ZERO personnes utilisaient quelque chose de pire que IE8, ce qui signifie que cette solution fonctionne pour littéralement tout. ).

Étape 1: l'image de référence comme un objet au lieu d'un img . Lorsque les objets échouent, ils n'affichent pas d'icônes brisées; ils ne font simplement rien. À partir d'IE8, vous pouvez utiliser les balises Object et Img de manière interchangeable. Vous pouvez redimensionner et faire tout ce que vous pouvez avec des images régulières. N'ayez pas peur de la balise d'objet; c'est juste une balise, rien de gros et d'encombrant n'est chargé et cela ne ralentit rien. Vous utiliserez simplement la balise img sous un autre nom. Un test de vitesse montre qu'ils sont utilisés de manière identique.

Étape 2: (Facultatif, mais génial) Collez une image par défaut à l'intérieur de cet objet. Si l'image que vous souhaitez se charge réellement dans l'objet , l'image par défaut ne s'affiche pas. Ainsi, par exemple, vous pouvez afficher une liste d'avatars d'utilisateurs, et si quelqu'un n'a pas encore d'image sur le serveur, il pourrait afficher l'image d'espace réservé ... pas de javascript ou de CSS requis du tout, mais vous obtenez les fonctionnalités de quoi prend la plupart des gens JavaScript.

Voici le code ...

<object data="avatar.jpg" type="image/jpg">
    <img src="default.jpg" />
</object>

... Oui, c'est aussi simple que cela.

Si vous souhaitez implémenter des images par défaut avec CSS, vous pouvez le rendre encore plus simple dans votre HTML comme ceci ...

<object class="avatar" data="user21.jpg" type="image/jpg"></object>

... et ajoutez simplement le CSS de cette réponse -> https://stackoverflow.com/a/32928240/3196360

Nick Steele
la source
6
D'une manière ou d'une autre, j'ai complètement raté cette idée, alors qu'elle est si évidente rétrospectivement! Malheureusement, je ne pense pas que la balise d'objet puisse gérer avec élégance des images réactives comme nous commençons à le voir sur la propriété img.srcset :(
Windgazer
2
Excellente idée, merci pour ça! Sur une note latérale, la balise d'objet bloque la molette de défilement (dans mon implémentation, au moins) ... si cela vous arrive, utilisez simplement object { pointer-events: none; }dans votre CSS (Source: stackoverflow.com/a/16534300 )
DHainzl
4
Cela brise cependant la sémantique des balises d'image. Je ne sais pas si les moteurs de recherche apprécieront votre utilisation de <object>balises au lieu de <img>balises. Cette approche est-elle compatible HTML5 et rendue correctement par tous les principaux navigateurs?
Pieter
6
Ceci est compatible HTML4 (conforme depuis 1997) et rendu correctement par tous les principaux navigateurs depuis IE8 / 2009 (d'autres navigateurs l'ont fait beaucoup, beaucoup plus tôt). Si un moteur de recherche ne comprend pas qu'un objet avec un type d'image est une image, il a eu 19 ans pour se mettre à jour, donc ce n'est probablement pas un très bon moteur ... même conçue lorsque cette solution répondait aux spécifications ... Jusqu'où voulez-vous remonter? :) C'est une solution solide comme le roc.
Nick Steele
6
@MonsterMMORPG car il n'utilise pas JavaScript et vous n'êtes pas toujours autorisé à le faire (dans le corps d'un e-mail, par exemple).
ForNeVeR
63

J'ai trouvé une excellente solution sur https://bitsofco.de/styling-broken-images/

img {  
  position: relative;
}

/* style this to fit your needs */
/* and remove [alt] to apply to all images*/
img[alt]:after {  
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: #fff;
  font-family: 'Helvetica';
  font-weight: 300;
  line-height: 2;  
  text-align: center;
  content: attr(alt);
}
<img src="error">
<br>
<img src="broken" alt="A broken image">
<br>
<img src="https://images-na.ssl-images-amazon.com/images/I/218eLEn0fuL.png" alt="A bird" style="width: 120px">

michalzuber
la source
1
Solution géniale utilisant uniquement CSS qui devrait être la réponse acceptée. L'article lié à est obsolète, car la prise en charge des navigateurs est désormais de 97,87%: caniuse.com/#feat=css-gencontent .
holm50
1
L' article lié a une excellente explication sur la façon dont les navigateurs gèrent les images, mais gardez à l'esprit que cette solution ne fonctionne que si vous avez un arrière-plan uni et que vous souhaitez tout couvrir avec une autre boîte de la même couleur unie, ou avec une autre image. Cette solution ne supprime pas ou ne cache pas vraiment l'icône d'image cassée, elle la recouvre simplement.
Claudio Floreani
3
Sur Chrome 70, il montre l'oiseau + une icône d'image cassée :(
Simon Arnold
2
^ Idem sur Firefox 63
dsturbid
1
@dailysleaze - Sur Firefox 64+, cela a été déplacé vers img[alt]::before. Vous pouvez l'utiliser display:inline-blocksi vous le souhaitez, car il est plus proche de l'original.
Adam Katz
41

Si vous ajoutez alt avec le texte alt = "abc", il affichera la vignette corrompue et le message alt abc

<img src="pic_trulli.jpg" alt="abc"/>

1er

Si vous n'ajoutez pas d'alt, il affichera la vignette corrompue

<img src="pic_trulli.jpg"/>

2e

Si vous voulez masquer le cassé, ajoutez simplement alt = "" il n'affichera pas de vignette corrompue ni de message alt (sans utiliser js)

<img src="pic_trulli.jpg" alt=""/>

Si vous voulez masquer celui qui est cassé, ajoutez simplement alt = "" & onerror = "this.style.display = 'none'" il n'affichera pas de vignette corrompue ni de message alt (avec js)

<img src="pic_trulli.jpg" alt="abc" onerror="this.style.display='none'"/>

Le quatrième est un peu dangereux (pas exactement), si vous voulez ajouter une image dans un événement onerror, il ne s'affichera pas même si Image existe en tant que style.display, c'est comme l'ajout. Alors, utilisez-le lorsque vous n'avez besoin d'aucune image alternative pour afficher.

display: 'none'; // in css

Si nous le donnons en CSS, alors l'élément ne s'affichera pas (comme image, iframe, div comme ça).

Si vous souhaitez afficher l'image et que vous souhaitez afficher un espace totalement vide en cas d'erreur, vous pouvez l'utiliser, mais faites également attention que cela ne prendra pas de place. Donc, vous devez le garder dans un div peut être

Lien https://jsfiddle.net/02d9yshw/

P Satish Patro
la source
2
OUI! Ajoutez juste alt=""! C'est littéralement ça! Je vous remercie. Tellement content d'avoir fait défiler vers le bas de la page. J'utilise le chargement paresseux et les images dans le cadre qui ne sont pas encore chargées (car le navigateur pense à tort que la fenêtre ne les a pas encore faites défiler) s'affichent comme des images cassées. Un petit rouleau, et ils réapparaissent. Les images brisées à leur place étaient si laides cependant
velkoon
25

Je pense que le moyen le plus simple est de masquer l'icône d'image cassée par la propriété text-indent.

img {
    text-indent: -10000px
}

Évidemment, cela ne fonctionne pas si vous voulez voir l'attribut "alt".

Burnee
la source
1
Le moyen le plus simple.
theerasan tonthongkam
17

au cas où vous voudriez garder / avoir besoin de l'image comme espace réservé, vous pouvez changer l'opacité à 0 avec une erreur et du CSS pour définir la taille de l'image. De cette façon, vous ne verrez pas le lien rompu, mais la page se charge normalement.

<img src="<your-image-link->" onerror="this.style.opacity='0'" />

img {
    width: 75px;
    height: 100px;
}
Ewald Bos
la source
16

J'ai aimé la réponse de Nick et j'ai joué avec cette solution. J'ai trouvé une méthode plus propre. Puisque :: before / :: after pseudos ne fonctionne pas sur les éléments remplacés comme img et object, ils ne fonctionneront que si les données de l'objet (src) ne sont pas chargées. Il maintient le HTML plus propre et n'ajoutera le pseudo que si l'objet ne se charge pas.

object {
  position: relative;
  float: left;
  display: block;
  width: 200px;
  height: 200px;
  margin-right: 20px;
  border: 1px solid black;
}
object::after {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  width: 100%;
  height: 100%;
  content: '';
  background: red url("http://placehold.it/200x200");
}
<object data="http://lorempixel.com/200/200/people/1" type="image/png"></object>

<object data="http://broken.img/url" type="image/png"></object>

Bartezz
la source
9

Si vous avez besoin de garder le conteneur d'image visible car il sera rempli plus tard et que vous ne voulez pas vous soucier de le montrer et de le cacher, vous pouvez coller une image transparente 1x1 à l'intérieur du src:

<img id="active-image" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/>

Je l'ai utilisé dans ce but précis. J'avais un conteneur d'image dans lequel une image allait être chargée via Ajax. Parce que l'image était grande et prenait un peu de temps à charger, il fallait définir une image d'arrière-plan en CSS d'une barre de chargement Gif.

Cependant, comme le src du était vide, l'icône d'image cassée apparaissait toujours dans les navigateurs qui l'utilisent.

La définition du Gif 1x1 transparent résout ce problème simplement et efficacement sans ajout de code via CSS ou JavaScript.

user2596313
la source
seule réponse qui a fonctionné toutes les autres ont laissé un contour blanc
futurelucas4502
8

Utiliser uniquement du CSS est difficile, mais vous pouvez utiliser des CSS au background-imagelieu de <img>balises ...

Quelque chose comme ça:

HTML

<div id="image"></div>

CSS

#image {
    background-image: url(Error.src);
    width: //width of image;
    height: //height of image;

}

Voici un violon qui fonctionne .

Remarque: j'ai ajouté la bordure dans le CSS sur le violon juste pour montrer où l'image serait.

Dryden Long
la source
C'est bien, mais cette solution n'est pas pour moi :) tag img masqué puis src est cassé, div - non :(
Geray Suinov
@GeraySuinov Ensuite, vous devrez peut-être utiliser Javascript
Dryden Long
4

Utilisez la balise d'objet. Ajoutez un texte alternatif entre les balises comme ceci:

<object data="img/failedToLoad.png" type="image/png">Alternative Text</object>

http://www.w3schools.com/tags/tag_object.asp

ThomasAFink
la source
3

Depuis 2005 , les navigateurs Mozilla tels que Firefox prennent en charge la :-moz-brokenpseudo-classe CSS non standard qui peut accomplir exactement cette requête:

td {
  min-width:64px; /* for display purposes so you can see the empty cell */
}

img[alt]:-moz-broken {
  display:none;
}
<table border="1"><tr><td>
  <img src="error">
</td><td>
  <img src="broken" alt="A broken image">
</td><td>
  <img src="https://images-na.ssl-images-amazon.com/images/I/218eLEn0fuL.png"
       alt="A bird" style="width: 120px">
</td></tr></table>

img[alt]::beforefonctionne également dans Firefox 64 (même si il était une fois img[alt]::afterdonc ce n'est pas fiable). Je ne peux pas faire fonctionner l'un ou l'autre de ces éléments dans Chrome 71.

Adam Katz
la source
Intéressant ... savez-vous si Chrome a une pseudo-classe similaire?
1000Gbps le
1
@ 1000Gbps - Je n'ai pas pu en trouver une lorsque j'ai fait cette réponse et je ne peux pas en trouver une maintenant, au moins avec des requêtes Web rapides et en regardant le bug mozilla 11011 . Vous pouvez en fait demander une telle chose dans Chromium (l'amont pour Chrome) si vous le souhaitez, mais comme ce n'est pas standard, rien ne garantit qu'ils le feront.
Adam Katz le
Je doute fort qu'ils le fassent en peu de temps, compte tenu du fait qu'ils ont eu du mal à gérer certains bugs désagréables que j'ai signalés là-bas ... Peu importe le fait que des pseudo-classes intégrées comme celle-ci seront supprimées de frameworks beaucoup de code JS écrit pour la même raison
1000Gbps
2

Vous pouvez suivre ce chemin comme une solution css

img {
        width:200px;
        height:200px;
        position:relative
   }
img:after {
        content: "";
        position: absolute;
        top: 0;
        left: 0;
        width: inherit;
        height: inherit;
        background: #ebebeb url('http://via.placeholder.com/300?text=PlaceHolder') no-repeat center;
        color: transparent;
    }
<img src="gdfgd.jpg">

Cenk YAGMUR
la source
Je pensais d'abord que c'était une bonne solution, mais cela ne fonctionne pas sur IE. Aussi pas lors de l'ajout d'un bloc d'affichage dans le css après
Glenn Franquet
1

Les images manquantes n'afficheront rien, ou afficheront un [? ] boîte de style lorsque leur source est introuvable. Au lieu de cela, vous voudrez peut-être remplacer cela par un graphique «image manquante» dont vous êtes sûr qu'il existe afin qu'il y ait une meilleure rétroaction visuelle que quelque chose ne va pas. Ou, vous pourriez vouloir le cacher entièrement. Cela est possible, car les images qu'un navigateur ne peut pas trouver déclenchent un événement JavaScript "d'erreur" que nous pouvons surveiller.

    //Replace source
    $('img').error(function(){
            $(this).attr('src', 'missing.png');
    });

   //Or, hide them
   $("img").error(function(){
           $(this).hide();
   });

De plus, vous souhaiterez peut-être déclencher une sorte d'action Ajax pour envoyer un e-mail à un administrateur du site lorsque cela se produit.

Ali Panahian
la source
1

L'astuce avec img::afterest une bonne chose, mais a au moins 2 inconvénients:

  1. non pris en charge par tous les navigateurs (par exemple, ne fonctionne pas sur Edge https://codepen.io/dsheiko/pen/VgYErm )
  2. vous ne pouvez pas simplement masquer l'image, vous la couvrez - donc pas si utile lorsque vous voulez afficher une image par défaut dans le cas

Je ne connais pas de solution universelle sans JavaScript, mais pour Firefox seulement il y en a une belle:

img:-moz-broken{
  opacity: 0;
}
Dmitry Sheiko
la source
0

La même idée que celle décrite par d'autres fonctionne dans React comme suit:

<img src='YOUR-URL' onError={(e) => e.target.style.display='none' }/>
Christian Fritz
la source
-3

Un moyen basique et très simple de faire cela sans aucun code requis serait de simplement fournir une instruction alt vide. Le navigateur renverra alors l'image comme vierge. Cela ressemblerait à si l'image n'était pas là.

Exemple:

<img class="img_gal" alt="" src="awesome.jpg">

Essayez-le pour voir! ;)

utilisateur45678
la source
10
Cela dépend du navigateur. Dans Chrome, vous aurez toujours la bordure d'image et l'icône d'image cassée en plus du texte alternatif (ici vide).
panzi
Si l'image est décorative et non impérative pour le contenu, un alt vide convient. En fait, il est recommandé de ne pas utiliser d'alt du tout. Sinon, cela est fortement déconseillé. Une image cassée est une image qui ne peut pas être vue, mais si elle a une balise alt, elle peut au moins être entendue. Si vous supprimez la balise alt, elle ne peut pas être vue OU entendue.
JP DeVries
2
@panzi J'ai testé la solution et il semble que Chrome ait changé son comportement. Il ne rendra pas l'icône d'image cassée si alt="". Il en va de même pour Firefox.
Philipp Mitterer
-4

Pour les futurs googleurs, en 2016, il existe un moyen CSS pur et sécurisé pour le navigateur de masquer les images vides à l'aide du sélecteur d'attributs:

img[src="Error.src"] {
    display: none;
}

Edit: Je suis de retour - pour les futurs googleurs, en 2019, il existe un moyen de styliser le texte alternatif et l'image de texte alternatif dans le Shadow Dom, mais cela ne fonctionne que dans les outils de développement. Vous ne pouvez donc pas l'utiliser. Désolé. Ce serait si gentil.

#alttext-container {
    opacity: 0;
}
#alttext-image {
    opacity: 0;
}
#alttext {
    opacity: 0;
}
VerticalGrain
la source
1
img[src=''] { display: none; } Cela est redevenu pertinent avec les modèles eBay uniquement html
IMOS