【脱ビギナーCSS】シンプルな基本のボタンを実装してみる

こんにちは。Web制作フリーランスのホリエです。

CSSって、かんたんに書けてしまう反面、後々再利用したり、保守したりする事も考えて実装しないと、またたく間にカオス化してしまいますよね(自戒をこめて)。

今回は、どんなウェブサイトでも必ず登場する基本のパーツであるボタンをとりあげ、正しいCSSの書き方を考えてみます。

なお、この記事の読者としては、下記のレベル感の方を想定しています。

  • HTML/CSSの入門を終えている(書籍、Progate / ドットインストールなどどれでもOK)
  • シンプルな既存サイトの模写、またはデザインカンプのコーディングを2,3ページ終えている

もちろん、初心者の方でも読んで頂くのはぜんぜんウエルカムですが、ある程度自己流でもCSSを書いた経験のある方のほうが、すんなり頭に入ってくるのではないかと思います。

完成コードと実装結果

コード

<a class="btn" href="#">基本のボタン</a>
/* メインカラーの設定 */
:root {
  --main-color: #1093cd;
}

/* 標準ボタン */
.btn {
  display:inline-block;  /* ① */
  width: 300px;  /* ② */
  max-width: 100%;  /* ③ */
  padding: 20px 10px;  /* ④ */
  color: var(--main-color);
  border: 2px solid currentColor;
  font-size: 1.125rem;  /* ⑤ */
  font-weight: bold;
  text-align: center;
  text-decoration: none;
  transition: 0.25s;
}

/* フォーカス、マウスホバー時 */
.btn:focus,
.btn:hover {  /* ⑥ */
  background-color: var(--main-color);
  border-color:  var(--main-color);
  color: #fff;
}

実装結果

See the Pen ボタン(ブログ公開用) by hori-suke (@hori-suke) on CodePen.

各プロパティの説明

①display:inline-block;

ボタンは単体で使われることが少なく、段落の中でテキストとともに使われることが多いパーツです。そのため、親の段落のtext-alignの値を自動的に反映させるために、display:inline-blockを設定しています。こうしておけば、ボタンを使用するたびに位置揃えのためのコードを書く手間を省略できます。

②width: 300px;

ボタンの最大幅を設定します。widthを指定した場合、ボタン内のテキストが長いときは、widthの幅は保ったまま、自動的に改行されます。

「width: 300px」と指定しており、ボタン内のテキストが長い状態
「width: 300px」と指定しており、ボタン内のテキストが長い状態

逆に改行させたくない場合は、widthの代わりにmin-widthを設定します。この場合、ボタンの最小幅(=min-width)を保ち、テキストにあわせて自動的にボタンの幅が伸びます。

「min-width: 300px」と指定しており、ボタン内のテキストが長い状態

つまり、テキストを改行させたいときはwidth、改行させたくないときはmin-widthを指定します。

③max-width: 100%;

スクリーンサイズが狭くなったときに、親要素の枠からボタンがはみ出ることを防ぐための指定です。100%=親要素の幅となります。

④padding: 20px 10px;

ついついやってしまいがちな書き方として、ボタンの高さをheight:〇pxのように、heightプロパティで指定してしまうことがあります。これだとボタン内のテキストが長い場合、ボタンの外側にはみ出てしまいます。

「height: 70px」と指定しており、ボタン内のテキストが長い状態
「height: 70px」と指定しており、ボタン内のテキストが長い状態

上記の理由で、ボタンにはheightを指定せず、上下左右のpaddingのみ指定します。

また、ボタン内テキストのフォントサイズに連動してpaddingも伸縮させたい場合は、paddingの単位をemにします。emはフォントサイズを基準にした相対値の単位ですので、ブラウザの設定等でフォントサイズが変われば、paddingも連動して変わります。

「font-size」と「paddingの単位」をそれぞれ変えた場合のボタンサイズの違い
「font-size」と「paddingの単位」をそれぞれ変えた場合のボタンサイズの違い
paddingへのemの多用にはご注意を

ブラウザの設定等でフォントサイズはいかようにも変化します。すると、デザインが容易に破綻し、ボタンに見えなくなることもあるので、emの多用は注意しましょう。

サンプルコードではpxで指定しているのは、そのためです。

⑤font-size: 1.125rem;

ユーザーフレンドリーなサイトのために、フォントサイズを指定するときは、絶対値(px)ではなく相対値(rem / em)を使います。各ブラウザが持っているフォントサイズ変更機能を反映させるためです。

ユーザーごとにフォントサイズの好みがあり、ブラウザ側でその設定を可能にしているのなら、それを活かす形で実装するのがコーダーの腕の見せ所でしょう。

但し、テキスト以外の要素(ブロックの幅、高さなど)も相対値で実装すべきかどうかは、制作するサイトの要件によって変わってきますので、実装前に確認しておくのが良いでしょう。

⑥.btn:focus, .btn:hover

キーボードでしか操作できないユーザーにとっては、tabキーでリンクをフォーカスしたときに見た目がはっきりと変化してほしいです。そのため、.btnの擬似クラスとして、定番のマウスホバー(:hover)に加え、フォーカス(:focus)を設定しています。

下記デモ画面内にて、tabキーでボタンにフォーカスを当てれば、マウスホバーと同様に見た目が変化することを確認できます。

See the Pen ボタン(ブログ公開用) by hori-suke (@hori-suke) on CodePen.

ブラウザの標準機能ではフォーカスリングが設定されていますが、サイトのデザインによってはフォーカスリングが出てるのかどうかわからない状態も発生します。そのため、:focusはできるだけ設定するようにしましょう。

(補足).btnのborderプロパティで使われているcurrentColorとは?

currentColorは、その要素自体に設定されているcolorプロパティの値を継承します。その値がなければ、直近の親要素のcolorプロパティの値を継承します。

つまり、currentColorは文字色を他のプロパティへ同期させたいときに便利な値です。

今回の例では、.btnに対しcolor: var(--main-color);が設定されているので、bordercurrentColorとすることで、ボーダー色が文字色と同じになります。一方、.btnの擬似クラス(.btn:focus, .btn:hover)ではcolor: #fff;が設定されているので、bordercurrentColorのままだと、ボーダー色が#fff(白)になり、ボーダー幅だけボタンが小さくなったように見えてしまいます。そのため、border-color: var(--main-color);を設定しています。

おわり

ボタンは一見かんたんに実装できるように思えますが、一つ一つのプロパティをみていくと意外と奥が深いですね。ボタンのコードをみるだけでも初心者かどうかがバレてしまうかも・・・(笑)

次回以降はこの基本のボタンを拡張する形で、いろんなパターンのボタンを実装していきたいと思います!

なお、この記事は以下の書籍を参考にさせていただいてます。CSS設計を体系的に学ぶには最高の一冊です。

この記事を書いた人

ホリエ

新卒で大企業に入社。16年後に「そうだ、これからは個人で生きていこう」と思いたち、フリーランスになった人。
Web制作を中心にこつこつモノづくりの日々を送っています。