みなさん、こんにちは。どんぶラッコです。
突然ですが、2020年8月に株式会社ProgLearnは株式会社quintetへと社名変更します。
その中で、お知らせページ内のメッセージ部分をこのようなノートのようなレイアウトにしています。

本日はこの部分をどのように作るのか?についてお伝えします。
border-bottom では実装できない!
一番最初に思いつく実装方針は border-bottomを使って要素の下に線を追加することです。
<p class="border">
あなたはほか無論その反対家によって方のためを引込んだでし。
</p>
.border {
padding: 4px 0;
border-bottom: 1px #ccc solid;
}
一見するといい感じに見えます。

しかし、この実装方法では、複数行になったときにレイアウトが崩れてしまいます。

ノートのように各行に線が引かれるようなレイアウトになって欲しいですよね。
そんな時はどうしたらいいのでしょうか。
linear-gradient と background-size!
今回使うのは、linear-gradient
と background-size
を用いる方法です。
linear-gradient
linear-gradientはグラデーションを作るときに使う関数ですね!
linear-gradient(色1, 色2)
の形式で指定します。
例では #ccc 色から透明 (transparent)に変化させています。

さてこのlinear-gradient、 linear-gradient(色1 **px, 色2 **px)
と記述することでグラデーションの開始位置を指定することができます。
例えば linear-gradient(yellow 100px, orange 150px);
と指定してみましょう。

そしてこのlinear-gradientを今回はこのように使います。
linear-gradient(#ccc 1px, transparent 2px);
すると、1pxまで #ccc 色, 2px以降は透明という指定になります。
つまり、線のような見た目になるんですね!

transparentではなく、色を指定してみると原理が納得いくと思います

background-size
では、なぜこんなややこしい指定をしているのか?
それは、背景として使うためなんですね。
そして、背景はリピートさせることができるのです。
…ちょっと何言ってるのかわからないと思うので、例を使って話します。
みなさん、 background-image
で背景画像を設置したことはあるでしょうか?
例えば、 幅・高さ共に 150px のダミー画像を用意します。

それを、幅・高さともに 300px の div要素 に適用するとどうなるでしょうか?
…そうなんです、画像が繰り返し表示されるんです。

これは backgroundの属性の一つ、 background-repeat
のデフォルト値が repeat
に指定されているからなんですね。
さて、話を戻すと我々は linear-gradient()
を使って、上に線が表示される背景画像を作成しました (透明だとわかりづらいので #eee で色をつけています)。

では、その背景画像要素を 1行分の高さにするとどうなるでしょうか?
…そうです!リピートされるんです。
今回は2文字分の高さにあたる、 2rem
を指定してみましょう。
background-size: auto 2rem;
2つの引数を指定すると 1つ目が横幅、2つ目が高さの指定になります (marginやpaddingと逆なのがややこしい!!)

無事に線を引けました!
あとは、pタグも 2rem
に揃えてあげて、余計なmarginを取り除いてあげましょう。

できました!完璧ですね
サンプル
ということで、最後にサンプルです
<div class="note">
<p>
あなたはほか無論その反対家によって方のためを引込んだでし。
</p>
<p>
あなたはほか無論その反対家によって方のためを引込んだでし。あなたはほか無論その反対家によって方のためを引込んだでし。あなたはほか無論その反対家によって方のためを引込んだでし。
</p>
</div>
.note {
background: linear-gradient(#ccc 1px, transparent 2px);
background-size: auto 2rem;
}
.note p {
line-height: 2rem;
margin: 0;
}
See the Pen ノートのようなレイアウトを作成する by cha1ra (@cha1ra) on CodePen.
CSSの仕組みを理解すると面白いですね!みなさんも試してみてください♪