ワイヤード・パンチ

サイトレイアウトを変えてみました。よろしければアンケートにご協力ください。

グリッドレイアウトを作るなら、floatやdisplay:flexより、display:gridが便利。

以前まで当サイトの記事一覧ページは、スマホ版に限らずPCでも、1カラムだけのレイアウトとなっていました。

しかしそれだと、どのような記事があるかパッと見でわかりづらいと感じたため、画面幅に応じてカラム数が異なるグリッドレイアウトに変更されるようにしました。

それを作成する際、昔ならfloatやdisplay:flexを使っていたところですが、今ならdisplay:gridを使うことで、あっという間に作成できるようになりました。

広告

floatを使った方法。

今回は、上の写真のように等幅の要素が横に3つ並んだレイアウトを作ってみます。

まずはhtmlから。

<div>
	<p>要素1</p>
	<p>要素2</p>
	<p>要素3</p>
</div>
<div>
	<p>要素4</p>
	<p>要素5</p>
	<p>要素6</p>
</div>

続けてcss。

div {
	overflow: hidden;
	background: #ccc;
}

p {
	float: left;
	background: #eee;
	width: calc(33.3333% - 7px);
	margin-right: 10px;
}

p:nth-of-type(3n) {
	margin-right: 0;
}

等幅の3つの要素なので、幅は33.3333…%としてます。

100%から3で割っても割り切れない値になってしまうので、とりあえず細かく小数点を入れておきます。

割り切れない値が入ってしまうことが、まず厄介ですね…。

次に、要素間の幅は10pxとしています。

しかし、単純にmarginを入れてしまうと、要素3つ合わせて100%となっている幅に、間隔の分をプラスしてしまうので100%を超えてしまい、要素が折り返してしまいます。

そのため、3等分の幅から2つ分のmarginを削った値を求めるため、calcを用いることになるのですが、この計算が非常に面倒。

1つの要素からmarginそのままの10pxを削ってしまうと、3つ目の隣が空いてしまいます。

だから1pxずつ削って、折り返しにならない値を探していくのですが、そもそもwidthが割り切れない値を無理に丸めたものになっているので、正しい値が出てきません。

また、1段の最後の要素の隣に間隔をつくってはいけないので、nth-of-type(3n)を書いて、3つごとにmarginを打ち消しています。

段の最後の要素に対して、いちいち専用の値を入れるのが面倒ですし、もし1段の要素の数が変わったら、nの隣の数字も書き直しです。

これらに加えてfloatを使っていると、overflow:hiddenで1段を囲わないと、次の段にも影響を及ぼしてしまいます

要素をあとから並び替えたくなる場合もあるのに、divで閉じ直すのが非常に面倒です。

とにかく、横並びの要素を実現するために、floatを使うのは古臭すぎます

display:flexを使った場合。

floatと比べると、格段にスッキリしていて、なおかつ編集しやすいコードとなっています。

まずhtmlから。

<div>
	<p>要素1</p>
	<p>要素2</p>
	<p>要素3</p>
	<p>要素4</p>
	<p>要素5</p>
	<p>要素6</p>
</div>

1段につき要素が3つであることに変わりはないのですが、段が変わってもdivを囲い直す必要がなくなりました。

続けてcss。

div {
	background: #ccc;
	display: flex;
	flex-wrap: wrap;
}

p {
	background: #eee;
	width: calc(33.3333% - 7px);
	margin-right: 10px;
}

p:nth-of-type(3n) {
	margin-right: 0;
}

flexには様々な使い道があるのですが、今回のように単純な横並びであれば、親要素にdisplay:flexを付けるだけでOKです。

でも、そのままだとすべて同じ段に入ってしまうので、親要素にflex-wrap:wrapを付けることで、折り返すようになります。

しかし、小要素を3等分するために、割り切れない値をwidthに入れていることは変わりありません

小要素にflex:1を付けると、widthがなくても等幅にすることができるのですが、通用するのは同じ段で要素を入れるときだけ。

このhtmlでflex:1をやってしまうと、1段に6等分になってしまいます

display:gridを使った場合。

そして今回のメイン。まずhtmlはflexのときと変わりありません。

<div>
	<p>要素1</p>
	<p>要素2</p>
	<p>要素3</p>
	<p>要素4</p>
	<p>要素5</p>
	<p>要素6</p>
</div>

一方でcssは、さらに簡略化できます。

div {
	background: #ccc;
	display: grid;
	grid-gap: 0 10px;
	grid-template-columns: 1fr 1fr 1fr;
}

p {
	background: #eee;
}

子要素に書かれていたwidthは、一切なくなりました。

親要素にあるgrid-template-columnsで、1段における要素の数と幅を決めています

上記の場合だと、値が3つなので要素の数は3つになり、すべて1frなので、合わせて3等分ということになります。

もし、左のfrを2にすれば1段の要素の幅が2:1:1になり、frを一個増やせば要素が1段につき4つになります。

先程までの書き方と比べると、1段の要素の数と大きさの比率を直感的に書けるようになりました。

割り切れない値を入れる必要がないので、先程まで最後の要素の右隣にあった微妙な隙間もなくなりました。

また、grid-gapは要素間の間隔を表しており、上下・左右の順で入力します。

1段の最後の要素に対して、打ち消しmarginを入れるなんてことも必要ありません

これでコードが見やすいのはもちろんのこと、あとから簡単に編集することができるでしょう。

なお、1段の要素をすべて等幅にする場合、わざわざその分frを書く必要はありません。

div {
	background: #ccc;
	display: grid;
	grid-gap: 0 10px;
	grid-template-columns: repeat(3, 1fr);
}

p {
	background: #eee;
}

repeatを使えば同じ幅の要素を繰り返すことができるので、さらに理解しやすいコードになるでしょう。

display:gridにはまだまだ使い道があるので、各自で調べてみて、cssの記述をもっと楽していきましょう。

余談。

冒頭に書いたとおり、PCで表示したときの記事一覧ページのレイアウトが大きく変わりました。

ただ、本当にこれが受け入れられるものがどうかわからないので、アンケートを取ってみます。

現在のレイアウトが見やすいかそうでないか、ご協力いただけると助かります。

アンケートフォームからコメントは投稿できないので、もしご意見がある方は、メールマストドンまでお願いします。