CSSスタイリングのコツ【レイアウト編】
はじめに
良いデザインにはルールがある
この本↓、絶対読んだ方がいいです。
良いデザインにはルールがあって、それに従うだけで作るアプリの見た目が劇的に変わっちゃいます。
僕はこの本を読んで感動しました。
で、そのデザインのルールを知ってると、おのずとCSSスタイリングの方法も見えてくるってことです。
なので、まずはこの本を読んでからこの記事を読んでくださいね。
...ってお忙しい皆さんが読んでくださるわけもないので、必要な部分だけ抜粋します。
意識すべきデザインのルール:整列
CSSスタイリングにおいてもっとも意識すべきデザインのルールは整列です。
Bad Example

Good Example

良いデザインでは、線が意識されて配置されています。
中央ぞろえは中央に線がありますが、テキストの左右がそろっていないので、整列が弱いです。
対して左揃えや右揃えであれば、強い透明な線が見えるようになります。
(中央ぞろえで整列を意識させる方法もありますが、それは本にお預けといたします)
CSSスタイリングのコツ
で、デザインのルールが分かれば、あとはFlexboxで簡単に作れます。
Flexboxは子要素を簡単に縦/横に並べる(整列させる)ことができます。
つまり、良いデザインは要素が整列されているはずなので、Flexboxで簡単にCSSに起こせるというわけです。
↓Flexboxのプロパティ
.parent-element {
display: flex;
flex-direction: row | column | row-reverse | column-reverse;
flex-wrap: nowrap | wrap;
align-content: normal | center | flex-start | flex-end | space-between | space-around | strech;
justify-content: normal | center | flex-start | flex-end | space-between | space-around | space-evenly;
align-items: normal | center | flex-start | flex-end | strech | baseline;
}
ちなみにReactのMaterial UI(@mui/material)ではStackを使うことで同じことができます。
<Stack direction="row" justifyContent="space-around" alignItems="center">
<Child />
<Child />
</Stack>
スタイリング例

スタイリング例にするデザイン
こちらを例に、実際にスタイリングしてみましょう。
なお、レイアウトに関係しないプロパティは書いてないものもあります。
ステップ1:線を引いて構造化する

構造化したデザイン
今回の場合はこんな感じに引きました。
ステップ2:外側からHTMLとCSSを書いていく
実際にHTMLとCSSを書いていきます。
分かりやすいようにインラインスタイルで書きます。
オレンジの部分まで
<div
style="
height: 100vh;
width: 100vw;
background-image: url(bg.png);
background-size: cover;
/* 以下Flexboxのプロパティ */
display: flex;
justify-content: center; /* 左右方向=中央揃え */
align-items: center; /* 上下方向=中央揃え */
"
>
<div style="height: 1400px; width: 788px; backdrop-filter: blur(20px)"></div>
</div>
Flexboxを使って中央に配置しています。
オレンジから黄緑まで
<div
style="
height: 1400px;
width: 788px;
backdrop-filter: blur(20px);
/* 以下Flexboxのプロパティ */
display: flex; /* 横並び */
justify-content: space-around; /* 左右方向=余白を入れる */
align-items: center; /* 上下方向=中央揃え */
"
>
<div>
Ryota Sasaki
Keio University Student Software Engineer
<img src="github.svg" alt="GitHub" />
<img src="wantedly.svg" alt="Wantedly" />
</div>
<div>
About Me
Skills
History
Portfolio Ver. 2
Portfolio Ver. 3
</div>
</div>
Flexboxを使って横並びで、外側の左右の余白が中央の半分(space-around)になるように設定しています。

DevToolsの画像
左の黄緑の中
<div
style="
/* 以下Flexboxのプロパティ */
display: flex;
flex-direction: column; /* 縦並び、左右方向=左揃え */
/* なお子要素のFlexboxはコメントを省略 */
"
>
<div style="height: 120px; display: flex; align-items: flex-end">
<div style="font-size: 80px">Ryota Sasaki</div>
</div>
<div>Keio University Student Software Engineer</div>
<div style="height: 120px">
<div style="height: 35px; display: flex">
<img src="github.svg" alt="GitHub" style="height: 100%" />
<img src="wantedly.svg" alt="Wantedly" style="height: 100%" />
</div>
</div>
</div>
Flexboxを使って縦並び、左揃えに配置しています。
ここで、ちょっとトリッキーなんですが、真ん中のKeio University Student Software Enginnerを縦方向の真ん中に持ってくるために、その上と下の要素をheight: 120px(flex-basis: 120pxでもよし)で固定しています。
オレンジにalign-items: centerが効いているので、上と下で均等な大きさの要素に挟まれている要素は真ん中に来ます。
さらに、Ryota Sasakiがflex-basis: 120pxの上に張り付いて浮かないようにFlexboxのalign-items: flex-endで下に下げています(bottom: 0のような効果)。
下のimgを囲むFlexboxは横並び用です。

DevToolsの画像
右の黄緑の中
<div
style="
width: 300px;
height: 400px;
/* 以下Flexboxのプロパティ */
display: flex;
flex-direction: column; /* 縦並び、左右方向=左揃え */
justify-content: space-evenly; /* 上下方向=余白を入れる */
"
>
<div style="border-top: 1px solid #fff; border-bottom: 1px solid #fff">About Me</div>
<div style="border-bottom: 1px solid #fff">Skills</div>
<div style="border-bottom: 1px solid #fff">History</div>
<div style="border-bottom: 1px solid #fff">Portfolio Ver. 2</div>
<div style="border-bottom: 1px solid #fff">Portfolio Ver. 3</div>
</div>
Flexboxには子要素のflex-directionに垂直な方向の長さ(幅)をそろえる効果があります。
Flexboxにすることで、中のdivの幅、ひいてはそのボーダーの長さをそろえています。

DevToolsの画像
ステップ3:微妙なずれを直す
特にテキストは、フォントや文字によって左端がずれています。
なので、実際の画面を見ながら、marginを入れるなどして、きちんと"整列"するようにずらしましょう。
今回の例では<div>Ryota Sasaki</div>にmargin-left: -6pxを設定しました。
全体像
<div
style="
height: 100vh;
width: 100vw;
background-image: url(bg.png);
background-size: cover;
/* 以下Flexboxのプロパティ */
display: flex;
justify-content: center; /* 左右方向=中央揃え */
align-items: center; /* 上下方向=中央揃え */
"
>
<div
style="
height: 1400px;
width: 788px;
backdrop-filter: blur(20px);
/* 以下Flexboxのプロパティ */
display: flex; /* 横並び */
justify-content: space-around; /* 左右方向=余白を入れる */
align-items: center; /* 上下方向=中央揃え */
"
>
<div
style="
/* 以下Flexboxのプロパティ */
display: flex;
flex-direction: column; /* 縦並び、左右方向=左揃え */
/* なお子要素のFlexboxはコメントを省略 */
"
>
<div style="height: 120px; display: flex; align-items: flex-end">
<div style="font-size: 80px; margin-left: -6px">Ryota Sasaki</div>
</div>
<div>Keio University Student Software Engineer</div>
<div style="height: 120px">
<img src="github.svg" alt="GitHub" />
<img src="wantedly.svg" alt="Wantedly" />
</div>
</div>
<div
style="
width: 300px;
height: 400px;
/* 以下Flexboxのプロパティ */
display: flex;
flex-direction: column; /* 縦並び、左右方向=左揃え */
justify-content: space-evenly; /* 上下方向=余白を入れる */
"
>
<div style="border-top: 1px solid #fff; border-bottom: 1px solid #fff">About Me</div>
<div style="border-bottom: 1px solid #fff">Skills</div>
<div style="border-bottom: 1px solid #fff">History</div>
<div style="border-bottom: 1px solid #fff">Portfolio Ver. 2</div>
<div style="border-bottom: 1px solid #fff">Portfolio Ver. 3</div>
</div>
</div>
</div>
Material UIのStackについて
ちなみにこの例↑はもともとReactのMaterial UI(@mui/material)で作ったものをHTML化して書いてます。
Material UIでは、Flexboxは<Stack />で書けて、通常のdiv要素としての<Box />と使い分けができるので、縦並び、横並び用のBoxは全部<Stack />を使うことで可読性が上がります。
そういうわけで、レイアウト関連は基本<Stack />で書いてたので、左の黄緑の外側のdivはFlexboxにする必要がないことに今気づきました(display: blockでも縦並びにはなる)。
が、このまま残しておきます。
おわりに
こんなん書きましたが、自己流なので、もっと良い方法があるよって方はコメント欄で教えていただければと思います。
Discussion