BEM 방법론 - CSS 클래스 네이밍


BEM(Block Element Modifier)은 CSS 클래스 이름을 체계적으로 작성하는 방법론입니다. 대규모 프로젝트에서 일관성 있고 재사용 가능한 컴포넌트를 만드는 데 도움이 됩니다.



언제 사용하나요?



  • 팀 프로젝트에서 일관된 네이밍 규칙 필요 시

  • 컴포넌트 기반 개발

  • CSS 충돌 방지가 필요한 경우

  • 유지보수가 쉬운 스타일시트 작성



BEM 구조


Block__Element--Modifier

Block: 독립적으로 의미 있는 컴포넌트
Element: Block의 구성 요소 (__)
Modifier: 상태나 변형 (--)


기본 예시


<!-- Block -->
<nav class="menu">
<!-- Element -->
<ul class="menu__list">
<li class="menu__item">
<!-- Element with Modifier -->
<a class="menu__link menu__link--active">홈</a>
</li>
<li class="menu__item">
<a class="menu__link">소개</a>
</li>
</ul>
</nav>

<!-- CSS -->
<style>
.menu { }
.menu__list { }
.menu__item { }
.menu__link { }
.menu__link--active { }
</style>


카드 컴포넌트 예시


<!-- HTML -->
<article class="card card--featured">
<img class="card__image" src="...">
<div class="card__content">
<h2 class="card__title">제목</h2>
<p class="card__description">설명...</p>
<button class="card__button card__button--primary">
자세히 보기
</button>
</div>
</article>

<!-- CSS -->
.card {
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
}

.card--featured {
border-color: #3498db;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}

.card__image {
width: 100%;
height: 200px;
object-fit: cover;
}

.card__content {
padding: 16px;
}

.card__title {
font-size: 18px;
margin-bottom: 8px;
}

.card__button {
padding: 8px 16px;
border: 1px solid #ccc;
background: white;
}

.card__button--primary {
background: #3498db;
color: white;
border: none;
}


버튼 컴포넌트


<!-- 다양한 버튼 변형 -->
<button class="btn">기본</button>
<button class="btn btn--primary">기본</button>
<button class="btn btn--secondary">보조</button>
<button class="btn btn--large">큰 버튼</button>
<button class="btn btn--primary btn--large">큰 기본</button>
<button class="btn btn--disabled">비활성화</button>

<!-- 아이콘 포함 -->
<button class="btn btn--icon">
<span class="btn__icon">🔍</span>
<span class="btn__text">검색</span>
</button>

.btn { }
.btn--primary { }
.btn--secondary { }
.btn--large { }
.btn--small { }
.btn--disabled { }
.btn__icon { }
.btn__text { }


SCSS와 함께 사용


.card {
border: 1px solid #ddd;

&--featured {
border-color: #3498db;
}

&__image {
width: 100%;
}

&__title {
font-size: 18px;

&--highlight {
color: #e74c3c;
}
}

&__button {
padding: 8px 16px;

&--primary {
background: #3498db;
}
}
}


네이밍 규칙








규칙좋은 예나쁜 예
소문자 사용card__titleCard__Title
하이픈으로 연결search-formsearchForm
의미 있는 이름user-avatarimg-round
중첩 제한card__titlecard__header__title


주의사항



  • Element는 Block에만 속함 (Element의 Element 금지)

  • Block은 독립적으로 사용 가능해야 함

  • Modifier는 단독 사용 불가 (기본 클래스와 함께)

  • 너무 깊은 중첩은 새 Block으로 분리



잘못된 예시


<!-- X 잘못됨: Element의 Element -->
<div class="card__header__title"></div>

<!-- O 올바름: 새 Block으로 분리 -->
<div class="card">
<div class="card-header">
<h2 class="card-header__title"></h2>
</div>
</div>

<!-- X 잘못됨: Modifier 단독 사용 -->
<button class="btn--primary"></button>

<!-- O 올바름: 기본 클래스와 함께 -->
<button class="btn btn--primary"></button>