Como ocultar o ícone de imagem quebrada usando apenas CSS / HTML?

193

Como ocultar o ícone de imagem quebrada? Exemplo : Exemplo

Eu tenho uma imagem com erro src:

<img src="Error.src"/>

A solução deve funcionar em todos os navegadores.

Geray Suinov
fonte
1
Eu tentei definir alt = "" e defini-lo como img teg background throw CSS live: {background: url (src), width: ...; height: ..} mas não é verdade. Minha tag img deve ocultar e src está quebrado.
Geray Suinov 26/02
Veja uma solução possível aqui - stackoverflow.com/questions/18484753/…, mas precisa de JS. Você não pode fazer isso apenas com CSS.
26414 JohanVdR
Consulte o atributo w3schools.com/jsref/event_onerror.asp "onerror"
Amy.js 22/16

Respostas:

273

Não há como CSS / HTML saber se a imagem está com um link quebrado, então você terá que usar JavaScript, não importa o que

Mas aqui está um método mínimo para ocultar a imagem ou substituir a fonte por um backup.

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

ou

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

Atualizar

Você pode aplicar essa lógica a várias imagens ao mesmo tempo, fazendo algo assim:

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

Atualização 2

Para uma opção CSS, veja a resposta do michalzuber abaixo. Você não pode ocultar a imagem inteira, mas altera a aparência do ícone quebrado.

Kevin Jantzer
fonte
3
Você pode fazer isso com HTML apenas usando a tag de objeto, pois ela pode ser usada para exibir imagens como a tag img e não exibe um link quebrado se a imagem não existir, funciona em todos os navegadores e já em outros países. como o IE8, por si só, você pode até usar imagens padrão com esse método, publiquei uma resposta com detalhes abaixo.
Nick Steele
1
Isso funcionou para mim, em vez da abordagem <object>, porque eu precisava que a imagem tivesse uma margem declarada, mas somente se uma imagem válida fosse encontrada, caso contrário, precisava ocupar espaço zero. <object> não possui o evento onerror, portanto essa não era uma opção lá. Uma regra de estilo para remover a margem, usando uma pseudo classe: empty, nunca foi acionada no objeto.
John Hatton
Eu tenho uma pergunta. existe uma maneira possível de dar o script comum para aplicar a cada tag de imagem na página, em vez de fornecer essa linha específica de script em cada tag de imagem. Obrigado @Kevin Jantzer
Lemdor
1
@ Ldordor - sim, você precisaria encontrar imagens em carga e anexar a função comum a cada uma. Você poderia usar jQuery ou baunilha JS para alcançar este objetivo (Eu atualizei a minha resposta com um exemplo)
Kevin Jantzer
Nas reações, é muito fácil fazer isso, o mesmo princípio se aplica a elas. Encontre este tutorial aqui - youtu.be/90P1_xCaim4 . A adição de um pré-carregador ( youtu.be/GBHBjv6xfY4 ) para imagem oculta a transição e ajuda a fornecer um bom UX.
Prem
143

Apesar do que as pessoas estão dizendo aqui, você não precisa de JavaScript, nem de CSS !!

Na verdade, é muito factível e simples apenas com HTML. Você pode até mostrar uma imagem padrão se uma imagem não carregar . Aqui está como ...

Isso também funciona em todos os navegadores, mesmo no IE8 (dos mais de 250.000 visitantes dos sites que hospedei em setembro de 2015, as pessoas da ZERO usavam algo pior que o IE8, o que significa que esta solução funciona para praticamente tudo ).

Etapa 1: referencie a imagem como um objeto em vez de um img . Quando os objetos falham, eles não mostram ícones quebrados; eles simplesmente não fazem nada. A partir do IE8, você pode usar as tags Obj e Img de forma intercambiável. Você pode redimensionar e fazer todo o material glorioso que puder com imagens regulares também. Não tenha medo da tag de objeto; é apenas uma etiqueta, nada grande e volumoso é carregado e não diminui a velocidade. Você estará usando a tag img com outro nome. Um teste de velocidade mostra que eles são usados ​​de forma idêntica.

Etapa 2: (opcional, mas incrível) Cole uma imagem padrão dentro desse objeto. Se a imagem que você deseja realmente carregar no objeto , a imagem padrão não será exibida. Por exemplo, você pode mostrar uma lista de avatares de usuários e, se alguém ainda não tiver uma imagem no servidor, poderá mostrar a imagem do espaço reservado ... não é necessário nenhum javascript ou CSS, mas você obtém os recursos do que leva JavaScript para a maioria das pessoas.

Aqui está o código ...

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

... Sim, é simples assim.

Se você deseja implementar imagens padrão com CSS, você pode torná-lo ainda mais simples em seu HTML assim ...

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

... e basta adicionar o CSS desta resposta -> https://stackoverflow.com/a/32928240/3196360

Nick Steele
fonte
6
De alguma forma, perdi completamente essa idéia, quando é tão óbvio em retrospecto! Infelizmente, eu não acho que a tag de objeto possa lidar com imagens responsivas como estamos começando a ver na propriedade img.srcset :(
Windgazer
2
Ótima idéia, obrigado por isso! Em uma nota lateral, a tag de objeto está bloqueando a roda de rolagem (na minha implementação, pelo menos) ... se isso acontecer com você, basta usar object { pointer-events: none; }no seu CSS (Fonte: stackoverflow.com/a/16534300 )
DHainzl
4
Porém, isso quebra a semântica das tags de imagem. Não sei se os mecanismos de pesquisa vão gostar do uso de <object>tags em vez de <img>tags. Essa abordagem é compatível com HTML5 e renderizada corretamente por todos os principais navegadores?
Pieter
6
Isso é compatível com HTML4 (compatível desde 1997) e renderizado corretamente por todos os principais navegadores desde o IE8 / 2009 (outros navegadores fizeram isso muito, muito antes). Se um mecanismo de pesquisa não entende que um objeto com um tipo de imagem é uma imagem, foram necessários 19 anos para acompanhar as especificações, por isso provavelmente não é um mecanismo muito bom ... Os adolescentes que estão na estrada dirigindo carros agora não eram mesmo concebido quando esta solução atendeu às especificações ... Até onde você quer voltar? :) Esta é uma solução sólida.
Nick Steele
6
@MonsterMMORPG porque ele não usa JavaScript, e você nem sempre tem permissão (no corpo de uma mensagem de email, por exemplo).
ForNeVeR 31/08/16
63

Encontrei uma ótima solução em 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
fonte
1
Solução impressionante usando apenas CSS, que deve ser a resposta aceita. O artigo vinculado está desatualizado, pois o suporte ao navegador agora é de 97,87%: caniuse.com/#feat=css-gencontent .
holm50
1
O artigo vinculado tem uma excelente explicação sobre como os navegadores manipulam imagens, mas lembre-se de que esta solução funciona apenas se você tiver um plano de fundo sólido e desejar cobrir tudo com outra caixa da mesma cor sólida ou com outra imagem. Esta solução não está realmente removendo ou ocultando o ícone de imagem corrompida, apenas a cobrindo.
Claudio Floreani
3
No Chrome 70, que mostra o pássaro + um ícone de imagem quebrada :(
Simon Arnold
2
^ O mesmo no Firefox 63
dailysleaze
1
@dailysleaze - No Firefox 64+, isso foi movido para img[alt]::before. Você pode usar display:inline-blockse quiser, pois está mais próximo do original.
Adam Katz
40

Se você adicionar alt com o texto alt = "abc", ele mostrará a miniatura em exibição corrompida e a mensagem alt abc

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

1º

Se você não adicionar alt, mostrará a miniatura em miniatura corrompida

<img src="pic_trulli.jpg"/>

2º

Se você deseja ocultar o quebrado, basta adicionar alt = "", ele não mostrará miniaturas corrompidas e nenhuma mensagem alt (sem usar js)

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

Se você deseja ocultar o quebrado, basta adicionar alt = "" & onerror = "this.style.display = 'none'", ele não mostrará miniaturas corrompidas e nenhuma mensagem alt (com js)

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

O quarto é um pouco perigoso (não exatamente), se você quiser adicionar qualquer imagem no evento onerror, ela não será exibida mesmo que a imagem exista como style.display é como adicionar. Portanto, use-o quando não precisar exibir nenhuma imagem alternativa.

display: 'none'; // in css

Se dermos em CSS, o item não será exibido (como imagem, iframe, div assim).

Se você deseja exibir uma imagem e deseja exibir um espaço totalmente em branco, se houver erro, poderá usar, mas também tome cuidado para não ocupar espaço. Então, você precisa mantê-lo em uma div

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

P Satish Patro
fonte
2
SIM! Basta adicionar alt=""! É literalmente isso! Obrigado. Tão feliz que eu rolei para o final da página. Estou usando o carregamento lento e as imagens no quadro que ainda não foram carregadas (porque o navegador pensa erroneamente que a janela de exibição ainda não rolou para elas) apareceram como imagens quebradas. Um pequeno pergaminho, e eles reaparecem. As imagens quebradas em seu lugar eram tão feias
velkoon
25

Acho que a maneira mais fácil é ocultar o ícone da imagem quebrada pela propriedade recuo do texto.

img {
    text-indent: -10000px
}

Obviamente, não funciona se você deseja ver o atributo "alt".

Burnee
fonte
1
A maneira mais fácil.
theerasan tonthongkam
16

gostei do resposta de Nick e estava brincando com esta solução. Encontrou um método mais limpo. Como os pseudos :: before / :: after não funcionam em elementos substituídos, como img e object, eles funcionarão apenas se os dados do objeto (src) não estiverem carregados. Ele mantém o HTML mais limpo e adicionará o pseudo somente se o objeto falhar ao carregar.

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
fonte
16

caso você queira manter / precisar da imagem como um espaço reservado, altere a opacidade para 0 com um onerror e algum CSS para definir o tamanho da imagem. Dessa forma, você não verá o link quebrado, mas a página carrega normalmente.

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

img {
    width: 75px;
    height: 100px;
}
Ewald Bos
fonte
9

Se você ainda precisa ter o contêiner de imagem visível devido ao preenchimento posterior e não quiser se incomodar em exibi-lo e ocultá-lo, pode colar uma imagem transparente 1x1 dentro do src:

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

Eu usei isso para esse fim exato. Eu tinha um contêiner de imagem que teria uma imagem carregada nele via Ajax. Como a imagem era grande e demorou um pouco para carregar, foi necessário definir uma imagem de plano de fundo no CSS de uma barra de carregamento de Gif.

No entanto, como o src do estava vazio, o ícone da imagem quebrada ainda apareceu nos navegadores que o usam.

A configuração do GIF 1x1 transparente corrige esse problema de maneira simples e eficaz, sem acréscimos de código por meio de CSS ou JavaScript.

user2596313
fonte
única resposta que funcionou todos os outros deixou um contorno branco
futurelucas4502
8

Usar apenas CSS é difícil, mas você pode usar CSS em background-imagevez de<img> tags ...

Algo assim:

HTML

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

CSS

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

}

Aqui está um violino de trabalho .

Nota: Eu adicionei a borda no CSS no violino apenas para demonstrar onde a imagem estaria.

Dryden Long
fonte
É bom, mas esta solução não é para mim :) a tag img ocultou e o src está quebrado, div - no :(
Geray Suinov
@GeraySuinov Então você pode ter que usar o Javascript
Dryden Long
4

Use a tag de objeto. Adicione texto alternativo entre as tags assim:

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

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

ThomasAFink
fonte
3

Desde 2005 , navegadores Mozilla como o Firefox suportam a :-moz-brokenpseudo classe CSS não padrão que pode realizar exatamente essa solicitação:

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]::beforetambém funciona no Firefox 64 (embora era uma vez, img[alt]::afterportanto, isso não é confiável). Não consigo que nenhum deles funcione no Chrome 71.

Adam Katz
fonte
Interessante ... você sabe se o Chrome tem uma pseudo classe semelhante?
1000Gbps 16/04
1
@ 1000Gbps - não consegui encontrar uma quando fiz essa resposta e não consigo encontrá-la agora, pelo menos com consultas rápidas na web e olhando para o bug do mozilla 11011 . Na verdade, você pode solicitar uma coisa dessas no Chromium (a montante do Chrome), se quiser, mas como não é padrão, não há garantia de que eles o farão.
Adam Katz
Eu duvido muito que eles façam isso em pouco tempo, levando em consideração que eles tiveram dificuldade em lidar com alguns erros desagradáveis ​​que eu relatei lá ... Não importa o fato de que pseudo-classes embutidas como esta serão removidas de estrutura um monte de código JS escrito pelo mesmo motivo
1000Gbps 16/04
2

Você pode seguir este caminho como uma solução 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
fonte
Primeiro, eu estava pensando que essa é uma boa solução, mas isso não está funcionando no IE. Também não ao adicionar bloco de exibição no CSS posterior
Glenn Franquet
1

As imagens ausentes não exibirão nada ou exibirão [? ] quando sua fonte não puder ser encontrada. Em vez disso, convém substituí-lo por um gráfico de "imagem ausente" que, com certeza, existe, para que haja melhor feedback visual de que algo está errado. Ou você pode querer ocultá-lo completamente. Isso é possível porque as imagens que um navegador não consegue encontrar disparam um evento JavaScript de "erro" que podemos observar.

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

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

Além disso, você pode acionar algum tipo de ação do Ajax para enviar um email a um administrador do site quando isso ocorrer.

Ali Panahian
fonte
1

O truque img::afteré uma coisa boa, mas tem pelo menos duas desvantagens:

  1. não é suportado por todos os navegadores (por exemplo, não funciona no Edge https://codepen.io/dsheiko/pen/VgYErm )
  2. você não pode simplesmente ocultar a imagem, cobre-a - de modo que não é útil quando você deseja mostrar uma imagem padrão no caso

Não conheço uma solução universal sem JavaScript, mas apenas para o Firefox existe uma boa:

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

Uma maneira básica e muito simples de fazer isso sem nenhum código necessário seria apenas fornecer uma instrução alt vazia. O navegador retornará a imagem em branco. Seria como se a imagem não estivesse lá.

Exemplo:

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

Experimente para ver! ;)

user45678
fonte
10
Isso depende do navegador. No Chrome, você ainda terá a borda da imagem e o ícone de imagem quebrada, além do texto alternativo (aqui vazio).
Panzi
Se a imagem é decorativa e não é imperativa para o conteúdo, uma alt vazia é adequada. Na verdade, é recomendado sem alt. Caso contrário, isso é altamente desaconselhável. Uma imagem quebrada é uma imagem que não pode ser vista, mas se tiver uma tag alt, ainda poderá ser ouvida. Se você tirar a tag alt, ela não poderá ser vista OU ouvida.
JP DeVries
2
@panzi Testei a solução e parece que o Chrome mudou seu comportamento. Não renderizará o ícone de imagem quebrada se alt="". O mesmo vale para o Firefox.
Philipp Mitterer
-4

Para futuros googlers, em 2016, existe uma maneira CSS pura e segura do navegador de ocultar imagens vazias usando o seletor de atributos:

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

Edit: Estou de volta - para futuros googlers, em 2019, há uma maneira de estilizar o texto alternativo e a imagem de texto alternativo no Shadow Dom, mas ele só funciona em ferramentas de desenvolvedor. Então você não pode usá-lo. Desculpe. Seria tão legal.

#alttext-container {
    opacity: 0;
}
#alttext-image {
    opacity: 0;
}
#alttext {
    opacity: 0;
}
VerticalGrain
fonte
1
img[src=''] { display: none; } Isso tornou-se relevante novamente com os modelos somente HTML do eBay
imos