CSSレイアウトパターン(2)幅・高さ固定+上下左右中央寄せ
「これだけは身に付けてほしい、6つのCSSレイアウトパターン」の詳細解説です。2つ目はボタン等で多用する「幅・高さ固定+上下左右中央寄せ」です。
はじめての方はお読みください↓↓
サンプル
実際にブラウザで見られるサンプルはこちらです。
ページタイトル(高さのみを固定)
ボタン(幅・高さの両方を固定)
なぜかわかりませんがカーソルを置いたときの効果が反映されません。枠の下の表示倍率を 0.5x にしてください。
基本的な挙動
タブレットの画面幅(640px・768px・1024px)を区切りとして、幅・高さ・文字サイズが変更されることが多いです。この手のパーツは、縦長の画面と横長の画面では見た目の印象が変わってくるためです。
このパターンが使用されるパーツ
主に「四角くてゆとりのあるパーツ」に使用されます。ボタン、ページタイトルなどの帯状に背景色がある見出し、ナビゲーションなどです。特にボタンは、モバイルでも最低44pxの領域が必要とされているため、頻繁に使用します。特にアイコンが中央に配置されているボタンではお世話になります。
この手のパーツについては、大きく取ったpaddingでサイズを確保する方法もあります。BootstrapなどのCSSフレームワークのボタンや、WordPressのテーマのボタンはテキストに何文字入るか予測できないので、paddingが使用されています。
ですがきっちりデザイン指示があり、中に何文字入るかわかっている現場のウェブ制作の場合は、paddingではきれいにサイズを揃えることが難しいです。このため、この記事で解説するwidth・heightを決めた範囲内に文字を中央寄せする方法が基本となります。
ここからは、ページタイトルと、ボタンの2パートに分けて解説します。
A:ページタイトルの作成
HTML
「pageHeader」というクラス名がよく使用されます。以下のとおり、タイトルを含める構造でマークアップします。英語名があればサブタイトルも入ります。
<div class="pageHeader">
<p class="pageHeader__subtitle">Information</p>
<h1 class="pageHeader__title">お知らせ</h1>
</div><!-- /.pageHeader -->
多くの制作会社が採用しているBEM記法だと、複数の単語からなるクラス名は途中に大文字をはさむので「pageHeader」となりますが、WordPressの公式テーマやブロックで使用されているSMACSS記法だと、特にそういう規定はないので以下の通りになります。
<div class="pageheader">
<p class="pageheader-subtitle">Information</p>
<h1 class="pageheader-title">お知らせ</h1>
</div><!-- /.pageheader -->
CSS
まず、display: flex を指定して、ページタイトルのタイプ(厳密にはレイアウトモデルと言います)を、flexboxに変更します。
.pageHeader {
display: flex;
}
このままだと、タイトルとサブタイトルが横並びになってしまいます。flexboxとなった要素の、子要素の並びのルールは、row(横)が基本値だからです。これをcolumn(縦)に変更します。
.pageHeader {
display: flex;
flex-direction: column;
}
続いて、子要素の配置を上下左右中央になるようにします。
align-items、justify-contentプロパティの両方をcenterにします。
.pageHeader {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
これで、カンプ通りの高さや背景色を指定すると、中の見出しが上下左右中央に配置されます。
.pageHeader {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 200px;
background-color: #eeeeee;
}
作業的にはこれで終わりなのですが、私は行高さを「1」にしています。
行高さがあると、文字の位置が微妙にずれ、カンプ通りにすることが難しくなります。ページタイトルが二行以上になることはありえないので保険をかけておきます。
.pageHeader {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 200px;
background-color: #eeeeee;
line-height: 1;
}
補足:デザイナーの意図が違うケース
ページタイトルとサブタイトルの両方がある場合、デザイナーさんの「縦中央」の解釈が違うことがあります。上の図のとおりですが、中央線がページタイトルの中央、ということです。
ぱっと見、気付きにくいうえに手戻りになってしまうので、上下余白が均等になっているかは作業前にカンプデータをきちんと測ってチェックしてください。
この場合はflexboxを使わず、position: absoluteで配置した方が早いと思います。もっとスマートな手がいくつか考えられますが、上級向けなのでここでは割愛します。
補足:見出しの文字の太さ
.pageHeader__title はそのページの大見出しなので、h1要素となることが多いですが、SEO(検索エンジン最適化)の都合で、ページによってp要素に変わることがあります。h1要素とp要素では何もCSSを指定していないときの文字の太さが異なるので注意が必要です。h1要素しか使わなさそうでも、font-weight: bold を指定しておいた方がよいです。
B:ボタンの作成
HTML
「button」もしくは「btn」というクラス名がよく使用されます。ほぼa要素、button要素、input要素となりますが、外観だけボタンっぽくしたい状況で、span要素でマークアップすることもあります。
「外観だけボタンっぽくしたい状況」については、またいずれ、別の記事でご紹介します。
<a href="#" class="button">今すぐ申し込む</a>
<button type="submit" class="button">今すぐ申し込む</button>
<input type="submit" class="button" value="今すぐ申し込む">
CSS
まず、box-sizing: border-box を指定します。
box-sizing プロパティは「要素の幅・高さにborderやpaddingを含めるか」を切り替えます。
.button {
box-sizing: border-box;
}
ほぼすべてのブラウザの初期値は、含めない(content-box)になっているのですが、ボタンには幅と同時に枠線が入ることが多く、計算がややこしくなるので変えます。
なお、すべての要素の見た目を打ち消す「CSSリセット」を使っていた場合は、最初からすべての要素が border-box になっているので不要です。
前項と同じように display: flex を指定して、ページタイトルのタイプ(厳密にはレイアウトモデルと言います)を、flexboxに変更します。
.button {
box-sizing: border-box;
display: flex;
}
アイコン付きのボタンなどで、複数の子要素があった場合は横並びになります。デザイン上の都合でアイコンとテキストを縦並びにしなければならない場合は、前項のとおり、column(縦)に変更してください。
続いて、子要素の配置を上下左右中央になるようにします。
align-items、justify-contentプロパティの両方をcenterにします。
.button {
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
}
これで、カンプ通りの幅、高さ、背景色を指定すると、中のテキストやアイコンが上下左右中央に配置されます。
.button {
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
width: 480px;
height: 70px;
background-color: #eeeeee;
}
a要素であれば、初期状態で下線が入るので消しておきます。
.button {
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
width: 480px;
height: 70px;
background-color: #eeeeee;
}
a.button {
text-decoration: none;
}
補足:正円、楕円ボタンについて
ボタンのデザインで頻繁に指示される「正円」「楕円」はレイアウトとは違うのですが、ウェブ制作では高さに直結するので補足しておきます。
widthとheightを同じ値、かつ、角を丸くする border-radius の値を「50%」にすると正円となります。
.button--circle {
width: 64px;
height: 64px;
border-radius: 50%;
}
値の単位が%の場合と、pxやremの場合では角丸の解釈が異なります。pxやremだと、 border-radius が height の半分を超えていると楕円になります。
例えばボタンが60pxだったら、半分の30pxを指定します。
.button--oval {
width: 300px;
height: 60px;
border-radius: 30px;
}
…ですが、実は上の図の通り「超えている」のであれば何でもよいです。
これを利用して「10em」などの、絶対に高さの半分を切らない値とすれば、デスクトップのサイズでも、スマートフォンのサイズでも関係なく楕円となり、border-radiusの上書きが不要になります。
.button--oval {
width: 240px;
height: 44px;
border-radius: 10em;
}
@media screen and (min-width:768px) {
.button--oval {
width: 360px;
height: 60px;
}
}
text-align: center との違い
CSSの経験が浅いと text-align: center と、この記事で解説した justify-content: center・align-items: center がごっちゃになりがちですが、3つともまったく別です。
ほとんどの場合は中身がテキストなので、text-align: center と書いても中央寄せになってくれますが、違いを理解していないと「text-align: centerを書いているのに、中身が中央に寄らないよー!」というハマりが起きます。
とりあえず「flexboxだったら、justify-content・align-itemsを使う」と覚えておいて、制作に慣れてきたら、MDNの解説や、いろいろな解説ブログを読んでください。
まとめ
スマートフォンが普及する前は、ディスプレイも小さく、1024px〜1280pxくらいのレイアウトだけを考えていればよかったので、内容が左寄せになっているカンプを多く見かけました。
ですが最近では、各端末での見た目の変化を意識する必要がありますし、大きな画面でゆったりと見せるデザインがトレンドになっているので、中央寄せが基本となっています。
flexboxでの上下左右中央寄せは少し敷居が高いですが、大きさの違うボタンの追加、改修等に強いので身に付けておいてほしいです。
今回はここまで。
このブログが、皆さんに必要なくなることを願っています。