bootstrapグリッドとbackground-sizeでカラムへの背景画像表示を実践形式で紹介
CSSのbackground-sizeプロパティは、レスポンシブルに背景画像の表示サイズを調整する事ができます。
通常、横長画像であればPC版はcontain、スマホ版はcoverを使うと100%で画像が収まりやすくなります。
背景画像を入れるクラス名はbootstrapのグリッドと同列に入れ、幅の操作を任せる様にしましょう。
グリッドの横ならびカラムに背景画像を入れたい
本記事では、グリッドレイアウトにbackground-sizeで背景画像を入れながら構成する流れを実戦形式で紹介します。
ベースとなるCSSフレームワークはbootstrap(3x)を例にしています。
ポイントは、それぞれのデバイス表示時に背景画像をどう見せるかでしょう。
背景画像表示には幅と高さが必要ですので、それをどれに担当させるのかにも着目して下さい。
background-sizeについて
background-sizeとは背景画像の表示サイズを調整するプロパティです。
プロパティの種類と値
background: auto; | 自動(初期値) |
---|---|
background: ○○% ○○%; | 背景領域に対する割合を幅、高さの順で指定 (片方を「auto」で指定する事も可) |
background: ○○px ○○px; | 背景画像のサイズを幅、高さの順で指定 (片方を「auto」で指定する事も可) |
background: contain; | 背景領域に収まる最大サイズ指定(縦横比保持) |
background: cover; | 背景領域が全て隠れるサイズ指定(縦横比保持) |
pxや%単位でも表示はできますが、今回は枠内に敷き詰める「contain」と「cover」を中心に使います。
pxや%を使う場合はbackground-positionも併用して、掲載場所を設定する事になります。
グリッドレイアウトと背景の設置
まずベースの枠組みとして、グリッドレイアウトによる「3列1段」を作っていきます。
bootstrapによる3列並び
シンプルにHTMLコードを書くと以下のようになるでしょう。
HTMLソース
<div class="row"> <div class="col-sm-4"> </div> <div class="col-sm-4"> </div> <div class="col-sm-4"> </div> </div>
コード表記について
今回は、本来外を囲う「container」の部分は省略しています。
本ブログのコンテンツ掲載幅を考慮して「sm」サイズを使っています。本番では環境に応じて「lg」や「md」も使って下さいね。
スマホ版では全て縦一列に並べますので「xs」も記載していません。
グリッドレイアウトは大部分がbootstrap.cssでコントロールされるので、枠部分のCSSは割愛します。
背景画像の設置
それでは3列の各カラムに背景画像を入れてみます。
カラム内と「同列」に、背景画像を入れるスタイル名を入れます。
この背景画像はスマホ版でも同じものを使いますので、大きめサイズを用意しています。
背景設置用クラス名を入れたソース
<div class="row"> <div class="col-sm-4 img1"><!--背景用クラス--> </div> <div class="col-sm-4 img2"><!--背景用クラス--> </div> <div class="col-sm-4 img3"><!--背景用クラス--> </div> </div>
背景画像設置CSS
.img1{ background: url(../images/bootstrap_backimg1.png) no-repeat; } .img2{ background: url(../images/bootstrap_backimg2.png) no-repeat; } .img3{ background: url(../images/bootstrap_backimg3.png) no-repeat; }
サンプル(PCでご覧下さい)
テキスト
テキスト
テキスト
背景画像が表示されない
実際に背景画像を入れてみるとわかりますが、この状態では背景画像は映りません。
テキストが入っている部分にしか表示されていない事がわかります。
背景画像を出すには
背景画像を表示するためには、2つの方法があります。
・カラム内に文章テキストを流し込む
・img1-3のCSSに高さを設定する
上記のサンプルの様にテキストの分だけカラムに「高さ」が生まれますので、そこだけ背景画像が表示されます。
3列それぞれテキスト量は違ってくるはずですので、カラムごとに背景の見える高さが変わるのは良くありません。
ですのでここはCSS側(img1-3)に適切な高さを設定します。
高さと幅の役割分担
CSSへの高さ設定
.img1{ height: 200px; background: url(../images/bootstrap_backimg1.png) no-repeat; } .img2{ height: 200px; background: url(../images/bootstrap_backimg2.png) no-repeat; } .img3{ height: 200px; background: url(../images/bootstrap_backimg3.png) no-repeat; }
CSSには要素の幅の指定がありませんが、幅はグリッド側(col-sm-4)が担当しているため必要ないのですね。
これがクラス名をcol-sm-4と同列に付けた一番の理由です。
逆に「高さ」はcol-sm-4側が担当しないので、必ず必要です。
サンプル(PCでご覧下さい)
背景画像は見える様になりましたが、サイズが大きいため一部分だけが見えている状態です。
高さとテキスト分量
時には高さを超える分量のテキストが入る事もありますよね。
今回背景画像は繰り返さない設定ですから、文字がはみ出てしまいます。
掲載するテキスト分量に応じた高さにするか、テキスト量を調節していきましょう。
bakcground-size:の設定
画像全体を枠内で見せるならば、縮小する必要があります。
そこで使うのがCSSのbackground-size:プロパティです。
background-size: contain;
このプロパティ値を「contain」にする事で、カラム内の「横幅」にフィットする様になります。
containは、縦横比を保持しつつ領域内に最大サイズで収まる様になります。
ですので画像の縦幅も、元サイズの縦横比率に合わせたサイズになります。
CSS
.img1{ height: 200px; background: url(../images/bootstrap_backimg1.png) no-repeat; background-size: contain; }
サンプル(PCでご覧下さい)
画像がカラムの横幅一杯に100%幅で収まっているのがわかると思います。
coverは高さにフィット
ここでbackground-sizeを「cover」にすると、今度は「高さ」を軸にフィットするようになります。
CSS
.img1{ height: 200px; background: url(../images/bootstrap_backimg1.png) no-repeat; background-size: cover; }
サンプル(PCでご覧下さい)
この様に設定された高さを軸にサイズ調整がされます。
本来画像の横幅はまだ広いため、上の例では各画像右部分が見えなくなっています。
※わかりにくいかも知れませんが、右端が見切れています。
ここでcontainを選ぶかcoverを選ぶかは、その背景画像によると思います。
幅重視で上下が多少見切れても良いのならcontain
高さ重視で横は見切れても良いのならcover
autoは原寸サイズ
autoを選ぶと元サイズ原寸のまま背景として埋め込まれます。
autoはbackground-sizeを設定していない時と同じですから、一部分が映った状態になります。
カラム要素の内側にボックス要素を入れる
今回背景画像を設定するクラスは、カラムレイアウトと同じ位置に入れています。
しかし場合によってはこのカラム枠内に、いろいろ装飾を施したい時があるでしょう。
その際、別途入れ子のボックス要素を挟み、それに設定する事を考えがちかも知れません。
入れ子でボックス要素を入れた場合
しかし専用要素を入れ子にした場合、いろいろ上手くいかない事が多くなってきます。
ボックス要素を入れ子で独立させたHTML構成
<div class="row"> <div class="col-sm-4"> <div class="img1"><!--専用ボックス要素--> コンテンツ </div> </div> <div class="col-sm-4"> <div class="img1"><!--専用ボックス要素--> コンテンツ </div> </div> <div class="col-sm-4"> <div class="img1"><!--専用ボックス要素--> コンテンツ </div> </div> </div>
入れ子の幅と枠の幅が干渉する
上記の様に入れ子ボックスにして背景画像を入れると、画像を幅一杯に敷き詰めずらくなります。
入れ子としてボックス要素を独立させると、要素に幅の指定も必要になります。これが外枠のグリッド幅と干渉するため非常に複雑になる事が原因です。
ですのでシンプルな背景設定で良いのなら、col-xx-xと同列にクラス名を付けましょう。
そうすれば、col-xx-xの部分が幅を担当してくれる様になります。
どうしても入れ子にしなければならない場合
ではシンプルに収める事ができない場合はどうすればよいでしょうか。
例えば1カラム内で「背景画像入りの要素を縦に複数並べる」場合などですね。
これだと背景画像入りのボックスクラスが複数必要になるので、単にcol-xx-xと同列にクラス名を1つ付けるだけでは済みません。
その場合は少し複雑になりますが、以下のような形にしましょう。
背景画像入りボックスを縦に並べる場合
<div class="row"> <div class="col-sm-4"> <div class="row"> <div class="col-sm-12 img1"><!--あえてカラムを入れて背景も入れる--> </div> <div class="col-sm-12 img2"> </div> <div class="col-sm-12 img3"> </div> </div> </div> <div class="col-sm-4"> … </div> <div class="col-sm-4"> … </div> </div>
横幅計算はグリッド側に担当してもらう事
本来はcol-sm-4の中に入れ子でcol-sm-12を入れる必要は無いのですが、横幅を担当してもらうためあえて入れ子にしています。
bootstrapのグリッドレイアウトを使うのなら、横幅はグリッド側に任せる事です。それ以外のスタイルは入れ子ボックス要素で担当しても良いと覚えておきましょう、
この様にグリッドレイアウトと共存するためには、役割分担を明確にする事が重要です。
スマホ版の確認
ではこのレイアウトをスマホで確認してみると、以下の様な形になりました。
高さ200pxにフィットしているため、横に隙間があるのがわかります。
背景画像を幅一杯に広げたい
ベストなのは画像がカラム幅一杯に広がってくれる事ですよね。
では高さが「300px」だった場合はどうなるのでしょう。
PCの場合
高さを300pxにしてもPC版ではbackground-sizeが「contain」ですから、やはり横幅にフィットします。
ですのでPC版の背景画像の見た目は変わらずです(no-repeatなので高さがあっても関係ない)。
スマホの場合
スマホで確認した場合、300pxにしたカラムは背景画像の横幅が見切れてしまいます。
高さを400pxにすればより顕著に見切れます。
横長画像か縦長画像か
背景画像に高さ指定をしている場合、スマホ版では元画像サイズによって調整する必要があります。
横長の画像であればある程、少ない高さで横幅に届きます。
縦長の画像であればある程、相当高さを入れないと横幅が届きません。
これはbackground-sizeが縦横比率を守るからです。
高さを大きくするデメリット
高さを300px等にするという事はそれだけ「隙間」ができる事を意味します。
スマホ版ではそれだけコンテンツが縦に長くなります。
PC番では2段目に別コンテンツを並べた時に大きな「空白」ができるので、違和感を感じる事でしょう。
画像のためにコンテンツの高さを合わせるのは良い事ではありません。
※メディアクエリでPC版とスマホ版で高さを変える事も一つの案です。
background-size: cover;で敷き詰める
では高さ200pxのまま、スマホ版の背景画像をカラム幅一杯に広げるためにはどのようにすればよいのでしょう。
そのためにはメディアクエリで1行追加するだけです。
CSS
@media only screen and (max-width: 767px){ .img1{ background-size: cover; } }
サンプル(スマホでご覧下さい)
これにより指定された要素はカラム幅一杯に広がります。
ただし高さは200pxのままですから、縮尺した高さが200pxより長い場合は下部分が見切れてしまう事になります。
縮尺した高さが200pxより短い画像の場合は、その分余白が出る事になりますね。
大きく高さを変更するよりはこちらの方が得策です。
縦長の画像の場合
縦長の画像を背景にしている場合、スマホ版で横幅一杯に拡大される分、下はかなり見切れた状態になります。
高さが200pxしかないからですね。
これを解消するには全てが見えるだけの高さに設定するか、スマホ版だけ別の写真に差し替える事です。
絶対配置を入れる場合
background-sizeとは直接関係ないのですが、ここで絶対配置についても触れておきます。
背景画像を入れた要素上の適切な位置に、絶対配置でテキストを置く事が多いからです。
絶対配置は、親要素に「幅と高さ」が設定されていないと自由に動かせないルールがあります。
絶対配置の準備
通常は、背景画像を設定したボックス要素に対して「position: relative;」を入れます。
その上で中のテキストに対し「position: absolute;」を設定します。
高さや幅は、そのボックス要素に対して設定されるのが普通です。
絶対配置CSS
.img1{ position: relative; height: 200px; background: url(../images/caniuse_img1.png) no-repeat; background-size: contain; } .img1 p{ position: absolute; bottom: 0; left: 0; }
上記では背景と高さ、そしてposition: relative;のみを入れています。
先ほど説明した通り「幅」はグリッド側が担当しているため、設定しなくて良い訳ですね。
入れ子ボックス要素にする場合
では先ほどと同様に絶対配置ボックスを縦に並べる必要がある場合を考えてみましょう。
<div class="row"> <div class="col-sm-4"> <div class="box"><!--絶対配置box--> 絶対配置テキスト </div> <div class="box"><!--絶対配置box--> 絶対配置テキスト </div> <div class="box"><!--絶対配置box--> 絶対配置テキスト </div> </div> </div>
上記の様に絶対配置用にbox要素を独立させた場合、box要素に幅と高さの指定が無いと絶対配置ができません。
高さの方はともかく、幅の方は外枠のグリッド幅と干渉する事はこれまで説明してきた通りです。
この様に絶対配置コンテンツ枠を複数縦に並べる場合は、以下の様にします。
絶対配置コンテンツ枠を複数縦に並べる場合
<div class="row"> <div class="col-sm-4"> <div class="row"> <div class="col-sm-12 box"><!--あえてカラムを入れてboxを入れる--> </div> <div class="col-sm-12 box"> </div> <div class="col-sm-12 box"> </div> </div> </div> <div class="col-sm-4"> … </div> <div class="col-sm-4"> … </div> </div>
先ほどと同様に、あえてcol-sm-12を入れ子で入れています。
多少面倒かも知れませんが、とにかく「幅」に関してはグリッド側に任せる事がコツです。
後はbox要素に高さや絶対配置の位置をするだけです。