CSS 방법론 - BEM

2022. 2. 14. 21:35HTML,CSS

728x90

이번 포스트에서는 CSS 방법론중 하나인 BEM(Block Element Modifier)에 관해서 알아보겠습니다.

 

CSS방법론이라고 하면 뭔가 거창해 보일수도 있지만

그냥 클래스네임을 짓는 여러가지 방법들이라 볼수 있고 BEM은 그 여러 방법중에 자주 채택되는 방법중 하나 입니다.

 

사실 요즘은 클래스 이름을 아예 신경쓰지 않도록 CSS Module이나 Styled Component 등을 더 많이 사용해서 잘 안쓰이긴하지만...

 

아무튼 정해진 표기법이 있다면 팀원들끼리 의사소통을 원활하게 할수 있고 또 유지보수도 더 쉽게 할수 있다는 장점이 있겠죠?

 

만약 다른 프로젝트에 참여하게 된다해도 BEM으로 작성된 코드를보며 어떤 요소들이 어떻게 연결되어있고 작동 하는지 더 쉽게 이해할수도 있습니다.

 

BEM은 Block Element Modifier의 줄임말이며 이 세가지의 단위를 기준으로 클래스 이름을 작성하게됩니다.

 


Block

  • 재사용이 가능한 독립적인 페이지 구성 요소입니다.

한곳에만 쓰일수 있는게 아니고 페이지 어디에서나 쓰일수 있는 컴포넌트 개념이라고 볼수있습니다. 제일 흔히 접할수 있는 블록으로는 header, footer, aside 이런 레이아웃의 기반이 되는 요소들이 있습니다.

 

 

See the Pen Untitled by Min Gee (@minki607) on CodePen

 

여기서 헤더, 왼쪽사이드바, 뉴스기사, 오른쪽사이드바, 푸터 모두다 블록으로 분류할수있습니다.

이뿐만 아니라 헤더같은 블록안에서도 더 많은 블록들이 존재 할수 있습니다.

 

출처: An overview of BEM. Source: Adapted from BEM 2019b

 

 

헤더안에 메뉴 블록이 존재하고 그안에 로고 블록, 검색 블록, 로그인 블록등 수많은 블록들이 함께 존재할수 있습니다.

이 모두 독립적으로 사용될수 있는 컴포넌트이기 때문입니다.

이러한 블록들의 클래스 이름을 짓는 방법은 간단합니다.

 

그냥 그대로 class 이름을 목적에 맞게 소문자와 숫자만을 이용해 결정하면 됩니다. header면 .header, button이면 .btn 만약 하나의 단어로 설명이 되지 않는다면 .related-article 이런식으로 두개의 단어를 hypen(-) 으로 이어 주면 됩니다.

이런 방식은 BEM을 몰랐다 하더라도 자연스럽게 써왔을 것입니다.

 


Element

  • 블록을 구성하는 요소들을 말합니다.

블록은 독립적이지만 element는 의존적이며 자신이 속한 블럭내에서 온전한 의미를 가지기 때문에 element 부분만을 다른곳에서 재사용하는건 불가능합니다.

 

출처: An overview of BEM. Source: Adapted from BEM 2019b

 

이런식으로 .menu 블록안에 4개의 탭 element가 존재할수 있습니다.


표기법은 .menu__tab 이런식으로 block 클래스이름과 element 클래스이름 사이에 두개의 언더스코어 (__)를 써주면 됩니다.

원활한 유지보수를 위해 블록과 앨리먼트 요소에게 css를 입힐때는:

 

  •  클래스 이름 선택자만을 사용할것 (Use class name selector only)

 

.menu__tab{}

 

  • 태그 이름 또는 아이디 선택자는 사용하지말것 (No tag name or ids)
  • 다른 블록/앨리먼트 요소에 의존하는 선택자를 사용하지말것 (No dependency on other blocks/elements on a page
!잘못된 방법
.menu-block .menu__tab{} /*element를 선택할때는 .menu__tab만 쓰기*/

 


Modifier

  • 블록이나 앨리먼트의 형태(appearance), 상태(state)나 행동(behaviour)을 변경하기 위해 사용. Modifier만을 단독적으로 사용할수는 없음.

예를들어 버튼의 모양 또는 비활성 상태를 나타내고자 할때 추가적으로 기입하여 사용할수있음. .form__button--disabled 이런식으로 블록 .form안에 앨리먼트인 .button 다음에modifer인 disabled가 오는식으로 표기할수있음. 또는 .form--color-pink 처럼 블록요소 다음에 바로 쓸수도 있음.

보통 첫번째 방식을 boolean type이라 하고 굳이 -disabled-true로 기입하지않고 뒤에 true를 생략하여 표시하는 방식이다. 두번째 방식은 key-value type 으로 key, value를 하이픈으로 연결하여 표시한 방식이다. (color-pink)

 

마지막으로 위 내용을 모두 적용한 아래의 예제를 살펴보겠습니다.

 

<form class="form form--theme-xmas form--simple">
  <input class="form__input" type="text" />
  <input
    class="form__submit form__submit--disabled"
    type="submit" />
</form>

 

출처: http://getbem.com/naming/

 

form이라는 블록이 두개의 input 앨리먼트를 담고있고 그중 하나의 input 앨리먼트가 disabled이라는 modifier를 갖고있는 구조입니다. form또한 theme-xmas 그리고 simple이라는 modifier가 적용되어있는걸 한눈에 볼수있습니다.

 

이런식으로 다른 사람이 작성한 코드임에도 각 요소들의 역활이나 구조들을 손쉽게 파악할수 있었습니다.

 

 

물론 BEM을 쓰지않았더라도 짧은 예제이기 때문에 이해하는데 큰 어려움은 없었겠지만 좀 더 체계적으로 다가갈수있는 방법임은 확실한것 같습니다.

 

물론 class이름이 필요이상으로 길어져 css 전처리기를 사용하지 않는다면 지저분해질수 있지만 프로젝트 의도나 규모에 맞게 적절히 사용한다면 단점보다는 장점이 더 부각되어 보이는 방법론이라고 생각합니다.