큰 꿈은 파편이 크다!!⚡️

BEM: CSS 네이밍 방법론 본문

Web FE

BEM: CSS 네이밍 방법론

wood.forest 2022. 8. 6. 21:38

책 "클린 코드"에서는 의미 있는 이름을 지어야 하는 이유와 이름을 의미있게 짓는 방법에 대해 한 챕터에 걸쳐 설명하고 있다. 입사하거나 팀 단위 프로젝트를 할 때에도 네이밍 컨벤션을 정해서 따라야 하는 만큼, 이름을 잘 짓고 바르게 이용하는 것은 소프트웨어 개발과 협업에 있어 중요한 요소이며, CSS를 작성할 때에도 예외가 아니다. 올바른 코드 스타일을 적용하면 유지보수하기 쉬운 코드가 되며, 이는 개발 과정의 효율성을 높여준다.

CSS 네이밍 방법론 중에서 가장 널리 알려진 BEM에 대해 정리하고, 이제부터 배운 내용을 적용해가며 내 기존 코드들의 CSS 네이밍을 리팩토링해보려 한다.🫡

  • BEM (Block, Element, Modifier) 👈
  • SMACSS (Scalable and Modular Architecture for CSS)
  • OOCSS (Object Oriented CSS)
  • SUITCSS (Structured class names and meaningful hyphens)

 

 

 

CSS 클래스 네이밍의 필요성

우리가 CSS를 작성하며 마주하는 고통에는 이런 것들이 있다.

  • 이미 존재하는 클래스 이름을 오버라이딩하므로써 사이드 이펙트 발생
  • 클래스 이름만으로는 스코핑scoping과 오버라이딩을 알기 어려움
  • 새로운 팀원들은 기존에 작성된 클래스에 대해 학습해야함
  • 중첩nesting을 처리하는 방법의 모호성

아래처럼 작성된 CSS는 선호되지 않는다. 다른 페이지에서 사용될 수도 있는 id(title) 설정이라던가, CSS 클래스 이름만 봤을 때 #title.divdiv.a에는 왜 저런 스타일이 들어가야하는지 이해하기 어렵기 때문이다.

#title {
  color: #3498db; 
}
#title.div {
  padding: 10px;
}

div.a {
  text-decoration: none;
}

 

 

 

 

BEM:  Block__Element--Modifier

BEM 방법의 특징

  • id를 사용하지 않는다.
  • 클래스 이름만으로 무엇을 하는지, 다른 클래스들과의 관계가 어떤지 알 수 있다.
  • 클래스명이 길어질 수 있다.

구성요소

BEM 네이밍은 세 가지 요소들을 -(하이픈), _(언더바)로 구분하여 작성한다.

1. 블록 Block

  • 모든 요소를 포함하는 컨테이너로, 스코프를 구분한다. 자체적으로 의미를 지닌 독립적인 Standalone 엔티티이다.
  • 블록은 중첩되거나 상호작용할 수 있지만, 문맥적으로 동등하며 우선순위나 계층이 없다.
  • ex. header, container, menu, checkbox, input

2. 요소 Element 

  • 블록의 일부분으로 독립적이지 않고, 블록에 종속되어 있다.
  • 요소를 체이닝해서 작성하지 않는다. (ex. .shopping-list__item__product-image)
  • ex. menu item,list item, checkbox captionheader title

3. 수정자 Modifier

  • 블록 또는 요소의 플래그, 스타일을 의미한다.
  • 모양, 동작, 상태 등을 바꾸기 위해 사용한다.
  • ex. disabledhighlightedcheckedfixedsize bigcolor yellow

 

 

 

네이밍 방법

블록__요소이름

블록의 이름을 정한 뒤, 내부의 요소는 __으로 이어서 작성한다.

이름을 여러 단어로 설정하는 경우(spacing이 필요한 경우)는 -로 이어서 작성한다. (ex. .head__my-eye)

<div class="head">
  <div class="head__eye">(o)</div>
  <div class="head__eye">(o)</div>
</div>

 

블록__요소이름--수정자

수정자의 이름을 추가할 때에는 기존 컨벤션에서 --로 이어서 작성한다.

 

<div class="head">
  <div class="head__eye head__eye--left">(o)</div>
  <div class="head__eye head__eye--right">(o)</div>
</div>

이를 통해 불필요하게 클래스를 중첩하여 사용할 필요가 없다.

//👍
.head__eye--left {
  color: black;
}

//👎
.head .head__eye .head__eye--left {
  color: black;
}

 

블록--수정자

블록의 이름을 정한 뒤, 수정자는 --으로 이어서 작성하며, 블록 또는 요소의 클래스는 그대로 두고 수정자를 포함한 클래스를 추가한다.

<!-- 👍 -->
<div class="eye eye--open">
  <div class="eye__iris eye__iris--blue">
    (o)
  </div>
</div>

<!-- 👎 -->
<div class="eye--open">
  <div class="eye__iris--blue">
    (o)
  </div>
</div>

 

 

실전 예제

이렇게 생긴 상품 카드를 만들어보자!

 

https://keepinguptodate.com/pages/2020/05/bem-visually-explained/

 

 

상품 사진, 설명 등 상품 내용을 담은 카드는 블록으로 작성한다.

Block

 

 

상품 카드 내부의 사진, 상품명, 가격 등은 요소를 나타낸다.

Element

 

 

마지막으로 상품 요소들에 특별한 스타일을 입히고 싶을 때 수정자를 추가한다.

Modifier

 

 

 

마무리

BEM이라는 방법론을 대강 알고는 있었지만.. 정확하게 몰랐기에 사용하지 않았었고, 이제는 사용해보고자 정리해보았다.

지금까지는 text-alert처럼 내가 알아볼 수 있다고 생각하고 하이픈으로 연결하는 방식을 사용했는데, tailwind같은 유틸리티-퍼스트 방식의 네이밍과 겹치면서 라이브러리의 네이밍인지 내 네이밍인지 알아보기 어려운 지경(...)에 오게되었기도 하고, 이제는 구현 중심이 아니라 유지보수성을 높이는 방향으로 리팩토링하고자 함이 컸다. 이 방식도 체화시켜보자!

 

Reference

- https://www.devbridge.com/articles/implementing-clean-css-bem-method/#:~:text=What%20is%20BEM%3F,by%20following%20some%20simple%20rules.

- https://velog.io/@nemo/bem

- http://getbem.com/naming/

- https://keepinguptodate.com/pages/2020/05/bem-visually-explained/

반응형