Menú de navegaciónMenú
Categorías

La mejor forma de Aprender Programación online y en español www.campusmvp.es

?id=d21d4c11-028e-4bdf-9d88-7dfb15f02368

Cómo aplicar estilos CSS a una imagen rota

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):

Icono y texto alqternativo que se muestran por defecto en una imagen rota

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í:

Así se vería una imagen rota con fondo rojo, texto blanco y la ruta a la imagen

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 contentel 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:

Logo de campusMVP sobre fondo azul oscuro

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:

Sobre un meme que es el dibujo de un hombre enfadado, aparece el texto: Aquí falta una imagen

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.

Pablo Iglesias Pablo Iglesias es diseñador en campusMVP. Cuenta la leyenda que, anidando listas HTML en busca de la página semánticamente perfecta, provocó un agujero espacio-temporal en IE tan grande, que en Redmond tuvieron que llamar al comando SG1 de Stargate para evitar una invasión alienígena. Puedes seguirlo en twitter ( @piglesias). Ver todos los posts de Pablo Iglesias
Archivado en: Desarrollo Web

¿Te ha gustado este post?
Pues espera a ver nuestro boletín mensual...

Suscríbete a la newsletter

La mejor formación online para desarrolladores como tú

Agregar comentario

Los datos anteriores se utilizarán exclusivamente para permitirte hacer el comentario y, si lo seleccionas, notificarte de nuevos comentarios en este artículo, pero no se procesarán ni se utilizarán para ningún otro propósito. Lee nuestra política de privacidad.