---
name: bem-scss
description: 'Write BEM-structured SCSS for Drupal themes using the s360-base-theme architecture. Use when: naming CSS classes, structuring component SCSS files, deciding block/element/modifier relationships, writing nested SCSS with the & operator, reviewing class names for BEM compliance, avoiding utility class anti-patterns.'
argument-hint: 'Component name and a brief description of its structure (e.g. "card with image, title, body, and a featured modifier")'
---

# BEM SCSS — s360-base-theme Conventions

> **Also load:** [drupal-theme](../drupal-theme/SKILL.md) for the full s360-base-theme file structure and toolkit functions.

## BEM Naming Rules

**Block** — the top-level component. Named with a single word or hyphenated words.
```
.card
.hero-banner
.site-header
```

**Element** — a part of the block. Separated by double underscores.
```
.card__image
.card__title
.card__body
.hero-banner__cta
```

**Modifier** — a variation or state. Separated by double hyphens.
```
.card--featured
.card--horizontal
.card__title--large
.site-header--sticky
```

**Key rules:**
- Elements belong to their block, never to another element: `.card__title` not `.card__body__title`
- Modifiers extend a block or element; always applied alongside the base class: `class="card card--featured"`
- Class names are always lowercase and hyphen-separated words within a segment

---

## SCSS File Structure

One block per SCSS file. The filename matches the block name: `_card.scss`.

```scss
@use "@s360-base-theme/ui-core/site-config";
@use "s360-scss-toolkit" as s360;

.card {
  // Block styles

  &__image {
    // Element styles
  }

  &__title {
    @include s360.font-size-ms(1);
  }

  &__body {
    font-size: s360.rem(16);
  }

  // -------------------------
  // Modifiers
  // -------------------------

  &--featured {
    // Modifier override styles
  }

  &--horizontal {
    // Structural modifier

    .card__image {
      // When structure changes significantly, reference the child directly
    }
  }
}
```

### The `&` operator rules

- `&__element` → compiles to `.block__element` ✓
- `&--modifier` → compiles to `.block--modifier` ✓
- `& + &` → adjacent sibling selectors ✓
- Avoid deep nesting: max 3 levels, max 2 `&` concatenations per chain
- NEVER: `.card { .title {} }` (descendant, not BEM)

---

## State Classes

For JavaScript-driven or Drupal-context states, use a `is-` prefix class alongside BEM:

```html
<div class="card card--featured is-active">
```

```scss
.card {
  &.is-active {
    // State applied by JS/Drupal
  }
}
```

---

## Anti-Patterns to Avoid

| Anti-pattern | Problem | Instead |
|---|---|---|
| `.card .title` | Descendant selector — not BEM | `.card__title` |
| `.featured-card` | Block name encodes modifier | `.card.card--featured` |
| `.card__body__text` | Element of element | `.card__text` (element of block) |
| `.mt-4`, `.text-center`, `.flex` | Utility classes — banned | Use toolkit functions in SCSS |
| `@import` in SCSS | Deprecated — BANNED | `@use` only |
| Inline styles in Twig | Bypasses SCSS layer | Add modifier class, style in SCSS |

---

## Drupal-specific Considerations

**Drupal adds wrapper classes you can't always control.** Work with them:

```scss
// Paragraphs wrapper
.paragraph--type--my-paragraph {
  // Target Drupal's generated class as the block
}

// Or rename via preprocess if you control the template:
// $variables['attributes']['class'][] = 'my-paragraph';
```

**Views result wrappers:**
```scss
.view-my-view {
  &__header {}
  &__row {}
  &__empty {}
  &__pager {}
}
```

---

## Naming Quick Reference

```
Component: "Event Card"
Block:     .event-card
Elements:  .event-card__image
           .event-card__date
           .event-card__title
           .event-card__excerpt
           .event-card__cta
Modifiers: .event-card--featured
           .event-card--compact
           .event-card__cta--secondary
```
