Jak ukryć obraz zepsuty Ikona używając tylko CSS / HTML?


194

Jak mogę ukryć ikonę uszkodzonego obrazu? Przykład : Przykład

Mam obraz z błędem src:

<img src="Error.src"/>

Rozwiązanie musi działać we wszystkich przeglądarkach.


1
Próbowałem ustawić alt = "" i ustawić img teg rzut CSS live: {background: url (src), width: ...; wzrost: ..} ale to nieprawda. Mój tag img musi się ukryć, a następnie src jest uszkodzony.
Geray Suinov

Zobacz możliwe rozwiązanie tutaj - stackoverflow.com/questions/18484753/... ale wymaga JS. Nie możesz tego zrobić z samym CSS.
JohanVdR

Odpowiedzi:


274

CSS / HTML nie ma możliwości sprawdzenia, czy obraz jest uszkodzony, więc będziesz musiał używać JavaScript bez względu na wszystko

Ale tutaj jest minimalna metoda ukrycia obrazu lub zamiany źródła na kopię zapasową.

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

lub

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

Aktualizacja

Możesz zastosować tę logikę do wielu obrazów jednocześnie, wykonując coś takiego:

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

Aktualizacja 2

Aby uzyskać opcję CSS, zobacz odpowiedź michalzubera poniżej. Nie możesz ukryć całego obrazu, ale zmieniasz wygląd uszkodzonej ikony.


3
Możesz to zrobić za pomocą HTML tylko przy użyciu znacznika object, ponieważ może on być używany do wyświetlania obrazów takich jak tag img, i nie wyświetla uszkodzonego łącza, jeśli obraz nie istnieje, działa we wszystkich przeglądarkach i tak daleko jako sam IE8, możesz nawet użyć domyślnych obrazów za pomocą tej metody, zamieściłem odpowiedź ze szczegółami poniżej.
Nick Steele,

1
To działało dla mnie zamiast podejścia <object>, ponieważ potrzebowałem, aby obraz miał zadeklarowany margines, ale tylko wtedy, gdy znaleziono prawidłowy obraz, w przeciwnym razie potrzebowałem go, aby zajął zero miejsca. <object> nie ma zdarzenia onerror, więc nie było takiej opcji. Reguła stylu usuwania marginesu przy użyciu pseudo-klasy: pusta nigdy nie została uruchomiona na obiekcie.
John Hatton,

Mam pytanie. czy istnieje możliwość wspólnego skryptu, który ma być stosowany do każdego znacznika obrazu na stronie, zamiast podawania tego wiersza skryptu w każdym znaczniku obrazu. dziękuję @Kevin Jantzer
Lemdor

1
@Lemdor - tak, musisz znaleźć obrazy przy załadowaniu i dołączyć do nich wspólną funkcję. Aby to osiągnąć, możesz użyć jQuery lub waniliowej JS (zaktualizowałem odpowiedź o przykład)
Kevin Jantzer,

W reakJs jest to bardzo łatwe, obowiązuje tam ta sama zasada. Znajdziesz ten samouczek tutaj - youtu.be/90P1_xCaim4 . Również dodanie preloadera ( youtu.be/GBHBjv6xfY4 ) do obrazu ukrywa przejście i pomaga zapewnić dobry UX.
Prem

143

Pomimo tego, co ludzie tutaj mówią, wcale nie potrzebujesz JavaScript, nawet CSS !!

Jest to w rzeczywistości bardzo wykonalne i proste tylko z HTML. Możesz nawet wyświetlić obraz domyślny, jeśli obraz się nie ładuje . Oto jak...

Działa to również we wszystkich przeglądarkach, nawet już w IE8 (z ponad 250 000 odwiedzających witryny, które hostowałem we wrześniu 2015 r., Ludzie ZERO używali czegoś gorszego niż IE8, co oznacza, że ​​to rozwiązanie działa dosłownie na wszystko ).

Krok 1: Odwołaj się do obrazu jako obiektu zamiast img . Kiedy obiekty zawodzą, nie pokazują uszkodzonych ikon; po prostu nic nie robią. Począwszy od IE8, można używać zamiennie znaczników Object i Img. Możesz również zmieniać rozmiar i robić wszystkie chwalebne rzeczy, które możesz zrobić, używając zwykłych zdjęć. Nie bój się znacznika obiektu; to tylko metka, nic dużego i nieporęczne jest ładowane i niczego nie spowalnia. Będziesz używać tagu img pod inną nazwą. Test prędkości pokazuje, że są one używane identycznie.

Krok 2: (Opcjonalnie, ale świetnie) Umieść domyślny obraz wewnątrz tego obiektu. Jeśli żądany obraz faktycznie ładuje się do obiektu , domyślny obraz nie zostanie wyświetlony. Na przykład możesz wyświetlić listę awatarów użytkowników, a jeśli ktoś nie ma jeszcze obrazu na serwerze, może wyświetlić obraz zastępczy ... javascript lub CSS wcale nie są wymagane, ale masz funkcje tego, co bierze większość ludzi JavaScript.

Oto kod ...

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

... Tak, to takie proste.

Jeśli chcesz zaimplementować domyślne obrazy za pomocą CSS, możesz uprościć ten kod HTML w ten sposób ...

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

... i po prostu dodaj CSS z tej odpowiedzi -> https://stackoverflow.com/a/32928240/3196360


6
Jakoś całkowicie tęskniłem za tym pomysłem, gdy jest to tak oczywiste z perspektywy czasu! Niestety nie sądzę, że tag obiektu może z wdziękiem obsługiwać responsywne obrazy, tak jak zaczynamy widzieć we właściwości img.srcset :(
Windgazer

2
Świetny pomysł, dziękuję za to! Na marginesie, tag obiektu blokuje kółko przewijania (przynajmniej w mojej implementacji) ... jeśli tak się stanie, po prostu użyj object { pointer-events: none; }w swoim CSS (źródło: stackoverflow.com/a/16534300 )
DHainzl

4
To jednak łamie semantykę znaczników obrazu. Nie wiem, czy wyszukiwarki polubią używanie <object>tagów zamiast <img>tagów. Czy to podejście jest zgodne z HTML5 i poprawnie renderowane przez wszystkie główne przeglądarki?
Pieter

6
Jest to zgodne z HTML4 (zgodne od 1997 r.) I poprawnie renderowane przez wszystkie główne przeglądarki od IE8 / 2009 (inne przeglądarki zrobiły to znacznie, znacznie wcześniej). Jeśli wyszukiwarka nie rozumie, że obiekt z typem obrazu jest obrazem, miał 19 lat na nadrobienie specyfikacji, więc prawdopodobnie nie jest to bardzo dobry silnik ... Nastolatki, które jeżdżą samochodami, nie były teraz nawet wymyślone, gdy to rozwiązanie spełnia specyfikacje ... Jak daleko chcesz się posunąć? :) To solidne rozwiązanie.
Nick Steele,

6
@MonsterMMORPG, ponieważ nie używa JavaScript i nie zawsze jest to dozwolone (na przykład w treści wiadomości e-mail).
ForNeVeR

63

Znalazłem świetne rozwiązanie na 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">


1
Niesamowite rozwiązanie wykorzystujące wyłącznie CSS, który powinien być akceptowaną odpowiedzią. Artykuł, do którego prowadzi link, jest nieaktualny, ponieważ obsługa przeglądarki wynosi teraz 97,87%: caniuse.com/#feat=css-gencontent .
holm50,

1
W połączonym artykule znajduje się doskonałe wyjaśnienie, w jaki sposób przeglądarki obsługują obrazy, ale należy pamiętać, że to rozwiązanie działa tylko wtedy, gdy masz solidne tło i chcesz pokryć wszystko innym polem o tym samym jednolitym kolorze lub innym obrazem. To rozwiązanie tak naprawdę nie usuwa ani nie ukrywa ikony uszkodzonego obrazu, tylko ją zasłania.
Claudio Floreani,

3
W Chrome 70 pokazuje ptaka + ikonę zepsutego obrazu :(
Simon Arnold

2
^ To samo w przeglądarce Firefox 63
dsturbid

1
@dailysleaze - w przeglądarce Firefox 64+ przeniesiono to do img[alt]::before. Możesz użyć, display:inline-blockjeśli chcesz, ponieważ jest bliżej oryginału.
Adam Katz,

41

Jeśli dodasz alt z tekstem alt = "abc" , pokaże to uszkodzoną miniaturę i alt wiadomość abc

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

1. miejsce

Jeśli nie dodasz alt, pokaże to uszkodzoną miniaturę

<img src="pic_trulli.jpg"/>

2. miejsce

Jeśli chcesz ukryć uszkodzony, po prostu dodaj alt = "" nie wyświetli uszkodzonej miniatury i żadnej wiadomości alt (bez użycia js)

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

Jeśli chcesz ukryć uszkodzony, po prostu dodaj alt = "" & onerror = "this.style.display = 'none'" nie wyświetli uszkodzonej miniatury i żadnej wiadomości alt (z js)

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

Czwarty jest trochę niebezpieczny (nie do końca), jeśli chcesz dodać dowolny obraz w zdarzeniu onerror, nie wyświetli się, nawet jeśli obraz istnieje jako styl. Wyświetlanie przypomina dodawanie. Dlatego używaj go, gdy nie potrzebujesz żadnego alternatywnego obrazu do wyświetlenia.

display: 'none'; // in css

Jeśli podamy go w CSS, to element nie będzie wyświetlany (jak image, iframe, div w ten sposób).

Jeśli chcesz wyświetlić obraz i chcesz wyświetlić całkowicie puste miejsce w przypadku błędu, możesz użyć, ale także uważaj, to nie zajmie miejsca. Więc musisz trzymać to w div

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


2
TAK! Po prostu dodaj alt=""! To dosłownie to! Dziękuję Ci. Cieszę się, że przewinąłem na dół strony. Używam leniwego ładowania, a obrazy w ramce, które nie zostały jeszcze załadowane (ponieważ przeglądarka błędnie uważa, że ​​rzutnia jeszcze do nich nie przewinęła) pokazały się jako uszkodzone obrazy. Mały zwój i znów się pojawiają.
Zepsute

25

Myślę, że najprostszym sposobem jest ukrycie ikony uszkodzonego obrazu za pomocą właściwości wcięcia tekstu.

img {
    text-indent: -10000px
}

Oczywiście nie działa, jeśli chcesz zobaczyć atrybut „alt”.


1
Najłatwiejszy sposób.
theerasan tonthongkam

17

jeśli chcesz zachować / potrzebować obraz jako symbol zastępczy, możesz zmienić krycie na 0 za pomocą onerroru i trochę CSS, aby ustawić rozmiar obrazu. W ten sposób nie zobaczysz uszkodzonego linku, ale strona ładuje się normalnie.

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

img {
    width: 75px;
    height: 100px;
}

16

Podobało mi się odpowiedź przez Nicka i grał wokół tego rozwiązania. Znaleziono czystszą metodę. Ponieważ pseudo :: before / :: after nie działają na zastąpionych elementach, takich jak img i object, będą działać tylko wtedy, gdy dane obiektu (src) nie zostaną załadowane. Utrzymuje HTML w czystości i doda pseudo tylko wtedy, gdy obiekt się nie załaduje.

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>


9

Jeśli nadal chcesz, aby pojemnik z obrazem był widoczny z powodu jego późniejszego wypełnienia i nie chcesz zawracać sobie głowy jego pokazywaniem i ukrywaniem, możesz umieścić przezroczysty obraz 1x1 wewnątrz src:

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

Użyłem tego właśnie do tego celu. Miałem kontener obrazu, który miał zostać załadowany do niego przez Ajax. Ponieważ obraz był duży i wymagał trochę załadowania, wymagał ustawienia obrazu tła w CSS paska ładowania Gif.

Ponieważ jednak plik src był pusty, ikona zepsutego obrazu nadal pojawiała się w przeglądarkach, które go używają.

Ustawienie przezroczystego GIF-a 1x1 rozwiązuje ten problem w prosty i skuteczny sposób, bez dodawania kodu przez CSS lub JavaScript.


jedyna odpowiedź, która zadziałała, pozostawiła biały kontur
futurelucas4502

8

Używanie tylko CSS jest trudne, ale możesz użyć CSS background-imagezamiast <img>tagów ...

Coś takiego:

HTML

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

CSS

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

}

Oto działające skrzypce .

Uwaga: dodałem obramowanie w CSS na skrzypcach, aby pokazać, gdzie będzie obraz.


To dobrze, ale to rozwiązanie nie dla mnie :) img tag ukrył, a następnie src jest zepsuty, div - nie :(
Geray Suinov

@GeraySuinov Może być konieczne użycie Javascript
Dryden Long


3

Od 2005 roku przeglądarki Mozilla, takie jak Firefox, obsługują niestandardową :-moz-brokenpseudoklasę CSS, która może spełnić dokładnie to żądanie:

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]::beforedziała również w Firefoksie 64 (choć kiedyś img[alt]::aftertak było, więc nie jest to wiarygodne). Nie mogę zmusić żadnego z nich do pracy w Chrome 71.


Ciekawe ... czy wiesz, czy Chrome ma podobną pseudoklasę?
1000 Gb / s

1
@ 1000 Gbps - nie mogłem znaleźć takiej odpowiedzi, kiedy ją znalazłem, i nie mogę jej teraz znaleźć, przynajmniej dzięki szybkim zapytaniom internetowym i patrząc na błąd 11011 Mozilli . Można faktycznie wystąpić coś takiego w chrom (upstream dla Chrome), jeśli chcesz, ale jak to jest nietypowa, nie ma pewności, że będzie to zrobić.
Adam Katz

Bardzo wątpię, że zrobią to w krótkim czasie, biorąc pod uwagę, że mieli trudności z radzeniem sobie z niektórymi paskudnymi błędami, które tam zgłosiłem ... Bez względu na to, że wbudowane pseudoklasy takie jak ta usuną z tworzy dużo kodu JS napisanego z tego samego powodu
1000 Gbps

2

Możesz podążać tą ścieżką jako rozwiązanie 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">


Najpierw myślałem, że to fajne rozwiązanie, ale to nie działa w IE. Również nie przy dodawaniu bloku wyświetlacza w późniejszym css
Glenn Franquet

1

Brakujące obrazy po prostu nic nie wyświetlają lub wyświetlają [? ], gdy nie można znaleźć źródła. Zamiast tego możesz zastąpić tę grafikę „brakującym obrazem”, co do którego istnieje pewność, że jest lepsza informacja wizualna, że ​​coś jest nie tak. Lub możesz chcieć to całkowicie ukryć. Jest to możliwe, ponieważ obrazy, których przeglądarka nie może znaleźć, odpalają „błąd” zdarzenia JavaScript, na które możemy patrzeć.

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

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

Ponadto możesz zainicjować jakieś działanie Ajax, aby wysłać wiadomość e-mail do administratora witryny, gdy to nastąpi.


1

Sztuczka z img::afterjest dobrą rzeczą, ale ma co najmniej 2 wady:

  1. nie obsługiwane przez wszystkie przeglądarki (np. nie działa na Edge https://codepen.io/dsheiko/pen/VgYErm )
  2. nie możesz po prostu ukryć obrazu, zakrywasz go - więc nie jest to pomocne, gdy chcesz pokazać domyślny obraz w obudowie

Nie znam uniwersalnego rozwiązania bez JavaScriptu, ale dla Firefoksa jest tylko jedno fajne:

img:-moz-broken{
  opacity: 0;
}

0

Ten sam pomysł opisany przez innych działa w React w następujący sposób:

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

-3

Podstawowym i bardzo prostym sposobem na zrobienie tego bez wymaganego kodu byłoby po prostu podanie pustej instrukcji alt. Przeglądarka zwróci wówczas obraz jako pusty. Wyglądałoby to tak, jakby nie było tam obrazu.

Przykład:

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

Wypróbuj to! ;)


10
To zależy od przeglądarki. W Chrome nadal będziesz mieć obramowanie obrazu i ikonę uszkodzonego obrazu oprócz (tutaj pustego) tekstu alternatywnego.
panzi

Jeśli obraz jest dekoracyjny i nie jest konieczny dla treści, pusta alt jest w porządku. W rzeczywistości jest to zalecane w ogóle. W przeciwnym razie jest to wysoce niewskazane. Zepsuty obraz jest obrazem, którego nie można zobaczyć, ale jeśli ma znacznik alt, nadal można go usłyszeć. Jeśli usuniesz tag alt, nie będzie można go zobaczyć LUB usłyszeć.
JP DeVries

2
@panzi Przetestowałem rozwiązanie i wygląda na to, że Chrome zmienił swoje zachowanie. Nie wyrenderuje ikony uszkodzonego obrazu, jeśli alt="". To samo dotyczy Firefoksa.
Philipp Mitterer,

-4

Dla przyszłych pracowników Google w 2016 roku dostępny jest bezpieczny sposób CSS do ukrywania pustych obrazów za pomocą selektora atrybutów:

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

Edycja: Wróciłem - dla przyszłych pracowników Google, w 2019 roku istnieje sposób na stylizowanie tekstu alternatywnego i obrazu tekstowego w Shadow Dom, ale działa tylko w narzędziach programistycznych. Więc nie możesz tego użyć. Przepraszam. Byłoby miło.

#alttext-container {
    opacity: 0;
}
#alttext-image {
    opacity: 0;
}
#alttext {
    opacity: 0;
}

1
img[src=''] { display: none; } Stało się to znowu aktualne w przypadku szablonów wyłącznie w serwisie eBay
imos
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.