Bloggerでレスポンシブイメージを使うのは大変!(img, srcset, sizes and picture in HTML 5.1)

  0 件のコメント

他のブログサービスではレスポンシブイメージがサポートされたという話も聞きますが、Bloggerはどっしり構えて昔のまま。GoogleはBloggerに力が入っていないので、多分このままサポートされないでしょう。というわけで自力で試してみましたが、難しさが身にしみました。

大変な理由を以下に書いてみます。

第3位: ブラウザごとに img要素 + srcset + sizes の動作が少しずつ異なる

まだHTML5.1が正式版ではないのでやむをえないのかもしれませんが、Chrome, Firefox, Safariなどのブラウザごとに少しずつ表示のされ方が異なります。Chromeなどはリロードを何度か繰り返すと、異なるサイズのイメージが選ばれたりします。特に非モバイル系で目立つようで、むしろモバイルの方が状況が良さそうに思えます。

第2位: Bloggerが img要素 + srcset + sizes (HTML5.1) をサポートしていない

自分で一生懸命HTML編集画面で書くか、img要素 + srcset, sizes属性のHTMLを生成するツールを自作する必要があります。前者は特別に一つの記事だけというならありですが、常時やりたい時にはツールを作るしかないでしょう。後者については、それほど複雑ではないので、プログラミングをかじったことがある方なら難しくないと思いますが、ブログの文章を書くだけでレスポンシブイメージにしたい、という方には道がありません。

第1位: 他のテンプレートへの変更が困難になる

ここまでの2つは越えられない山ではありません。しかし、最後の難物がこの「テンプレート」というブログのシステム。話が少々細かくなるので端折って書くと、完全にレスポンシブイメージにしようとすると、特定のテンプレートにロックインされてしまい、他のテンプレートへの乗り換えが非常に難しくなります。以下に説明とゆる〜い回避策を書きます。

img要素 + srcset, sizes属性でのレスポンシブイメージ(サイズ変更だけ)の記述は、例えば以下のようになります。(※コードは「srcsetとsizes」(日本語訳)より引用)

<img src="small.jpg"
     srcset="large.jpg 1024w,
             medium.jpg 640w,
             small.jpg  320w"
     sizes="(min-width: 36em) 33.3vw,
            100vw"
     alt="A rad wolf" />

問題は、sizesとして画面幅に応じて変わる表示幅(赤字の部分)の記述が必要なこと。ブログの場合テンプレートがそれを決めているので、一般人にはなかなかうかがい知ることができません。テンプレートのソースを見たり、画面幅を変えていった時の変化から知ることはできますが、それを記事のコードに埋め込むということは、そのテンプレートに依存したHTMLソースになってしまうということ。テンプレートを変えるときには記事すべてを修正することになり、現実的にほぼ不可能になってしまいます。(これまたツールを書けば対応できそうですが。)

回避方法

これを回避するには、大雑把でよければ以下の方法があります。

<img src="small.jpg"
     srcset="large.jpg 1024w,
             medium.jpg 640w,
             small.jpg  320w"
     sizes="100vw"
     style="max-width: 100%"
     alt="A rad wolf" />

sizesからテンプレート依存の表示幅を取り除き、常に画面幅いっぱい(100vw: ビューポート幅の100%)として画像を選ぶようにします(sizes="100vw")。そしてstyleで画像を自動拡縮して表示領域幅に合わせます(style="max-width: 100%")。これは、srcsetとsizesは、複数の画像のサイズと表示幅をヒントとしてブラウザに教える仕組みであって、画像の表示幅を直接指示する仕組みではないことを利用しています。(それはstyleの役目。ブラウザの挙動がまだ怪しいこともあり、レスポンシブの場合でも、写真のサイズを揃えて並べたい時などは積極的に使うべき。)

おおよそこれでいいのはなぜ?

ネットワーク帯域にシビアなモバイルでは、ブログは1カラム表示になるのが一般的ですから、テンプレートが指定する表示幅はほぼブラウザの画面幅と同じです。したがって選ばれる画像も同じあるいは大差ないものになるので、データ転送量への影響はほぼないと言えます。

問題は2カラム以上あるいは多数のサムネイル表示の場合。小さい画像でいいのに画面幅いっぱいを前提とした画像を指定することになります。しかし、それらのレイアウトはモバイルではなくPCで表示される場合がほとんどで、ネットワーク帯域は十分なことが多いでしょうから、多少大きな画像が選ばれたとしても問題にならないケースが多いと推測されます。うん、いちおうモバイル重視ですね。

もっといい方法は?

なお、このような問題を避けるために、

      sizes="100cw"

のように、ビューポート幅単位(vw)ではなくクライアント領域幅単位(cw:こんなのはありません)での指定ができれば、テンプレート非依存にできそうです。一見良いアイディアに見えますが、ブラウザは、javascriptやcssを評価する前 (=表示レイアウト判明前=表示幅が決まる前) に速攻で画像をWebサーバーに要求してしまうため、これは成立しません。残念!

2016年2月時点では、上記のような面倒さと、ブラウザのサポートにやや不安があることから、以前ご紹介したようにjavascriptで実現する方が良さそうです。
リンク:【Bloggerでレスポンシブデザインの画像サイズ問題を解決する方法

縦長の写真にimg,srcset,sizesを使う場合の記述方法

ところで、レスポンシブイメージの説明はいつも横長(ランドスケープ)の写真がサンプルに使われます。一般にランドスケープの写真の方が多いことと、幅の説明がしやすいからでしょうけど、縦長(ポートレート)の場合はどうするのがいいのでしょうか? 新しいimgでは、srcset,sizesが加わるので、なかなか混乱します。一つずつ整理しながらみていきましょう。

srcset,sizesとstyleは分けて考える

まず、関連する要素は、srcset, sizes, styleの3つです。このうち、srcsetとsizeがイメージの選択に関わるもの、styleが表示そのものに関わるものですので、明確に分けて考える必要があります。そうしないと頭がぐちゃぐちゃになります。

style: 幅をアスペクト比に設定

表示に関してはstyleが全てを握っています。どのイメージを選択したとしても、結局表示幅はstyleで決まります。また、縦横に限らずいろいろなアスペクト比の写真が混在する場合は、長辺のサイズを同一にするのがバランスよく見えます。ランドスケープとポートレートの写真、どちらもブログの幅いっぱい(width:100%)に表示されると、ポートレートの写真が異様に大きく見えますからね。全部スマホの縦位置で撮った写真ならここまで気を使う必要はなく、みな同じく幅100%で良いでしょうけど、一般にはそうではありません。したがって、styleに関しては、アスペクト比2:3の場合を例にとると、以下が良いでしょう。66%は比率、横/縦です(※ランドスケープの場合も考慮すると100%が上限)。

 style="width: 66%"

次に、styleで指定したサイズに最もフィットする解像度のイメージを選択するようsrcsetとsizesの記述を決めます。

sizes: これもアスペクト比に設定

styleでwidthを66%にしたのであれば、それが表示される幅の上限になります。sizesはビューポートに対するイメージ幅の比率ですから、上限はほぼそれに等しくなると考え、やはり66%が良いでしょう。

  sizes="66vw"

srcset: シンプルにファイルのパスとイメージの幅を書く

最後にsrcset。ここには表示に関するパラメーターは存在せず、イメージのサイズに関する情報があるのみです。したがって、ストレートにイメージのファイル名とその幅をペアにして記述していくだけです。通常の場合と同じですね。

Bloggerのケース

さて、これだけだと少々実践的でないので、Bloggerでイメージを扱う場合の方法と組み合わせて見てみましょう。先に書いたように、BloggerではアップロードしたイメージはWeb API経由でサイズを自由に変えられます。その時にどういう記述にするのがいいでしょうか? いろいろ試しましたが、オススメなのは以下の方法。

■イメージのサイズは"s"で指定する。"w"や"h"も使えるが、長辺のサイズを揃える観点からは、ここは"s"にしておけば、それに続く値も固定にできてわかりやすいです。

■そして、イメージのパスに続くサイズは"w"限定ですから、ここをアスペクト比に従って変えてやります。例えばアスペクト比2:3の写真を長辺の指定200(/s200/)とするなら、対応する幅は200*2/3=132、となります。

ここまでの設定を全部まとめると以下のようになります。

<img 
  src=".../s800/....jpg" 
  sizes="66vw" 
  srcset="
    .../s200/....jpg 132w,
    .../s320/....jpg 211w,
    .../s400/....jpg 264w,
    .../s640/....jpg 422w,
    .../s800/....jpg 528w,
    .../s1600/....jpg 1056w" 
  style="width: 66%" />

冷静に考えるとまあそうかなという感じでした。

※繰り返しになりますが、本記事の方法は、あくまでモバイルが1カラム表示で、表示領域幅がほぼブラウザ幅に等しいことが前提です。ご自身のテンプレートに依存しますので、ご注意ください。その場合でも、モバイルでの表示幅が◯%と分かっているなら、100%→◯%, 縦長の場合はsizesとstyleのwidthを×アスペクト比すれば、同じ効果が得られるはず、です。


0 件のコメント :

コメントを投稿

Related Posts Plugin for WordPress, Blogger...