mcpField
B
bem-structure

bem-structure

github.com/rolemodelデザイン・UI7195 回インストール3 日前に更新
リポジトリ

bem-structure について

bem-structure は、フロントエンド開発者向けに BEM を使った CSS の作成とレビューを AI に案内するスキルです。意味の明確な命名と明示的なセレクターを重視し、RoleModel の Optics コンポーネントの再利用を優先します。

主な機能

  1. 01BEM のブロック・要素・修飾子の規則
  2. 02明示的で意味の伝わるクラス名
  3. 03タグ・ID・階層セレクターの回避
  4. 04修飾子への明示的なセレクター
  5. 05Optics コンポーネントの優先的な再利用

活用シーン

  1. 01新しい画面向けの BEM スタイル作成
  2. 02既存 CSS のリファクタリングやレビュー
  3. 03BEM に沿わないクラス名の修正
  4. 04Optics コンポーネントを再利用するかの判断

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/rolemodel/skills --skill bem-structure

インストール後、Claude Code で/bem-structureを入力して読み込まれたか確認します。

詳細

概要

このスキルは、明確な命名規則とコンポーネント構造を用いて、保守性、拡張性、再利用性に優れたスタイルシートを作成するため、BEM(Block Element Modifier)手法に基づくCSSの記述をAIにガイドします。また、スコープ、リスク、アーキテクチャへの影響を判断しながら、Optics(当社のRoleModelデザインシステム)と組み合わせてBEMを使用し、すでに存在するものを再作成しないようにします。ニーズに合うOpticsコンポーネントがすでにある場合は、新しいBEMブロックを作成するのではなく、必要に応じてそのコンポーネントを使用、またはオーバーライドしてください。

エージェントは、明確さ、予測可能性、意図しない副作用の最小化を優先する必要があります。

キーワード:CSSレビュー、BEM構造、BEM手法、CSSのベストプラクティス、CSSのリファクタリング、CSSのレビュー、CSSを修正、BEMを修正、CSSをBEM化

BEMとは?

BEMはBlock Element Modifierの略です。フロントエンド開発で、再利用可能なコンポーネントとコード共有を実現するための手法です。

パターン構文例
ブロック.block.card
エレメント.block__element.card__title
ブロック修飾子.block--modifier.card--elevated
エレメント修飾子.block__element--modifier.card__title--large
複数単語の名前.block-name.user-profile
命名規則
  • ほかの開発と同様に、意図が伝わる名前が重要です。
  • BEMでは、名前で伝える意図は適用されるスタイルや見た目ではなく、インターフェース上の目的に基づきます。
  • 修飾子(small、large、paddedなど)を除き、特定のスタイルを表す名前は通常、適切ではありません。
  • 特定のワークフローに基づく命名は、場合によっては許容されます(曜日を含むカレンダーなど)。
  • 共通するワークフローの種類に基づく命名が適切です(form、table、card、buttonなど)。
  • より広いUIの抽象概念に基づく命名は必ずしも必要ではありませんが、コンテキストが不要な抽象的なケース(primary、largeなど)では使用できます。
  • 目的が明確に伝わるほど具体的でありながら、該当する場合には再利用できるほど汎用的な名前にしてください。再利用が常に可能、または望ましいとは限らないため、無理に汎用化しないでください。
  • 解釈の余地がなく、明示的な名前を使うようにしてください。特に修飾子では、この点を考慮する必要があります。
  • 修飾子には明示的な&の使用を組み合わせ、フラットなBEMクラスを使用してください。
  • DOM構造はCSSクラス構造に従う必要はありません。

プロジェクトの制約やその他の理由により、これらのガイドラインに従えない場合は、チャットの出力で逸脱の理由を記載してください。

基本構文

✅ GOOD(このようにしてください)

.block {
  .block__element {
    &.block__element--modifier { }
  }
  
  &.block--modifier { }
}
<div class="block">
  <div class="block__element">...</div>
  <div class="block__element block__element--modifier">...</div>
</div>

<div class="block block--modifier">
  <div class="block__element">...</div>
  <div class="block__element">...</div>
</div>

🚫 BAD(このようにはしないでください)

.block {
  .block--modifier { } /* Use `&` before all Modifier class names */
}

.block_element { /* Use `__` between Blocks and Elements and nest Element within the Block */
  &.block__element-modifier { } /* Use `--` between the Modifier and its Element */
}
<div class="block">...</div>  
<div class="block__element">...</div> 
  <div class="block__element--modifier">...</div> 
</div>

<div class="block__element"> 
  <div class="block__element">...</div> 
</div>

ルールの概要

  • すべてのクラス名は、完全かつ明示的なBEM形式でなければなりません。整理のためのネストは許可されますが、セレクターでタグ名やIDに依存してはいけません。
  • &は、完全なセレクターへのテキスト上の参照としてのみ使用できます。
  • &を使ってクラス名を構成してはいけません(&--、&__)。
  • ネストは整理のためだけに使用します。明示的なBEMクラス名が必要です。必要に応じて、ブロック内のエレメントにスコープを限定するために、ネストしたセレクターを使用できます。
  • セレクターを明示的なままにしつつ、ブロックまたはエレメントと修飾子を近くに記述するために、&を使用できます。

✅ GOOD(このようにしてください)

.card {
  &.card--featured {}
  &.card--compact {}
  &.card--featured {
    &.card--compact {}
  }
}

🚫 BAD(このようにはしないでください)

.card {
  &--featured {}
  &__title {}
  &__title--large {}
}

ブロック

それ自体で意味を持つ独立したエンティティをカプセル化します。ブロックはネストしたり相互に作用したりできますが、意味的には対等であり、優先順位や階層はありません。コントローラーやモデルなど、DOM表現を持たない全体的なエンティティもブロックにできます。

命名:

ブロック名には、小文字のラテン文字、数字、ハイフンを使用できます。CSSクラスを作成するには、名前空間を指定する短いプレフィックスを追加します:.block。長いブロック名に含まれるスペースはハイフンに置き換えます。

HTML:

クラス名を受け入れるDOMノードであれば、どれもブロックにできます。

✅ GOOD(このようにしてください)

<div class="card">...</div>
<div class="button">...</div>
<div class="menu">...</div>
<div class="header">...</div>
<div class="search-form">...</div>
<div class="user-profile">...</div>
<div class="modal">...</div>
<div class="navigation">...</div>
<div class="dropdown-menu">...</div>

🚫 BAD(このようにはしないでください)

<div class="searchForm">...</div>
<div class="button_primary">...</div>
<div class="userProfile">...</div>
<div class="dropdown__menu">...</div>  
CSS:

クラス名セレクターのみを使用してください。タグ名や ID は使用しないでください。ページ上の他のブロックや要素に依存させないでください。

✅ GOOD(このようにしてください)

.card { }
.button { }
.menu { }
.header { }
.search-form { }
.user-profile { }
.modal { }
.navigation { }
.dropdown-menu { }

🚫 BAD(このようにはしないでください)

.searchForm {}
.button_primary {}
.userProfile {}
.dropdown__menu {} /* Don't use element syntax for blocks */
}

Element

ブロックの一部であり、単独では意味を持ちません。各要素は意味的にそのブロックと結び付いています。

命名:

要素名には、小文字のラテン文字、数字、ハイフン、アンダースコアを使用できます。CSS クラスは、ブロック名の後にアンダースコアを 2 つ付け、さらに要素名を続けて作成します:.block__elem。長い要素名のスペースはハイフンに置き換えます。

HTML:

ブロック内の DOM ノードはどれも要素にできます。同じブロック内では、すべての要素は意味的に等しいものとして扱います。CSS では、その要素を含むブロックの外で使用しないでください。

✅ GOOD(このようにしてください)

<div class='block'>
  <div class='block__element'>
    <div class='block2'>
      <div class='block2__element'>...</div>
    </div>
  </div>
</div>

🚫 BAD(このようにはしないでください)

<div class='block'>
  <div class='block__element'>
    <div class='element__element'>...</div> 
  </div>
</div>
CSS:

CSS では、要素を所属するブロックの内側にネストしてください。構造を DOM の構造と一致させる必要はありません。

✅ GOOD(このようにしてください)

/* Card block with elements */
.card { /* This is the block; elements are inside */
  .card__header { }
  .card__title { }
  .card__body { }
  .card__footer { }
  .card__image { }
}

/* Menu block with elements */
.menu {
  .menu__item { }
  .menu__link { }
  .menu__icon { }
}

/* Search form block with elements */
.search-form {
  .search-form__input { }
  .search-form__button { }
  .search-form__label { }
}

🚫 BAD(このようにはしないでください)

/* Don't create deeply nested element names */
.menu {
  .menu__item { }
  .menu__item__link { } /* Improper naming structure */
  .menu__item__link__icon { } /* Improper naming structure */
}

Modifier

ブロックまたは要素に付けるフラグです。外観、動作、状態を変更するために使用します。

命名:

修飾子名には、小文字のラテン文字、数字、ハイフン、アンダースコアを使用できます。CSS クラスは、ブロック名または要素名の後にハイフンを 2 つ付けて作成します:.block--modifier、.block__elem--modifier、および .block--color-black(.block--color-red も同様)です。複雑な修飾子名のスペースはハイフンに置き換えます。

次の場合は、独立した要素を作成する代わりに修飾子を使用してください:

  • 変更が単純な状態の変更である(例:アクティブ、無効、強調表示)
  • 変更が単純な外観の変更である(例:サイズ、色、レイアウト)
  • 変更によって、新たな要素を必要とするコンテンツや機能が追加されない

要素にデフォルトの状態と修飾子で表す別の状態がある場合は、基本要素にデフォルトのスタイルを設定し、修飾子が適用されたときにそのスタイルを上書きしてください。デフォルト状態専用の要素を作成したり、このケースに 2 つの修飾子を作成したりしないでください。

🚫 BAD(このようにはしないでください)

.product-card__image {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.product-card__placeholder {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, var(--op-color-neutral-plus-six) 0%, var(--op-color-neutral-plus-seven) 100%);
}

✅ GOOD(このようにしてください)

.product-card__image {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  
  &.product-card__image--placeholder {
    object-fit: unset;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, var(--op-color-neutral-plus-six) 0%, var(--op-color-neutral-plus-seven) 100%);
  }
}
HTML:

修飾子は、ブロックまたは要素の DOM ノードに追加する追加のクラス名です。修飾子クラスは、変更対象のブロックまたは要素にのみ追加し、元のクラスも残してください。つまり、修飾子クラスは常に、ベースとなるブロックまたは要素のクラスと併用する必要があります。

✅ GOOD(このようにしてください)

<div class="block block--modifier">...</div>
<div class="block block--size-big block--shadow-yes">...</div>

🚫 BAD(このようにはしないでください)

<div class="block--modifier utility">...</div> 
CSS:

✅ GOOD(このようにしてください)

.menu {
  .menu__item {
    &.menu__item--active { }
  }
  .menu__link { }
  .menu__icon { }
  
  &.menu--padded { }
}

🚫 BAD(このようにはしないでください)

.menu {
  .menu__item {
    .menu__item--active { } /* No ampersand */
  }
  
  .menu__link { }
  .menu-link-active { } /* Bad name structure */
  .menu__icon { }
  
  .menu__padded { } /* Improper modifier structure; should be using `&` and `--`, not `__` */
}

その他のルール

  • クラスのみを使用します(ID は使用しません)
  • フラットなクラスとセレクターのみを使用します
  • タグに基づくスタイル設定はしません
  • DOM の階層に基づくスタイル設定はしません
  • 1 つのブロックにつき、概念上の責務は 1 つにします
  • 必要に応じて、ブロックの中にブロックを含められます
  • 要素は、それが属するブロックの外には存在しません
  • 複数の単語からなる名前には kebab-case を使用します:.user-profile、.dropdown-menu
  • 要素名では、ブロックと要素の区切りにアンダースコア 2 つ(__)を使用します
  • 修飾子名では、ブロックまたは要素と修飾子の区切りにハイフン 2 つ(--)を使用します
  • 名前は意味が明確で、説明的かつ意図が伝わるものにします(外観に基づく名前は避けます)
  • 広く理解されていない略語は避けます
構文の例

theme: "xmas" および simple: true の修飾子を持ち、input と submit の要素を持つフォームブロックがあるとします。また、フォームが未入力のときに送信を防ぐため、submit 要素には disabled: true の修飾子があります。

✅ GOOD(このようにしてください)

<form class="form form--theme-xmas form--simple">
  <input class="form__input" type="text" />
  <input
    class="form__submit form__submit--disabled"
    type="submit" />
</form>
.form {
  .form__input { }
  .form__submit {
    &.form__submit--disabled { }
  }
  
  &.form--simple { }
  &.form--theme-xmas { }
}

🚫 BAD(このようにはしないでください)

<form class="form form-simple form--theme-xmas "> 
  <input class="form_input" type="text" /> 
  <input
    class="form__submit--disabled" 
    type="submit" />
</form>
.form {
  .form__input { }
  .form_submit { /* Use `__` between Block and Element */
    .form__submit--disabled { } /* Use `&` before all Modifier class names */
  }
  
  &.form-simple { }  /* Use `--` between Element and Modifier */
}

&.form--theme-xmas { } /* Must nest Elements and Modifiers within Block */

コメント