自作したホームページがぐちゃぐちゃの地獄になった話
HTMLとCSSの勉強が進み、かっこいいサイトと同じ見た目のものを再現できるようになってきました。
ちょっと勉強するだけでこんなにできるなんてちょろいな〜なんて思った私は、自分のホームページを作ることにしました。
VSCodeを開いて、index.htmlとstyle.cssを用意してコードを書き始めます。
<div class="top">
<div class="box">
<h2 class="title-main">お知らせ</h2>
</div>
<div class="box">
<p class="text-small">最新情報です</p>
</div>
</div>
コンテンツを囲む箱は.box、見出しは.title-main、補足テキストは.text-small。
「お、クラス再利用できててエンジニアっぽくない?」とか思ってました。
CSSもそれっぽく書いていきます。
.title-main {
color: red;
font-size: 24px;
}
.text-small {
font-size: 14px;
margin-top: 8px;
}
.box {
margin-bottom: 32px;
}
ブラウザで見るとちゃんと赤いタイトルと適度な余白が出てきて、「うんうん、いい感じじゃん」とご満悦です。
…が、書き進めていくうちに、追加したり変更したい要素がどんどん出てきます。
- トップページのタイトルだけ、もうちょっと落ち着いた色にしたくなる
- 「お知らせ」の箱と「ブログ」の箱、同じ
.boxだけど雰囲気を変えたくなる - この
.boxだけ余白を多めにしたくなる
当時の自分は、これが地獄の入口だなんて全く気づいていないので
とりあえず新しいクラスを追加して個別に整えればいいか〜
というテンションで、どんどんクラスを追加していきます。
<div class="top">
<div class="box box-1">
<p class="title-main top-title">お知らせ</p>
</div>
<div class="box box-2">
<p class="text-small">最新情報です</p>
</div>
</div>
.boxに加えて.box-1、.box-2。
.title-mainに加えて.top-title。
当時の自分の中ではちゃんと理由があって
-
.box… 全部の箱に共通 -
.box-1… 1個目の箱だけ余白を増やしたい -
.box-2… 2個目の箱だけ背景を変えたい -
.title-main… 全ページ共通の見出し -
.top-title… トップページの見出しだけ色を変えたい
みたいなイメージです。
CSSもそれに合わせて増えていきます。
.box {
margin-bottom: 32px;
}
.box-1 {
margin-top: 40px;
}
.box-2 {
background-color: lightyellow;
}
.title-main {
color: red;
font-size: 24px;
}
.top-title {
color: brown;
}
ここまでは、まだギリ分かります。
問題は、これを何度も繰り返したあとの姿です。
ページを追加するたびに
-
.box-1、.box-2、.box-3 -
.box-main、.box-top、.box-bottom -
.title-main、.title-main2、.title-sub、.title-subsub
みたいなクラスがどんどん増えていきます。
「この.box-2って何の箱だっけ?」
「box-mainとbox-topの違いって何?」
数日経つと、もう自分でもよく分からない。
それでも先に進めてしまうので、ちょっとデザインを直したくてstyle.cssを開くと
- どのクラスが今も使われていて
- 適用されてないクラスも沢山あって
- どこを変えるとどこが壊れるのか
まったく見当がつかない状態になります。
既存のクラスはもうどうなっているのか分からないので、クラスを追加しても要素が変わらない時は、idを追加して力技で解決していきます。
- 新しいクラスや
idをどんどん追加する - 使っているのかよく分からないクラスが何故か大量にある
- よく分からない余白や要素を打ち消すために、とりあえず
display: none;で隠す
みたいなことを繰り返しました。
そのうち
「ちょっと色を変えたいだけなのに、どこを直せばいいのか分からない......」
という状態になり、結果として
自分で書いたのに、自分で触りたくないコード
が出来上がりました。
ホームページを作るときに大切なこと
さすがにこれはまずいなと思って、そこから本や記事を読んだり、人のコードを眺めたりしながら分かってきたのは、ざっくり言うとこんなことです。
- HTMLは「骨組み」がとっても大事
- 骨組みを考えるためには「クラス名のルール(命名規則)」を知る必要がある
- CSSは命名規則という「共通のルール」があるとカオスになりにくい
- とりあえずの付け足しではなく、「目的」から考えた方が結果的に楽
この記事は、そんなふうにカオスな自作サイトを作ってしまった初心者の自分が ここは本当に最初から知っておきたかった と感じた考え方を、同じような悩みを持っている人に向けてまとめたものです。
まず「このサイトで何をしてほしいか」を一言で決める
僕が最初にやらかしたのは、目的を決めずにいきなりコードを書き始めたことでした。
ヘッダーを作って、ヒーロー画像を置いて、ボタンを置いて......。
「なんかかっこよさそうだから」という理由だけでセクションを増やしていくと
- 何を一番見てほしいサイトなのか
- どの情報がオマケなのか
が自分でも分からなくなります。
そこで、最初に自分にこう聞くようにしました。
このサイトで、ユーザーに何をしてほしい?
この問いかけにすぐ答えられるならバッチリです。
たとえば
- カフェサイト → お店の雰囲気を知って、行ってみようと思ってほしい
- ポートフォリオ → 実績を見て、問い合わせしてほしい
- ブログ → 記事を読んで、SNSをフォローしてほしい
これが決まると
- どのセクションを一番目立たせるか
- どこにボタンを置くべきか
- ナビに何を載せるか
がかなり決めやすくなりました。
「なんのイメージもわかないよ〜!」という方は、インスピレーションがわき出るリンクを下に貼っておきます。
たくさんのカッコいいwebサイトが紹介されているので、想像を膨らませてみてください。
HTMLの「骨組み」をちゃんと作る
ここで言う「骨組み」は
どんなブロックが、どんな順番で並んでいるか
というHTMLの構造のことです。
例えば、シンプルなトップページならこんな感じになります。
- ヘッダー(ロゴ+ナビゲーション)
- メインビジュアル(動画や大きな画像)
- ピックアップ記事(スライダー)
- 記事一覧
- お問い合わせフォーム
- フッター
まずはノートに作りたいホームページのざっくりした構成を書いてみたり、FigmaやPhotoshopでワイヤーっぽくイメージを固めてみます。
それができたら、簡単なブロックごとの骨組みをHTMLにしてみます。
<body>
<header class="header">ロゴ + メニューアイコン</header>
<main>
<section class="hero">目立つ動画</section>
<section class="slider">
<h2 class="slider__title">ピックアップされた記事</h2>
</section>
<section class="article">記事の紹介</section>
</main>
<footer class="contact">お問い合わせフォーム</footer>
</body>
ここで意識しているのは
-
<header>、<main>、<section>、<footer>などの意味のあるタグを使うこと -
sectionごとに「このブロックは◯◯を伝える場所」と一言で言えるようにすること
この時点では、見た目はまだダサくて全然OKです。
「何がどこにあるか」が分かれば完璧です。
命名規則ってなに?まずはBEMをざっくり知る
ぐちゃぐちゃカオス地獄を生み出した後で、僕はようやく 命名規則 という言葉に出会いました。
CSS 命名 おすすめみたいなキーワードで検索していると、だいたい出てくるのがこのワードです。
BEM(Block Element Modifier)
命名規則にはいくつか種類がありますが、BEMはかなりスタンダードで、ドキュメントや記事も多いです。
初心者的には、まずBEMを一つの基準として知っておくとすごく楽だなと感じました。
BEMは何者かをざっくり一言でいうと
「どの部品の、どのパーツで、どんな状態か」を
クラス名だけで分かるようにするルール
みたいなものです。
細かいルールを全部覚える必要はなくて、雰囲気だけ掴めばOKです。
BEMの3つの要素
BEMは名前の通り、3つの要素でクラス名を組み立てます。
- Block(ブロック)… ひとかたまりの部品(セクションやコンポーネント)
- Element(要素)… その部品の中にあるパーツ
- Modifier(状態)… 色違い、サイズ違いなど「状態の違い」
コードで見るとこんな感じです。
/* Block */
.card { ... }
/* Element(Blockの中のパーツ) */
.card__title { ... }
.card__text { ... }
/* Modifier(Blockのバリエーション) */
.card--featured { ... }
-
.cardが「カード」という部品本体 -
.card__titleが「カードの中のタイトル」 -
.card--featuredが「ちょっと目立たせたいカード」
HTML側もこうなります。
<article class="card card--featured">
<h3 class="card__title">おすすめ記事</h3>
<p class="card__text">説明文が入ります。</p>
</article>
クラス名を見ただけで、「これはcardブロックの、タイトル要素なんだな」と分かります。
僕がやらかしていた.box-1や.title-main2みたいな名前だと、数日後には本当に何のことか分からなくなりますが、BEMっぽく書くとかなりマシになります。
ガチガチなBEMじゃなくて「ゆるBEM」からでいい
本家のBEMにはもっと細かいルールもありますが、そこまで全部覚えようとしなくても大丈夫です。
というのも、これは初心者だから雰囲気だけで良いという話ではなく、 プロの現場でもふわっとした感じのBEMがよく使われているらしいです。(ちゃんと命名すると冗長になりすぎて却って不便らしい)
僕が実際にやっているのは、このくらいのゆるい運用です。
-
大きなまとまりには単純なクラス名を付ける
- 例)
.header、.hero、.slider、.article、.contact
- 例)
-
その中のパーツには
ブロック名__パーツ名を付ける- 例)
.header__logo、.hero__title、.article__item
- 例)
-
状態やバリエーションが欲しくなったときだけ
--を使う- 例)
.btn--primary、.btn--ghost
- 例)
完璧なBEMではないですが
「どのブロックの、どのパーツか」がクラス名から分かる
という一番おいしいところだけ借りてくるイメージです。
さっきの骨組みにBEMっぽくクラスを付けてみる
先ほど作った骨組みに、実際にクラス名を肉付けしてみます。
元はこんな感じでした。
<body>
<header class="header">ロゴ + メニューアイコン</header>
<main>
<section class="hero">目立つ動画</section>
<section class="slider">
<h2 class="slider__title">ピックアップされた記事</h2>
</section>
<section class="article">記事の紹介</section>
</main>
<footer class="contact">お問い合わせフォーム</footer>
</body>
これを、BEMの考え方を軽く取り入れて肉付けしてみると、こんな感じになります。
<body>
<header class="header">
<div class="header__inner">
<div class="header__logo">ロゴ</div>
<button class="header__menu-button">MENU</button>
</div>
</header>
<main>
<section class="hero">
<div class="hero__media">目立つ動画</div>
<p class="hero__copy">キャッチコピーが入ります</p>
<a href="#" class="hero__button btn btn--primary">詳しく見る</a>
</section>
<section class="slider">
<h2 class="slider__title">ピックアップされた記事</h2>
<div class="slider__list">
<article class="slider__item">記事1</article>
<article class="slider__item">記事2</article>
<article class="slider__item">記事3</article>
</div>
</section>
<section class="article">
<h2 class="article__title">記事の紹介</h2>
<div class="article__list">
<article class="article__item">
<h3 class="article__item-title">記事タイトル</h3>
<p class="article__item-text">記事の説明文が入ります。</p>
</article>
<!-- 以降、記事カードが増えていく -->
</div>
</section>
</main>
<footer class="contact">
<h2 class="contact__title">お問い合わせ</h2>
<form class="contact__form">
<div class="contact__field">
<label class="contact__label" for="name">名前</label>
<input class="contact__input" id="name" />
</div>
<div class="contact__field">
<label class="contact__label" for="email">メールアドレス</label>
<input class="contact__input" id="email" type="email" />
</div>
<div class="contact__field">
<label class="contact__label" for="message">お問い合わせ内容</label>
<textarea class="contact__textarea" id="message"></textarea>
</div>
<button class="contact__submit btn btn--primary" type="submit">送信</button>
</form>
</footer>
</body>
……これ、さっきまでの.box-1地獄と比べてめちゃくちゃ分かりやすくないですか?
classを見るだけで「headerの中のロゴだな」「heroの中のボタンだな」「contactの中のフォームだな」と一目で分かります。
style.cssを開いても、どのクラスがどのブロックの一部なのかがすぐに追いかけられます。
こういうふうに、BEMの考え方をベースにしながらdivやclassを付けていくだけでも、HTMLの段階でかなりスッキリした「骨組み」が作れます。
正直、この骨組みがしっかりしていれば、そのあとCSSを書くときはめちゃくちゃ楽になります。
色や余白を調整するときも、「このセクションのこのパーツだけを変えたい」が素直に書けるようになるので、あの頃みたいに.box-2や.title-main2とにらめっこする時間がだいぶ減りました。
おわりに
最初に作った自作サイトは、今振り返るとほぼスプラッター映画でした。
style.cssを開くと、画面いっぱいに並ぶ.box-1、.box-2、.title-main2、よく分からないidたち…。
あれはもはやコードではなく、未来の自分への嫌がらせです。
でも、ぐちゃぐちゃのコードから逃げずに眺め続けたおかげで
- 目的を決めてから作り始めること
- HTMLの骨組みを先につくること
- BEMをヒントにclassを付けること
このあたりの大事さが、ようやく頭じゃなくて体感で分かってきました。
もしこの記事を読んでいるあなたが
- 画面いっぱいの謎のクラスたち
- なんとなく増え続ける
id
このあたりに心当たりがあるなら、設計から意識してみましょう
今日いきなり完璧な設計を目指さなくて大丈夫です。
次にコードを書くときに、どれか一つだけでも試してみてください。
- サイトの目的を一行メモしてから書き始める
- 骨組みだけ先にHTMLにしてみる
- class名を、見た目ではなく「役割+場所」で付けてみる
それだけでも、数日後の自分がstyle.cssを開いたときの絶望感はかなり減ります。
将来の自分に向けて
ぐちゃぐちゃだけど、ちゃんと考えようとしてたんだな
と思ってもらえるコードを、一緒に増やしていきましょう。
少なくとも、.box-1と.title-main2に怯えてブラウザを閉じていた頃よりは、きっと前進しているはずです。
