Cuando el navegador no puede cargar una imagen, suele mostrar una imagen de un icono de imagen rota genérico. Aunque este tipo de elementos no se suelen modificar, puede haber casos concretos en los que nos interese hacerlo, por ejemplo, en una web con contenidos generados por el usuario donde se quiere destacar bien este hecho, en sistemas gestores de contenido en los que ciertas imágenes (por ejemplo ornamentales para la cabecera) son opcionales y les quieres dar un aspecto por defecto si no están, o simplemente porque quieres cuidar hasta el más mínimo detalle del diseño de la web.
Veamos un ejemplo práctico con esta imagen:
<img class="imagen-rota-especial"
src="img/imagen-que-no-existe.png"
alt="Este es el texto alternativo de la Imagen rota" />
Si la imagen no existe en la ruta que se indica en el atributo src, se verá algo así, un icono acompañado del texto alternativo del atributo alt
(si lo tiene):
Entre lo más básico que podríamos hacerle estaría ponerle el texto en color, en este caso rojo:
img {
color:red;
}
También podríamos ponerle el fondo de color:
img {
background-color:red;
}
Pero nos puede dar problemas si vamos a usar imágenes con canal alpha, como PNGs transparentes:
Usando :before
en la imagen rota
Hay una solución mucho más eficiente y que permite más opciones de personalización a través de los pseudoelementos :before
y :after
. Como norma general, en las imágenes no se pueden utilizar estos pseudoelementos porque las imágenes son elementos externos al documento, lo explica muy bien nuestro tutor José Manuel Alarcón en este post de su blog técnico.
Pero cuando el enlace a la imagen está roto, sí que se pueden usar, al menos en los navegadores de escritorio más comunes.
En primer lugar definimos el tamaño de la imagen y la posicionamos de forma relativa...
img {
display:block;
position:relative;
width:fit-content;
height: fit-content;
min-width:250px;
min-height:80px;
font-family: 'Open Sans', sans-serif;
font-size:15px;
}
...posicionamos el :before
encima de la imagen rota de forma absoluta:
img:before {
/*Solo se muestra en imágenes rotas*/
display:block;
box-sizing: border-box;
content: "\0026A0 Imagen rota: \A" attr(src);
white-space: pre-wrap;
position: absolute;
background-color:red;
color:#fff;
text-align:center;
top:0;
left:0;
right:0;
bottom:0;
padding:20px;
}
...y se vería así:
Al no poder cargarse la imagen, se muestra el pseudoelemento :before
que contiene un símbolo de peligro, el mensaje "Imagen rota" y el contenido del atributo src
gracias a la función attr()
, que nos permite utilizar en content
el contenido de cualquier atributo. Al visualizar la ruta, podemos identificar mucho mejor qué imagen está fallando sin tener que ir al código fuente.
Combinando :before
y :after
Pero además de :before
, podemos usar :after
, así que vamos a montar un aviso más completo y, de paso, con colores más discretos. Esta vez, además de usar el atributo src
usaremos el contenido del atributo alt
:
De nuevo posicionamos la imagen en relativo y ya le aplicamos los estilos comunes de texto:
img {
display:block;
box-sizing: border-box;
position:relative;
width:100%;
max-width:fit-content;
min-width:350px;
height: fit-content;
min-height:120px;
font-family: 'Open Sans', sans-serif;
font-size:14px;
border:0;
padding:10px;
}
Y posicionamos de forma absoluta el :before
arriba y el :after
abajo. Ojo con las alturas, porque el color de fondo y los bordes deben ir en los pseudoelementos:
img:before {
/*Solo se muestra en imágenes rotas*/
display:block;
box-sizing: border-box;
content: "\0026A0 Imagen rota \A";
white-space: pre-wrap;
position: absolute;
color:#333;
text-align:center;
top:0;
left:0;
right:0;
padding:20px 20px 10px;
height:61px;
border: 1px solid #ccc;
border-bottom:0;
border-radius: 5px 5px 0 0;
background-color:#eee;
font-weight:bold;
font-size:18px;
}
img:after {
/*Solo se muestra en imágenes rotas*/
display:block;
box-sizing: border-box;
content: attr(alt) "\A (Ruta: " attr(src)")";
white-space: pre-wrap;
position: absolute;
color:#333;
text-align:center;
left:0;
right:0;
bottom:0;
padding:0px 20px 20px;
min-height:61px;
border: 1px solid #ccc;
border-top:0;
background-color:#eee;
border-radius: 0 0 5px 5px;
}
Y nos quedaría así:
En cualquiera de las dos soluciones el punto clave es posicionar la imagen como relative
para poder situar en absolute
cualquier pseudoelemento que usemos. O lo que es lo mismo, usaremos los pseudoelementos para tapar el icono y el alt
que se muestran por defecto.
Bola extra: Para poder hacer retornos de carro dentro del content
tienes que usar el caracter unicode escapado \A
y que el pseudoelemento tenga definida la propiedad white-space
con los valores pre
o pre-wrap
Ten cuidado, porque probablemente tendrás que aplicar anchos y alturas fijas, o al menos definir bien valores mínimos y máximos. Valora en todo momento cómo necesitas que fluya el contenido y vigila que los pseudoelementos no se te superpongan a otros contenidos.
Método alternativo: poner una imagen por defecto con <object>
Esta solución personalmente no me gusta tanto porque supone modificar el codigo HTML, pero la comento por si le puede resultar útil a alguien.
Podemos usar una imagen por defecto si insertamos la imagen como un elemento <object>
en vez de usar <img>
.
Importante: En el atributo data
especificaremos la ruta a la imagen y en el atributo type
el tipo de imagen. Dentro del <object>
irá la imagen de sustitución.
Sería algo así:
<object data="img/logo-campusmvp-azul.png" type="image/png">
<img src="img/falta-imagen.jpg" alt="Aquí falta una imagen" />
</object>
Y se vería la imagen logo-campusmvp-azul.png
:
En cambio, si la imagen del object
no existe:
<object data="img/imagen-que-no-existe.png" type="image/png">
<img src="img/falta-imagen.jpg" alt="Aquí falta una imagen" />
</object>
...se vería la imagen de sustitución img/falta-imagen.jpg
:
Espero que este post te haya resultado útil. Te dejo todos estos ejemplos comprimidos dentro de este archivo .zip (52KB). Si tienes alguna duda o quieres aportar algo, no dejes de escribir tu comentario.
Fecha de publicación: