Work/HTML, CSS

[CSS] BEM - Key Concept

디쟈이너 2021. 1. 23. 11:31

✏️ BEM을 익히기 위해 BEM Methology 사이트를 번역하며 학습/정리 한 내용입니다.


Block

논리적이고 기능적으로 독립된 페이지 컴포넌트이며 웹 컴포넌트와 동일합니다. 블록은 동작(JavaScript), 템플릿, 스타일(CSS), 기타 구현 기술을 캡슐화합니다. 블록이 독립적일 경우 블록의 재사용은 물론 프로젝트 개발 및 지원 프로세스를 용이하게 할 수 있습니다.

Block 특징

중첩 구조

블록은 다른 블록 내부에 중첩될 수 있습니다.

예를들어 head 블록은 로고(logo), 검색 폼 (search), 권한(auth) 블록을 포함할 수 있습니다.

유연한 배치

블록은 페이지에서 이동하거나 페이지 또는 프로젝트간에 이동이 가능합니다. 블록을 독립적인 엔터티(entities)로 구현하면 페이지의 위치를 변경할 수 있으며 블록의 적절한 기능과 모양을 보장할 수 있습니다.

따라서 블록의 CSS 또는 JavaScript 코드를 수정하지 않고도 로고와 권한 부여 블록을 바꿀 수 있습니다.

재사용

인터페이스는 동일한 블록의 여러 인스턴스를 포함할 수 있습니다.

Element

블록 외부에서 사용할 수 없는 블록의 구성요소입니다.

예를들어, 메뉴 항목은 메뉴 블록의 컨텍스트 외부에서 사용되지 않으므로 엘리먼트입니다.

A block or an element: which one should I create?

Using elements within elements is not recommended by the BEM methodology

Modifier

블록이나 엘리먼트의 모양과 동작을 정의하는 엔티티입니다.

모디파이어는 옵셔널하게 사용됩니다.

모디파이어를 사용하는 동안 같은 블록을 조금 다르게 보여준다는 점에서 HTML의 속성(attributes)과 그 본질이 유사합니다.

예를 들어 menu 블록의 모양은 메뉴 블록에 사용하는 모디파이어에 따라 변경될 수 있습니다.

모디파이어는 런타임(예: 블록의 DOM 이벤트에 대한 대응) 또는 다른 블록을 통해 변경될 수 있습니다.

예를들어, 잘못된 사용자가 로그인 버튼을 클릭 (DOM event)할 때 잘못된 자격 증명을 입력하면 'visible' 한 모디파이어가 오류 메시지와 함꼐 숨겨진 블록에 설정됩니다.

BEM entity

블록, 엘리먼트, 모디파이어를 BEM 엔티티라고 부릅니다.

이 개념은 개별 BEM 도면 요소를 지칭하는 것과 블록, 엘리먼트, 모디파이어의 일반 용어로 사용할 수 있는 개념입니다.

Mix

단일 DOM 노드에서 호스팅되는 서로 다른 BEM 엔티티 스타일입니다.

  • 코드 중복을 방지하면서 여러 BEM 엔티티의 동작과 스타일을 결합합니다
  • 기존 BEM 엔티티를 기반으로 의미론적으로 새 인터페이스를 구성합니다

한 블록과 다른 블록의 한 엘리먼트로 구성된 혼합의 경우룰 고려해봅니다.

링크의 역할을 하는 link라는 블록이 있다고 가정합니다. 우리는 메뉴 항목을 링크로 변경해야합니다. 이 경우 아래와 같은 수행방법이 있을 수 있습니다.

  • 메뉴 항목을 링크로 바꾸는 모디파이어를 만든다. 이러한 모디파이어를 구현하려면 link 블록의 동작과 스타일을 복사해야합니다. 이경우, 코드가 중복됩니다.
  • 일반 link 블록과 menu 블록의 link 엘리먼트를 혼합하여 사용합니다. 두 개의 BEM 엔티티가 혼합되면 코드를 복제하지 않고도 링크 기능을 하는 link 블록과 menu 블록의 추가 CSS 규칙을 사용할 수 있습니다.

BEM tree

블록, 엘리먼트, 모디파이어 측면에서 웹 페이지의 구조를 표현합니다. BEM은 엔티티의 이름, 상태, 순서, 중첩, 보조 데이터를 설명하는 DOM tree의 추상적인 개념입니다.

실제 프로젝트에서 BEM 트리는 트리 구조를 지원하는 모든 형식으로 표현할 수 있습니다.

<header class="header">
    <img class="logo">
    <form class="search-form">
        <input class="input">
        <button class="button"></button>
    </form>
    <ul class="lang-switcher">
        <li class="lang-switcher__item">
            <a class="lang-switcher__link" href="url">en</a>
        </li>
        <li class="lang-switcher__item">
            <a class="lang-switcher__link" href="url">ru</a>
        </li>
    </ul>
</header>

위 DOM tree는 아래의 BEM tree와 일치합니다.

header
    logo
    search-form
        input
        button
    lang-switcher
        lang-switcher__item
            lang-switcher__link
        lang-switcher__item
            lang-switcher__link

XML과 BEMJSON 포맷에서는 아래와 같이 표현됩니다.

<block:header>
    <block:logo/>
    <block:search-form>
        <block:input/>
        <block:button/>
    </block:search-form>
    <block:lang-switcher>
        <elem:item>
            <elem:link/>
        </elem:item>
        <elem:item>
            <elem:link/>
        </elem:item>
    </block:lang-switcher>
</block:header>

{
    block: 'header',
    content : [
        { block : 'logo' },
        {
            block : 'search-form',
            content : [
                { block : 'input' },
                { block : 'button' }
            ]
        },
        {
            block : 'lang-switcher',
            content : [
                {
                    elem : 'item',
                    content : [
                        { elem : 'link' }
                    ]
                },
                {
                    elem : 'item',
                    content : [
                        { elem : 'link' }
                    ]
                }
            ]
        }
    ]
}

Block 구현(implementation)

BEM 엔티티의 측면을 결정하는 다양한 기술들입니다.

  • behavior
  • appearance
  • tests
  • templates
  • documentation
  • description of dependencies
  • additional data (e.g., images).

구현 기술

블록을 구현하기 위해 사용하는 기술들입니다.

  • behavior — JavaScript, CoffeeScript
  • appearance — CSS, Stylus, Sass
  • templates — BEMHTML, BH, Pug, Handlebars, XSL
  • documentation — Markdown, Wiki, XML.
반응형