본문 바로가기

웹 개발/Frontend

CSS) BEM convention의 개념과 사용시 유의사항

BEM convention 이란,

CSS 방법론 중 하나로 지금 내가 팀에서 사용하고 있는 방법이다. 

BEM은 Block-Element-Modifier의 약자로 id나 class 명을 작성할 때 사용하는 규칙이다. B.E.M은 언더바 두개 (_ _)로 연결하여 표현한다. 

Block을 의미하는 이름_ _Element를 의미하는 이름--Modfier를 의미하는 이름

block, element, modifier은 다음을 의미한다. 

BEM Naming convention

  • 소문자, 숫자만을 사용한다. 
  • 단어 여러개를 조합하는 경우에는 하이픈(-)으로 연결한다. 

Block

  • 재사용 가능한 독립적인 HTML 컴포넌트를 의미한다. 
  • 형태가 아닌 목적에 맞게 결정한다. 예를 들어 red, active 등의 상태가 아닌 menu, button 등의 컴포넌트 사용 목적을 의미해야 한다. 
  • 블록은 여백이나 위치 등의 영향을 받지 않는 독립적인 요소이다. 태그, id 선택자를 사용하면 안된다. 

Element

  • 블록 내 특정 기능을 담당하는 부분을 의미한다. 예를 들어 button이라는 블럭 내에 텍스트를 button_ _text 라고 표현할 수 있다. 
  • Element 역시 형태가 아닌 목적에 맞게 결정해야 한다.
  • Element는 블록의 일부분으로만 사용할 수 있고, 다른 Element의 일부분으로는 사용될 수 없다. 
  • Block안에 Element는 선택적이다. 없을 수도 있다! button이라는 블럭 하나만 나타내는 클래스명만 존재할 수도 있는 것! 

Modifier

  • Block의 모양, 사이즈, 상태 등을 의미한다. 
  • modifier는 더블 하이픈(- -)으로 연결한다. block_ _element--modifier 이렇게! 
  • modifier에는 두가지 타입이 있다. 
    1. boolean type: disabled와 같이 수식어 사용 여부가 true/false를 의미하는 타입 
    2. key-value type: color-red 와 같이 키 밸류 타입을 하이픈으로 연결해서 표현하는 타입 
  • 수식어는 단독으로 사용할 수 없고, block과 element에 추가하여 사용해야 한다

BEM 컨벤션을 제대로 숙지하지 않고 얼추.. 비슷하게 흉내만 내고 있었던 것 같아서 반성하게 된다.. 이제 제대로 사용해야 겠다. 추가로 사소님이 참고하라고 보내주신 참고 자료 'BEM을 사용하면서 자주 하는 실수'에 대한 포스트를 읽고 정리해보았다. 

 

 

Four most common mistakes

1. Block과 Element의 잘못된 중첩 관계

블럭을 중첩하여 사용할 수 없다. 하나의 block 내부에 다른 block class를 사용하거나 다른 block의 element를 사용할 수 없다. 

❌ Wrong

<article class="card">
    <header class="header">
        <h2 class="card__headline"></h2>
    </header>
</article>

✅ Correct

<article class="card">
    <header class="card__header">
        <h2 class="card__headline"></h2>
    </header>
</article>

 

2. 증손자(..?) Element 사용

 block 내부에 사용되는 Element 내부에 또 Element를 사용한다고 해서 2depth Element로 표현하지 않는다. 내가 하던 실수가 바로 이것이었다.ㅠㅠ 요소 내부에 있으니까 당연히 요소 내부 요소로 정의해야 한다고 착각했다ㅠㅠ

card라는 block 내부에 header라는 element 내부에 headline이라는 element를 사용했다면 아래와 같이 card__header__headline이라고 표현하면 안되고 card__headline이라고 해야 한다. 

❌ Wrong

<article class="card">
    <header class="card__header">
        <h2 class="card__header__headline"></h2>
    </header>
</article>
 

✅ Correct

<article class="card">
    <header class="card__header">
        <h2 class="card__headline"></h2>
    </header>
</article>

3. 베이스 클래스 없는 Modifier 사용 

수식어는 block이나 element 요소 없이 사용할 수 없다. 

❌ Wrong

<article class="card--highlight">
    <header class="card__header"></header>
</article>
 

✅ Correct

<article class="card card--highlight">
    <header class="card__header"></header>
</article>

 

4. 너무 큰 block 

하나의 블럭 내에 너무 많은 Element가 들어간다면 그 block의 범위가 너무 크다고 의심해봐야 한다. 하나의 블럭의 규모를 잘 산정해야 한다. 

❌ Wrong

<body class="body">
    <header class="body__header"></header>
    <main class="body__main"></main>
    <footer class="body__footer"></footer>
</body>
 

✅ Correct

<body class="body">
    <header class="header"></header>
    <main class="main"></main>
    <footer class="footer"></footer>
</body>

 

 


References