CSS・並べる・配置する

Gridで格子に並べる

縦横きれいにそろった格子は、Gridの得意技。何列にするかを一行決めるだけで、カードがタイルのように整列する。

写真ギャラリーや商品カードのように、縦横きちんとそろった格子を作りたい。そんなときに力を発揮するのが 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 はその子だけ——親で揃えるか、子だけ変えるかの違いです。

このレッスンのまとめ

  1. 親に display: grid;grid-template-columns列の数を決める
  2. fr は割合の単位(1fr 1fr で均等に2分割、小数でも指定できる)
  3. 一列ならFlexbox、格子ならGridで使い分ける
  4. 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はとても向いています。

ブラウザ表示。ページ全体が中央に寄り、ヒーローが2列、すきなものが4つの格子に、じこしょうかいの本文とれんらくフォームのラベルがすき間をあけてきれいに並んでいる
バラバラだった部分が、それぞれきれいな格子に収まりました。