[CSS/SCSS] BEM 방식

SUYA·2025년 6월 18일

📘 CSS/SCSS

목록 보기
2/3
post-thumbnail

프로젝트 규모가 커지면, 클래스 네이밍이 점점 복잡해지고, 스타일 충돌이나 유지보수의 어려움도 생긴다.
컴포넌트 중심으로 구조를 설계하면서 SCSS를 함께 사용하기 시작했고, 효율적으로 관리하기 위해 BEM 방식에 따라 클래스 이름을 짓기 시작했다. (물론, 클래스 이름이 길어지면 살짝 번거로운 듯 하지만. . 😅)

BEM 방식 작성은 구조의 일관성과 재사용성으로 인해 관리가 훨씬 쉬워진다!


✅ BEM이란?

BEM은 CSS 방법론 중 하나로, Block, Element, Modifier를 뜻한다.

독립적인 컴포넌트 Block과 그 블럭을 구성하는 Element, 그리고 블럭이나 앨리먼트 속성을 담당하는 Modifier. BEM 방식은 HTML 요소들을 이 세 가지로 분류해서 클래스 이름을 짓는 방법을 말한다.

🌠 BEM 방식 규칙

  • BEM은 기본적으로 ID를 사용하지 않으며, class만을 사용한다.
  • '어떻게 보이는가'가 아닌, '어떤 목적인가'에 따라 이름을 짓는다.
    예를 들어, 어떤 에러 메시지를 띄우는 태그에 .red가 아닌 .error라는 목적에 맞는 이름을 지어줘야한다.
  • 이름을 연결할때는 - 하이픈 하나만 써서 연결한다.



Block

BEM의 첫번째 구성 요소 Block.
블럭은 독립적인 기능이나 역할을 가지는 요소를 말한다.
쉽게 말하면, 어딘가에 종속되지 않아서 여기저기 재사용이 가능한 단위를 말한다.

블럭 요소는 블럭을 감쌀 수 있다.

🌠 Block 요소: .header, .nav

<header class="header">
	<nav class="nav">
    ...
   	<nav>
</header>

예시로, Search UI 컴포넌트를 가지고 자세히 설명해보겠다.

🌠 Block 요소: .search-form

<form class="search-form"></form>



Element

엘리먼트는 블럭 내부에 속한 요소로, 블럭의 일부를 구성한다.
블럭이 독립적인 형태라면, 엘리먼트는 의존적인 형태이다. 자신이 속한 블럭 안에서만 의미를 가지기 때문에 블럭 밖으로 꺼내서 다른데 쓸 수 없다.

클래스 네이밍은 __로 구분 짓는다.

위에서 설명한 .search-form은 어느 곳에다가 재사용해도 되지만,
내부의 inputbutton.search-form을 위한 인풋 창이자 버튼이기 때문에, .search-form에 종속되어야만 의미가 있는 것이다.

🌠 Element 요소: .search-form__input, .search-form__button

<form class="search-form">
	<input class="search-form__input" />
	<button class="search-form__button">Search</button>
</form>

또한, 블럭 요소처럼 엘리먼트도 중첩 사용 가능하다.

🌠 Element 요소: .search-form__content, .search-form__input, .search-form__button

<form class="search-form">
  <div class="search-form__content">
    <input class="search-form__input search-form__input--focused" />
    <button class="search-form__button">Search</button>
  </div>
</form>



Modifier

모디파이어는 엘리먼트나 블럭의 스타일, 기능을 수정하거나 변형하는 데 사용된다.
클래스 네이밍은 --로 구분 짓는다.

--focused가 수식어에 해당한다.
이런식으로 작성된 걸 불리언(boolean) 타입이라고 하는데, 그 값이 true라고 가정하고 사용한다.

🌠 Modifier 요소: .tab__item--focused

<ul class="tab">
    <li class="tab__item tab__item--focused"></li>
    <li class="tab__item">탭 02</li>
    <li class="tab__item">탭 03</li>
</ul>

그리고, 키-밸류(key-value) 타입도 있다. 이건 하이픈으로 성질-내용을 작성한다.
🌠 Modifier 요소: .form-login--theme-normal

  <form class="form-login form-login--theme-normal">
    <input type="text" class="form-login__id"/>
    <input type="password" class="form-login__password"/>
  </form>



✅ 스타일링

BEM 방식으로 마크업 구조를 작성하고 SCSS를 사용해 스타일링하면 길게 늘어지는 셀렉팅을 막아주고, 컴포넌트 요소를 쉽게 찾을 수 있다.

<form class="search-form">
  <div class="search-form__content">
    <input class="search-form__input search-form__input--focused" />
    <button class="search-form__button">Search</button>
  </div>
</form>
// css
.search-form{}
.search-form .search-form__content{}
.search-form .search-form__input{}
.search-form .search-form__input--focused{}
.search-form .search-form__button{}

// scss
.search-form {
  &__input {
    &--focused {
    }
  }
  &__button {
  }
}



✅ 장점

클래스 구조가 명확하다

요소의 역할과 위치, 상태를 클래스 이름만 보고도 파악할 수 있다.

<nav class="header__nav--active"><nav>

CSS의 재사용성과 유지보수가 좋아진다

BEM은 각각의 요소와 상태를 독립적인 클래스 형태로 분리하기 때문에, 불필요한 중첩 없이 필요한 스타일만 적용할 수 있다.

전역 네임스페이스 충돌을 줄일 수 있다

BEM은 block을 중심으로 네임스페이스를 구분하므로, 클래스 이름 충돌 가능성을 줄여준다.



✅ 단점

클래스 이름이 길어진다

BEM방식은 역할과 계층을 명확하게 표현할 수 있다는 장점이 있지만, 반대로 클래스 이름이 길어지고 반복적으로 사용되는 경우가 많다. HTML 코드의 양이 많아지고 코드 가독성이 떨어질 수 있다는 단점이 있다.

<div class="card__title--highlighted"></div>

복잡한 UI에서는 구조가 오히려 부담이 될 수 있다

컴포넌트가 복잡해지고 중첩 구조나 다양한 상태를 표현해야 할 경우, BEM 클래스 조합이 지나치게 복잡해질 수 있다.

초반 러닝 커브가 있다

규칙이 명확한 대신, 초반에는 익숙해지는 데 시간이 필요하다.


참고자료

https://getbem.com/introduction/
https://nykim.work/15

profile
기술 블로그

0개의 댓글