見出し画像

CSSを学習中の方へ。レイアウトが崩れない書き方を知りたいと思いませんか?私もその1人です。では、説明します。

HTML/CSSを学習中で、noteでの学習や動画学習などをしていてこんな経験はないですか?

・「なんで、この要素を指定するんだろう?」
・「一応調べてみた」→が、なんとなくの理解で進む
・「某noteなどで学習していると、そのコードを打ち込んでいけばなんとなくサイトが出来上がってしまう」
・「意味わかってないけどできたからとりあえずOKとしよう」

これ非常に危険です。
何が危険かというと、一通りコードを打ち込んでサイトが出来上がるとわかった気になってしまう点が非常に危険です。
「一つ一つ意味を分かっていながらコードを打ち込んでいく」のと
「なんとなくの理解でコードを打ち込んでいく」
どちらが良いかは一目瞭然ですよね。
「この要素、プロパティを指定することでこうブラウザに表示される」ということがイメージ出来ているというのは非常に大事です。
逆にイメージできていない場合は、理解できていない証拠なので、その点はしっかり理解する必要があります。

長々と前置きしましたが、
このnoteでご紹介するのはCSSの基礎的な概念でありながら意外にちゃんと学べる情報が少ない為、ここを知っておかないと必ずレイアウトを組む時に躓く、あるいは理解しないまま進んでしまうことになるので、しっかり理解しておきたい概念の部分についてご紹介します。

※ちなみこちらのnoteはしまぶーさんに許可をいただいた上で、YouTube動画を参考にして作成いたしました。一部補足を付け加えたり、省いていたりしています。

結論
内容を読むことで得られる効果
ボックスモデルの基礎が理解できるようになる。
- ブロック要素インライン要素の違いとは何ぞや?が理解できるようになる。
- 某noteで学習する際に、指定している内容が理解できるので、「この要素にこのプロパティを指定すると、こう表示されるはずだ」が理解できる。
- 結果サイト構築する際に、cssをどのように指定すれば良いかが手に取るようにわかるようになる。
このnoteで学ぶ内容
- Padding
- Margin
- マージンの相殺
- Border box
- box-sizing
- ボックス要素
- インライン要素
- displayプロパティ
対象読者
- CSSのリンク指定の仕方が分かっている
- CSS学習に躓いている人
- ショートハンドを理解している
- ボックスモデルって何?という人
- margin, padding, display:block;, display:inlne;, display:inline-block;, box-sizingについて深く理解できていない人
- ブロック要素、インライン要素って何?っていう人
- ドットインストールでcssについてある程度学んだが、上記内容がいまいち理解できていない人
- 最終的にサイト構築を迷いなく完成を目指したい人
環境
私の環境は
- OS:windows
- エディタ:VSCode
- ブラウザ:Google chrome

margin, padding, margin相殺について


まずは基本的なwidth,heightを指定した場合にどうなるかを考えてみましょう。
width,height→指定した大きさに横幅、高さが指定される
以下にHTMLとCSSを用意しました。

<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Box Model</title>
   <link rel="stylesheet" href="css/style.css">
</head>
<body>
   <!-- レイアウトをしっかり組む為の基礎概念 -->
   <!-- ボックスモデルの基本 -->
   <div class="block1">ブロック1</div>
   <div class="block2">ブロック1</div>
   <div class="margin">マージン相殺</div>
</body>
</html>

CSSの指定

/* ボックスモデルの基礎 */
body {
   margin: 0;
}
.block1 {
   background: cyan;
}
.block2 {
   background: pink;
}
.margin {
   background: violet;
}

わかりやすくbackground指定をしています。
上記の指定の状態だと以下のようになるかと思います。
ちなみにbackgroundをしているしているのは視覚的に見やすく、どこからどこまでの範囲なのかがわかるので、理解しやすくするために指定しています。
学習する際にはぜひbackgroundを指定して値をいじってみましょう。
bobyに対してmargin:0を指定しているのはデフォルトで余計なmarginがかかっているのでそれを取り除く為に記載しています。

画像2

ではこれにwidth,heightを指定してみましょう。


/* ボックスモデルの基礎 */
body {
   margin: 0;
}

.block1 {
   background: cyan;
}
.block2 {
   background: pink;
   width: 100px;
   height: 100px;
}
.margin {
   background: violet;
}

以下のようになったかと思います。
widthで横幅100px
heightで高さ100px
ここまでOKかと思います。

画像2

これが基本です。
ではこれにpaddingを指定します。
以下を指定すると、上下左右に20pxずつの余白が生まれるはずです。

.block2 {
   background: pink;
   width: 100px;
   height: 100px;
   /* Padding */
   padding: 20px 20px 20px 20px;
}


画像3

chromeのデベロッパーツールで確認してみるとよりわかりやすいかと思います。
windowsの場合はF12、Macの場合はoption + command + iです
以下のように上下左右20pxずつdivに対する内側の余白が出来たかと思います。

画像4

chromeのデベロッパーツールのComputedをクリックしてみます。
padding 20となっていてしっかり余白が取れています。

画像5

paddingについて理解出来たところで次にmarginです。
百聞は一見に如かずpaddingをコメントアウトしてmarginを以下のように指定してみましょう。

※コメントアウトのショートカットキーは
windowsの場合「Ctrl+/」
Macの場合「command+/」です。
.block2 {
   background: pink;
   width: 100px;
   height: 100px;
   /* Padding */
   /* padding: 20px 20px 20px 20px; */
   /* Margin */
   margin: 20px 20px 20px 20px;
}

marginを上下左右20px指定したことにより外側に余白が出来たのが分かります。

画像6

chromeのデベロッパーツールのComputedをクリックしてみます。
margin 20となっていてしっかり余白が取れています。

画像7

次にmargin相殺についてお話しします。
margin相殺とは「相殺」つまりmarginが打ち消し合って、指定した範囲のmarginが指定されてないことを言います。
こちらも実際に見てみましょう。

.block2 {
   background: pink;
   width: 100px;
   height: 100px;
   /* Margin */
   margin: 20px 20px 20px 20px;

}
.margin {
   background: violet;
   margin-top: 20px; 

}

div要素のmarginクラスに対してmargin-top:20pxを指定しました。
こちらどのような結果になるでしょうか?
div.block2のクラスで下(bottom)にmargin:20pxを指定
div.marginのクラスでmargin-top:20pxを指定しているので、
合計40px分の余白が出来ると思いますか?
実は結果は以下のようなります。

画像8

そう。結果は一緒なんです。これがmarginの相殺です。

.block2{
    margin: 20px 20px 20px 20px;
}

.margin {
   background: violet;
   margin-top: 20px; 
}

div.block2で指定した20pxのmarginと
div.margin-topで指定した20pxで打ち消し合って、結果余白は20pxになってしまいます。
これがmarginの相殺の特徴で、marginは大きい方の値のmarginが適用されます。
試しにdiv.marginのmargin-topを40pxに指定してみましょう。

画像9

下にdiv.block2のmargin20pxが適用され、残り20px分空白が出来ているのがわかります。

画像10

上にdiv.marginの40pxが適用されdiv.block2の要素までmarginが適用されているのがわかります。

box-sizingについて

box-sizingとは
CSS ボックスモデルの既定では、要素に割り当てられた width および height は、要素のコンテンツ領域のみに適用されます。要素に境界線やパディングがある場合、画面にレンダリングされる矩形の大きさは width および height にこれらを加えたものになります。つまり、 width および height を設定する際には、境界線やパディングが加えられるように値を調整しなければなりません。例えば、 width: 25%; で左や右のパディングまたは左や右の境界がある 4 つのボックスを並べた場合、既定では親コンテナーの制約の中で 1 行には並びません。
box-sizing プロパティは上記の振る舞いを調整するために使用できます。
MDN引用

これだけだとちょっと何言っているのかわからないので実践していきましょう。
先ほどのdiv.block2に対してboderも指定しました。

.block2 {
   background: pink;
   width: 100px;
   height: 100px;
   /* Padding */
   padding: 20px 20px 20px 20px;
   /* Margin */
   margin: 20px 20px 20px 20px;
   border: 5px solid red;
}

以下のようになったかと思います。

画像12

デベロッパーツールで見てみると、

画像11

paddingとmarginの間にborder5pxが指定されたのがわかるかと思います。

画像13

ただ、ここで疑問が生じます。
もう一度デベロッパーツールを確認してみます。

画像14

div.block2にはwidth:100px, height:100pxを指定したかと思います。
にもかかわらずデベロッパーツールで確認するblock2の幅と高さは150pxとなっております。
これはなぜか?
padding,borderの値がすべて足されているからです。
実際に計算するとwidth, height:100px+(padding:20px × 2)+(border:5px × 2)
計150px(高さについても同じ)となっております。
実際のwidthの指定値よりも大きくなってしまいます。
この点をよく理解しておかないと、widthを100pxで指定しているのになんで?という問題が生じてしまいます。

これを解消するプロパティがbox-sizing: border-boxです。
実際にbox-sizing: border-boxを指定してみましょう。

.block2 {
   background: pink;
   width: 100px;
   height: 100px;
   /* Padding */
   padding: 20px 20px 20px 20px;
   /* Margin */
   margin: 20px 20px 20px 20px;
   border: 5px solid red;
   box-sizing: border-box;
}

画像15

これでwidth, height:50px + (padding:20px × 2) + (border:5px × 2) = 100px
になりました。

画像16

実際にはすべての要素に対してbox-sizing: border-boxを指定するのは非効率になるので、以下のように指定しておくと、すべての要素に対して指定が可能となります。

html {
   box-sizing: border-box;
}

*, ::before, ::after {
   box-sizing: inherit;
}

html要素に対してbox-sizing : border-boxを指定して
*, ::befor, ::afterにはbox-sizing: inheritを指定します。
「*」すべてのという意味があります。
「::befor」「::after」は疑似要素
「inherit」は受け継ぐ などの意味があります。
要するにすべての要素に対してbox-sizing: border-boxを指定していることになります。

このnoteの最終章ブロック要素とインライン要素について

ブロック要素とはMDNでは以下のように説明されています

ブロックレベル要素は常に新しい行から始まり、利用可能な全幅を取ります (できる限り左右に伸びます)

インラインボックスは以下

インライン要素は新しい行から始まらず、必要な幅のみを占有します。

かなり簡潔に書かれていますが、
- 全幅を取るのか、文字の数分幅を取るのか
- 改行されるか、されないか
ここが大きなポイントになってくるかと思います。
こちらも実際にブラウザで確認していきましょう。

まず、「全幅を取るのか、文字の数分幅を取るのか」について確認していきましょう。
HTMLは以下のソースコードをエディタにコピペしてください

<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Box Model</title>
   <link rel="stylesheet" href="css/style.css">
</head>
<body>
   <!-- ブロック要素とインライン要素について -->
   <div>ブロック</div>
   <span>インライン</span>
</body>
</html>

CSSは以下の通りです。

div {
   background: cyan;
}
span {
   background: pink;
}

結果をブラウザで確認すると以下のようなっているかと思います。

画像17

これがブロック要素とインライン要素の違いです。

前述したように
ブロック要素:利用可能な全幅を取ります (できる限り左右に伸びます)
インライン要素:必要な幅のみを占有します。

上記の意味はブラウザで表示された通りです。

では次に改行されるか、されないかについて見ていきたいと思います。

<body>
   <!-- ブロックボックスとインラインボックスについて -->
   <div>ブロック</div>
   <div>ブロック</div>
   <div>ブロック</div>
   <span>インライン</span>
   <span>インライン</span>
   <span>インライン</span>
</body>
</html>

divとspanタグをいくつかコピペして増やしてください。
ちなみにwindowsの場合はカーソルを置いて「Shift+Alt+↓↑(上下矢印キー)」でコピペが可能です。(Macの場合:Option+Shift+↓↑(上下矢印キー))
ではブラウザで確認していきましょう。

画像18

上記のようになったかと思います。

div要素はブロック要素のため、改行されています。
逆にspan要素はインライン要素のため改行されていません。
ちなみに要素がブロックなのか、インラインなのかの判断については


上記を調べていただくとわかります。

次にwidth,height,margin,padding,borderプロパティの指定した場合の表示についても確認していきましょう。
一旦HTMLを以下のようにdivとspanを戻して下さい。

<body>
   <!-- ブロックボックスとインラインボックスについて -->
   <div>ブロック</div>
   <span>インライン</span>
</body>
</html>

まずはwidth,heigthについて。CSSはwidth,heightを指定します。

div {
   background: cyan;
   width: 300px;
   height: 300px;
}
span {
   background: pink;
   width: 300px;
   height: 300px;
}

こちらブラウザで表示するとどのように表示されるでしょうか?
イメージできますか?
イメージ出来ている方は理解できています。
逆に出来ていない場合には、ここで理解しましょう。

画像19

わかりやすくデベロッパーツールの画像にしました。
ブロック要素にはwidth,heightが指定され、インライン要素は指定されずインラインのままです。
これがブロック要素とインライン要素の特徴です。

では次に、div要素の中にspan要素が入った場合の挙動を確認してみます。
HTMLは以下のようにします。

<body>
   <!-- ブロックボックスとインラインボックスについて -->
   <div class="block">ブロック要素だよ<span>ブロック要素の中にあるインライン要素だよ</span>この状態でmargin,padding,
   borderプロパティを指定するとどうなるかな?</div>
</body>
</html>

CSSを以下のように指定します。

.block {
   background: cyan;
}

.block span {
   background: pink;
}

ブラウザで確認してみましょう。

画像20

上記のように表示されたかと思います。
ブロック要素の中にインライン要素がしっかり指定されています。
ではブロック要素に対してmargin,paddingを指定してみましょう。
コードは以下を指定します。

.block {
   background: cyan;
   margin: 20px;
   padding: 20px;
}

画像21

div.blockに対してmargin,paddingが効いたのが分かるかと思います。
では今度はspan要素に対してmargin,padding,borderを付けてみましょう。
どういった挙動になるでしょうか?CSSは以下のように指定します。

.block span {
   background: pink;
   margin: 20px;
   padding: 20px;
   border: 1px solid red;
}

画像22

はい。こうなります。
プロパティは効いているのですが、インライン要素はこのように表示が崩れてしまいます。
こういった表示崩れが生じてしまうので、インライン要素に対してmargin,padding,borderの指定はしない方が良いでしょう。
これがインライン要素ではなくブロック要素である場合には表示崩れは起きずにしっかりmargin,padding,borderが効くようになります。
実際に試してみましょう。
HTMLは以下のように指定します。

<body>
   <!-- ブロックボックスとインラインボックスについて -->
   <div class="block">ブロック要素だよ<div>ブロック要素の中にあるインライン要素だよ</div>この状態でmargin,padding,
   borderプロパティを指定するとどうなるかな?</div>
</body>
</html>

CSSは以下のようにします。

.block div {
   background: pink;
   margin: 20px;
   padding: 20px;
   border: 1px solid red;
}

ではブラウザで確認してみましょう。

画像23

ブロック要素の特徴である、改行がされていて、margin,padding,borderがしっかり効いているのがわかります。

こういった表示崩れを起こさない為にもブロック要素とインライン要素の特徴は把握しておく必要があります。

次にdisplayプロパティについて見ていきます。
ここまで理解できていると、こちらのサルワカさんのサイトで紹介されているblockとinlineについては、このnoteを見る前と後で見た場合では理解がだいぶ深まっているはずです。

これから説明するdisplayについてもしっかりコードとブラウザでの確認作業をすることで理解が深まるはずです。
ではやっていきましょう。

display: block,inlineとは
- ブロック要素をインライン要素にする
- インライン要素をブロック要素にする

ことです。
先ほどのCSSに対してdisplay:inlineを指定してみましょう。

.block div {
   display:inline;
   background: pink;
   margin: 20px;
   padding: 20px;
   border: 1px solid red;
}

ブラウザ確認してみます。

画像24

divはブロック要素であるにもかかわらず、インライン要素になっています。
逆も見ていきましょう。
span要素に対して、display:blockを指定するとどうなるでしょうか?
HTMLは以下のようにします。

<body>
   <!-- ブロックボックスとインラインボックスについて -->
   <div class="block">ブロック要素だよ<span>ブロック要素の中にあるインライン要素だよ</span>この状態でmargin,padding,
   borderプロパティを指定するとどうなるかな?</div>
</body>
</html>

CSSは.block spanに変更後、display:blockを指定してブラウザ確認してみます。

.block span {
   display:block;
   background: pink;
   margin: 20px;
   padding: 20px;
   border: 1px solid red;
}

画像25

span要素がblock要素に変わったのがわかるかと思います。
最後にブロック要素でありながらインライン要素でもある指定の仕方もあります。
それがdisplay:inline-blockです。
イメージ的には要素の並び方はインライン的で、要素の中身はブロック的であるところです。
ではこちらも実際にやってみましょう。
span要素に対してdisplay: inline-blockを指定してみます。

.block span {
   display:inline-block;
   background: pink;
   margin: 20px;
   padding: 20px;
   border: 1px solid red;
}

ブラウザで確認してみましょう。

画像26

上記ののようになったかと思います。
display: inline-blockを指定するとspanがブロック要素となり、ブロック要素の特徴である改行がなされましたが、並びがインライン的に変わったのが分かるかと思います。
文字が改行されず回り込んでいます。
これがdisplay: inline-blockの特徴です。
こちらについても先ほど添付したサルワカさんのサイトで詳しく解説されてますので、併せて確認されると良いでしょう。

補足としてdisplayにはnoneという指定方法もあります。
noneとは非表示にすることで、レスポンシブ対応するときによく使用されます。
ブラウザの幅がスマホサイズの場合は非表示
タブレット~PCのサイズの場合は表示させる
などの時によく使用されるので、こちらについても余談として覚えておくと良いでしょう。

ここまでいかがでしたでしょうか?
実践する際には必ずコードに記載したことをブラウザで確認するということをセットで行うようにしましょう。
それを地道にやっていくことが近道となり、基礎力が上がっていきます。
逆にこれをやらないといつまでたっても理解できるようにならず、知識が定着しません。
大事なのでもう一度言いますが、実践する際には必ずコードに記載したことをブラウザで確認する作業をセットで行ってください。

最後に

ここまで読んでいただき誠にありがとうございます。
僕自身web系のエンジニアではないのですが、初学者の手助けになればと思い、情報発信をしている所存です。
この点が分かりづらい、もっとこういった情報を知りたいということありましたらコメント、ご感想いただけると幸いです。

また、ブログも運営しております。
普段プログラミング学習で思うようにできず、悩んでいる、学習の仕方がわからない、エンジニアってどんなことしているの、など
プログラミングにおけるマインドについて情報発信しております。


この記事が気に入ったらサポートをしてみませんか?