[CSS] BEM - CSS : 선택자
✏️ BEM을 익히기 위해BEM Methology 사이트를 번역하며 학습/정리 한 내용입니다.
tag 선택자나 ID 선택자를 사용하지 않습니다. 블록과 엘리먼트의 스타일은 class 선택자로 스타일링합니다.
Class 선택자
클래스 선택자는 모든 HTML 엘리먼트에 정의되어있습니다. class 속성은
<header class="header"> <!-- `header__button` — block element `header`; `button` — block; `button_theme_islands` — modifier. --> <button class="header__button button button_theme_islands">...</button> </header>
tag와 class를 결합한 선택자
BEM 방법론은 선택자에 tag와 class를 결합하는것을 권장하지 않습니다 (예를들어 button.button) 이는 CSS 명시도를 올려 재정의가 더욱 어렵게 만듭니다.
HTML:
<button class="button">...</button>
button.button 선택자에 CSS를 정의한경우 button_active 모디파이어를 클래스 선택자로 재정의했을 때 제대로 동작하지 않습니다. button.button_active 와 같이 작성해야 명시도가 올라가 제대로 정의되게 됩니다.
아래와 같이 간단한 선택자 사용을 권고합니다.
.button {} .button_active {}
선택자 중첩
BEM 방법론을 사용하면 중첩 선택자를 사용할 수 있지만 최소로 사용하는것을 권장합니다. 선택자의 중첩은 코드 커플링을 증가시키고 재사용을 불가능하게 만듭니다.
유효한 사례
블록의 상태 또는 테마 집합에 상대적인 스타일을 변경해야 한다면 중첩이 적합합니다.
.button_hovered .button__text { text-decoration: underline; } .button_theme_islands .button__text { line-height: 1.5; }
결합 선택자
BEM 방법론은 선택자의 결합을 권장하지 않습니다. .button.button_theme_islands 와 같은 선택자 결합은 CSS의 명시도를 높여 재정의를 어렵게 합니다.
예제:
<button class="button button_theme_islands">...</button>
.button.button_theme_islands 에 CSS 규칙을 정의하고, 버튼에 active 모디파이어를 추가합니다
<button class="button button_theme_islands button_active">...</button>
.button_active 은 .button.button_theme_islands 선택자보다 명시도가 낮기 때문에 CSS 속성을 재정의할 수 없습니다. 재정의를 수월하게 하기 위해 모디파이어의 선택자도 .button 선택자와 결합하여 .button.button_theme_islands 아래에 선언되어야 합니다.
.button.button_theme_islands {} .button.button_active {}
위와 같은 복잡도 증가를 방지하기 위해, 아래와 같이 간단한 선택자를 작성하세요.
.button_active {} .button {}
명명하기
선택자의 이름은 선택자가 나타내는 BEM 엔티티를 명확하게 설명해야합니다.
.button {} .button__icon {} .button__text {} .button_theme_islands {}
우리는 이 선언이 단일 블록을 처리하며 HTML 구현이 아래와 같을거란걸 상상할 수 있습니다.
<button class="button button_theme_islands"> <span class="button__icon"></span> <span class="button__text">...</span> </button>
선택자가 아래와 같다면 HTML 구현을 추측하기가 매우 어려울 것입니다.
.button {} .icon {} .text {} .theme_islands {}
icon, text, theme_islands 라는 이름은 많은 정보를 담지 못하는 이름입니다.
블록, 엘리먼트, 모디파이어 네이밍 규칙은 아래와 같은 장점이 있습니다.
- CSS 선택자의 이름을 가능한 유용하고 명확하게 만들어준다
- 이름이 충돌하는 문제를 해결한다
- 블록이나 엘리먼트에 대한 스타일을 독립적으로 정의한다
예제:
<div class="logo logo_theme_islands"> <img src="URL" alt="logo" class="logo__img"> </div> <!-- `user` block--> <div class="user user_theme_islands"> <img src="URL" alt="user-logo" class="user__img"> ... </div>.logo {} /* CSS class for the `logo` block */ .logo__img {} /* CSS class for the `logo__img` element */ .logo_theme_islands {} /* CSS class for the `logo_theme_islands` modifier */ .user {} /* CSS class for the `user` block */ .user__img {} /* CSS class for the `user__img` element */ .user_theme_islands {} /* CSS class for the `user_theme_islands` modifier */