写真ギャラリーや商品カードのように、縦横きちんとそろった格子を作りたい。そんなときに力を発揮するのが Grid(グリッド)です。Flexboxが「一列に並べる」のが得意なのに対し、Gridは格子状に敷きつめるのが得意です。
何列にするかを決める
Flexboxと同じく、並べたいものを親で囲み、その親に display: grid; をつけます。ちがうのは、列の設計を書くところ。
.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 16px;
}
grid-template-columns: 1fr 1fr 1fr; は「3つの等しい列を作る」という意味。fr は”割合”の単位で、1fr 1fr 1fr なら均等に3分割されます。中の部品は、その格子に上から順に、きれいに収まっていきます。
列の幅は自由に配れる
fr の数字を変えれば、列の幅の配分も変えられます。
.grid {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 16px;
}
これは「左を広め(2)、右を狭め(1)の2列」。fr は残りのスペースを比率で分け合うので、画面の大きさが変わっても、割合を保ったまま伸び縮みします。
CSSFlexboxで横に並べる一列に並べるFlexboxを思い出そう——Gridとは得意分野がちがう→fr比率は小数でも書ける
2fr 1fr のような整数の比率だけでなく、1.05fr 0.95fr のように小数でも指定できます。
.hero {
display: grid;
grid-template-columns: 1.05fr 0.95fr;
}
ぴったり半分の1fr 1frだと少し機械的に見えるとき、ほんの少しだけ左を広くする——といった微妙な調整に小数のfrが便利です。数字の意味そのものは整数のときと同じで、比率で分け合うだけです。
格子の中で、部品自体を寄せる:justify-items / justify-self
Gridには、格子のマス目の中で部品をどう寄せるかを決める道具もあります。
.grid {
display: grid;
justify-items: start;
}
justify-items は親につけて、すべての子を「マスの中でどこに寄せるか」揃えます(start=左寄せ、center=中央、stretch=目いっぱい・初期値)。1つの子だけを個別に寄せたいときは、その子自身に justify-self をつけます。
.btn {
justify-self: start;
}
justify-items は全員まとめて、justify-self はその子だけ——親で揃えるか、子だけ変えるかの違いです。
このレッスンのまとめ
- 親に
display: grid; + grid-template-columns で列の数を決める
fr は割合の単位(1fr 1fr で均等に2分割、小数でも指定できる)
- 一列ならFlexbox、格子ならGridで使い分ける
justify-items(親・全員)/justify-self(子・1つだけ)でマスの中の寄せ方を決める
並べ方の道具が2つそろいました。最後は、部品を重ねたり・画面に貼りつけたりする position で、レイアウトの仕上げに入ります。
:::
やってみよう:全体・ヒーロー・すきなものを格子に組む
<main>にclass="wrap"をつけます。さらに、写真と名前・あいさつ文をひとまとめにする<section class="card hero">を新しく作り、名前とあいさつ文だけを<div class="hero__body">でくくります。
<main class="wrap">
<section class="card hero">
<div class="hero__body">
<h1 class="hero__title">こんにちは、<br><span class="name">しまちゃん</span>です。</h1>
<p>おえかきとラーメンがすきなしまです。はじめてつくった、じぶんのホームページへようこそ!</p>
</div>
<figure class="hero__art">
<div class="hero__disc">
<img src="/shima/hand.png" alt="しまちゃんの写真">
</div>
<figcaption class="hero__caption">はじめまして、しまちゃんです</figcaption>
</figure>
</section>
...
</main>
見出しにもclass="hero__title"をつけました。これまでh1タグ全体に指定していた大きさや色は、これで.hero__titleという本物のクラスにお引っ越しです。
.wrap {
max-width: 940px;
margin: 0 auto;
padding: 26px 24px 44px;
display: grid;
gap: 22px;
}
.hero {
display: grid;
grid-template-columns: 1.05fr 0.95fr;
align-items: center;
gap: 36px;
}
.hero__body {
display: grid;
gap: 16px;
justify-items: start;
}
.hero__title {
font-size: 40px;
font-weight: bold;
line-height: 1.2;
}
.hero__title .name {
color: #e8734e;
}
.likes__grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
gap: 14px;
}
.contact-form {
display: grid;
gap: 12px;
max-width: 420px;
margin: 20px auto 0;
text-align: left;
}
.contact-form .btn {
justify-self: start;
}
すきなものの<ul>にはclass="likes__grid"を、れんらくの<form>にはclass="contact-form"を、同じ要領で足しておきます。.wrapはページ全体を真ん中に寄せる格子、.heroは写真と文章を2列に、.likes__gridはすきなものを4列に、.contact-formは入力欄を縦に並べる格子です。.btnだけjustify-self: start;で、フォームの中で左寄せにします。
同じ「縦に積む格子」は、じこしょうかいの本文にも使えます。2つの<p>を<div class="about__text">でくくりましょう。
<div class="about__text">
<p>こんにちは! しまちゃんといいます。おえかきするのがだいすきで、しゅうまつはよくラーメンをたべにいきます。</p>
<p>このページは、はじめてじぶんでつくったWebサイトです。さいごまでつくれたら、きみもこれがつくれるよ!</p>
</div>
.about__text {
margin-top: 18px;
font-size: 16px;
max-width: 60ch;
display: grid;
gap: 12px;
}
.about__text p {
margin: 0;
}
.contact-formの中の<label>にも、同じ考え方が使えます。ラベルの文字と入力欄を、縦にきれいに積みましょう。
.contact-form label {
display: grid;
gap: 6px;
font-weight: bold;
font-size: 13px;
}
gapのおかげで、<p>どうし・ラベルの文字と入力欄のあいだに、自然なすき間ができます。段落や部品を「ただ並べる」だけでなく「詰まりすぎず読みやすく積む」のにも、Gridはとても向いています。
バラバラだった部分が、それぞれきれいな格子に収まりました。