CSS 방법론(SMACSS,BEM,OOCSS)

- 7 mins

css의 활용도가 높아지고 대규모 프로젝트가 많아짐에 따라 코드베이스를 유지보수하기가 어려워졌고 이를 해결하기 위해 css를 작성하는 방법에 대한 여러 가이드라인을 문서화하기 시작했습니다. css방법론에는 대표적으로 SMACSS,BEM,OOCSS가있고 이 세 방법론 모두 같은 지향점을 갖고있습니다.

SMACSS (Scalable and Modular Architecture for CSS)

smacss는 css를 모듈화하고 확장 가능하게 만드는것을 목표로 하며 스타일을 다섯가지로 분류하고, 각 유형에 맞는 선택자(selector)작명법(naming convention),코딩 기법을 제시합니다.

  1. 기초(Base)
  2. 레이아웃(Layout)
  3. 모듈(Module)
  4. 상태(States)
  5. 테마(Theme)

기초 - Base

html, body{height:100%;}
body{font-family:나눔고딕, 돋움, arial, sans-serif;font-size:12px;line-height:19px;color:#6f6f6f;}
body, div, h1, h2, h3, h4, h5, h6, ul, ol, li, dl, dt, dd, p, 
form, fieldset, input, table, tr, th, td{margin:0;padding:0}
h1, h2, h3, h4, h5, h6{font-weight:normal;font-size:100%}
ul, ol, li{list-style:none}
fieldset, img{border:none}

레이아웃 - Layout

#content {width:80%;float:left}
#aside {width:20%}
.l-fixed #content {...}
.l-fixed #aside {...}

모듈 - Module

<div class="box">
  <span class="box-name"> ... </span>
  <span class="box-items"> ... </span>
</div
.box { ... }
.box-name { ... }
.box-items { ... }

상태 - State

<div class="btn_area">
  <a href="#" class="btn btn_good is-active">좋아요</a>
  <a href="#" class="btn btn_bad">나빠요</a>
</div>

테마 - Theme

// base.css
.header {
    background-color: green;
}
// theme.css
.header {
    background-color: red;
}

BEM (Block Element Modifier)

클래스를 구조화하여 이름을 지정, 코드의 유연성과 유지 관리 가능성을 높이는 방법이며 블록(block), 요소(element), 상태(modifier)로 구분하여 클래스 작성한다. 클래스명을 작명 할 때 에는 Block__Element–Modifier 로 작명한다.

Block

.header { ... }
.block { ... }
.footer { ... }

Element

.header { ... }
.header__link { ... }
.header__tap { ... }
.header__tap__item { ... }
/* Good */
.block__elem {
    color : yellow;
}
/* Bad */
.block .block__elem{
    color : yellow;
}
div .block__elem{
    color : yellow;
}

Modifier

.header--hide { ... }
.header__tap--big { ... }
.header__tap--big { ... }

BEM을 활용한 마크업

<header class="layout-header">
    <div class="layout-header__wrapper">
        <h1 class="layout-header__logo">
            <a href=""><img src="" alt=""></a>
        </h1>
        <nav class="layout-gnb">
            <h2 class="__accessibility">전체 메뉴</h2>
            <ul class="layout-gnb-menu">
                <li class="layout-gnb-menu__item">...</li>
                <li class="layout-gnb-menu__item">...</li>
                <li class="layout-gnb-menu__item">...</li>
            </ul>
        </nav>
    </div>
</header>
<main id="container" class="layout-container">
    <div class="main-container">
        <section class="main-visual" id="main-visual">
            <h2 class="__accessibility">메인 비주얼</h2>
            <ul class="main-visual__wrapper">
                <li class="main-visual__item">
                    <figcaption class="main-visual__item-figure">
                        <h3 class="main-visual-item-main__sub">...</h3>
                        <h2 class="main-vusual-item-main__title">...</h2>
                    </figcaption>
                    <img src="" alt="" class="main-visual__image">
                </li>
            </ul>
            <button type="button" 
                    class="main-visual__button main-visual__button--prev">이전</button>
            <button type="button" 
                    class="main-visual__button main-visual__button--next">다음</button>
        </section>
    </div>
</main>
.main-visual {
    margin: 0 auto;
    position: relative;
    width: 100%;
    height: 950px;
    overflow: hidden;
    min-width: 1140px;
    max-width: 1920px;
}

.main-visual__wrapper {
    position: relative;
    width: 100%;
    height: 100%;
    z-index: 1;
}

.main-visual__item-figure {
    width:1140px;
    margin:0 auto;
    position:relative;
    display:inline-block;
    z-index:1;
    padding-top:281px;
    height:100%;
}

BEM의 가장 큰 장점은 클래스명의 고유화로 직관적이며 CSS 및 UI가 구조화 된 장점을 누릴 수 있다.


OOCSS (Object Oriented)

CSS를 모듈 방식으로 코딩하여 중복을 최소화하는 기법

  1. 구조와 외형의 분리 (Separate structure and skin)
  2. 컨테이너와 내용 분리 (Separate container and content)

구조와 외형의 분리

// 기존 방식
<a class=”facebook_btn”>Facebook</a>
<a class=”twitter_btn”>Twitter</a>

// OOCSS 적용
<a href="#" class="btn bluebg">장바구니</a>
<a href="#" class="btn redbg">바로구매</a>

.btn {공통 버튼 스타일 정의}

컨테이너와 내용 분리

<div class="header common-width">Header</div>
<div class="footer common-width">Footer</div>

.header{ ... }
.footer{ ... }
.common-width{ ... }
<h3 class="subtitle"> H3 subtitle </h3>
<span class="subtitle"> span subtitle </span>

.subtitle { ... }

OOCSS는 마크업에 클래스를 추가하기때문에 HTML이 오히려 유지보수가 어렵다는 의견이 있고, 가독성이 떨어진다. 그러나 CSS코드가 재사용되면서 코드의 길이가 줄어들고 파일크기가 작아져 속도를 향상시킬수 있다.


결론

각각의 방법론에는 장/단점이 존재하기 때문에 자신에게(팀원 및 프로젝트별로) 최적의 방법론을 사용하는것이 중요하다. 분명한 점은 다른 개발자들이 나의 코드를 직관적으로 이해하고 많은 고민할 필요 없이 코드를 수정하여 공헌할 수 있게 하기 위해서는 잘 정의된 css가 중요하다.

참고

CSS 방법론 — BEM (Block Element Modifier) CSS방법론 SMACSS, BEM, OOCSSWIT - NTS UIT Blog

rss facebook twitter github gitlab youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora quora