--- id: wiki-2026-0508-bem title: BEM category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Block Element Modifier, BEM Methodology] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [css, bem, methodology, naming-convention] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: CSS framework: BEM --- # BEM ## 매 한 줄 > **"매 Block, Element, Modifier 매 명시적 naming"**. BEM은 Yandex가 2009년 도입한 CSS naming methodology — `.block__element--modifier` 형식으로 component scope를 explicit encode하여 specificity war 없이 large CSS codebase를 maintain. 2026 기준 CSS Modules / Tailwind / CSS-in-JS에 밀렸으나 SSR-heavy + design-system context에서 여전히 active. ## 매 핵심 ### 매 3 entity - **Block**: 매 standalone component — `.button`, `.menu`, `.card`. - **Element**: 매 block 내부 part — `.card__title`, `.menu__item`. - **Modifier**: 매 variation/state — `.button--primary`, `.menu__item--active`. ### Naming rule - `.block` - `.block__element` (double underscore) - `.block--modifier` 또는 `.block__element--modifier` (double dash) - 매 hyphen 매 word separator: `.search-form__input--wide`. ### 매 응용 1. Design system component class 명명. 2. CSS Module 없이 SSR 환경 scope 격리. 3. SCSS partial 으로 component file 별 분리. ## 💻 패턴 ### Basic BEM ```html
``` ```css .button { padding: 0.5rem 1rem; } .button--primary { background: #0066cc; color: #fff; } .button--primary:hover { background: #0052a3; } .card { border: 1px solid #ddd; border-radius: 4px; } .card--featured { border-color: gold; } .card__title { font-size: 1.25rem; } .card__body { color: #555; } .card__link--external::after { content: ' ↗'; } ``` ### SCSS with & parent selector ```scss .menu { display: flex; &__item { padding: 0.5rem 1rem; &--active { background: #eee; font-weight: bold; } &:hover { background: #f5f5f5; } } &--vertical { flex-direction: column; } } ``` ### BEM with React (JSX) ```tsx import classNames from 'classnames'; function Button({ variant = 'default', size = 'md', children, disabled }) { const cls = classNames( 'button', `button--${variant}`, `button--${size}`, { 'button--disabled': disabled } ); return ; } ``` ### BEM helper utility ```ts function bem(block: string) { return (element?: string, modifier?: string | string[]) => { const base = element ? `${block}__${element}` : block; if (!modifier) return base; const mods = (Array.isArray(modifier) ? modifier : [modifier]) .filter(Boolean) .map(m => `${base}--${m}`) .join(' '); return `${base} ${mods}`; }; } const card = bem('card'); card(); // 'card' card('title'); // 'card__title' card('title', 'large'); // 'card__title card__title--large' card(undefined, 'featured'); // 'card card--featured' ``` ### Don't nest blocks deeply ```css /* 매 BEM rule: 매 element 의 element 의 X */ /* X */ .card__body__title /* O — 매 flat */ .card__title ``` ### Mix vs nest ```html ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Server-rendered, no build | BEM | | React + build pipeline | CSS Modules / Tailwind | | Design system stable | BEM (predictable) | | Rapid prototyping | Tailwind | | Theme-heavy | CSS-in-JS / vanilla-extract | **기본값**: 2026 신규 프로젝트 — Tailwind / CSS Modules. Legacy / framework-agnostic — BEM. ## 🔗 Graph - 부모: [[CSS 구조 설계 방식]] - 응용: [[Design System]] · [[SCSS (Sass)|SCSS]] - Adjacent: [[CSS Modules]] · [[CSS_Architecture_and_Styling|Tailwind CSS]] ## 🤖 LLM 활용 **언제**: convert legacy CSS to BEM, generate consistent class names, BEM rule lint. **언제 X**: 매 modern utility-first project — Tailwind 가 더 적합. ## ❌ 안티패턴 - **Element 의 element**: `.card__body__title` — flat 으로 변경. - **Modifier 만 사용**: `.large` — must be `.button--large`. - **Block 의 child selector**: `.card .card__title` — flat naming 의 point 의 lost. - **Camel case mix**: `.cardTitle` — 매 BEM 규칙 hyphen. ## 🧪 검증 / 중복 - Verified (Yandex BEM official, getbem.com). - 신뢰도 A. - 매 동일 wiki에 [[BEM|BEM (Block Element Modifier)]] file 존재 — both kept as alias siblings. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — BEM 3 entity + helper pattern 정리 |