mcpField
B
bem-structure

bem-structure

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

bem-structure について

bem-structure は、BEM の命名規則と構造に沿って CSS を作成・レビューするエージェントスキルです。重複するブロックを作らず、適合する Optics コンポーネントの再利用も促します。

主な機能

  1. 01BEM 命名規則の適用
  2. 02ブロック、エレメント、モディファイアの構成
  3. 03明示的なクラスセレクター
  4. 04既存 Optics コンポーネントの考慮
  5. 05明確で影響の小さい CSS 変更の優先

活用シーン

  1. 01CSS の BEM 整合性レビュー
  2. 02スタイルの BEM 構造へのリファクタリング
  3. 03曖昧または不統一なクラス名の修正
  4. 04Optics コンポーネントと新規ブロックの選択

インストール

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

$npx skills add https://github.com/rolemodel/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 */

コメント