横並びの画像やコンテンツを簡単にレスポンシブ表示する方法 [拡張編]

マークアップ言語

以前「横並びの画像をCSSで簡単にレスポンシブ表示する方法」という記事を書かせていただきましたが、何よりも「簡単に」という点を重視していた事もあって、本当にタイトル以上でも以下でも無いそのまんまの事しか出来ないのがずっと気になっていました。

そこで、今回はそれを発展させた拡張版と言いますか、表示するデバイスの画面サイズに合わせてカラム(列)数を変えたり、画像以外のちょっとしたコンテンツも並べられるよう改良を加えました。

今回は画像でもテキストでも何でもOK

ちなみに前回の記事というのはこちらになります。

単純に画像を横並びに表示したいだけで、PCでもスマホでも全く同じ見え方になればいいという事なら上記のエントリーを参考にしていただいても特に問題無いかと思いますが、当エントリーでは画像に限定せずコンテンツ枠を作成してその枠を制御する形になるので、その中には画像やテキストなどの要素を好きなように組み合わせて表示させる事が出来ます。

ただ、そのコンテンツ枠に入れる要素のスタイリングに関しては必要に応じて各自でお願いしますという事になりますが、当エントリーの後半にいくつかサンプルを掲載しておきますのでそれらが参考になれば幸いです。

基本的な作業手順

コピペするだけで使えるCSSとHTMLのサンプルを用意しましたので、どなたにも簡単に利用していただけるのではないかと思います。

尚、作業内容としては以下のような流れになります。

  • コピペ用CSSをstyle.cssなどにまるっとコピペ
  • コピペ用HTMLを使用したい場所にコピペしてカラム数を設定
  • コンテンツ枠を必要な数だけコピペで増やす
  • 表示したいコンテンツを@コンテンツ内容@に挿入、またはコピペ

以上です、簡単ですね?

現在利用しているWordPressのテーマやHTMLのテンプレートによっては、必ずしも当エントリーで想定した結果にならない場合がありますので、その点はあらかじめご了承下さい。

コピペ用CSSの説明

こちらがコピペ用CSSになります。とりあえず最初は何も考えずにまるっとコピペしていただいて、それから好きなようにカスタマイズするなり不要な部分を削除するなりしていくのがよろしいかと思います。

コピペ用CSS
/* フレックスボックスの基本設定 等間隔(両端揃え)折返しあり */
[class^="flex-col"] {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
}

/* コンテンツ下のマージン */
.flex-child { margin-bottom: 10px; }

/* 各カラム毎のコンテンツと疑似要素の横幅 */
.flex-col2 .flex-child { width: calc( (100% - 10px) / 2 ); }

.flex-col3::after,
.flex-col3 .flex-child { width: calc( (100% - 20px) / 3 ); }

.flex-col4::before,
.flex-col4::after,
.flex-col4 .flex-child { width: calc( (100% - 30px) / 4 ); }
	
/* 最終行は両端揃えにしない */
.flex-col3::after,
.flex-col4::before,
.flex-col4::after { content: ""; }

.flex-col4::before { order: 1; }

/* レスポンシブ対応 */

/* 991px以下で4列 → 3列 */
@media screen and (max-width: 991px) {
	.flex-col4::after,
	.flex-col4 .flex-child { width: calc( (100% - 20px) / 3 ); }
}

/* 767px以下で4列・3列 → 2列 */
@media screen and (max-width: 767px) {
	.flex-col3 .flex-child,	
	.flex-col4 .flex-child { width: calc( (100% - 10px) / 2 ); }
}

/* 575px以下で全て1列 */
@media screen and (max-width: 575px) {
	.flex-col2 .flex-child,
	.flex-col3 .flex-child,
	.flex-col4 .flex-child { width: 100%; }
}
最初の「フレックスボックスの基本設定」の部分ですが、ベンダープレフィックスはもう必要無さそうだったので省略してあります。やっぱりついてないとちょっと不安だという方はお手数ですが調べて追加しておいて下さいね?

一応それっぽくコメントはつけたつもりですが、CSSの内容をざっくりと説明してみます。

フレックスボックスの基本設定

折返しありなので設定したカラム数よりコンテンツ数が多い場合は折り返して次の行に表示されます。いわゆるグリッド表示と言えばいいでしょうか。

カラム毎のコンテンツ幅

2~4カラムの各コンテンツ幅の設定をしています。%指定にするとデバイス(PCとかモバイルとか)の画面サイズによってカラムの間隔にバラつきが出るので、カラム間のマージンを10px固定にして、それを100%から引いた値をカラム数で割って求めてみました。

そんな面倒な事しなくてもいいですよ?という事なら普通に%指定に修正していただいてOKです。私は妙なところに拘る傾向があるようでして…そのくせ大事なところは結構アバウトだったりするんですけどね?

最終行は両端揃えにしない

カラム数とコンテンツ数が同じかその倍数の場合は全く問題ありませんが、そうでない場合にコンテンツ数によっては下の画像のようになっちゃう事があるんですよね。

これはバグではなく両端揃え(space-between)にしているからなんですが、最終行だけは普通に左詰めで表示したいので、疑似要素(beforeとかafterとかいうやつです)を使ってそうならないようにしてあります。特に気にならない方はこの部分を削っていただいて構いません。

尚、これは3カラム以上の時に起こる現象なのでPCでは2カラム、スマホでは1カラムというような使い方の場合は不要になります。

レスポンシブ対応

PCでは4カラム、タブレットでは2~3カラム、スマホでは1カラムといった感じで、デバイスの画面サイズによってカラム数を変化させる事が出来ます。もちろんこの機能も必要無ければ削除していただいて構いませんし、ブレークポイント(何pxで~という区切り)は必要に応じて適当なサイズに修正してご利用下さい。

コピペ用HTMLの説明

コピペ用のHTMLはこちらになります。以下のフォーマットが基本になりますので、この形だけは崩さないように注意して下さいませ。

コピペ用HTML
<div class="flex-col2">
	<div class="flex-child">
		@コンテンツ内容@(ここに画像やテキストなどを入れます)
	</div>
	<div class="flex-child">
		@コンテンツ内容@(ここに画像やテキストなどを入れます)
	</div>
</div>

一番外枠のdivタグのクラス名は以下のように設定します。

  • 2カラムの場合:flex-col2
  • 3カラムの場合:flex-col3
  • 4カラムの場合:flex-col4

5カラム以上の使用は想定していませんが、当エントリーのHTMLとCSSを部分的にコピペしてちょちょいとイジれば対応出来ると思いますので、必要であればぜひ挑戦してみて下さい。

コンテンツ枠

その内側にあるflex-childがコンテンツ枠になります。これを表示したいコンテンツの数だけコピペで増やして使用して下さい。設定したカラム数を超えたコンテンツ枠は折り返して表示されます。

例えば外枠をflex-col4と設定してコンテンツ枠を8つ作成した場合は4列の2行という事になります。

サンプルとコーディング例

コンテンツ枠の使用例としてサンプルをいくつか用意しました。先ほどのコピペ用HTMLで言うと@コンテンツ内容@の部分にメディアを追加したりコードを貼り付ける形で使用します。

画像(リンク無し)

画像を貼り付けるだけの最もシンプルな例で、WordPressなら普通にメディアを追加するだけでOKです。その場合、HTMLにクラスやサイズなどが自動的に付加されますが、特に問題無いのでそのままでも大丈夫です。

画像(リンク無し)

<img src="https://~.jpg" alt="">

画像(リンク有り)

こちらは画像にリンクがついている場合の例ですが、手順的にはリンク無しの場合と何も変わらないので特に意識する必要はありません。

画像(リンク有り)

<a href="https://~"><img src="https://~.jpg" alt=""></a>

画像(キャプションつき)

キャプションというのは画像につく説明文の事ですが、WordPressでは画像にキャプションが設定されているとメディアを追加した時に自動的にこの形式になります。

画像のキャプション設定

この形式とか言ってサンプルのコードは貼っていませんが、これはショートコードで本文中に挿入されるので、そのまま表示させようとすると"[“を重ね打ちしたりエンティティ変換という作業が必要になるんですが、そうしたところでビジュアルエディタとテキストエディタを切り替えたりすると消えちゃうので…と言うか実際に何回か消えて嫌になったのでそこは省略させて下さいという事でひとつお願いします。

YouTube

WordPressならoEmbed機能を無効化していなければ短縮URLだけで表示してくれますし、埋め込み用のembedコードを貼り付けても同様に表示出来るかと思います。

YouTube
https://youtu.be/xxxxxxxxxxx
	または
<iframe src="https://www.youtube.com/embed/~"></iframe>

テキスト

タグで括らずにそのまま書く事も出来ますが、投稿や固定ページの本文と同じスタイルが適用されないようなので、pタグやspanタグなどで括った方がいいかもしれません。WordPressの場合は自動整形で削除されないようにダミーでもいいので何かクラス名をつけておくとよさそうです。

テキスト
<p class="flex-text">@テキスト@</p>
	または
<span class="flex-text">@テキスト@</span>

見出し+画像+テキスト

本文と同じように見出しをつけて画像とテキストを入れたりする事も出来ます。

見出し+画像+テキスト
<h3>@見出し+画像+テキスト@</h3>
<img src="https://~.jpg" alt="">
<p class="flex-text">@テキスト@</p>

CSSのカスタマイズが必要な例

この辺りは利用しているテーマやテンプレートによって変わってくると思いますが、とりあえず今思いつく範囲でカスタマイズ例を挙げておきますので、必要に応じてコピペ用CSSに追記してご利用下さい。

見出しのマージン調整

一般的に見出しには上下にマージンが取ってある事が多いので、コンテンツ枠の中で見出しを使う場合は恐らく修正が必要になると思います。

見出しのマージン調整

.flex-child h4 { margin: 0 0 20px; }

画像サイズをコンテンツの幅に合わせる

画像のサイズがコンテンツ枠より小さい場合に余白が出来てしまうので、画像サイズをコンテンツ枠に合わせて引き伸ばします。ただし、画像は枠にフィットするので見映えは良くなりますが、引き伸ばした分だけ画質は悪くなる事に注意です。

画像サイズをコンテンツの幅に合わせる

.flex-child img { width: 100%; }

キャプションつき画像関連

画像とキャプションを含む枠とキャプション部分のカスタマイズです。

キャプションつき画像関連
/* キャプションつき画像をボーダーで囲む */
.flex-child figure {
	border: 1px solid #ddd;
}

/* キャプションをセンタリング */
.flex-child .wp-caption {
	text-align: center ;
}

/* キャプションのフォントサイズ調整 */
.flex-child .wp-caption-text {
	font-size: 14px;
}
コンテンツ内に限らずサイト全体に適用していい場合は.flex-childはつけなくてOKです。

キャプションつき画像の注意点

このキャプションつき画像は本文中にショートコードで挿入される形になりますが、そのショートコードに含まれるwidthのせいか「画像のサイズがコンテンツ幅より小さい場合、コンテンツに合わせる」というCSSが効きません。

だったらwidthを消せばいいんじゃね?と思い削除すると、今度はキャプションそのものが表示されなくなってしまうという…ぐぬぬ。

かと言って!importantは使いたくないしどうしたものかと試行錯誤したところ、captionのショートコード内のwidthをコンテンツ幅より小さくならない値に修正する事で回避出来ました。どこかでちゃんとした対策は考えたいと思いますが、もし今その状態になった場合はとりあえずそれでご容赦を…

コンテンツ枠をボーダーで囲む

これは文字通りコンテンツの外側にボーダーを引くというものですが、ボーダーをつけたい時とつけたくない時の両方に対応出来るような方法を考えてみました。

CSSはこんな感じで作成しておいて

コンテンツ枠をボーダーで囲む場合のCSS
//* コンテンツ枠をボーダーで囲む */
.flex-with-border {
	padding: 20px;
	border: 1px solid #ddd;
	border-radius: 4px;
}

HTMLはボーダーをつけたい時だけコンテンツ枠のクラスに上記で作成したflex-with-borderを追加するという感じでどうかなと。

コンテンツ枠をボーダーで囲む場合のHTML

<div class="flex-child flex-with-border">

実際どんな感じになるかはこの後のサンプルで確認出来るようにしてあります。

コンテンツ内側の下にムダな余白が出来る

コンテンツ枠の中にpタグを使ってテキストを入れた場合、テーマやテンプレートによってはpタグに設定されたマージンの分だけ更に余白が出来てしまう場合があります。そんな時は最後のpタグだけ下のマージンを無くす事で対応出来ました。

コンテンツ内の最後のPタグのみ下マージン無し

.flex-child p:last-child { margin-bottom: 0; }

実際の使用例

それではここまでに紹介したCSSとHTMLを使ってデモ用のサンプルを作ってみました。

2カラムのサンプル

画像(リンク有り)

Gibson LesPaul

画像(キャプションつき)

Fender Amplifer
Fender Amplifer

画像(リンク有り)

YouTubeの動画埋め込みもOKですが、ちゃんと視聴しようと思うとサイズ的には2カラムが限界でしょうか。

テキスト

時にはテキストだけのコンテンツ枠を作りたい場合もあるんじゃないかと思います。これはそんな時に利用して下さい。とりあえず適当に文章を書いてみたりなんかしたりして。

とは言うもののあくまでもサンプルなんで、あまり長い文章とか書くのも難しいんですけどね…ひとまずこの辺でいい事にしよう、そうしよう。

3カラムのサンプル

CSSのカスタマイズ例で挙げたコンテンツ枠にボーダーをつけたサンプルをいくつか入れてみました。

画像+テキスト

幻想的な風景画像1

画像(リンク無し)+テキストのコンテンツ枠です。

画像+テキスト

幻想的な風景画像2

画像(リンク有り)+テキストのコンテンツ枠(ボーダー有り)です。

画像+テキスト

幻想的な風景画像3
幻想的な風景画像3

画像(キャプションつき)+テキストのコンテンツ枠です。

テキスト

テキストのみのコンテンツ枠(ボーダー有り)です。

YouTube+テキスト

YouTube+テキストのコンテンツ枠(ボーダー有り)です。

ボーダー有り無しのコンテンツが混在すると?

ボーダーをつけた枠だけ見出しがズレていたり画像がひと回り小さいのは、CSSでコンテンツの枠にpaddingがつけてあるからです。そうしないと枠にくっついちゃいますからね。

実際にボーダー有りと無しのコンテンツを混在させる事があるかは使い方次第ですが、あくまでもデモ用のサンプルでこんな風にも出来ますよという事なので、その辺りは使用する際に確認しながら調整していただければと思います。

4カラムのサンプル

コンテンツ内容のパターンはこのくらいでいいかな?という事で、最後はコンテンツ枠のレスポンシブ表示のみの確認とさせていただきます。

幻想的な都会の画像4
幻想的な都会の画像3
幻想的な都会の画像2
幻想的な都会の画像1
幻想的な風景画像3
幻想的な風景画像2
幻想的な風景画像1
幻想的な都会の画像3
Gibson LesPaul
Fender Amplifer

既知の問題点

今後の課題にするかは正直何とも言えませんが、とりあえず現時点でわかっている事を挙げておきます。あとはバグ報告をいただけたらここに追記する形になるでしょうか…無ければ無いにこした事はありませんが。

コンテンツ枠の高さはその行で最大の枠に合わせられる

これはアスペクト比(縦横比)の違う画像を並べた時に一番わかりやすいですが、コンテンツ枠の高さは全て同じでも画像の高さは当然合わないので見た目があまりキレイではありません。

これをCSSで何とかしようとすると色々と制約がついたり面倒な部分が多いので、一番てっとり早いのはあらかじめ使用する画像のサイズや比率を揃えておく事です。

それでも、どうしてもCSSでという事ならmax-heightやobject-fitなどで頑張ってみて下さいね?レスポンシブでカラム数を変化させている場合はそちらも設定する必要がありそうです。

投稿・固定ページ・ウィジェットで活用して下さい

何と言いますか「なんちゃってBootstrap」的な感じのカスタマイズでしたが、投稿・固定ページ・ウィジェットなど好きな場所で活用していただければと思います。

当エントリーの内容は私なりに十分検証したつもりですが、WordPressやその他のCMS・静的サイト、使用しているテーマやテンプレート、ブラウザの違いなどで「なんじゃこりゃー」的な想定の遥か斜め上の事態になる可能性もありますので、使用される前にテスト用ページなどで動作確認した上でご利用下さい。

バグ報告やご意見など、何かありましたらお手数ですが当エントリーのコメントか問い合わせフォームからご一報いただけると幸いです。