😺
【13日目】『リーダブルコード』を意識してHTML/CSSをリファクタリングしてみた
技術ブログ13日目。
本日は、HTML/CSSの読みやすさを追求します。
〇課題
複雑な「料金プラン表」
一見正しく表示されますが、特定の要素を強調するためにセレクタが複雑化しており、後からのデザイン変更やプラン追加が困難な密結合なコードを改善します。
〇修正前コード(動くけれど読みにくいコード)
<section class="pricing">
<div class="main-container">
<div class="plan-box">
<h3>基本プラン</h3>
<p class="price">¥980</p>
<button>申し込む</button>
</div>
<div class="plan-box active">
<div class="badge">人気</div>
<h3>プロプラン</h3>
<p class="price">¥2,980</p>
<button>申し込む</button>
</div>
<div class="plan-box">
<h3>ビジネスプラン</h3>
<p class="price">¥9,800</p>
<button>申し込む</button>
</div>
</div>
</section>
/* 巨大な式(長いセレクタ)と複雑な制御フロー */
section.pricing div.main-container div.plan-box {
width: 300px;
padding: 20px;
border: 1px solid #ccc;
float: left; /* 古い手法 */
margin: 10px;
}
/* 読み手の脳に負担をかける複雑な条件指定 */
section.pricing div.main-container div.plan-box.active {
border: 2px solid #ff4500;
transform: scale(1.1);
background-color: #fffaf0;
}
/* 深すぎるネストのような指定 */
section.pricing div.main-container div.plan-box.active h3 {
color: #ff4500;
font-size: 24px;
}
/* マジックナンバー(説明のない数値) */
section.pricing div.main-container div.plan-box.active p.price {
margin-top: 15px;
font-weight: 900;
color: #333;
}
/* 状態によって打ち消し合うコード */
section.pricing div.main-container div.plan-box button {
background-color: #eee;
border: none;
padding: 10px 20px;
}
section.pricing div.main-container div.plan-box.active button {
background-color: #ff4500;
color: white;
}
〇リファクタリングの指針
名著『リーダブルコード』に基づき、以下の点を意識しました。
巨大な式を分割する
長いセレクタはHTML構造への依存が強く修正に弱いため、クラス名1つで指定できるように簡略化する。
制御フローを読みやすくする
詳細度(セレクタの強さ)の競合を避け、スタイルの上書きが予測通りに動くように設計する。
説明用変数(CSS変数)の導入
具体的な数値や色に名前をつけることで、デザインの意図をコードに反映させる。
〇修正後コード
<section class="pricing">
<div class="pricing__grid">
<article class="plan-card">
<h3 class="plan-card__title">基本プラン</h3>
<p class="plan-card__price">¥980</p>
<button class="plan-card__button">申し込む</button>
</article>
<article class="plan-card plan-card--active">
<span class="plan-card__badge">人気</span>
<h3 class="plan-card__title">プロプラン</h3>
<p class="plan-card__price">¥2,980</p>
<button class="plan-card__button">申し込む</button>
</article>
<article class="plan-card">
<h3 class="plan-card__title">ビジネスプラン</h3>
<p class="plan-card__price">¥9,800</p>
<button class="plan-card__button">申し込む</button>
</article>
</div>
</section>
:root {
/* 変数に情報を詰め込む*/
--color-primary: #ff4500;
--color-border: #ccc;
--color-bg-light: #fffaf0;
--color-text-main: #333;
--spacing-base: 20px;
}
/* レイアウト:Flexboxで制御フローを単純化*/
.pricing__grid {
display: flex;
justify-content: center;
gap: 24px;
padding: 40px;
flex-wrap: wrap;
}
/* 基本コンポーネント:式を分割して簡潔なセレクタに */
.plan-card {
flex: 1;
min-width: 280px;
max-width: 320px;
padding: var(--spacing-base);
border: 1px solid var(--color-border);
border-radius: 8px;
text-align: center;
transition: all 0.3s ease;
}
.plan-card__title {
font-size: 1.25rem;
margin-bottom: 16px;
}
.plan-card__price {
font-size: 2rem;
font-weight: 900;
margin-bottom: 24px;
}
.plan-card__button {
width: 100%;
padding: 12px;
border: none;
background-color: #eee;
cursor: pointer;
}
/* 状態の変化:差分だけを記述する(制御フローの最適化) */
.plan-card--active {
border: 2px solid var(--color-primary);
background-color: var(--color-bg-light);
transform: scale(1.05);
position: relative;
}
.plan-card--active .plan-card__title {
color: var(--color-primary);
}
.plan-card--active .plan-card__button {
background-color: var(--color-primary);
color: white;
}
.plan-card__badge {
position: absolute;
top: -12px;
left: 50%;
transform: translateX(-50%);
background: var(--color-primary);
color: white;
padding: 4px 12px;
border-radius: 20px;
font-size: 0.8rem;
}
〇主な修正ポイント
セレクタの簡略化:
長いセレクタを廃止。
クラス名1つに集約することで、HTMLの階層変更に左右されない「疎結合」なコードにしました。
詳細度のフラット化:
タグ名をセレクタに含めず、全てクラスベースに統一。予期せぬスタイルの競合を防いでいます。
CSS変数の導入:
色や余白を変数化し、プロジェクト全体で一貫性を保てるようにしました。
モダンなレイアウト:
float を flexbox に置き換え、要素間の間隔(gap)を直感的に制御できるようにしました。
〇参照先
▼公式ドキュメント
▼書籍
リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック
以上
Discussion