CSSによる配置(発展)
CSSのボックスモデル
HTMLの要素はすべて、一定の高さと幅を持った四角形だと考えることができます。その四角形は
- content(中身)
- padding(中身と境界線の間の幅)
- border(境界線)
- margin(境界線の外側の余白)
の4重構造になっています。
「CSS」のページの演習を例に構造を見てみましょう(構造がわかりやすいよう、border
を10px
に変更しています)。
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<title>Title</title>
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<div class="box">Foo</div>
</body>
</html>
.box {
margin: 30px;
padding: 30px;
border: 10px solid #aaa;
border-radius: 10px;
box-shadow: 0px 0px 2px 1px #aaa;
}
このページを開発者ツールを使って見てみましょう。
4重に色分けされた構造が見えます。
content
は主にwidth
やheight
などのプロパティを、
padding
, border
, margin
はそれぞれ主にpadding
, border
, margin
などのプロパティを操作することで制御できます。
width
, height
, padding
, border
, margin
の値を変えると開発者ツールの表示がどう変わるか試してみましょう。
ブロックレベル要素とインライン要素
HTMLの要素は、ブロックレベル要素とインライン要素に分類されます。
ブロックレベル要素は見出しや段落、表など、文章を構成する基本単位となる要素です。
常に前後に改行が入り、可能なところまで(親要素いっぱいまで)左右に広がります。
そのため、ブロックレベル要素を複数並べて書くと、上から下へと配置されていきます。
ブロックレベル要素にはdiv
要素やp
要素、table
要素、ul
要素などがあります。
以下ではブロックレベル要素であるdiv
要素を3つ並べています。
<body>
<div class="box1">box1</div>
<div class="box2">box2</div>
<div class="box3">box3</div>
</body>
.box1 {
background-color: lightcoral;
}
.box2 {
background-color: lightblue;
}
.box3 {
background-color: lightgreen;
}
インライン要素は文章の一部や表の要素など、ブロックレベル要素の内容となる要素です。
前後に改行は伴わず、必要な幅だけを占有します。
そのため、インライン要素を複数並べて書くと、左から右へと配置されていきます。
インライン要素にはspan
要素やa
要素、img
要素やinput
要素があります。
以下ではインライン要素であるspan
要素を3つ並べています。
<body>
<span class="box1">box1</span>
<span class="box2">box2</span>
<span class="box3">box3</span>
</body>
ブロックレベル要素の中にはブロックレベル要素もインライン要素も配置することができますが、インライン要素の中にブロックレベル要素を配置することはできません。
また、インライン要素の場合、width
やheight
は適用されません。
演習
display
プロパティを操作することで要素の挙動を変更することができます。
上記のコードで、ブロックレベル要素であるdiv
要素にdisplay: inline
を、インライン要素であるspan
要素にdisplay: block
を指定してみると表示はどう変わるか、試してみましょう。
フレックスボックス
フレックスボックスを利用すると、要素を横や縦に並べたり、間隔を均等に取って並べたり、順番を指定して並べたりといった柔軟な配置を簡単に行うことができます。
フレックスボックスを利用するには、配置したい要素の親要素にdisplay: flex
を適用します。
以下のように、box1
, box2
, box3
という3つのdiv
要素がwrapper
というdiv
要素の中に並んでいる状態を考えましょう。
<body>
<div class="wrapper">
<div class="box1">box1</div>
<div class="box2">box2</div>
<div class="box3">box3</div>
</div>
</body>
このままだとブロックレベル要素であるdiv
要素が並んでいるだけなので、box1
, box2
, box3
は縦に並んで表示されます。
box1
, box2
, box3
の親要素であるwrapper
にdisplay: flex
を指定すると、要素は横並びに表示されます。
.wrapper {
display: flex;
}
フレックスボックスを使用すると複雑な配置も簡単に実現できます。
一つの例として、justify-content: space-around
をwrapper
に指定してみると、要素の周囲に同じだけの間隔が空きます。
.wrapper {
display: flex;
justify-content: space-around;
}
他にもたくさんの配置がフレックスボックスによって実現可能なので、調べてみましょう。
グリッド
1次元で要素をレイアウトしていくフレックスボックスに対して、グリッドには行と列の2次元で要素をレイアウトする発想があります。
グリッドを利用するには、配置したい要素の親要素にdisplay: grid
を適用し、grid-template-columns
プロパティで列の幅を、grid-template-rows
プロパティで行の幅を指定します。
grid-column
やgrid-row
を使うと、開始ラインや終了ラインを指定して項目を配置することができます。
以下のコードを試してみましょう。
<body>
<div class="wrapper">
<div class="box1">box1</div>
<div class="box2">box2</div>
<div class="box3">box3</div>
<div class="box4">box4</div>
</div>
</body>
.wrapper {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px;
}
.box1 {
background-color: lightcoral;
}
.box2 {
background-color: lightblue;
}
.box3 {
grid-column: 3 / 4;
grid-row: 1 / 3;
background-color: lightgreen;
}
.box4 {
grid-column: 1 / 3;
grid-row: 2 / 3;
background-color: lightseagreen;
}
position
position
プロパティを操作すると、要素の位置指定の基準を変更することができます。
position: static
: デフォルトの状態です。
position: relative
: 要素の本来の位置から相対的にどれだけずらすかを指定することができます。
<body>
<div class="box1">box1</div>
<div class="box2">box2</div>
<div class="box3">box3</div>
<div class="box4">box4</div>
<div class="box5">box5</div>
<div class="box6">box6</div>
</body>
.box2 {
position: relative;
top: 50px;
left: 50px;
width: 200px;
height: 200px;
background-color: lightblue;
}
position: absolute
: 周囲の要素を無視し、ページ内で絶対的にどの位置にあるかを指定することができます。
上のコードのposition: relative
をposition: absolute
に変えてみましょう。
.box2 {
position: absolute;
top: 50px;
left: 50px;
width: 200px;
height: 200px;
background-color: lightblue;
}
position: fixed
: absolute
に似ていますが、画面をスクロールしても要素は同じ場所に留まります。
上のコードのposition: relative
をposition: fixed
に変えてみましょう。
.box2 {
position: fixed;
top: 50px;
left: 50px;
width: 200px;
height: 200px;
background-color: lightblue;
}
以下のように、absolute
の場合はスクロールするとbox2
も動いていきましたが、
fixed
の場合はスクロールしてもbox2
は同じ場所に留まっています。
親要素を基準にして子要素の位置を指定する
position
プロパティを使うと、親要素を基準にして子要素の位置を指定することができます。
そのような場合、親要素にrelative
を、子要素にabsolute
を指定します。
<body>
<div class="box1">
box1
<div class="box2">box2</div>
</div>
</body>
.box1 {
position: relative;
width: 400px;
height: 400px;
background-color: lightcoral;
}
.box2 {
position: absolute;
right: 50px;
bottom: 50px;
width: 200px;
height: 200px;
background-color: lightblue;
}
上のコードのbox1
にmargin-left: 200px
を指定して位置をずらしてみましょう。
.box1 {
position: relative;
margin-left: 200px;
width: 400px;
height: 400px;
background-color: lightcoral;
}
box1
の位置が変わっても、box2
のbox1
に対する位置は変化していません。
レスポンシブデザイン
デバイスの画面サイズに応じて適切なレイアウトで表示を行うデザインをレスポンシブデザインと呼びます。
スマートフォン用、PC用などと個別のサイトを作らずとも、同一のCSSであらゆるデバイスに対応することができます。
メディアクエリ
画面サイズによって異なるスタイルを適用させたい際にはメディアクエリを使います。
スマートフォン等でもサイトをデバイス本来の画面サイズで表示するために、head
要素の中に以下を記述しましょう。
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
メディアクエリの基本的な形は@media (条件) {条件が真の場合に適用されるスタイル}
のようになります。
以下の例を試してみましょう。
<body>
<div class="box1">box1</div>
</body>
.box1 {
background-color: lightcoral;
}
@media (max-width: 800px) {
.box1 {
background-color: lightblue;
}
}
ウインドウの幅を変えてみると要素はどのようになるか、試してみましょう。
パーセント指定
長さの指定は、親要素に対する比率によって行うこともできます。
以下の例を試してみましょう。
<body>
<div class="box1">box1</div>
<div class="box2">box2</div>
</body>
.box1 {
background-color: lightcoral;
width: 50%;
}
.box2 {
background-color: lightblue;
width: 700px;
}
ウインドウの幅を変えてみると要素の幅はどのようになるか、試してみましょう。
max-width
, min-width
max-width
, min-width
を使うと、要素の幅の上限と下限を指定することができます。
以下の例を試してみましょう。
<body>
<div class="box1">box1</div>
<div class="box2">box2</div>
<div class="box3">box3</div>
</body>
.box1 {
background-color: lightcoral;
width: 80%;
max-width: 800px;
}
.box2 {
background-color: lightblue;
width: 80%;
min-width: 500px;
}
.box3 {
background-color: lightgreen;
width: 80%;
}
ウインドウの幅を変えてみると要素の幅はどのようになるか、試してみましょう。
演習
これまでの知識を活用して、料金プランの説明をするページを作ってみましょう。
スマホ等でも見やすく表示されるようにしてみましょう。