※この記事は、スライドモードでご覧ください
1990年代後半
CSSはまだ普及していなかった
どのようにHTMLを装飾していたか
index.html
<h2 align="center">
<font color="#ff0000" size="7">やめ太郎について</font>
</h2>
htmlのタグに直書きしていた
ページ数が多いと大変・・・
同じコードを何度も書かなければならない
修正が発生したときも大変
例えば・・・
依頼主「おぼろげながら浮かんできたでぇ・・・」
依頼主「緑という色がな!」
依頼主「見出しの色は、緑や!」
ワイ「ファッ!?」
ワイ「全50ページの見出し、ぜんぶ変更でっか!?」
ワイ「今日も残業や・・・」
そんなこともあったかもしれません
時は流れ・・・
2000年代
CSSが普及してきた
style.css
.heading2 {
font-size: 48px;
color: #ff0000;
text-align: center;
margin-bottom: 60px;
}
例えば、クラス名に対してCSSを書く
index.html
<h2 class="heading2">やめ太郎について</h2>
HTMLタグに、そのクラス名を書く
タグにクラス名をつけるだけで装飾できるようになった
スタイルの塊に名前をつけて、使いまわせるようになった
修正する手間も減った
例えば・・・
依頼主「また見出しの色を変更や!」
ワイ「はいはい、おぼろげながら浮かんできたんですね」
style.css
.heading2 {
font-size: 48px;
- color: #ff0000;
+ color: #0000ff;
text-align: center;
margin-bottom: 60px;
}
ワイ「これで修正完了や!」
1ファイル修正すれば、全ページに反映される
でも、逆に修正しづらいことも・・・
修正の影響範囲が大き過ぎる
1ファイル修正しただけで、多数のページに影響が出る
ワイ「クラス名が被ってたりして、直したい部分以外が変わってしまうことはないやろか・・・」
気軽に修正できない
どうすればいいか
クラス名が重複しないための工夫が必要
そこでBEM
例えば・・・
index.html
<ul class="userList">
<li class="item">
<span class="text">太郎</span>
</li>
<li class="item">
<span class="text">次郎</span>
</li>
</ul>
item
とかtext
って、他と被りそう・・・
item
のスタイルを修正したら、ほかの部分にも影響が出るかも・・・
クラス名をもっと工夫せな・・・
せや、BEMや!
index.html
<ul class="userList">
<li class="item">
<span class="text">太郎</span>
</li>
<li class="item">
<span class="text">次郎</span>
</li>
</ul>
これを・・・
index.html
<ul class="userList">
<li class="userList__item">
<span class="userList__text">太郎</span>
</li>
<li class="userList__item">
<span class="userList__text">次郎</span>
</li>
</ul>
こう!
親のクラス名を頭につければ、他と重複しない
クラス名が長くなりがち&なんだか愚直
でも割と便利
ここで一回まとめ
CSSのおかげで
- 同じスタイルを何度も直書きしなくてよくなった
- 一箇所修正すれば全ページに反映されるようになった
ワイ「命名には注意が必要やけど、だいぶ便利になったで!」
しかし・・・
依頼主「おぼろげながら浮かんできたでぇ・・・」
依頼主「見出しのデザイン、もっと凝った感じにしたいんや!」
依頼主「せやから・・・」
依頼主「h2
タグの中に、span
タグを入れてくれや!」
ワイ「ファッ!?」
index.html
<h2 class="heading2">やめ太郎について</h2>
これを・・・
index.html
<h2 class="heading2">
<span>やめ太郎について</span>
</h2>
こう!
ワイ「これは・・・CSSだけじゃどうにもならへん・・・」
ワイ「50ページ、全部修正するか・・・」
50ページ修正している間に・・・
時は流れ・・・
現代
コンポーネントの時代
ワイ「50ページ修正している間に2021年になってもうたわ・・・」
ワイ「現代には、Reactいう便利なライブラリがあるらしいで」
ワイ「HTMLの塊を、部品みたいにして使い回せるみたいや」
ワイ「コンポーネントいうやつやな」
ワイ「ちょっと使ってみよか」
/components/Heading2.tsx
export const Heading2: React.FC = ({ children }) => {
return (
<h2>{children}</h2>
)
}
ワイ「早速、このコンポーネントを・・・」
/components/Heading2.tsx
export const Heading2: React.FC = ({ children }) => {
return (
<h2>
<span>{children}</span>
</h2>
)
}
ワイ「こうや!」
ワイ「1ファイル修正しただけで、全ページに反映できたで!」
ワイ「素敵やん?」
ワイ「ところで、CSSはどうやって書くんや?」
※Emotionというライブラリを使用している想定です
components/Heading2.tsx
const heading2 = css`
font-size: 48px;
color: #ff0000;
text-align: center;
margin-bottom: 60px;
`
const span = css`
font-weight: normal;
`
export const Heading2: React.FC = ({ children }) => {
return (
<h2 css={heading2}>
<span css={span}>
{children}
</span>
</h2>
)
}
ワイ「なるほどな」
components/Heading2.tsx
const heading2 = css`
font-size: 48px;
color: #ff0000;
text-align: center;
margin-bottom: 60px;
`
const span = css`
font-weight: normal;
`
ワイ「cssという関数に、CSSのコードを渡してやって」
ワイ「それをheading2
とspan
という変数に格納」
components/Heading2.tsx
export const Heading2: React.FC = ({ children }) => {
return (
<h2 css={heading2}>
<span css={span}>
{children}
</span>
</h2>
)
}
ワイ「それをHTML(JSX)のタグに、属性みたいに渡してやるんやな」
style.css
.heading2 {
font-size: 48px;
color: #ff0000;
text-align: center;
margin-bottom: 60px;
}
ワイ「普通のCSSではこう書いていたところを・・・」
components/Heading2.tsx
const heading2 = css`
font-size: 48px;
color: #ff0000;
text-align: center;
margin-bottom: 60px;
`
ワイ「Emotionではこう、JSの中に書くんやな」
ワイ「CSS-in-JSいうやつやな」
ワイ「あれ・・・でもなんか、書き方が変わっただけで」
ワイ「あんま進化してない気もするけど」
ワイ「何が良くなったんやろな」
メリット
名前が被らない
span
なんていう短い名前をつけたとしても
自動的に、一意なクラス名を生成してくれる
例:css-1duww6s-span
ほかのファイルでspan
という同名のスタイルを作っていても大丈夫
<h2 class="css-1ax0e8a-heading2">
<span class="css-1duww6s-span">
やめ太郎について
</span>
</h2>
描画されるHTMLはこんな感じ
.css-1ax0e8a-heading2 {
font-size: 48px;
color: #ff0000;
text-align: center;
margin-bottom: 60px;
}
.css-1duww6s-span {
font-weight: normal;
}
CSSはこんな感じで生成される
これによって
スタイルの名前づけが楽になる
重複を避けるために、長いクラス名をつける必要もない
むしろもう、名前は要らないかもしれない
components/Heading2.tsx
export const Heading2: React.FC = ({ children }) => {
return (
<h2
css={css`
font-size: 48px;
color: #ff0000;
text-align: center;
margin-bottom: 60px;
`}
>
<span
css={css`
font-weight: normal;
`}
>
{children}
</span>
</h2>
)
}
HTML(JSX)の中に直で書くこともできる
ワイ「でも、HTML(JSX)の中に直書きでスタイリングするのは、なんか抵抗が・・・」
やめ太郎のトラウマ
直書きすると、デメリットがあった気がする
HTMLの中に直で書くと、同じコードを何度も書かなければならない
何箇所も修正しなければならない
いえ
→コンポーネント化されているので大丈夫
→何回も書かなくていい
→1箇所だけ修正すればいい
ワイ「あ、そうか・・・」
むしろメリットがある
例えば
components/Heading2.tsx
export const Heading2: React.FC = ({ children }) => {
return (
<h2 css={heading2}>
<span css={span}>
{children}
</span>
</h2>
)
}
ワイ「この、h2タグにあたってるheading2
ってスタイルは」
ワイ「コードの中のどこにあるんかな〜?」
ワイ「あった、あった、修正しよか」
って探す必要がなくなる
HTMLとCSSを行き来する必要がなくなる
なぜなら
HTMLの中に、CSSも書いてあるから
components/Heading2.tsx
export const Heading2: React.FC = ({ children }) => {
return (
<h2
css={css`
font-size: 48px;
color: #ff0000;
text-align: center;
margin-bottom: 60px;
`}
>
<span
css={css`
font-weight: normal;
`}
>
{children}
</span>
</h2>
)
}
ただ、大きめのコンポーネントだと見た目ゴチャッとするかも
ちなみに・・・
Tailwind CSS
components/TailwindHeading2.tsx
export const TailwindHeading2: React.FC = ({ children }) => {
return (
<h2 class="text-xl text-center mb-12">
<span class="font-normal">
{children}
</span>
</h2>
)
}
Tailwind CSSも、単機能なクラスをたくさん使って
HTMLの中でスタイリングする感じで、考え方が似てますよね!
まとめ
HTMLの中にCSSを直書きすることで・・・
- スタイルに名前をつけなくて済む
- 「この値は、要するにこういうものだから・・・この名前だな!」
→という思考コストを削減できる
- 「この値は、要するにこういうものだから・・・この名前だな!」
- HTMLとCSSのコードを行き来しなくて済む
- コンポーネント化されていれば、何度も書く必要もない
逆に、名前をつけるメリット
基本的に、なんでも名前をつけたほうがいいです
細かく名前をつけない場合
const totalPrice = 1000 + 1000 * 0.1
細かく名前をつけた場合
const itemPrice = 1000
const taxRate = 0.1
const tax = itemPrice * taxRate
const totalPrice = itemPrice + tax
なんのための数値か分かるため、リーダブルに。
「説明変数」なんて呼ばれます
でも・・・
components/Heading2.tsx
export const Heading2: React.FC = ({ children }) => {
return (
<h2
css={css`
font-size: 48px;
color: #ff0000;
text-align: center;
margin-bottom: 60px;
`}
>
<span
css={css`
font-weight: normal;
`}
>
{children}
</span>
</h2>
)
}