web-dev-qa-db-ja.com

CSSを使用したフォールバック画像

リモート画像を表示する<img>があります。 リモートイメージに到達できない場合は、別のローカルイメージにフォールバックするにします。

<img class="cc_image fallback" src="http://www.iconarchive.com/download/i82888/limav/flat-gradient-social/Creative-Commons.ico"> 

.cc_image {
    width: 256px;
    height: 256px;
}

.cc_image.fallback {
    /* this URL here is theoretically a local one (always reachable) */
    background-image: url('https://cdn2.iconfinder.com/data/icons/picons-basic-3/57/basic3-010_creative_commons-256.png');
}

src画像が見つからない場合、背景画像が表示されるように機能します。

欠点は次のとおりです。

  • 常に背景画像をロードします(追加のHTTPリクエスト)
  • 背景画像の上に表示される元の画像の場所に小さなnot-found-icon(Safariの疑問符)が表示されます(大きな問題ではありませんが、しかし、私はそれを取り除きたいです)

どうすればこれらの問題を解決できますか?または:同じ結果を達成するための他の技術はありますか?

この質問 が見つかりましたが、指定されたソリューションはJavascriptまたは<object>に依存しています(Chromeでは機能しないようです)。可能であればJavascriptを使用しない純粋なCSS/HTMLソリューションが必要です。

複数のbackground-imageについては知っていますが、それが適切なオプションであるかどうかはわかりません(ブラウザーのサポート?および到達不能なイメージでフォールバックしますか?)。または、SVG画像をdata-uriとして埋め込むことを考えていました。

最も柔軟な(そして互換性のある)方法の提案?

9
Kamafeather

残念ながら、Javascriptまたはオブジェクトタグなしで両方を達成することはできません。

これを行うと、画像アイコンの欠落を回避できます。

画像をコンテナに入れます(すでにコンテナに入っている場合があります)。コンテナの幅と高さを画像と同じにします。

  1. フォールバック画像をコンテナの背景画像として設定します。
  2. リモート画像をimgタグの背景画像として設定します。
  3. 画像のsrcとして1x1ピクセルの透明なpngをロードします(追加のHTTPリクエストなしでそれを行う方法についてはコードを参照してください)。

コード:

[〜#〜] html [〜#〜]

<!-- you could use any other tag, such as span or a instead of div, see css below -->
<div class="cc_image_container fallback">
    <img class="cc_image" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" style="background-image: url(*your remote image*)"/>
</div>

[〜#〜] css [〜#〜]

.fallback {
    background-image: url(*fallback image here*);
    display: inline-block; /*to ensure it wraps correctly around the image, even if it is a a or span tag*/
    min-width: specify a minimum width (could be the width of the fallback image) px; 
    min-height: specify a minimum height (could be the height of the fallback image) px;
    background-position: center center; // fallback for older browsers
    background-size: cover;
    background-repeat: no-repeat;
}

.cc_image {
    min-width: same as container px;
    min-height: same as container px;
    background-position: center center; // fallback for older browsers
    background-size: cover;
    background-repeat: no-repeat;
}
  • min-widthおよびmax-width背景画像が表示されたままであることを確認してください。
  • background-position画像の中央部分が表示されたままになり、古いブラウザでは適切に機能が低下することを確認します
  • background-size背景画像のサイズを変更して、要素の背景を塗りつぶします。 cover値は、要素を完全に覆うように画像のサイズが変更されることを意味します(画像の外縁の一部がトリミングされる場合があります)
  • Img srcタグのbase64データは、透明な1pxpngです。
  • これには、通常のユーザーや一部のボットが画像を保存できない可能性があるという追加の利点があります(基本的な画像保護)
  • 唯一の欠点は、フォールバックイメージに対して追加のHTTPリクエストが1つ残っていることです。
11
beerwin

私はあなたと共有したいCodepenの解決策を見つけました: https://codepen.io/anon/pen/Eqgyyo

body {
  color: #2c3e50;
  font-family: 'verdana';  
  line-height: 1.35em;
  padding: 30px;
}
h1 {
  margin-bottom: 40px;
}
ul {
  list-style: none;
  padding: 0;
}
* {
  box-sizing: border-box;
}

img {
  color: #95a5a6;
  font-size: 12px;
  min-height: 50px;
  position: relative;
  
}
img:before {
  background: #f1f1f1;
  border: 1px solid #ccc;
  border-radius: 3px;
  content: '\1F517' ' broken image of 'attr(alt);
  display: block;
  left: 0;
  padding: 10px;
  position: absolute;
  top: -10px;
  width: 100%;
}
<h1>Broken image fallback CSS</h1>
<img src="no-image-here" alt="Cats with synthesizers in the space " />

<br /><br />
<ul>
  <li>✓ Firefox</li>
  <li>✓ Chrome</li>
  <li>✓ Opera</li>
  <li>✗ Safari (desktop, mobile)</li>
  <li>✗ iOS webview</li>
</ul>
2
Gerfried