BEM(Block, Element, Modifier)이란?
BEM (Block, Element, Modifier)은 CSS 코드를 구조화하고 조직화하는 방법론이다. 코드의 유지 보수성, 가독성 및 확장성을 향상시키기 위해 명명 규칙 및 CSS 아키텍처에 대한 모듈식 접근 방식을 제공한다. BEM은 러시아 검색 엔진 회사인 Yandex가 소개했으며, 웹 개발자들 사이에서 인기를 얻었다.
Yandex
Finds everything
yandex.com
BEM 방법론은 세 가지 핵심 구성 요소로 구성된다.
블록(Block)
블록은 독립적이고 재사용 가능하며 논리적으로 독립된 개체로, 사용자 인터페이스(UI)의 의미 있는 부분을 나타낸다. 블록의 예로는 헤더, 푸터, 버튼, 내비게이션 메뉴가 있다. BEM에서 블록은 일반적으로 하이픈으로 구분된 단어 하나 또는 짧은 단어 조합으로 명명된다.
예시: .header, .footer, .button, .nav-menu
요소(Element)
요소는 블록의 일부로서 독립적인 의미가 없고 블록과 의미론적으로 연결되어 있다. 요소는 블록 내에서 특정 기능을 수행하며 블록 외부에서는 사용할 수 없다. BEM에서 요소 이름은 두 개의 밑줄(__)로 구분된 블록 이름과 요소 이름을 결합하여 형성된다.
예시: 블록 .nav-menu가 주어진 경우, 그 안의 요소는 .nav-menu__item 또는 .nav-menu__link라고 명명될 수 있다.
수식어(Modifier)
수식어는 블록 또는 요소의 모양, 상태 또는 동작을 정의하는 속성이다. 수식어는 기본 기능을 변경하지 않고 블록 또는 요소의 변형을 생성하는 데 사용된다. BEM에서 수식어 이름은 블록 또는 요소 이름과 수식어 이름을 두 개의 대시(--)로 구분하여 결합하여 형성된다.
예시: 블록 .button이 주어진 경우, "비활성화" 상태에 대한 수식어는 .button--disabled로 명명될 수 있다. 요소 .nav-menu__item이 주어진 경우, "활성" 상태에 대한 수식어는 .nav-menu__item--active로 명명될 수 있다.
네이밍 규칙
공통
- 소문자, 숫자 만을 조합
- 조합은 -(하이픈)으로 연결하여 작명
/* 잘못된 예 */
.redBox{
color: red;
}
/* 올바른 예 */
.red-box{
color: red;
}
- Naming의 조합은 형태>의미>순서_상태를 기본순서로 사용
/* Naming 조합 잘못된 예 */
cancle_btn_off_01.gif
.msgbox-off-toggle
/* Naming 조합 올바른 예 */
btn_cancle_01_off.gif
.msgbox-toggle-off
- Naming 규칙의 _(언더바) 조합은 파일, 폴더, 이미지에 사용
/* 잘못된 예 */
customerService
/* 올바른 예 */
customer_service
- 1, 2와 같은 한자리 정수는 사용하지 않고 01, 02와 같이 사용을 권장
/* 잘못된 예 */
cyber_center_1, cyber_center_2
/* 올바른 예 */
cyber_center_01, cyber_center_02
Block Name
<div class="menu">...</div>
.menu {
color: red;
}
- Block Name은 해당 Element 및 Modifier에 대한 네임 스페이스를 정의
- 형태(red, big)가 아닌 목적(menu, button)에 맞게 결정해야 함
- 환경에 영향을 받지 않아야 함(여백, 위치 설정 x)
- 태그, id선택자로 사용하면 안됨
- 기본적인 component를 나타냄
Element Name
동일한 블록의 동일한 요소는 동일한 이름을 갖는다. 예를 들어, 메뉴 블록의 모든 메뉴 항목은 menu__item이라고 한다.
<div class="menu">
...
<span class="menu__item"></span>
</div>
.menu__item {
color: red;
}
- Element Name은 __(이중 밑줄)로 Block Name과 구분
- 블록 안에서 특정 기능을 담당하는 부분
- block__element 형태로 사용
- 형태(red,big)가 아닌 목적(item, text, title, list)에 맞게 결정해야 함
- 블록에 종속되어 있어 블록의 부분으로만 사용할 수 있고 다른 요소의 부분으로 사용할 수 없음
- 선택적으로 사용가능해야 함(요소가 없을 수도 있음)
Modifier Name
<div class="menu">
...
<span class="menu__item menu__item_visible menu__item_type_radio"> ... </span>
</div>
.menu__item_visible {
}
.menu__item_type_radio {
}
- Modifier Name은 _(단일 밑줄)로 Block 또는 Element Name과 구분
- Modifier Value는 _(단일 밑줄)로 Modifier Name과 구분
- 시작 이름은 영문 대문자, 숫자, 특수문자로 시작할 수 없음(파일 및 폴더 제외)
- component가 아니라 요소(element)도 수정할 수 있음
- 블록이나 요소의 모양(color, size), 상태(disabled, checked..)를 정의함
BEM 방법론의 장점
모듈성
블록, 요소, 수식어의 명확한 구분은 구성 요소의 재사용성과 교환 가능성을 촉진한다. 이러한 모듈성은 더 빠르고 효율적인 개발과 더 쉬운 유지보수를 가능하게 한다.
가독성
표준화된 명명 규칙으로 인해 개발자들이 코드의 구조와 목적을 한눈에 이해하기 쉬워지므로 새로운 팀원들의 학습 곡선을 줄이고 협업을 단순화한다.
확장성
BEM의 모듈식 접근 방식은 대규모 프로젝트에 적합하며 명명 충돌의 위험을 최소화하고 일관된 코드 구성을 촉진한다.
쉬운 디버깅
BEM의 명확한 명명 구조로 인해 CSS에서 문제를 찾아 해결하기가 더 쉬워진다. 어떤 블록, 요소, 수식어가 문제를 일으키는지 더 쉽게 파악할 수 있기 때문이다.
BEM 방법론으로 작성된 코드 예시
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BEM Example</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header class="header">
<div class="header__logo">MyLogo</div>
<nav class="nav-menu">
<a href="#" class="nav-menu__link">Home</a>
<a href="#" class="nav-menu__link nav-menu__link--active">About</a>
<a href="#" class="nav-menu__link">Services</a>
<a href="#" class="nav-menu__link">Contact</a>
</nav>
</header>
<main class="main-content">
<section class="hero">
<h1 class="hero__title">Welcome to Our Website!</h1>
<p class="hero__subtitle">We provide the best services in the industry.</p>
<button class="button button--primary">Get Started</button>
</section>
</main>
<footer class="footer">
<p class="footer__text">Copyright © 2023 - All rights reserved.</p>
</footer>
</body>
</html>
CSS
/* Blocks */
.header {
background-color: #333;
display: flex;
justify-content: space-between;
padding: 1rem;
}
.nav-menu {
display: flex;
list-style: none;
}
.main-content {
padding: 2rem;
}
.hero {
text-align: center;
}
.footer {
background-color: #333;
color: white;
padding: 1rem;
text-align: center;
}
/* Elements */
.header__logo {
color: white;
font-size: 1.5rem;
}
.nav-menu__link {
color: white;
margin-left: 1rem;
text-decoration: none;
}
.hero__title {
font-size: 3rem;
}
.hero__subtitle {
font-size: 1.5rem;
margin-top: 1rem;
}
.footer__text {
margin: 0;
}
/* Modifiers */
.nav-menu__link--active {
border-bottom: 2px solid white;
}
.button {
background-color: #333;
border: none;
color: white;
cursor: pointer;
font-size: 1rem;
margin-top: 2rem;
padding: 0.5rem 1rem;
}
.button--primary {
background-color: #007bff;
}
Reference
BEM — Introduction
Introduction On smaller brochure sites, how you organize your styles isn’t usually a big concern. You get in there, write some CSS, or maybe even some SASS. You compile it all into a single stylesheet with SASS’s production settings, and then you aggre
getbem.com
BEM 101 | CSS-Tricks
The following is a collaborative post by guest Joe Richardson, Robin Rendle, and a bunch of the CSS-Tricks staff. Joe wanted to do a post about BEM, which we
css-tricks.com
CSS naming methodology(BEM)
✅ Naming Case CSS Naming 방법론을 알아보기 전, 대표적인 Naming Case는 어떤 것들이 있는 지 알아보자 kebab-case(케밥 표기법) kebab-cas
velog.io