Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use when naming the CSS classes for a UI component that has sub-parts and variant states: name them as block__element--modifier, not ad-hoc hyphen or camelCase names. Do NOT use for writing the CSS property rules themselves or for choosing colors, spacing, or layout values.
.claude/skills/bem-css-naming/SKILL.md| Model | Lift | Δ tokens | Δ turns | Cases | Verified |
|---|---|---|---|---|---|
| gemini-3.6-flashbest | +23% | +50% | 0% | 22 | 54d ago |
| gemini-3.5-flash | pending re-run | — | |||
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-19 | ✗→✓ | ▲ Improved | — | — |
| case-01 | ✗→✓ | ▲ Improved | — | — |
| case-11 | ✗→✓ | ▲ Improved | — | — |
| case-17 | ✗→✓ | ▲ Improved | — | — |
| case-02 | ✗→✓ | ▲ Improved | — | — |
Enforces the block__element--modifier class-naming grammar on every CSS class you name for a UI component. Apply whenever the task is to name the classes for a component and its parts and states; not to write the CSS declarations themselves and not to choose visual values.
A component's class names are built from three kinds of name, joined by fixed delimiters:
card, modal, nav. Words withina single name are joined by a single hyphen: site-header, product-card.
underscore __: card__title, modal__close, nav__item. Never a single hyphen (card-title), never camelCase (cardTitle), never a descendant selector (.card .title).
--: card--featured, nav__item--active, button--disabled.
nested visually inside another part is still block__thing, never block__part__thing: write card__title, not card__header__title.
it: class="button button--primary", never class="button--primary" by itself. The modifier only adjusts; the base carries the shared styles.
fixed: single hyphen - inside a multi-word name, double underscore __ before an element, double hyphen -- before a modifier.
The base's ad-hoc default is on the left; the conforming BEM names on the right.
A search form with a field, a submit control, and a disabled state:
BEFORE .searchForm .searchForm .input .submitBtn .disabled
AFTER .search-form
.search-form__field
.search-form__submit
.search-form--disabledA media object (image beside body text) with a reversed variant:
BEFORE .media .media-img .mediaBody .media.reverse
AFTER .media
.media__image
.media__body
.media--reversedAn element that carries its own state — the modifier attaches to the element, used with it:
BEFORE <li class="active"> /* bare state class */
AFTER <li class="breadcrumb__crumb breadcrumb__crumb--current">block__element. A label inside a field insidea form is search-form__label, not search-form__field__label. Flatten to one level.
inside a card is button (its own block), not card__button, when it is used elsewhere too.
class="button button--large button--primary".
--active/--disabled; a value uses akey-value form --size-large / --theme-dark (still the double-hyphen delimiter).
__. Don't use a single hyphen (card-title),camelCase (cardTitle), or a descendant selector.
--. Don't use a single hyphen or a bare state class like .active.block__a__b..cardTitle, .card-title, .card .title, .active.card_title, card-title for an element;button-primary for a modifier).
menu__list__item instead of menu__item.block, block__element, or block[__element]--modifier.__; modifier delimiter is --; both are doubled.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-19 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +23 percentage points is the difference between those two pass rates over the 22 comparable cases. 2 cases got worse with the skill loaded, and they are included in that figure.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.5-flash | verified | 7/10/2026 | +40% |
Other measured skills in the registry, with their headline benchmark lift.