2019.07.21

CSSコーディングレシピ集(コンポーネント編)


この記事では、CSS を学び始めの方を対象に、よくあるコンポーネント(部品)のコーディング方法を紹介します。

以下のシリーズ記事のコンポーネント編です。

ボタン

まずはコンポーネントの基本(?)、ボタンです。

See the Pen Buttons by Masahiro Harada (@MasahiroHarada) on CodePen.

特に難しいことはしていませんが、ここでのポイントは2つあります。「display の明示」と「マルチクラス」です。

ボタンコンポーネントは、displayinline-block と明示します。なぜなら、<a> 要素も <button> 要素と同じように、ボタンとして見せる必要がある場合が多いためです。

<button> 要素はブラウザデフォルトの displayinline-block であるのに対し、<a> 要素は inline なので、高さなどの見た目が揃わなくなってしまいます。そのため、display: inline-block と明示的にスタイルを指定して、<button> 要素であっても <a> 要素であっても、ボタンを表すクラスを付与すれば同一の見た目になるようにします。

また、ボタンには色々なバリエーションが存在する場合も多いです。上の例では、横幅いっぱい、枠のみ、色違いのバリエーションを載せてみました。

これらのバリエーション違いは、マルチクラスで表現すると管理しやすいです。

シングルクラスの例
<button class="button">...</button>
<button class="fullwidth-button">...</button>
<button class="outline-button">...</button>
マルチクラスの例
<button class="button">...</button>
<button class="button button-fullwidth">...</button>
<button class="button button-outline">...</button>

どんなバージョンのボタンでも、基本的ないくつかのスタイルを共有しているはずです。例えば、角の丸さやパディングや文字サイズなど(仮に共有していなかったらデザインに整合性が欠けている)。

そこで、基本となるクラス(上の例では .button)に共通のスタイルおよびデフォルトのスタイルを持たせます。そして button-fullwidthbutton-outline といったバリエーションを表すクラスで必要な箇所のみスタイルを上書きします。

このように複数のクラスでスタイルを管理すると、記述の重複を抑えることができます。ボタンに限らず、バリエーション違いが存在するコンポーネントで活用できるテクニックです。

テキストを丸める

続いて、テキストを丸める記述です。

CodePen の一番下(緑背景)は、3行以上が丸められます。

See the Pen テキスト丸め by Masahiro Harada (@MasahiroHarada) on CodePen.

一行の文字丸めは、もうあるあるですね。以下の3兄弟が登場します。

.text-ellipsis {
  overflow: hidden; /* あふれた部分を非表示 */
  text-overflow: ellipsis; /* あふれた部分に省略記号を表示 */
  white-space: nowrap; /* 改行させない */
}

複数行の文字丸めは、簡単な方法はありません。
もっとも簡単な方法は、上の CodePen でも紹介している、-webkit-line-clamp を利用した方法でしょう。ただし、ベンダープレフィックス(-webkit)からも予想できるように、Chrome でしか動きません。

.text-multiline-ellipsis {
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
}

Chrome のみの対応で OK なのであればこの方法を試してもいいかもしれませんが、そんなことは稀でしょう。他にもネットの記事を漁ると、「CSS のみ」で複数行の文字丸めを実現する(とても複雑な)方法をいくつか見つけることができます。ただ、私が試した限りでは、日本語で、どんな場合でも美しく表示できる、CSS のみの方法は存在しないようです。

JavaScript を使用して丸めることもできますが、私の一番のオススメは、サーバサイドがある場合はサーバサイドにお願いして、あらかじめ丸めてもらうことです。これがシステム全体にとっても、最もシンプルな解決策だと思います。

矢印(三角形)

簡単な矢印のような図形であれば、CSS で表現することができますし、画像などを用意するよりも簡便でしょう。

矢印は、border を利用して作成します。詳しい仕組みについては、「CSS 三角形」や「CSS 矢印」で検索するとたくさん出てくるので割愛します。

ボタン

矢印をボタンに収めるパターンです。

See the Pen 矢印 by Masahiro Harada (@MasahiroHarada) on CodePen.

  • 意味のない図形は、しばしば beforeafter の擬似要素で表現します。
  • 作成した三角形や矢印をボタンに収める際は、前回の記事で紹介した、絶対位置と transform を用いた上下中央寄せのテクニックを用います。

吹き出し

こちらは三角形を使って吹き出しを表現する例です。全体をチャット風にしてみました。

See the Pen 吹き出し by Masahiro Harada (@MasahiroHarada) on CodePen.

三角形を position: absolute にすることで、上下左右自由な場所に配置できます。

画像

特定の枠内に画像を綺麗に収めるパターンです。

たとえば Instagram の投稿一覧画面のように、特定の幅と高さを持った枠内に、横長だったり縦長だったりする画像を綺麗に収めるには、object-fit を使うのが最もシンプルです。

See the Pen Fit Image by Masahiro Harada (@MasahiroHarada) on CodePen.

縦長、横長画像のそれぞれ一番右のように、何も処理をしないと画像は歪んでしまいますが、object-fit を用いることで「短辺に合わせてあふれた部分はカット」や「長辺に合わせて画像全体を表示」などの表現を簡単に得ることができます。

object-fit に関してはこちらの記事が詳しいので参考にしてください。

様々なリスト

最後に、リストの表現を紹介します。

ランキング

See the Pen Ranking by Masahiro Harada (@MasahiroHarada) on CodePen.

スタイルの記述については CodePen の CSS 欄をご覧いただきたいですが、ここで伝えたいポイントは、CSS 設計についてです。

リストとリストの内容は、別のコンポーネントとして捉えると、管理がしやすいです。

<!-- OK -->
<ul class="card-list">
  <li class="card-list-item">
    <article class="card">...</article>
  </li>
</ul>

<!-- NG -->
<ul class="card-list">
  <li class="card">...</li>
</ul>

上の CodePen で言うと、ランキングのリストと一つ一つのランキングアイテムを、別のクラスに分けて考えようということです。

たとえばランキングアイテムは灰色の線で区切られていますが、この線はランキングアイテムそのものが持つべきではなく、リストが持つべきだと思います。なぜなら、この線の目的はランキングアイテム同士の境界を示すことだと考えられ、つまりこのリストの並び方をしたときのみ必要、リストの内容(ランキングアイテム)自体には不要だからです。

よくあるのは、何らかのコンポーネントのリストが、特定の間隔を持っているパターンです。この間隔のマージンをコンポーネントそのものに持たせると、扱いにくくなります。あとで別の文脈でそのコンポーネントを使いたくなったときに、その文脈においては不要なマージンを持ってしまっているためです。

コンポーネントの独立性を保つように設計すると、上記のような不便を防ぐことができます。「リストとリストの内容を別のクラスで管理する」ことはその方法の一つです。

メニュー

こちらはリンクのリストですが、末尾に矢印が付いています。こういうリストもよく目にしますよね。

See the Pen メニューリスト by Masahiro Harada (@MasahiroHarada) on CodePen.


以上、よくあるコンポーネント(部品)のコーディング方法をいくつか紹介しました。