1주차에 HTML/CSS로 개인 블로그 만들기 과제를 하면서 정말 많은 태그들에 클래스명을 붙여야 했는데요 . .
그때마다 어떤 클래스명으로 이름을 지을지 고민이 되더라고요 !
그래서 어떻게 하면 통일성 있고 의미 있게 네이밍을 할 수 있을지 고민하다가 CSS 방법론을 접하게 되었습니다.
CSS 방법론
CSS를 어떤 방법으로 구성하면 더 효율적으로 구성할 수 있는가에 대한 방법론
저는 여러 방법론 중에서도 직관적인 BEM에 대해 정리하려고 합니다.
BEM (Block Element Modifier)
블록(Block), 요소(Element), 수정자(Modifier)의 세 가지 개념을 사용하여 클래스 네이밍을 작성하는 방법론
중요한 점은 BEM을 사용할 때 ID 셀렉터나 요소 셀렉터를 사용하면 안 됨 🙅🏻♀️
대신 클래스 선택자만 사용하여 스타일을 정의함 🙆🏻♀️
BEM 네이밍 방법
.block__element--modifier의 구조
BEM 구성요소
1. 블록 (Block)
= 재사용할 수 있는 기능적으로 독립적인 페이지 구성요소
(-> BEM은 UI를 독립된 블록으1로 분리함으로써 복잡한 페이지에서도 간단하고 신속하게 개발을 수행하는 것이 목적인 모듈 기반의 방법론임)
- Block 이름은 상태(state)가 아닌 목적(purpose)을 나타냄
- 좋은 ex) menu, header, btn -> 목적
- 나쁜 ex) red, big, left -> 상태
- Block은 환경에 영향을 미치지 않아야 함
- margin이나 position 설정 X
- Block은 서로 중첩 가능함
2. 요소 (Element)
= Block 내부의 부분으로, Block과 별도로 사용할 수 없음
- Element 이름은 상태(state)가 아닌 목적(purpose)을 나타냄
- 명명법 : block-name__element-name
- Element는 서로 중첩 가능함
- 중요한 점은 Element는 Block의 부분이지 다른 Element의 부분이 아님
- ex) 두 번째 방식이 올바른 BEM 접근법
- 아이콘과 텍스트는 menu__item의 하위 요소처럼 보이지만, BEM에서는 모든 Element를 Block에 직접 연결함 -> 이렇게 해야 클래스명이 더 간결해지고, HTML 구조가 변경되어도 클래스명을 유지할 수 있음 !!
- ex) 두 번째 방식이 올바른 BEM 접근법
<!-- 1. 잘못된 네이밍 방식 -->
<ul class="menu">
<li class="menu__item">
<i class="menu__item__icon"></i>
<span class="menu__item__text">메뉴 항목</span>
</li>
</ul>
<!-- 2. 올바른 네이밍 방식 -->
<ul class="menu">
<li class="menu__item">
<i class="menu__icon"></i>
<span class="menu__text">메뉴 항목</span>
</li>
</ul>
<!-- 만약 아이콘과 텍스트가 메뉴 아이템에 특별히 종속되어 있음을 표현하고 싶다면 ?? -->
<!-- 하이픈(-)을 사용하여 연관성을 표현 -->
<ul class="menu">
<li class="menu__item">
<i class="menu__item-icon"></i>
<!-- item-icon이라는 하나의 Element -->
<span class="menu__item-text">메뉴 항목</span>
</li>
</ul>
Block ? Element ?
- 다른 컴포넌트에 의존하지 않고 코드가 재사용 → Block
- 부모 엔티티 없이 구분해서 사용할 수 없다면 → Element
- 더 작은 부분으로 나뉘어져야 하는 Elements → Block이나 Mix로 교체
3. 수정자 (Modifier)
= Block 또는 Element의 모양, 상태, 또는 동작을 정의함
- Modifier 이름은 외관(appearance), 상태(state), 행동(behavior)을 나타냄
- ex) size_big, block_focused, directions_left
- 홀로 사용되지 않으며, 항상 수정할 Block이나 Element에 붙어서 사용됨
Modifier의 유형
- 동일한 유형의 Modifier를 동시에 사용하면 안 됨 !
<!-- 잘못된 예: size에 대한 두 가지 Modifier를 동시에 사용 -->
<button class="button button--size-large button--size-small">버튼</button>
<!-- 올바른 예: 서로 다른 속성에 대한 Modifier는 함께 사용 가능 -->
<button class="button button--size-large button--theme-dark">큰 어두운 버튼</button>
1. Boolean Modifier
- Modifier의 유무만 중요하고 그 값이 무관할 때 사용함
- ex) 버튼이 비활성화 상태인지, 메뉴 항목이 선택되었는지 등
- 명명법 : block-name_modifier-name, block-name__element-name_modifier-name
<button class="button button_disabled">비활성화 버튼</button>
<div class="menu__item menu__item_selected">선택된 메뉴</div>
2. Key-Value Modifier
- Modifier 값이 중요한 경우에 사용함
- ex) 버튼 크기(대/중/소), 테마 색상(빨강/파랑) 등
- 명명법 : block-name_modifier-name_modifier-value, block-name__element-name_modifier-name_modifier-value
<button class="button button_size_large">큰 버튼</button>
<div class="menu__item menu__item_theme_dark">어두운 테마 메뉴</div>
MindBEMding
= Modifier 전후의 구분 문자를 언더바 한 개에서 하이픈 두 개로 변경한 스타일
block-name--modifier-name
<!-- 원래 BEM -->
<button class="button button_disabled">비활성화 버튼</button>
<button class="button button_size_large">큰 버튼</button>
<!-- MindBEMding -->
<button class="button button--disabled">비활성화 버튼</button>
<button class="button button--size-large">큰 버튼</button>
4. Mix
= Block과 Element가 하나의 HTML 요소에 존재하는 것
- 코드 중복을 피하면서 여러 엔티티의 동작과 스타일을 결합할 수 있음
- 기존 BEM 엔티티를 기반으로 의미상 새로운 인터페이스 컴포넌트를 작성할 수 있음
- 가급적 상세도를 높이지 않고 Block의 독립성을 유지할 수 있음
<!-- Mix 예시 -->
<div class="header post__header">
<!-- header라는 독립된 블록이면서 동시에 post의 요소 -->
</div>
BEM 사용 이점
1. 클래스명 고민 시간 감소 : BEM의 명확한 규칙 덕분에 네이밍 과정이 훨씬 체계적이고 빨라짐
2. 구조와 역할의 명확한 파악 : BEM 방식으로 클래스명을 지정하면 HTML과 CSS 사이의 관계가 명확해짐
- ex) .nav-menu__link--active라는 클래스명만 봐도 이것이 네비게이션 메뉴의 링크 중 활성화된 상태임을 바로 알 수 있음
.nav-menu__link--active {
color: #0066cc;
border-bottom: 2px solid #0066cc;
}
3. CSS 충돌 방지 : BEM 방식으로 이름을 지정하면 클래스명이 구체적이고 유일해지기 때문에, CSS 선택자 간의 충돌이 크게 줄어듦 -> 복잡한 레이아웃에서 매우 유용함
4. 재사용성 증가 : 블록 단위로 컴포넌트를 설계하므로 다른 페이지에서도 같은 컴포넌트를 쉽게 재사용할 수 있음
BEM 사용 시 주의할 점
1. 클래스명이 길어지는 문제
- 특히 깊은 중첩 구조에서는 클래스명이 엄청 길어진다 ,,
<!-- 너무 긴 클래스명의 예시 -->
<div class="blog-post__content__image-gallery__item--featured">
- 해결책 : 너무 깊은 중첩을 피하고, 필요하다면 새로운 블록으로 분리하기
- ex) 여기서 image-gallery를 독립적인 블록으로 분리하고, Mix 패턴을 활용하면 더 깔끔한 구조를 만들 수 있음
<!-- 더 나은 접근법 -->
<div class="blog-post__content">
<div class="image-gallery">
<div class="image-gallery__item image-gallery__item--featured">
</div>
</div>
</div>
2. 요소와 블록의 구분
- 어떤 것을 블록으로 정의하고, 어떤 것을 요소로 정의해야 할지 헷갈릴 수 있음
- 해결책 : 재사용 가능성을 기준으로 판단하기 ! 여러 곳에서 독립적으로 사용될 수 있는 컴포넌트라면 블록으로, 특정 블록에 종속된다면 요소로 정의하면 됨
다양한 CSS 방법론이 있으니, 관심 있으신 분들은 아래 참고 자료를 통해 OOCSS, SMACSS 등 다른 방법론들도 함께 알아보세요 ! 모두 파이팅 ☺️
[참고]
https://wit.nts-corp.com/2015/04/16/3538
[CSS방법론] SMACSS, BEM, OOCSS | WIT블로그
세상이 바뀌는 속도보다 약간 더 빠르게 웹은 발전하고 있습니다. 특히 그 중에서도 CSS는 기존에 경험하지 못한 속도로 다양한 부분이 변화하고 있습니다. CSS의 활용도가 높아지고 대규모 프로
wit.nts-corp.com
https://mine-it-record.tistory.com/655
[CSS] CSS 방법론이란? (ft. OOCSS / BEM / SMACSS)
CSS 방법론 CSS 방법론이란 CSS를 어떤 방법으로 구성하면 더 효율적으로 구성할 수 있는가에 대한 방법론이다. 즉, 쉽게 말하면 CSS에서 클래스 네임을 쉽게 정의하기 위한 일종의 규칙이라고 생각
mine-it-record.tistory.com
'1주차' 카테고리의 다른 글
반응형 CSS의 시작 – 미디어 쿼리부터 프리픽스까지 (1) | 2025.04.11 |
---|---|
<template> 태그와 Shadow DOM을 활용한 HTML 구성 분리 (0) | 2025.04.11 |
JS에서 Truthy와 Falsy 그리고 단락평가 (0) | 2025.04.11 |
HTTP/1.1 vs HTTP/2 vs HTTP/3: 개념과 차이점 정리 (0) | 2025.04.11 |
HTML/CSS로 구현하는 반응형 웹의 기본 구조 (0) | 2025.04.11 |