LoginSignup
1

More than 5 years have passed since last update.

【CSS設計】合成コンポーネントを@extendで実装する

Last updated at Posted at 2017-01-18

コンポーネントを作る際、別のコンポーネントをパーツとして使うことがあります。
例えば、以下のアンケートテーブルでは、「アンケート行」が1つのコンポーネントになっていて、その中で「ボタン」コンポーネントが使われています。

component-composition-1.png

これを素直に実装すると、「アンケート行」と「ボタン」をそれぞれ独立したコンポーネントとして実装し、HTML 上で組み合わせる、という感じになるかと思います。

.action-btn {
  // ボタンのスタイル
}

.enquete {
  // アンケート行のスタイル
}
<table class="enquete-table">
  <tr><th>アンケート名</th><th>回答</th></tr>
  <tr class="enquete">
    <td class="enquete__title">アンケート1</td>
    <td class="enquete__action"><button class="action-btn">回答する</button></td>
  </tr>
  <tr class="enquete">
    <td class="enquete__title">アンケート2</td>
    <td class="enquete__action"><button class="action-btn">回答する</button></td>
  </tr>
  <tr class="enquete">
    <td class="enquete__title">アンケート3</td>
    <td class="enquete__action"><button class="action-btn">回答する</button></td>
  </tr>
</table>

これでも悪くはないのですが、.enquete.action-btn の関係を Sass 上で表現できないため、「この2つを組み合わせて使う」というルールをどこかに定めておかなければなりません。

また、「回答済み」のスタイルをつくる際も、

component-composition-2.png

.action-btn {
  // ボタンのスタイル

  &--disabled {
    // 利用できないボタンのスタイル
  }
}

.enquete {
  // アンケート行のスタイル

  &--done {
    // 回答済みのスタイル
  }
}
  <tr class="enquete enquete--done">
    <td class="enquete__title">アンケート3</td>
    <td class="enquete__action"><button class="action-btn action-btn--disabled">回答済み</button></td>
  </tr>

というように、それぞれの Modifier を用意して HTML 上で組み合わせなければならず、伝えなければならないルールが増えてしまいます。

コンポーネントの関係を Sass 上で表現する

.enquete の Element としてボタンクラスを用意し、@extend を使って .action-btn を適用します。

.enquete {
  // アンケート行のスタイル

  // 回答ボタン
  &__answer-btn {
    @extend .action-btn;
  }
}
  <tr class="enquete">
    <td class="enquete__title">アンケート1</td>
    <td class="enquete__action"><button class="enquete__answer-btn">回答する</button></td>
  </tr>

このようにすると、回答ボタンに .action-btn を使っていることが Sass を見ただけで分かるようになり、HTML を書く際に「組み合わせのルール」を参照する必要もなくなります。

また、使うボタンを .action-btn から .control-btn に変更することになった場合、元の実装だと HTML の該当箇所をすべて見つけ出して修正しなければならず、手間がかかる上に修正漏れが発生する可能性もありますが、この方法なら @extend するクラスを変更するだけで済みます。

回答済みボタンの Modifier も Sass 側で吸収する

.enquete--done.enquete__answer-btn に、@extend を使って .action-btn--disabled を適用します。

.enquete {
  // アンケート行のスタイル

  &--done {
    // 回答済みのスタイル

    // 回答ボタン
    .enquete__answer-btn {
      @extend .action-btn--disabled;
    }
  }
}
  <tr class="enquete enquete--done">
    <td class="enquete__title">アンケート3</td>
    <td class="enquete__action"><button class="enquete__answer-btn">回答済み</button></td>
  </tr>

これで回答済みのボタンには .action-btn--disabled を使っていることが Sass を見ただけで分かるようになり、HTML 側も単に .enquete--done Modifier を使っているだけのように書くことができます。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1