¿Cómo ocultar el icono roto de la imagen usando solo CSS / HTML?

194

¿Cómo puedo ocultar el icono de imagen rota? Ejemplo : Ejemplo

Tengo una imagen con error src:

<img src="Error.src"/>

La solución debe funcionar en todos los navegadores.

Geray Suinov
fuente
1
Traté de establecer alt = "", y establecer img teg background throw CSS live: {background: url (src), width: ...; altura: ..} pero no es cierto. Mi etiqueta img debe esconderse, entonces src está roto.
Geray Suinov
Vea una posible solución aquí: stackoverflow.com/questions/18484753/… pero necesita JS. No puede hacer esto solo con CSS.
JohanVdR

Respuestas:

274

CSS / HTML no puede saber si la imagen está rota, por lo que tendrá que usar JavaScript sin importar qué

Pero aquí hay un método mínimo para ocultar la imagen o reemplazar la fuente con una copia de seguridad.

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

o

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

Actualizar

Puede aplicar esta lógica a varias imágenes a la vez haciendo algo como esto:

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">

Actualización 2

Para una opción CSS, vea la respuesta de michalzuber a continuación. No puede ocultar toda la imagen, pero cambia la apariencia del icono roto.

Kevin Jantzer
fuente
3
Puede hacerlo con HTML solo usando la etiqueta de objeto, ya que se puede usar para mostrar imágenes al igual que la etiqueta img, y no muestra un enlace roto si la imagen no existe, funciona en todos los navegadores y desde hace mucho tiempo Como IE8 por sí solo, incluso puede usar imágenes predeterminadas con este método, publiqué una respuesta con los detalles a continuación.
Nick Steele
1
Esto funcionó para mí en lugar del enfoque <objeto> porque necesitaba que la imagen tuviera un margen declarado, pero solo si se encontraba una imagen válida, de lo contrario, necesitaba que ocupara un espacio cero. <objeto> no tiene el evento onerror, por lo que esa no era una opción allí. Una regla de estilo para eliminar el margen, usando una: pseudo clase vacía, nunca se activó en el objeto.
John Hatton
Tengo una pregunta. ¿hay alguna manera posible de dar el script común para aplicar para cada etiqueta de imagen en la página en lugar de dar esta línea de script en particular en cada etiqueta de imagen? gracias @Kevin jantzer
Lemdor
1
@Lemdor: sí, necesitaría encontrar imágenes en carga y adjuntar la función común a cada una. Puede usar jQuery o vanilla JS para lograr esto (he actualizado mi respuesta con un ejemplo)
Kevin Jantzer
En reaccionar es muy fácil hacer eso, el mismo principio se aplica allí. Encontré este tutorial aquí: youtu.be/90P1_xCaim4 . Además, agregar un precargador ( youtu.be/GBHBjv6xfY4 ) para la imagen oculta la transición y ayuda a proporcionar una buena experiencia de usuario.
Prem
143

A pesar de lo que la gente dice aquí, no necesitas JavaScript, ¡ni siquiera necesitas CSS!

En realidad, es muy factible y simple solo con HTML. Incluso puede mostrar una imagen predeterminada si una imagen no se carga . Así es cómo...

Esto también funciona en todos los navegadores, incluso desde IE8 (de más de 250,000 visitantes a sitios que alojé en septiembre de 2015, ZERO personas usaron algo peor que IE8, lo que significa que esta solución funciona literalmente para todo ).

Paso 1: haga referencia a la imagen como un objeto en lugar de un img . Cuando los objetos fallan, no muestran iconos rotos; ellos simplemente no hacen nada. A partir de IE8, puede usar las etiquetas Object e Img indistintamente. Puedes cambiar el tamaño y hacer todas las cosas gloriosas que puedas con imágenes regulares también. No tengas miedo de la etiqueta del objeto; es solo una etiqueta, no se carga nada grande y voluminoso y no ralentiza nada. Simplemente usarás la etiqueta img con otro nombre. Una prueba de velocidad muestra que se usan de manera idéntica.

Paso 2: (Opcional, pero impresionante) Pegue una imagen predeterminada dentro de ese objeto. Si la imagen que desea realmente se carga en el objeto , la imagen predeterminada no se mostrará. Entonces, por ejemplo, podría mostrar una lista de avatares de usuario, y si alguien aún no tiene una imagen en el servidor, podría mostrar la imagen de marcador de posición ... no se requiere JavaScript ni CSS, pero obtiene las características de qué toma JavaScript para la mayoría de las personas.

Aquí está el código ...

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

... Sí, es así de simple.

Si desea implementar imágenes predeterminadas con CSS, puede hacerlo aún más simple en su HTML de esta manera ...

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

... y simplemente agregue el CSS de esta respuesta -> https://stackoverflow.com/a/32928240/3196360

Nick Steele
fuente
66
¡De alguna manera extrañé completamente esta idea, cuando es tan obvio en retrospectiva! Desafortunadamente, no creo que la etiqueta del objeto pueda manejar con gracia imágenes receptivas como si empezáramos a ver en la propiedad img.srcset :(
Windgazer
2
Gran idea, gracias por eso! En una nota al margen, la etiqueta de objeto está bloqueando la rueda de desplazamiento (al menos en mi implementación) ... si esto le sucede, simplemente use object { pointer-events: none; }en su CSS (Fuente: stackoverflow.com/a/16534300 )
DHainzl
44
Sin embargo, esto rompe la semántica de las etiquetas de imagen. No sé si a los motores de búsqueda les gustará que uses <object>etiquetas en lugar de <img>etiquetas. ¿Es este enfoque compatible con HTML5 y se representa correctamente en todos los principales navegadores?
Pieter
66
Esto es compatible con HTML4 (compatible desde 1997) y se representa correctamente por todos los principales navegadores desde IE8 / 2009 (otros navegadores lo hicieron mucho, mucho antes). Si un motor de búsqueda no entiende que un objeto con un tipo de imagen es una imagen, ha tenido 19 años para ponerse al día con las especificaciones, por lo que probablemente no sea un motor muy bueno ... Los adolescentes que están en la carretera conduciendo autos ahora no estaban incluso concebido cuando esta solución cumplió con las especificaciones ... ¿Qué tan atrás quieres ir? :) Esta es una solución sólida como una roca.
Nick Steele
66
@MonsterMMORPG porque no usa JavaScript, y no siempre se le permite (en un cuerpo de un mensaje de correo electrónico, por ejemplo).
ForNeVeR
63

Encontré una gran solución en 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
fuente
1
Impresionante solución utilizando puramente CSS, que debería ser la respuesta aceptada. El artículo vinculado está desactualizado, ya que el soporte del navegador ahora es del 97,87%: caniuse.com/#feat=css-gencontent .
holm50
1
El artículo vinculado tiene una excelente explicación sobre cómo los navegadores manejan las imágenes, pero tenga en cuenta que esta solución solo funciona si tiene un fondo sólido y desea cubrir todo con otra caja del mismo color sólido, o con otra imagen. Esta solución no está realmente eliminando u ocultando el icono de imagen rota, solo lo está cubriendo.
Claudio Floreani
3
En Chrome 70, muestra el pájaro + un icono de imagen rota :(
Simon Arnold
2
^ Lo mismo en Firefox 63
dsturbid
1
@dailysleaze: en Firefox 64+, esto se movió a img[alt]::before. Puede usarlo display:inline-blocksi lo desea, ya que está más cerca del original.
Adam Katz
41

Si va a agregar alt con el texto alt = "abc" , mostrará la miniatura corrupta del show y el mensaje alt abc

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

Primero

Si no va a agregar alt, mostrará la miniatura de mostrar corrupto

<img src="pic_trulli.jpg"/>

2do

Si desea ocultar el roto simplemente agregue alt = "" no mostrará una miniatura corrupta y ningún mensaje alternativo (sin usar js)

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

Si desea ocultar el roto simplemente agregue alt = "" & onerror = "this.style.display = 'none'" no mostrará la miniatura corrupta y ningún mensaje alternativo (con js)

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

El cuarto es un poco peligroso (no exactamente), si desea agregar cualquier imagen en un evento de error, no se mostrará incluso si la imagen existe como style.display es como agregar. Por lo tanto, úselo cuando no requiera ninguna imagen alternativa para mostrar.

display: 'none'; // in css

Si lo damos en CSS, entonces el elemento no se mostrará (como imagen, iframe, div así).

Si desea mostrar la imagen y desea mostrar un espacio totalmente en blanco en caso de error, puede usarlo, pero también tenga cuidado de que esto no ocupe ningún espacio. Por lo tanto, debe mantenerlo en un div puede ser

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

P Satish Patro
fuente
2
¡SI! ¡Solo agrega alt=""! ¡Eso es literalmente! Gracias. Me alegro mucho de haberme desplazado hasta el final de la página. Estoy usando carga diferida y las imágenes en marco que aún no se han cargado (porque el navegador cree erróneamente que la ventana gráfica aún no se ha desplazado hacia ellas) se muestran como imágenes rotas. Un pequeño pergamino, y reaparecen. Sin embargo
Velkoon
25

Creo que la forma más fácil es ocultar el icono de imagen rota por la propiedad de sangría de texto.

img {
    text-indent: -10000px
}

Obviamente no funciona si quieres ver el atributo "alt".

Burnee
fuente
1
La forma más fácil.
theerasan tonthongkam
17

en caso de que desee conservar / necesitar la imagen como marcador de posición, puede cambiar la opacidad a 0 con un error y algo de CSS para establecer el tamaño de la imagen. De esta manera no verá el enlace roto, pero la página se carga normalmente.

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

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

me gustó el respuesta de Nick y estaba jugando con esta solución. Encontré un método más limpio. Dado que :: before / :: after pseudos no funcionan en elementos reemplazados como img y object, solo funcionarán si los datos del objeto (src) no están cargados. Mantiene el HTML más limpio y solo agregará el pseudo si el objeto no se carga.

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
fuente
9

Si aún necesita tener el contenedor de imágenes visible debido a que se rellenará más adelante y no desea molestarse en mostrarlo y ocultarlo, puede pegar una imagen transparente 1x1 dentro del src:

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

Usé esto para este propósito exacto. Tenía un contenedor de imágenes que iba a tener una imagen cargada a través de Ajax. Debido a que la imagen era grande y tardó un poco en cargarse, requería establecer una imagen de fondo en CSS de una barra de carga de GIF.

Sin embargo, debido a que el src del estaba vacío, el ícono de la imagen rota seguía apareciendo en los navegadores que lo usan.

La configuración del Gif 1x1 transparente soluciona este problema de manera simple y efectiva sin adiciones de código a través de CSS o JavaScript.

usuario2596313
fuente
la única respuesta que funcionó todas las demás dejó un contorno blanco
futurelucas4502
8

Usar CSS solo es difícil, pero podría usar CSS en background-imagelugar de <img>etiquetas ...

Algo como esto:

HTML

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

CSS

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

}

Aquí hay un violín que funciona .

Nota: Agregué el borde en el CSS en el violín solo para demostrar dónde estaría la imagen.

Dryden Long
fuente
Está bien, pero esta solución no es para mí :) La etiqueta img se ocultó y luego src se rompió, div - no :(
Geray Suinov
@GeraySuinov Entonces quizás tengas que usar Javascript
Dryden Long
3

Desde 2005 , los navegadores Mozilla como Firefox han admitido la pseudoclase :-moz-brokenCSS no estándar que puede cumplir exactamente esta solicitud:

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]::beforetambién funciona en Firefox 64 (aunque alguna vez fue img[alt]::afterasí que esto no es confiable). No puedo hacer que ninguno de los dos funcione en Chrome 71.

Adam Katz
fuente
Interesante ... ¿sabes si Chrome tiene una pseudoclase similar?
1000Gbps
1
@ 1000Gbps: no pude encontrar una cuando hice esa respuesta y no puedo encontrarla ahora, al menos con consultas web rápidas y mirando el error 11011 de Mozilla . En realidad, podría solicitar tal cosa en Chromium (el flujo ascendente para Chrome) si lo desea, pero como no es estándar, no hay garantía de que lo hagan.
Adam Katz
Dudo mucho que lo hagan en poco tiempo, teniendo en cuenta que les fue difícil lidiar con algunos errores desagradables que he informado allí ... No importa el hecho de que las pseudo-clases incorporadas como esta se eliminarán de crea una gran cantidad de código JS escrito por la misma razón
1000Gbps
2

Puedes seguir este camino como una solución 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
fuente
Primero estaba pensando que esta es una buena solución, pero esto no funciona en IE. Tampoco al agregar bloque de pantalla en el css posterior
Glenn Franquet
1

Las imágenes que faltan no mostrarán nada o mostrarán un [? ] cuadro de estilo cuando no se puede encontrar su fuente. En su lugar, es posible que desee reemplazar eso con un gráfico de "imagen faltante" que está seguro de que existe para que haya una mejor respuesta visual de que algo está mal. O bien, es posible que desee ocultarlo por completo. Esto es posible porque las imágenes que un navegador no puede encontrar activan un evento JavaScript de "error" que podemos observar.

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

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

Además, es posible que desee activar algún tipo de acción de Ajax para enviar un correo electrónico a un administrador del sitio cuando esto ocurra.

Ali Panahian
fuente
1

El truco con img::afteres bueno, pero tiene al menos 2 desventajas:

  1. no es compatible con todos los navegadores (por ejemplo, no funciona en Edge https://codepen.io/dsheiko/pen/VgYErm )
  2. no puede simplemente ocultar la imagen, la cubre, por lo que no es tan útil cuando desea mostrar una imagen predeterminada en el caso

No conozco una solución universal sin JavaScript, pero solo para Firefox hay una buena solución:

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

La misma idea descrita por otros funciona en React de la siguiente manera:

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

Una forma básica y muy simple de hacer esto sin ningún código requerido sería proporcionar una declaración alt vacía. El navegador devolverá la imagen en blanco. Se vería como si la imagen no estuviera allí.

Ejemplo:

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

Pruébalo para ver! ;)

usuario45678
fuente
10
Eso depende del navegador. En Chrome, también tendrá el borde de la imagen y el ícono de la imagen rota, además del texto alternativo (aquí vacío).
panzi
Si la imagen es decorativa y no es imprescindible para el contenido, una alt vacía está bien. De hecho, se recomienda sobre no alt en absoluto. De lo contrario, esto es altamente desaconsejable. Una imagen rota es una imagen que no se puede ver, pero si tiene una etiqueta alt, al menos aún se puede escuchar. Si quita la etiqueta alt, no se puede ver ni escuchar.
JP DeVries
2
@panzi Probé la solución y parece que Chrome cambió su comportamiento. No mostrará el icono de imagen rota si alt="". Lo mismo vale para Firefox.
Philipp Mitterer
-4

Para los futuros googlers, en 2016 hay una forma segura de navegador de CSS puro para ocultar imágenes vacías usando el selector de atributos:

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

Editar: estoy de vuelta: para futuros googlers, en 2019 hay una manera de diseñar el texto alternativo real y la imagen de texto alternativo en Shadow Dom, pero solo funciona en las herramientas de desarrollador. Entonces no puedes usarlo. Lo siento. Sería muy lindo

#alttext-container {
    opacity: 0;
}
#alttext-image {
    opacity: 0;
}
#alttext {
    opacity: 0;
}
VerticalGrain
fuente
1
img[src=''] { display: none; } Esto volvió a ser relevante con las plantillas html solo de eBay
imos