###### tags: `CSS`
# CSSを書いてみよう
(推定時間:1時間半)
## もくじ
- [CSSファイルを作成](#CSSファイルを作成)
- [インラインスタイル](#インラインスタイル)
- [内部スタイルシート](#内部スタイルシート)
- [外部スタイルシート](#外部スタイルシート)
- [デフォルトのスタイルについて](#デフォルトのスタイルについて)
- [デフォルトスタイルの打ち消し](#デフォルトスタイルの打ち消し)
- [CSSリセットしてみる](#CSSリセットしてみる)
- [スタイルの順番](#スタイルの順番)
- [!important](#important)
- [ID・クラス・要素セレクター・インラインスタイル](#ID・クラス・要素セレクター・インラインスタイル)
- [継承](#継承)
- [基本的なスタイルを試してみよう](#基本的なスタイルを試してみよう)
- [background-color・color](#background-color・color)
- [width・height](#width・height)
- [margin・border・padding](#margin・border・padding)
- [まとめ](#まとめ)
- [参考](#参考)
## CSSファイルを作成
HTML 講座と同様のディレクトリ,もしくはお好きなディレクトリに`index.html` と `style.css` を作成します.

HTML ファイルには以下のコードをコピペしてください.
```htmlembedded
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS講座</title>
</head>
<body>
<header>
<h1>はじめてのCSS</h1>
</header>
<main>
<h2>CSSを書いていく</h2>
<div>
<p>1つ目の段落</p>
<p>2つ目の段落</p>
<p>3つ目の段落</p>
</div>
<ul>
<li><a href="https://www.youtube.com">YouTube</a></li>
<li><a href="https://qiita.com">Qiita</a></li>
<li><a href="https://yosse95ai.github.io/">yosse95aiのサイト</a></li>
</ul>
</main>
</body>
</html>
```
コピペ出来たら,ブラウザで開いてください.
開き方は,[GitHub Pagesの準備](https://hackmd.io/@kit-web-team/github-pre#indexhtml%E3%82%92%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%81%A7%E8%A1%A8%E7%A4%BA) でやった通りです!

## インラインスタイル
以下のように h1 要素の属性を追加する.
```htmlembedded
<h1 style="color: red; font-size: 24px;">はじめてのCSS</h1>
```
このように,属性に直接スタイル定義をするのがインラインスタイルである.

## 内部スタイルシート
以下のように,head 要素内に style 要素を追加し,h2 要素に関する CSS を記述する.
```htmlembedded
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS講座</title>
<!-- ここから追加 -->
<style>
h2 {
color: green;
font-size: 24px;
}
</style>
<!-- ここまで -->
</head>
```
このように,head 要素内に style を定義することを内部スタイルシートである.

## 外部スタイルシート
外部スタイルシートは最もよく使う.
今までのスタイリングをすべて消去し,以下のように head 要素内で `style.css` を読み込みます.
```htmlembedded
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- ここから追加 -->
<link rel="stylesheet" href="style.css">
<!-- ここまで -->
<title>CSS講座</title>
</head>
```
`link 要素`では外部のファイルやCDN(Content Delivery Network)を,現在のHTML内に読み込むことができる.
`style.css`を以下のように修正します.
```css
h1 {
color: red;
font-size: 24px;
}
h2 {
color: green;
font-size: 24px;
}
```
先ほどのページとまったく同じ見た目になったと思います.
このように,外部のCSSファイルを読み込んでスタイルを適用するのが,外部スタイルシートである.
これ以降は,style.css に CSS を記述することを想定する.
## デフォルトのスタイルについて
header の背景色(`background-color`プロパティ)を黄色っぽくすることを考える.
この場合,よく見るWebサイトのヘッダーのように,なってほしいが,実際は以下のようになる.
<iframe height="430" style="width: 100%;margin-bottom:10px;" scrolling="no" title="deault_css" src="https://codepen.io/yosse95ai-the-decoder/embed/MWQBvbK?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/yosse95ai-the-decoder/pen/MWQBvbK">
deault_css</a> by yosse95ai (<a href="https://codepen.io/yosse95ai-the-decoder">@yosse95ai-the-decoder</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>
若干,上左右に隙間が空いているような感じになる.

これは,ブラウザデフォルトのスタイルが効いているからです.
この隙間(margin)だけでなく,様々なプロパティに対してデフォルトのスタイリングがあてられています.
デフォルトのスタイリングは,(今回のヘッダーに隙間ができるみたいに)都合の悪い場合もあるため,一般的には,このデフォルトのスタイルを無効化して独自にスタイリングします.
例えば,ワイルドカード(`*`)を使って,すべての要素に対する `margin` プロパティのデフォルト値を初期化してみましょう.
一般にこれは `CSSリセット` などと呼ばれます.
<iframe height="311" style="width: 100%;margin-bottom:10px;" scrolling="no" title="destyle_css_margin" src="https://codepen.io/yosse95ai-the-decoder/embed/NWyBvjQ?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/yosse95ai-the-decoder/pen/NWyBvjQ">
destyle_css_margin</a> by yosse95ai (<a href="https://codepen.io/yosse95ai-the-decoder">@yosse95ai-the-decoder</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>
いかがでしょう?すべての要素のデフォルトの`margin`値をリセットしました.
先ほどよりコンパクトになり,ヘッダー部分も期待したスタイリングになっていると思います.
### デフォルトスタイルの打ち消し
先ほどやった,`margin` プロパティ以外にも様々なプロパティに対して,デフォルト値が設定されています.(たとえば,h1 要素のフォントサイズ等…)
毎回一つ一つ個人で消していくのは大変な作業ですが,多くの先駆者たちがデフォルトのスタイルを消すための CSS を定義してくれています.
私たちは,それをありがたく使わせていただくのが賢いやり方です.
いくつか列挙します.
- [destyle.css](https://github.com/nicolas-cusan/destyle.css)
- とにかくすべてのスタイルをリセットします.
- 例えば,h1 だろうが p だろうが同じフォントサイズです
- CDN: `<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/destyle.css@1.0.15/destyle.css"/>`
- [modern.css](https://github.com/andy-piccalilli/modern-css-reset)
- tailwindcssで標準設定されているというのもあって使っている人は多い(らしい)
- 無難なリセット設定になっている
- CSSファイル自体も最小限にとどめているため、読み込み速度がはやい
- CDN: `<link rel="stylesheet" href="https://unpkg.com/modern-css-reset/dist/reset.min.css"/>`
- [ress.css](https://github.com/filipelinhares/ress)
- modern.css 並に CSSファイル を最小限に留められている.
- 各タグに標準で設定されている margin や padding は全て0に設定されている.
- CDN: `<link rel="stylesheet" href="https://unpkg.com/ress/dist/ress.min.css" />`
- また、`npm`も用意されている.
`destyle.css`を使用したCSSリセットの場合,以下のようになる.
<iframe height="320" style="width: 100%;padding-bottom:10px;" scrolling="no" title="destyle_css" src="https://codepen.io/yosse95ai-the-decoder/embed/VwQBzRV?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/yosse95ai-the-decoder/pen/VwQBzRV">
destyle_css</a> by yosse95ai (<a href="https://codepen.io/yosse95ai-the-decoder">@yosse95ai-the-decoder</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>
`modern.css`を使用したCSSリセットの場合,以下のようになる.
<iframe height="326" style="width: 100%;margin-bottom:10px;" scrolling="no" title="Untitled" src="https://codepen.io/yosse95ai-the-decoder/embed/zYRLdad?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/yosse95ai-the-decoder/pen/zYRLdad">
Untitled</a> by yosse95ai (<a href="https://codepen.io/yosse95ai-the-decoder">@yosse95ai-the-decoder</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>
両者で若干の違いを感じ取っていただけて,CSSリセットについて理解していただければ幸いです.
### CSSリセットしてみる
head 要素内に 以下の`link` 要素を追加してください.
必ず,`style.css`(自分で作成したスタイルシート)より前で読み込んでください.
```htmlembedded
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- ここから追加(順番大事) -->
<link rel="stylesheet" href="https://unpkg.com/modern-css-reset/dist/reset.min.css" />
<!-- ここまで -->
<link rel="stylesheet" href="style.css">
<title>CSS講座</title>
</head>
```
この読み込み方法は,CDNと呼ばれます.
外部のサーバーに置かれているファイルを読み込むことができます.
自身の手元にファイルの実態を置かずに,簡単に導入できるメリットがある一方,ネットワーク環境がないと読み込むことができないデメリットもあります.
ただし,ネットワーク上に公開したページは,おそらくネットワークにつながっているので,そこまで心配する要素ではないかもしれませんが,提供元が公開をやめてしまったり,提供元のサーバーが停止した場合,スタイルが効かなくなる可能性も考えられるので,ケースバイケースで利用してください.
最悪の場合を想定する場合は,GitHub からファイルをダウンロードして,手元に置いておくのがいいでしょう.
## スタイルの順番
スタイルは上から順に適用され,これを`ソースオーダー`といいます.
h2 タグに対して,2回スタイルを適用することを考えます.
<iframe height="331" style="width: 100%;margin-bottom:10px;" scrolling="no" title="Untitled" src="https://codepen.io/yosse95ai-the-decoder/embed/VwQBBpK?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/yosse95ai-the-decoder/pen/VwQBBpK">
Untitled</a> by yosse95ai (<a href="https://codepen.io/yosse95ai-the-decoder">@yosse95ai-the-decoder</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>
文字色(color)が上書きされたことが分かります.
つまり,プロパティが二重に宣言された場合,下に配置したものが最終的にブラウザに適用されるということです.
このように,詳細度が同レベルであるときは,ソースオーダーによってスタイルが決まります.
CDNを読み込むとき,link 要素の順番を念押ししたのはこういうことであり,`style.css` の後に読み込むと,`style.css` にもCSSリセットが効いてしまいます.
### !important
使用することはあまり推奨されていませんが,知っておくことも大事です.
先ほどのものから,h2 セレクターの `color: green;` に `!important` をつけてみましょう.
<iframe height="350" style="width: 100%;margin-bottom:10px" scrolling="no" title="important" src="https://codepen.io/yosse95ai-the-decoder/embed/zYRLJQP?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/yosse95ai-the-decoder/pen/zYRLJQP">
important</a> by yosse95ai (<a href="https://codepen.io/yosse95ai-the-decoder">@yosse95ai-the-decoder</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>
このように詳細度を無理やり変更することで,文字色が `green` になりました.
やはり,詳細度の順が変わるとわかりづらくなり,デバッグが難しくなるのでむやみに使わず,なるべく避けるべきです.
### ID・クラス・要素セレクター・インラインスタイル
詳細度の違いによる、スタイルの適用を見ていきましょう!
`index.html` の `div` 要素内を以下のように書き換えます.
```htmlembedded
<div>
<p>属性なし</p>
<p class="my-cls">クラスを指定</p>
<p id="my-id" class="my-cls">IDとクラスを指定</p>
<p class="my-cls" style="color: #000000">インラインスタイル</p>
</div>
```
これに対して,様々なセレクターによるスタイルの宣言を行っていきます.
ちなみに以下の`color`プロパティ値にカラーコードを書いていますが,見方は`#RRGGBB`(R:赤,G:緑,B:青)の値を設定しており,その値は16進数(0~F)で指定します.
0が最小,Fが最大値です.(カラーの作り方はそのうち慣れます.)
<iframe height="351" style="width: 100%;margin-bottom:10px;" scrolling="no" title="Untitled" src="https://codepen.io/yosse95ai-the-decoder/embed/OJQwaXj?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/yosse95ai-the-decoder/pen/OJQwaXj">
Untitled</a> by yosse95ai (<a href="https://codepen.io/yosse95ai-the-decoder">@yosse95ai-the-decoder</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>
単純な見方をすれば,p 要素はすべて青色(`#0000FA`)になるような気がします.
しかし,ここで詳細度に着目します.
まず,インラインスタイルは,常に外部のスタイルシートを上書きするため,インラインスタイル適用部分は黒色(`#000000`)で表示されています.
クラスが指定されていますが,関係なく上書きされます.
次に,クラスセレクターです.クラスセレクターは要素セレクターよりも詳細度が高いため,先に宣言しても,後に宣言された要素セレクターより優先されます.
そのため,文字色も緑色(`#00DD00`)になっています.
次に,IDセレクターです.クラスセレクターとIDセレクター両方が指定されている要素がありますが,この場合,IDセレクターの詳細度がより高いため,文字色も赤色(`#FF0000`)になっています.
以上のことから,何も属性などの指定がない一つ目の p 要素のみ,要素セレクターのスタイルになります.
### 継承
以下のように,`div` 要素と `ul` 要素の間にマークアップを追加します.
内容は,料理のレシピ()です.
今回は`継承`を体感してほしいだけなので,コピペでOKです!
```htmlembedded
<hr>
<div>
<h3>レシピ集</h3>
<ul class="main">
<li>
<span>納豆ごはんのレシピ</span>
<ol>
<li>ご飯を茶碗によそいます.</li>
<li>納豆をかき混ぜます.</li>
<li>ご飯の上にかけたら完成です!</li>
</ol>
</li>
<li>
<span>卵かけのレシピ</span>
<ol class="content">
<li>ご飯を茶碗によそい,真ん中に穴を開けます.</li>
<li>穴の中に卵を割り入れ,お好みで醤油を1回し.</li>
<li>混ぜたら完成です!</li>
</ol>
</li>
</ul>
</div>
<hr>
```
クラス属性の説明ですが,`ul` 要素に `main` という名前のクラスを付与し,2つ目の `ol` 要素(卵かけのレシピ)に `content` という名前のクラスを付与しました.
それではスタイリングしていくわけですが,今回は`継承`を体感してほしいだけなので,こちらもコピペでOKです!
<iframe height="600" style="width: 100%;margin-bottom:10px;" scrolling="no" title="Untitled" src="https://codepen.io/yosse95ai-the-decoder/embed/NWyBepV?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/yosse95ai-the-decoder/pen/NWyBepV">
Untitled</a> by yosse95ai (<a href="https://codepen.io/yosse95ai-the-decoder">@yosse95ai-the-decoder</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>
`ul` 要素に対して行ったスタイリングが,子要素である `li` 要素,間接的な子要素(孫)の `ol`,`span` 要素にも適用されています.これがスタイルの`継承`です.
ただし,`width` などのいくらかのプロパティは継承されません.
つまり,`ul` 要素に `width:50%;`と書いただけで継承され,子要素(`span`,`ol`)が親要素のさらに `50%` の幅になったりということはありません.
また,継承されたプロパティも,`content` クラスの宣言ブロックのように,上書きすることができます.
この場合,継承されたスタイルよりも,その要素に近いスタイルが優先されます.
`content` クラス内の `li` の場合,継承された `main` クラスのスタイルより,`content` クラスのスタイルの方が近いのでこちらが採用されます.
## 基本的なスタイルを試してみよう
よく使われるプロパティを簡単に試してみます.
もう少し深い使い方は,別でまとめます.
### background-color・color
これは,一度使っていますが改めて.
- background-color
- 背景色
- color
- 文字色
レシピの記述してある `div` 要素に `class="bg-333"` とクラスを付与します.
そして,以下のようにスタイルを宣言します.
<iframe height="600" style="width: 100%;margin-bottom:10px;" scrolling="no" title="Untitled" src="https://codepen.io/yosse95ai-the-decoder/embed/OJQwYzN?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/yosse95ai-the-decoder/pen/OJQwYzN">
Untitled</a> by yosse95ai (<a href="https://codepen.io/yosse95ai-the-decoder">@yosse95ai-the-decoder</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>
### width・height
- width
- 要素の幅
- height
- 要素の高さ
`header` 要素セレクターと `bg-333` クラスセレクターに以下を参考に,プロパティ宣言を追加します.
<iframe height="600" style="width: 100%;margin-bottom:10px;" scrolling="no" title="width_height" src="https://codepen.io/yosse95ai-the-decoder/embed/RwQBmEW?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/yosse95ai-the-decoder/pen/RwQBmEW">
width_height</a> by yosse95ai (<a href="https://codepen.io/yosse95ai-the-decoder">@yosse95ai-the-decoder</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>
ヘッダーの高さとレシピ集の幅が変化したことが分かると思います.
### margin・border・padding
- margin
- 要素外周の空間
- border
- padding すぐ外側の実線
- padding
- コンテンツ周囲のスペース
一番最初の `div` 要素に,適当なクラス名(`mpb`)を付けます.
そしてそれに対して,スタイルを宣言してみましょう.
順番としては,`margin: 20px 30px 20px 40px;` を宣言し,スタイルを確認してみます.
次に,`border: 3px solid #333;` を宣言し,スタイルを確認します.
最後に,`padding: 20px 40px;` を宣言し,スタイルを確認します.
以上の順番でやるとスタイル適用の動きが分かりやすいと思います.
<iframe height="400" style="width: 100%;margin-bottom:10px;" scrolling="no" title="margin_padding" src="https://codepen.io/yosse95ai-the-decoder/embed/ZErMWrv?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/yosse95ai-the-decoder/pen/ZErMWrv">
margin_padding</a> by yosse95ai (<a href="https://codepen.io/yosse95ai-the-decoder">@yosse95ai-the-decoder</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>
開発者ツールで確認してみましょう.
Google Chrome で右クリックをします.
そして,検証やほかのブラウザなら検証(開発)用ツールと出ているものをクリックします.
F12キーでも同じことができるはずです.

そして,`Elementsタブ` を開き、追加した `mbp` クラスが付与されている `div` 要素を探してクリックします.

色がついたと思いますが,以下の領域をそれぞれ示します.
- オレンジ:marginの領域
- 黄色 :borderの領域
- 薄い緑 :paddingの領域
- 薄い青 :コンテンツの領域

Stylesタブの下の方に行くと,ボックス上のグラフィックで確認できます.
`margin` と `padding` は特に重要な概念なので使いこなしていきましょう!
## まとめ
ここまでで,いろいろなCSSの概念や基本的なボックスの考え方を伝えてきました.
次は,いい感じにスタイリングをしながら,いろいろなプロパティを試していきましょう.
スライドに戻りましょう.
## 参考
### テキスト
- [CSS の基本](https://developer.mozilla.org/ja/docs/Learn/Getting_started_with_the_web/CSS_basics)
- [【2022年版】おすすめのリセットCSS3選【CDNのコピペあり】](https://zenn.dev/yurukei20/articles/ffdbde17cd0853)
### 動画
- [CSS講座 - しまぶーのIT大学](https://youtube.com/playlist?list=PLwM1-TnN_NN5jWN09yjtxWng2XZa88ate)