BEM 방법론 - CSS naming convention
BEM이란?
블록 내 블록 중첩을 위한 구조로 HTML에서 수행하는 역할에 따라 CSS 클래스의 이름을 지정하는 방법이다.
Block, Element, Modifier로 구성된다.
Block
블록의 기준은 무엇인가?
독립적으로 재사용 가능한 컴포넌트 단위, html 기준으로 특정 기능을 감싼 부분 (wrapper)을 Block으로 이해할 수 있을 것 같다.
ex) nav menu, form wrap 등
Block 정의에 대한 다른 블로그 참조 :
블록에 추가하려는 이 BEM 요소를 웹 사이트의 다른 영역에서 구성 요소로 사용할 수 있습니까?
,재사용 가능한 기능적으로 독립적인 페이지 컴포넌트
Element
Block을 구성하는 단위
ex) ul이 Block이라면 li는 Element
Block 이름 앞에 __
를 붙이고 Element의 이름을 작성한다. ex) .card__image
Modifier
상태나 속성 등이 다른 블록이나 Block이나 Element를 표현할 때 사용
ex) disabled, active
Block이나 Element 이름 앞에 --
를 붙이고 Modifier의 이름을 작성한다. ex) .card__image--active
정리
위 BEM에 대한 설명을 조합해보면 BEM 방법론으로 클래스를 만드는 규칙은 .block__element--modifier
이라고 할 수 있다.
html 작성
기본 구조
위와 같은 Block 구조는 아래와 같은 html 코드로 표현할 수 있다.
1
2
3
4
5
6
<div class="card">
<img class="card__image" />
<h2 class="card__title">I am a card</h2>
<p class="card__description">I am the card paragraph</p>
<a class="card__button">Learn more</a>
</div>
중첩
Block 안에 Block이 있는 경우 내부의 Block은 독립된 컴포넌트이면서 Element이기도 하다.
.btn
이라는 Block을 구성해놨는데, 이 btn이 card라는 Block 안에서도 사용된다면 어떻게 구성해야 할까?
1
2
3
4
5
6
7
<div class="card">
<img class="card__image" />
<h2 class="card__title">I am a card</h2>
<p class="card__description">I am the card paragraph</p>
<!-- The button is now it's own block -->
<a class="btn">Learn more</a>
</div>
위와 같이 .card__
방식을 사용하지 않고 .btn
을 사용하면 독립적인 컴포넌트를 유지하게 된다.
만약 .card
안에서의 .btn
에만 css를 적용하고 싶다면 아래처럼 클래스를 중첩하여 작성하면 된다.
1
2
3
4
5
6
7
<div class="card">
<img class="card__image" />
<h2 class="card__title">I am a card</h2>
<p class="card__description">I am the card paragraph</p>
<!-- The element AND block class is applied to the button -->
<a class="card__button btn">Learn more</a>
</div>
Element의 Element
Block 안의 Element 안에 Element가 또 있는 경우,
1
2
3
4
5
6
<form class="search-form">
<div class="search-form__content">
<input class="search-form__content__input" />
<button class="search-form__content__button">Search</button>
</div>
</form>
위처럼 .Block__Element__Element
형식으로로 작성하지 않고 .Block__Element
로 작성한다.
content, input, button 모두 .search-form
의 동일한 depth의 Element로 보는 것이다.
이 부분은 Element의 depth를 명확히 표현해야 할 때나 개인의 코딩 스타일에 따라 갈릴 것 같다.
1
2
3
4
5
6
<form class="search-form">
<div class="search-form__content">
<input class="search-form__input" />
<button class="search-form__button">Search</button>
</div>
</form>
modified
1
2
3
4
5
<ul class="tab">
<li class="tab__item tab__item--focused">탭 01</li>
<li class="tab__item">탭 02</li>
<li class="tab__item">탭 03</li>
</ul>
css 작성
1
2
3
4
5
6
7
8
9
10
11
12
.menu {
&__item {
&--active {
}
&--disabled {
}
}
&__button {
&--focus {
}
}
}
참고사이트
How To Nest Blocks Within Blocks in BEM
[CSS 방법론] BEM 방식
Boost Your CSS with BEM Naming and SASS Nesting