ブログやギャラリーでサイズの異なる画像を制御する方法
前回は記事内の最初の画像を一覧にアイキャッチ画像として出力し、画像がない場合は特定の画像を表示するということでWordPressの投稿の手間を少なくする方法という記事を書きましたので今回はその出力した画像を制御する方法を書きます。
完全に制作者向けで、webのコーディングのテクニック的な内容ですが、こういう見せ方ならできるという方法をwebデザインのみを行っている方に知っていただければと思います。
まず大前提として現段階でcssだけで全てのブラウザに対応する方法はありません。
それでは行きましょう。
cssプロパティobject-fit
これを知ったのは恥ずかしいことにここ半年でした。いろんなサイトのソースをみて勉強していますが、このobject-fitはさほど普及してはいないと感じます。
レスポンシブに対応しているサイトではもっと普及していいかと思うのですが・・・
ひとまず説明していきますが、制作者の方の大半は画像の比率が変わることを許せないと思いますのでobject-fitのcoverとcontainに絞って説明していきます。
不用意な隙間が気になる方はcoverをつかい、写真全体を見せたいという方はcontainという感じで好みに応じてコーダーに指示すればいいと思います。
親要素のdivをよく撮影するカメラのアスペクト比に合わせてあげれば横長の画像の場合は全て表示され、縦長の場合のみトリミングor縮小されるというふうになります。
ラフの段階では横長の画像で考えていたけどお客様が縦長の画像を挿入してレイアウトが崩れることは日常茶飯事だと思います。
「横長の画像しか入れないでください」ではなく「どんな画像でも大丈夫です」のほうがお客様に優しいですよね。
安心しないでください
object-fitはIEとEdgeに対応していません。(2016.12現在)
というのが悲しい現実。さすがにIEとEdge両方に対応してないとなるとなかなか導入が難しいです。
iOS SafariやAndroidには対応しているので画面の小さい中で画像ばかりに領域を取られたくないスマホには向いてます。
ですがこのサイトのWORKSはまるでobject-fit:containがどのブラウザでも対応しているかのような振る舞いをしています。
ヒントは正方形のdivを作る方法
縦横100pxの正方形のdivは簡単に作れますが、横幅に対して30%の正方形のdivは少し細工をしないと作れません。
:before属性を利用する
正方形にしたい要素に:beforeでpadding-top:100%をしてあげるとその要素のwidthが:before要素のheightになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<div class="square"> <div class="content"> </div> <div> .square { position: relative; } .square:before { display: block; content: ""; padding-top: 100%; } .content { position: absolute; top: 0; width: 100%; height: 100%; } |
ということは、このdiv.contentのwidthとheightを画像のサイズにしてしまえばいい!
これに気付いたときは歓喜しました。制作するにあたりいろんなサイトを参考にしていたのですがこの方法を実践しているサイトを見つけられなかったので・・・
そんな僕の喜びは置いといてこの方法でobject-fitのような振る舞いをさせていきます。
まずはHTMLとCSSを準備
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<article> <div class="silver"> <a href="記事のURL"> <img src="画像のパス"> </a> </div> </article> article { width: 33.3%; } .silver { width: 100%; } .silver:before { content: ""; display: block; padding-top: 70.71%; //比率に応じて変更 } a { position: absolute; top: 0; } img{ width: auto; } |
次にjavascriptを準備
1 2 3 4 5 6 7 8 9 10 11 12 |
$(document).ready(function () { var w = $('.silver').width(); var h = $('.silver').height(); $('.silver a').css({'width': w +'px','height': h +'px'}); $('.silver img').css({'max-height': h +'px'}); }); $(window).resize(function () { var w = $('.silver').width(); var h = $('.silver').height(); $('.silver a').css({'width': w +'px','height': h +'px'}); $('.silver img').css({'max-height': h +'px'}); }); |
articleのwidthが33.3%なのは一列に3つの画像を配置するためですので、一列に4つの場合は25%のように都度変更してください。
.silverは白銀比(1:√2)、A4とかB5などの用紙サイズです。黄金比よりも白銀比の方が日本人に馴染みがあるらしいので。
ですので画像の比率に合わせてpadding-topの値も変更してください。
absoluteしてるaタグがはみ出さないようにaタグにはdiv.silverのサイズを代入しています。
画像も同じようにaタグの大きさを超えるとはみ出してしまいます。
横長の画像がジャストサイズで、縦長の場合は縮小するのでmax-heightをaタグの高さにします。
こうすることでこんな感じに仕上がります。
この方法ならどのブラウザでも網羅できます。(Edgeの環境がないのでEdgeでの確認はできてないですがきっと大丈夫かと)
正直javascriptの知識はhtmlやcssに比べたら浅いので上記をコピペしてもうまく動作しないかもしれません。
そんなときはこのサイトの中身を覗き見してください。
なかなか理解するのが難しいですが…ぜひ試したいですね
クライアントさんによってはデカイ画像をそのままブチ込んじゃって、
親要素よりはみ出しちゃってる…てな場合でも対応可能かしら??(´・ω・`)
ちなみにEdgeでも問題なしでしたYO(・∀・)
今日はIEのmargin: 0 auto;のバグに悩まさせられたーww
てかこの方法よく思いついたねー(*゚∀゚*)
:beforeのpadding-topの値を想定される比率にしておけば(お客様が使用するカメラに合わせれば)、親要素divの高さ=子要素aな高さ=孫要素imgの高さは必ずなので縦方向にはみ出すことは100%ないと。
実験してないですがaタグにoverflow:hiddenつけたら仮に超横長の画像きても左右のはみ出した部分は表示されないかと…