CSS 방법론(CSS Architecture / Methodologies)에 대해서 아시나요? CSS 방법론은 CSS를 체계적으로 관리하고 유지보수를 쉽게 하기 위한 설계 철학이나 규칙의 모음이라고 할 수 있습니다. 단순히 예쁘게 보이는 걸 넘어서, 정해진 규칙이 대규모 프로젝트에서도 깨지지 않고, 확장 가능하게 만드는 것을 목표로 합니다. 오늘은 여러 가지 CSS 방법론 중에서 BEM 방식에 대해 알아보도록 하겠습니다.
BEM 방식이란?
BEM은 Block, Element, Modifier의 줄임말로, CSS 클래스명을 구조적이고 일관성 있게 짓기 위한 네이밍 방법론입니다. 특히 유지보수와 협업이 중요한 대규모 프로젝트에서 특히 빛을 발하는 CSS를 더욱 체계적으로 관리할 수 있도록 도와줍니다.
구성요소 | 요소 설명 | 예시 | |
Block | 독립적인 UI 구성 단위 | card, form, header | |
Element Block | 내부의 구성 요소 | card__title, form__input | |
Modifier Block | Block이나 Element의 변형/상태 | card--highlighted, form__input--error |
BEM 방식은 Block, Element, Modifier 이렇게 3가지 구성요소를 가지고 있는데요. 하나씩 살펴보도록 하죠.
Block(블록)
Block은 독립적으로 존재할 수 있는 UI의 가장 큰 구성 단위입니다. 예를 들어 버튼, 카드, 네비게이션 바처럼 하나의 덩어리를 의미합니다. 클래스명은 보통 단어 하나로 구성되며 예를 들자면
- .button
- .card
- .header
이런 식으로 네이밍 지어 사용하게 됩니다. 이러한 Block은 외부에 영향을 받지 않고, 내부 구조를 가지며 독립적으로 재사용 가능합니다. 한마디로 정의하자면 Block은 BEM 구조에서 "기본이 되는 중심 단위" 라고 생각하시면 되겠습니다.
Element (엘리먼트)
block__element
Element는 Block 내부에 있는 세부 구성 요소를 의미합니다. 단독으로는 사용할 수 없고 반드시 Block과 함께 사용해야 하며, Block과의 관계를 드러내기 위해 Block__Element 이런식으로 네이밍을 해야 합니다. 예를 들자면
- .card__title
- .menu__item
- .form__label
이런 식으로 사용합니다. 위와 같이 네이밍 하면 각각 card, menu, form Block의 구성 요소로써 사용되는군요. 이렇게 Element는 독립적으로 사용되지 않으며, __(언더바 2개)를 통해 Block 뒤에 붙습니다. 기능적으로는 Block의 일부 역할을 수행하거나, 시각적 요소를 구성합니다. 즉, Block을 구성하는 필수적이고 종속적인 자식 요소라고 생각하시면 이해가 편할 듯합니다.
Modifier (모디파이어)
block__element--modifier
block--modifier
Modifier는 Block 또는 Element의 상태나 버전을 표현할 때 사용됩니다. 작성법은 --(하이픈 2개) Block--Modifier 또는 Block__Element--Modifier 이러한 형태로 작성합니다. 예를 들자면
- .button--primary
- .menu__item--active
- .card__image--rounded
이런 식으로 Block이나 Block + Element의 조합 뒤에 --하이픈 2개를 붙여서 작성하면 됩니다. Modifier는 요소의 색상, 크기, 강조 여부, 활성화 상태 등을 다르게 적용할 수 있게 하는데요. Block이나 Element에 여러 Modifier를 조합하여 다양한 UI 변형을 만들 수 있습니다. 즉, Modifier는 스타일과 기능의 유연한 확장을 가능하게 해주는 수단이라고 보시면 되겠습니다.
BEM 방식 사용 예시
단일 BLOCK
<header class="header"> ... </header>
<footer class="footer"> ... </footer>
<button class="button">클릭</button>
Block + Element
<article class="card">
<h2 class="card__title">제목입니다</h2>
<p class="card__description">설명 내용입니다</p>
</article>
<nav class="menu">
<ul>
<li class="menu__item">홈</li>
<li class="menu__item">소개</li>
</ul>
</nav>
Block + Modifier
<button class="button button--primary">확인</button>
<button class="button button--secondary">취소</button>
<div class="card card--highlighted">중요 카드</div>
<nav class="menu menu--horizontal">
<div class="menu__item">A</div>
<div class="menu__item">B</div>
</nav>
Block + Element + Modifier
<article class="card">
<h2 class="card__title card__title--large">큰 제목</h2>
</article>
<ul class="menu">
<li class="menu__item menu__item--active">현재 선택됨</li>
<li class="menu__item">비활성</li>
</ul>
<form class="input">
<input type="text" class="input__field input__field--error" />
</form>
Element 내 상태 표현 (접근성/상호작용 중심)
<div class="tab">
<button class="tab__button tab__button--disabled" disabled>비활성 탭</button>
<button class="tab__button">활성 탭</button>
</div>
<aside class="sidebar">
<section class="sidebar__section sidebar__section--collapsed">
접힌 사이드바
</section>
</aside>
<form class="form">
<input type="text" class="form__input form__input--focused" />
</form>
구조 | 예시 | 클래스 의미 |
Block | .button | 독립 컴포넌트 |
Block + Element | .card__title | 구성 요소 |
Block + Modifier | .button--primary | 상태/버전 |
Block + Element + Modifier | .card__title--large | 구성 요소의 상태 |
상태 중심 Modifier | .tab__button--disabled | 접근성·상호작용 중심 상태 |
네이밍 조합 예시
- form__input--error : 입력 오류
- nav__item--active : 현재 선택된 메뉴
- card__image--rounded : 둥근 테두리 이미지
- dropdown--open : 열려 있는 상태
- button--loading : 로딩 중
- toolbar--visible : 툴 바 보이는 중
- avatar--sm, avatar--lg : 크기별 아바타
BEM 방식을 사용했을 때의 장점
구조가 명확한 클래스 네이밍
BEM은 클래스 이름만 봐도 어떤 구성 요소에 속해 있는지 바로 이해할 수 있도록 설계됩니다.
예를 들어 card__title이라는 클래스는 card라는 블록 안에 있는 title 요소임을 바로 알 수 있습니다.
독립적이고 모듈화 된 설계
BEM은 하나의 Block이 독립적으로 동작하도록 구성합니다. 다른 Block과 충돌 없이 재사용이 가능하기 때문에, 규모가 커지더라도 구조가 무너지지 않습니다.
다양한 상태 표현에 용이
Modifier를 활용하면 요소의 상태나 버전을 클래스로 쉽게 표현할 수 있습니다.
- button--primary (주 버튼)
- .menu__item--active (선택된 메뉴)
이처럼 클래스 이름만으로 스타일 상태를 명확하게 구분할 수 있습니다.
협업에 유리한 방식
BEM은 규칙이 일관되고 명확하기 때문에 팀원 간 코드 해석이 쉬워지고, 클래스 충돌도 최소화됩니다. title, box 같은 애매한 클래스명을 줄이고, 의미 있는 이름을 사용할 수 있습니다.
스타일 계층 구조가 명확
BEM은 Block > Element > Modifier 구조를 따르므로 어떤 스타일이 어디에 적용되는지 쉽게 파악할 수 있습니다. 특정 구성 요소만 스타일을 바꾸고 싶을 때도 범위를 좁혀서 수정할 수 있어 효율적입니다.
자바스크립트와의 연동이 쉬움
JS를 통해 상태를 변경할 때 Modifier 클래스를 활용하면 매우 간단하게 처리할 수 있습니다.
modal.classList.add('modal--open');
이처럼 상태에 따라 클래스를 추가하거나 제거하는 작업이 직관적으로 이루어집니다.
그 외 특징들
- 어떤 프레임워크(React, Vue 등)에서도 쉽게 적용할 수 있습니다.
- 태그에 의존하지 않고 클래스 이름으로 구조를 설계할 수 있습니다.
- 클래스가 하나의 역할만 담당하도록 구성되기 때문에 유지보수가 편리합니다.
'Web > HTML, CSS' 카테고리의 다른 글
[HTML] p 태그 줄바꿈(개행) 적용 안될 때 해결법 (1) | 2024.01.31 |
---|---|
[CSS] position : sticky 속성 - 요소를 스크롤에 따라오게 만들기 (0) | 2023.07.15 |
[CSS] position : fixed 속성 - 특정 위치에 요소 고정시키기 (0) | 2023.07.12 |
[CSS] position 속성 - HTML 요소 위치 제어하기 (0) | 2023.07.11 |