본문 바로가기
1주차

BEM으로 시작하는 CSS 방법론

by kdggspy 2025. 4. 11.

1주차에 HTML/CSS로 개인 블로그 만들기 과제를 하면서 정말 많은 태그들에 클래스명을 붙여야 했는데요 . .

그때마다 어떤 클래스명으로 이름을 지을지 고민이 되더라고요 !

 

그래서 어떻게 하면 통일성 있고 의미 있게 네이밍을 할 수 있을지 고민하다가 CSS 방법론을 접하게 되었습니다.


CSS 방법론

CSS를 어떤 방법으로 구성하면 더 효율적으로 구성할 수 있는가에 대한 방법론

 

 

저는 여러 방법론 중에서도 직관적인 BEM에 대해 정리하려고 합니다.

 

BEM (Block Element Modifier)

블록(Block), 요소(Element), 수정자(Modifier)의 세 가지 개념을 사용하여 클래스 네이밍을 작성하는 방법론

 

중요한 점은 BEM을 사용할 때 ID 셀렉터나 요소 셀렉터를 사용하면 안 됨 🙅🏻‍♀️

대신 클래스 선택자만 사용하여 스타일을 정의함 🙆🏻‍♀️

 

BEM 네이밍 방법

.block__element--modifier의 구조

 

BEM 구성요소

1. 블록 (Block)

= 재사용할 수 있는 기능적으로 독립적인 페이지 구성요소

(-> BEM은 UI를 독립된 블록으1로 분리함으로써 복잡한 페이지에서도 간단하고 신속하게 개발을 수행하는 것이 목적인 모듈 기반의 방법론임)

 

- Block 이름은 상태(state)가 아닌 목적(purpose)을 나타냄

  • 좋은 ex) menu, header, btn -> 목적
  • 나쁜 ex) red, big, left -> 상태

- Block은 환경에 영향을 미치지 않아야 함

  • margin이나 position 설정 X

- Block은 서로 중첩 가능함

 

2. 요소 (Element)

= Block 내부의 부분으로, Block과 별도로 사용할 수 없음

 

- Element 이름은 상태(state)가 아닌 목적(purpose)을 나타냄

- 명명법 : block-name__element-name

- Element는 서로 중첩 가능함

  • 중요한 점은 Element는 Block의 부분이지 다른 Element의 부분이 아님
    • ex) 두 번째 방식이 올바른 BEM 접근법
      • 아이콘과 텍스트는 menu__item의 하위 요소처럼 보이지만, BEM에서는 모든 Element를 Block에 직접 연결함 -> 이렇게 해야 클래스명이 더 간결해지고, HTML 구조가 변경되어도 클래스명을 유지할 수 있음 !!
<!-- 1. 잘못된 네이밍 방식 -->
<ul class="menu">
  <li class="menu__item">
    <i class="menu__item__icon"></i>
    <span class="menu__item__text">메뉴 항목</span>
  </li>
</ul>

<!-- 2. 올바른 네이밍 방식 -->
<ul class="menu">
  <li class="menu__item">
    <i class="menu__icon"></i>
    <span class="menu__text">메뉴 항목</span>
  </li>
</ul>

<!-- 만약 아이콘과 텍스트가 메뉴 아이템에 특별히 종속되어 있음을 표현하고 싶다면 ?? -->
<!-- 하이픈(-)을 사용하여 연관성을 표현 -->
<ul class="menu">
  <li class="menu__item">
    <i class="menu__item-icon"></i>
    <!-- item-icon이라는 하나의 Element -->
    <span class="menu__item-text">메뉴 항목</span>
  </li>
</ul>

 

 

Block ? Element ?

- 다른 컴포넌트에 의존하지 않고 코드가 재사용 → Block
- 부모 엔티티 없이 구분해서 사용할 수 없다면 → Element
- 더 작은 부분으로 나뉘어져야 하는 Elements → Block이나 Mix로 교체

 

3. 수정자 (Modifier)

= Block 또는 Element의 모양, 상태, 또는 동작을 정의함

 

- Modifier 이름은 외관(appearance), 상태(state), 행동(behavior)을 나타냄

  • ex) size_big, block_focused, directions_left

- 홀로 사용되지 않으며, 항상 수정할 Block이나 Element에 붙어서 사용됨

 

Modifier의 유형

  • 동일한 유형의 Modifier를 동시에 사용하면 안 됨 ! 
<!-- 잘못된 예: size에 대한 두 가지 Modifier를 동시에 사용 -->
<button class="button button--size-large button--size-small">버튼</button>

<!-- 올바른 예: 서로 다른 속성에 대한 Modifier는 함께 사용 가능 -->
<button class="button button--size-large button--theme-dark">큰 어두운 버튼</button>

 

1. Boolean Modifier

- Modifier의 유무만 중요하고 그 값이 무관할 때 사용함

- ex) 버튼이 비활성화 상태인지, 메뉴 항목이 선택되었는지 등

- 명명법 : block-name_modifier-name, block-name__element-name_modifier-name

<button class="button button_disabled">비활성화 버튼</button>
<div class="menu__item menu__item_selected">선택된 메뉴</div>

 

2. Key-Value Modifier

- Modifier 값이 중요한 경우에 사용함

- ex) 버튼 크기(대/중/소), 테마 색상(빨강/파랑) 등

- 명명법 : block-name_modifier-name_modifier-value, block-name__element-name_modifier-name_modifier-value

<button class="button button_size_large">큰 버튼</button>
<div class="menu__item menu__item_theme_dark">어두운 테마 메뉴</div>

 

 

MindBEMding

= Modifier 전후의 구분 문자를 언더바 한 개에서 하이픈 두 개로 변경한 스타일

block-name--modifier-name
<!-- 원래 BEM -->
<button class="button button_disabled">비활성화 버튼</button>
<button class="button button_size_large">큰 버튼</button>

<!-- MindBEMding -->
<button class="button button--disabled">비활성화 버튼</button>
<button class="button button--size-large">큰 버튼</button>

 

4. Mix

= Block과 Element가 하나의 HTML 요소에 존재하는 것

 

- 코드 중복을 피하면서 여러 엔티티의 동작과 스타일을 결합할 수 있음

- 기존 BEM 엔티티를 기반으로 의미상 새로운 인터페이스 컴포넌트를 작성할 수 있음

- 가급적 상세도를 높이지 않고 Block의 독립성을 유지할 수 있음

<!-- Mix 예시 -->
<div class="header post__header">
  <!-- header라는 독립된 블록이면서 동시에 post의 요소 -->
</div>

 

BEM 사용 이점

1. 클래스명 고민 시간 감소 : BEM의 명확한 규칙 덕분에 네이밍 과정이 훨씬 체계적이고 빨라짐

 

2. 구조와 역할의 명확한 파악 : BEM 방식으로 클래스명을 지정하면 HTML과 CSS 사이의 관계가 명확해짐

  • ex) .nav-menu__link--active라는 클래스명만 봐도 이것이 네비게이션 메뉴의 링크 중 활성화된 상태임을 바로 알 수 있음
.nav-menu__link--active {
  color: #0066cc;
  border-bottom: 2px solid #0066cc;
}

 

3. CSS 충돌 방지 : BEM 방식으로 이름을 지정하면 클래스명이 구체적이고 유일해지기 때문에, CSS 선택자 간의 충돌이 크게 줄어듦 -> 복잡한 레이아웃에서 매우 유용함

 

4. 재사용성 증가 : 블록 단위로 컴포넌트를 설계하므로 다른 페이지에서도 같은 컴포넌트를 쉽게 재사용할 수 있음

 

BEM 사용 시 주의할 점

1. 클래스명이 길어지는 문제

- 특히 깊은 중첩 구조에서는 클래스명이 엄청 길어진다 ,,

<!-- 너무 긴 클래스명의 예시 -->
<div class="blog-post__content__image-gallery__item--featured">

 

- 해결책 : 너무 깊은 중첩을 피하고, 필요하다면 새로운 블록으로 분리하기

  • ex) 여기서 image-gallery를 독립적인 블록으로 분리하고, Mix 패턴을 활용하면 더 깔끔한 구조를 만들 수 있음
<!-- 더 나은 접근법 -->
<div class="blog-post__content">
  <div class="image-gallery">
    <div class="image-gallery__item image-gallery__item--featured">
    </div>
  </div>
</div>

 

2. 요소와 블록의 구분

- 어떤 것을 블록으로 정의하고, 어떤 것을 요소로 정의해야 할지 헷갈릴 수 있음

- 해결책 : 재사용 가능성을 기준으로 판단하기 ! 여러 곳에서 독립적으로 사용될 수 있는 컴포넌트라면 블록으로, 특정 블록에 종속된다면 요소로 정의하면 됨

 

다양한 CSS 방법론이 있으니, 관심 있으신 분들은 아래 참고 자료를 통해 OOCSS, SMACSS 등 다른 방법론들도 함께 알아보세요 ! 모두 파이팅 ☺️

 

[참고]

https://wit.nts-corp.com/2015/04/16/3538

 

[CSS방법론] SMACSS, BEM, OOCSS | WIT블로그

세상이 바뀌는 속도보다 약간 더 빠르게 웹은 발전하고 있습니다. 특히 그 중에서도 CSS는 기존에 경험하지 못한 속도로 다양한 부분이 변화하고 있습니다. CSS의 활용도가 높아지고 대규모 프로

wit.nts-corp.com

https://mine-it-record.tistory.com/655

 

[CSS] CSS 방법론이란? (ft. OOCSS / BEM / SMACSS)

CSS 방법론 CSS 방법론이란 CSS를 어떤 방법으로 구성하면 더 효율적으로 구성할 수 있는가에 대한 방법론이다. 즉, 쉽게 말하면 CSS에서 클래스 네임을 쉽게 정의하기 위한 일종의 규칙이라고 생각

mine-it-record.tistory.com