[CSS] 방법론 bem 방식

munju·2023년 3월 20일
3
post-thumbnail

이포스트는 예제로 이해하는 BEM, css bem 방식, css방법론-bem방식, bem CHEAT SHEET , [css 방법론-bem방식] 을 참고하여 게시하였습니다.

bem 방식

CSS 방법론은 협업 시 사람마다 다른 코드 구조 및 스타일 정의를 통일 시키고, 코드의 재사용성을 높이며, 유지 보수와 확장에 용이하도록 도움을 주는 여러 가지 방법론을 제시합니다.

bem 방식은 여러 CSS 방법론 중 하나로, 직관적인 규칙을 통해 쉬운 의미 예측을 가능하게 하는 네이밍 기법입니다.

  • BEM은 Block Element Modifier 의 약자입니다. 이 세 가지 요소를 각각 더블 언더바(__)와 더블 하이픈(--) 으로 구분 지어 작성한다.
.nav {}
.nav__list {}
.nav__list--active {}

->bem 방식으로 작성한 코드

.nav {
  &__list {
    &--active {}
  }
}

-> bem 방식은 CSS 전처리기인 SASS SCSS LESS 등에서 일관된 코딩 구조를 만드는데에 효과적이다.

BEM 사용법

-이미지 출처

BEM 의 구조

BEM은 block, Element, Modifier를 뜻한다.
이 세가지로 구성된 이름을 짓는 것. 그리고 각각 __-- 로 구분한다.

.header__navigation--navi-text {
	color:red;
}

위 코드에서 header는 Block, navigation은 Element, navi-text는 Modifier가 된다.

BEM은 기본적으로 ID를 사용하지 않으며, class만을 사용한다.

또 '어떻게 보이는가'가 아니라 '어떤 목적인가'에 따라 이름을 짓는다.
예를 들어, 에러메세지를 띄우는 P 태그에게는 .red가 아닌, .error라는 이름을 줘야한다. 이름을 연결할때는 block-name과 같이 하이픈 하나만 써서 연결한다.

Block / Element /Modifier

1. Block

  • 블럭은 재사용이 가능하고 어딘가에 종속되어 있지 않은, 기능적으로 독립적인 컴포넌트를 뜻합니다.
    --예를들어, Logo블럭은 어딘가에 종속되지 않는다. 헤더에 쓰일 수도 있고, 푸터에 쓰일 수도 있다. 여기저기 붙였다가 떼었다 할 수 있다. 이렇게 재사용할 수 있는 요소를 블럭이라고 한다.
    또 블럭은 블럭을 감쌀 수 있다. .header > .logoheader 라는 블럭 안에 logo라는 블럭이 들어간 형태이다.

  • 블럭은 독립적으로 사용되어야 하기에 여백이나 위치값(margin, position)은 직접적으로 선언하지 않는 것이 좋습니다.

  • 블럭은 서로 중첩이 가능하며, 우선순위 또는 계층 구조가 없습니다. 한 페이지 내 블럭과 엘리먼트에게 의존하지 않습니다.

2. Element

엘리먼트는 블럭을 구성하는 단위로
블럭은 독립적인 형태인 반면, 엘리먼트는 의존적인 형태이다. 자신이 속한 블럭 내에서만 의미를 가지기 때문에 블럭 안에서 다른데에 쓰일 수 없다.

<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 이란 블럭은 다른곳에 마음껏 붙여도 된다. 하지만 내부의 input 과 button은 검색을 위한 인풋창이자 버튼이기 때문에, search-form 안에서만 존재 의미가 있는 엘리먼트다.

엘리먼트 또한 중첩이 가능하다.

.block > .block__element1 > .block__element2도 가능하다.

BEM의 재미있는 점은, .block_element2를 .block_element1의 하위 엘리먼트로 보지 않고 둘 다 똑같이 .block의 엘리먼트로 취급한다는 점이 같다. 그래서 클래스네임에 캐스케이딩을 여러번 표시할 필요가 없다.

따라서 BEM은 아래와 같이 사용하지 않는다.

<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>

위 형태는 block-name__element-name이란 형식을 따르고 있지 않기 때문에,
아래와 같이 사용한다.

<form class="search-form">
	<div class="search-form__content" >
		<input class="search-form__input" />
		<button class="search-form__button">Search</button>
	</div>
</form>

3. Modifier

모디파이어는 블럭이나 엘리먼트의 속성을 담당한다. 생긴게 조금 다르거나, 다르게 동작하는 블럭이나 엘리먼트를 만들때 사용하면 된다.

<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 가 수식어에 해당한다. 저렇게 작성된걸 불리언(boolean)타입이라고 하는데, 그 값이 true라고 가정하고 사용한다.

키-밸류(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 tile--color-gray">VIP 로그인 (준비중)</strong>
	<form class="form-login form-login--theme-special form-login--disalbed">
		 <input type="text" class="form-login__id" />
		 <input type="password" class="form-login__password" />
	</form>
</div>

위 예시에서 color-gray와 theme-normal은 key-value타입에 해당한다.

<div class="header">
	<div class="header__inner">
		<div class="tabzilla"></div>
		<div class="header__logo"></div>
		<div class="header__auth"></div>
		<div class="nav"></div>
		<div class="header__search"></div>
	</div>
</div>

위 코드에서 .header는 블럭이며, .header__로 시작하는 태그들은 모두 엘리먼트에 해당하고,
.tabzilla와 .nav는 엘리먼트가 아닌 블럭. 다른곳에서 독립적으로 쓸 수 있기 때문에 블럭으로 지정한것이다.

단점

  1. 클래스네임이 너무 길다.
    마크업이 한눈에 들어오지 않는다는 단점이 있다.
    특히 스크립트로 모디파이어를 변경해야할 때, classList.add("block-name__element-name--modifier")처럼 길게 작성해야하는 건 불편해보인다.

  2. 더블클릭 선택이 불편하다.
    하이픈과 언더바가 함께 있어, 더블클릭해서 클래스네임을 선택할 때 한 번에 선택이 안된다.

profile
Web publisher

2개의 댓글

comment-user-thumbnail
2023년 3월 20일

이해가 잘 되요 😚

1개의 답글