Programming/CSS

BEM 방법론 집중 정리

dayeon.O_O.dev 2022. 5. 3. 20:15

BEM의 기본 구조 및 장점

기본 구조

  • Block(”블록”, 구역), Element(요소), Modifier(”변경자”, 수식어) 컨벤션 사용
  • 각각 --, __로 구분
  • 기본적으로 ID를 사용하지 않으며, 오직 class만을 사용
  • '어떻게 보이느냐'가 아닌 '어떤 목적인가'에 따라 이름 지음
    • 예시
      • 에러 메시지를 띄우는 P 태그에는 .red가 아닌 .error라는 이름
      • block-name과 같이 하이픈 하나만 써서 해결

장점

  • class name 중복을 방지
  • 직관적임
  • 전체 DOM tree 구조를 다시 보지 않아도 됨

Block Element Modifier 각 개념 정리

Block (블록)

: 구성 요소의 가장 바깥쪽 상위 요소를 블록으로 정의

  • 재사용 가능한 기능적으로 독립적인 페이지 컴포넌트 (다른 곳에 여기저기 사용 가능)
  • 문단 전체에 적용된 element 또는 element를 담고 있는 컨테이너
  • (A functionally independent page component that can be reused)

Element (요소)

: 구성 요소 안쪽에는 하나 또는 그 이상의 요소가 있을 수 있음

  • block 안에서 특정 기능을 수행하는 컴포넌트, element는 상황에 따라 달라짐
  • 블럭은 독립적인 반면, 엘리먼트는 의존적인 형태. 자신이 속한 블럭 내에서만 의미를 가짐
  • 블럭 안에서 떼어다 다른 곳에 사용할 수 없음

Modifier (변경자)

: 블록 또는 요소는 변경자를 이용하여 변형을 표시할 수 있음

  • 블럭이나 엘리먼트의 속성을 담당하는 entity(=개체)
  • 블럭 또는 요소의 외관이나 상태를 변화시키는 것
  • 특정 요소의 스타일을 수정할 필요가 있을 때 modifier만 활용하면 됨
  • 요소/블럭 다음 두개의 하이픈을 추가하여 modifier를 표시
  • boolean: modifier의 유무가 중요할 때 사용
  • key-value: modifier 값이 중요할 때 사용

Block 사용을 위한 개념, 가이드라인 및 주의할 점

개념

<form class="search-form">
    <input class="search-form__input"/>
    <button class="search-form__button">Search</button>
</form>
  • 블럭: .search-form
    • 독립적으로 재사용이 가능
  • 엘리먼트: .search-form__input과 .search-form__button
    • 검색을 위한 인풋창이자 버튼, search-form 안에서만 존재 의미가 있음
    • 하위 엘리먼트는 상위 엘리먼트의 네임을 따르지 않고, 오직 블록의 네임을 따름

nesting (중첩)

<form class="search-form">
    <input class="search-form__input"/>
    <button class="search-form__button">Search</button>
</form>
  • Block들은 얼마든지 중첩이 될 수 있으며, 중첩의 레벨은 얼마든지 가질 수 있음
  • Element들 또한 서로 중첩될 수 있음
  • 한 Element는 항상 한 Block의 부분, 이것은 Element의 이름이 계층구조로 선언될 수 없음을 의미
  • BEM에서는 엘리먼트 인식 기준이 다름, “모든 엘리먼트는 블록을 따른다”
    • 예시
      • 엘리먼트 또한 중첩이 가능!
      • .block > .block__element1 > .block__element2
      • 일때, BEM에서는 .block__element1를 .block__element2의 하위 엘리먼트로 보지 않고 둘 다 똑같이 .block의 엘리먼트로 취급
      • 👉🏻 클래스네임에 캐스케이딩을 여러번 표시할 필요가 없음
      <!-- 잘못된 사용 방법 -->
      <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>
      
      <!-- 바르게 사용된 방법, 모든 엘리먼트들은 블록의 이름을 따름 -->
      <form class="search-form">
        <div class="search-form__content">
            <input class="search-form__input"/>
            <button class="search-form__button">Search</button>
        </div>
      </form>
      

Membership

  • 한 element는 항상 한 블록의 부분이어야 하며, 블록으로부터 분리되어 사용될 수 없음

Optionality

  • element는 block component에서 선택사항임
  • (모든 block들이 element들을 가지지 않음)

Modifiers의 타입들

행동, 상태, 외양을 정의한다.

boolean

<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>
  • 위 코드에서 —-focused가 수식어에 해당
  • 불리언 타입. 그 값이 true라고 가정하고 사용
  • modifier의 풀 네임 구조
    • block-name_modifier-name
    • block-name__element-name_modifier-name

key-value

<div class="column">
  <strong class="title">일반 로그인</strong>
  <form class="form-login form-login--theme-normal">
    <input type="text" class="form-login__id"/>
    <input type="password" class="form-login__password"/>
  </form>
</div>
 
<div class="column">
  <strong class="title title--color-gray">VIP 로그인 (준비중)</strong>
  <form class="form-login form-login--theme-special form-login--disabled">
      <input type="text" class="form-login__id"/>
      <input type="password" class="form-login__password"/>
  </form>
</div>
  • color-gray와 theme-normal가 key-value타입에 해당
  • modifier의 풀 네임 구조
    • block-name_modifier-name_modifier-value
    • block-name__element-name_modifier-name_modifier-value
  • 예시
    • islands 디자인 테마를 가진 메뉴 menu_theme_islands

부가적인

MIX

  • 단일 DOM node에서 다른 BEM entity들을 사용하기 위한 기술
  • 아래와 같이 혼합 가능
    • 행동과 다수의 entity들을 코드의 중첩없이 결합
    • 이미 존재하는 UI 컴포넌트를 기반으로 한 의미 상 새로운 UI 컴포넌트를 만들 때
    • 예시
      • search-form block의 스타일과 header block의 search-form element의 스타일을 결합했음
      • 이런 접근은 search-form이 block으로 적용되는 동안 header__search-form element의 위치, margin 설정 가능
      • 결과적으로, padding 값을 정의하지 않았기 때문에 모든 환경에서도 block 사용 가능
    • <div class="header"> <div class="search-form header__search-form"></div> </div>

File Structure

  • BEM 방법론에서 채택된 컴포넌트 접근법은 프로젝트의 파일 구조에도 적용이 가능
  • block, element modifier의 구현은 독립적인 기술 파일들로 분리됨
  • 파일은 유형이 아닌 의미별로 그룹화 됨
  • 이 분리된 파일들을 각각 따로 연결 가능
  • 특성
    • 단일 block은 단일 directory를 가짐
    • block과 directory는 같은 이름을 가짐
    • block들의 구현체는 독립된 기술 파일들로 나뉘어짐
    • block directory는 그 block element들과 modifier들을 위한 subdirectory를 위해 root directory에 있음
    • element directory는 그 block element들과 modifier들을 위한 subdirectory를 위해 root directory에 있음

내용의 오류가 있다면 피드백 남겨주시면 감사드리겠습니다 🙏

'Programming > CSS' 카테고리의 다른 글

SCSS (SASS) 코딩 컨벤션  (0) 2022.06.12
SCSS 문법  (0) 2022.06.12
SCSS 개념 (feat. SASS와 차이점)  (0) 2022.06.12
CSS 방법론  (0) 2022.05.03