여러 개발자가 참여하는 대규모 프로젝트를 진행하면 기술보다 더 중요한 문제에 부딪힙니다. 바로 ‘CSS 클래스 이름을 어떻게 지을 것인가?’ 하는 문제입니다.
card, list, title, button… 이런 클래스 이름들은 다른 곳에서 중복될 위험이 크고, 이름만 봐서는 구조를 파악하기 어렵습니다. 결국 스타일이 꼬이고 덮어쓰기가 반복되는 ‘CSS 지옥’을 경험하게 됩니다. 😱
BEM은 이런 혼란을 막기 위해 탄생한, 클래스 이름을 짓는 매우 유명하고 직관적인 **방법론(Methodology)**입니다. BEM은 클래스 이름에 명확한 구조를 부여하여, CSS를 예측 가능하고, 재사용하기 쉽고, 확장성 있게 만들어 줍니다.
BEM의 세 가지 구성 요소
BEM은 **Block(블록), Element(요소), Modifier(수정자)**의 약자이며, 클래스 이름은 이 세 가지를 조합하여 만듭니다.
block__element--modifier
1. B – Block (블록)
블록은 재사용이 가능한 기능적으로 독립적인 페이지 컴포넌트를 의미합니다. 블록은 그 자체로 의미가 있어야 합니다.
- 특징: 독립적이고, 재사용이 가능합니다.
- 예시:
.header,.menu,.card,.search-form,.button - 작명 규칙: 컴포넌트의 목적을 나타내는 한 단어. (
class="card")
비유 🧱: 블록은 하나의 독립된 ‘레고 블록’입니다.
.button이라는 레고 블록은 어디에 가져다 놓아도 버튼의 역할을 합니다.
2. E – Element (요소)
요소는 블록의 일부분으로, 스스로는 의미를 갖지 못하는 종속적인 부품입니다.
- 특징: 블록에 종속적이며, 블록 없이는 단독으로 사용할 수 없습니다.
- 예시:
.card의 제목인.card__title,.menu의 항목인.menu__item - 작명 규칙:
블록이름__요소이름(두 개의 언더스코어__로 연결)
비유: 요소는 레고 블록의 ‘돌기’ 부분과 같습니다. 돌기 자체만으로는 아무 의미가 없으며, 레고 블록에 붙어있을 때 비로소 제 역할을 합니다.
.card__title은.card안에서만 의미가 있습니다.
중요: 요소는 다른 요소에 중첩될 수 없습니다. card__header__title은 잘못된 방식입니다. 항상 block__element 형태를 유지해야 하므로 card__title로 작성합니다.
3. M – Modifier (수정자)
수정자는 블록이나 요소의 모양, 상태, 행동이 달라질 때 사용합니다.
- 특징: 외형(색상, 크기)이나 상태(활성화, 비활성화)의 변화를 표현합니다.
- 예시:
- 블록 수정:
.button--primary,.card--dark - 요소 수정:
.menu__item--active
- 블록 수정:
- 작명 규칙:
블록(또는 요소)이름--수정자이름(두 개의 하이픈--으로 연결)
비유: 수정자는 레고 블록의 ‘색상’이나 ‘크기’와 같습니다. ‘파란색 버튼’은 여전히 버튼(블록)이지만, 색상(수정자)만 다른 버전입니다.
BEM 실전 예제
BEM 규칙을 적용한 카드 컴포넌트의 예시입니다.
HTML:
<div class="card card--dark">
<img class="card__image" src="image.jpg" alt="Card Image">
<h3 class="card__title">BEM은 강력하다</h3>
<p class="card__text">클래스 이름만 봐도 구조를 알 수 있습니다.</p>
<a href="#" class="button button--primary">더 알아보기</a>
</div>
SCSS (BEM과 궁합이 좋습니다):
.card {
border: 1px solid #ccc;
border-radius: 8px;
&__image {
width: 100%;
height: auto;
}
&__title {
font-size: 1.5rem;
margin: 10px;
}
&__text {
margin: 10px;
}
/* --dark 수정자가 붙었을 때의 스타일 */
&--dark {
background-color: #333;
border-color: #555;
.card__title, .card__text { // 수정자 내부의 요소 스타일 변경
color: white;
}
}
}
요약 및 정리
- BEM은 Block(블록), Element(요소), Modifier(수정자) 규칙으로 클래스 이름을 짓는 CSS 방법론입니다.
block__element--modifier라는 명확한 구조를 통해 클래스 이름만으로도 컴포넌트의 구조와 역할, 상태를 예측할 수 있습니다.- 클래스 이름의 충돌을 방지하고, CSS의 재사용성과 유지보수성을 크게 향상시켜 여러 개발자와의 협업에 매우 효과적입니다.
SCSS가 CSS를 작성하는 ‘문법’을 업그레이드했다면, BEM은 CSS를 관리하는 ‘규칙’을 제공합니다