안녕하세요, 일루넥스 개발팀 정민지입니다.
오늘은 지난 번 다루었던 BEM에 이어 SMACSS에 대해 소개해보려고 합니다.
Scalable and Modular Architecture for CSS의 줄임말로,
점점 복잡해지고 관리하기 어려워지는 CSS를 효과적으로 쓸 수 있도록 돕는 스타일 가이드입니다.
조나단 스눅(Jonathan Snook)이 제안한 CSS 작성 규칙 SMACSS를 적용하면 재사용과 유지보수가 쉽고,
확장 가능한 모듈식으로 CSS 코드를 작성할 수 있습니다.
SMACSS의 핵심은 CSS 스타일을 몇 가지 범주로 묶는 것입니다. 이렇게 함으로써 규칙과 패턴이 생기고, 스타일을 이해하기 쉽게 정리할 수 있습니다.
이를 바탕으로 SMACSS의 CSS 스타일은 **기본(Base), 레이아웃(Layout), 모듈(Module), 상태(State), 테마(Theme)** 총 다섯 가지로 나뉩니다.
기본 스타일은 초기값 설정을 의미하며, reset.css 같은 초기화 파일도 이에 포함 됩니다.
대부분 하나의 요소(elements)로 이루어져있으며 속성 선택자, 가상 클래스 선택자, 후손 선택자, 자식 선택자 등으로 구성되어 있습니다.
기본 스타일은 클래스 또는 아이디 선택자를 포함하지 않습니다.
예를 들면 기본 링크 스타일, 기본 폰트 스타일과 바디의 배경 선언 등이 이에 포함됩니다.
기본 스타일을 정의할 때 **!important
**는 허용하지 않습니다.
html, body, form {margin:0;padding:0;}
input[type=text] {border:1px solid #999;}
a {color:#000;}
a:hover {color:#666;}
레이아웃 스타일은 큰 틀의 레이아웃, 페이지의 다양한 요소를 배치하고 구별하는데 사용합니다.
주요 컴포넌트에는 header
, footer
, aside
등이 있으며, 주요 컴포넌트 내의 하위 컴포넌트에는 nav
, item list
, form
등이 있습니다.
주요 컴포넌트는 id, 하위 컴포넌트는 class를 사용하여 스타일을 작성합니다.
클래스명을 사용할 때는 접두사로 **l-
, layout-
**를 사용해야 합니다.
ex) l-fixed
: 유무에 따라 가변 폭으로 할지 고정 폭으로 할지 결정하는 레이아웃
#content {width:80%;float:left;}
#aside {width:20%}
.l-fixed #content {
width: 600px;
margin-right: 10px;
}
.l-fixed #aside {
width: 200px
}
모듈 스타일은 버튼, 위젯, 배너 등과 같이 페이지에서 재사용을 위한 스타일입니다.
네비게이션, 슬라이드, 위젯 등이 모두 모듈에 해당되며, 모듈은 레이아웃이나 다른 모듈 안에 위치할 수 있습니다.
따라서 각 모듈은 독립적으로 존재할 수 있도록 설계해야 하며, 재사용을 위해 CSS 선택자로 id, 엘리먼트 선택자를 피하고 클래스명을 사용해야 합니다.
만약 엘리먼트 셀렉터를 사용해야 한다면, .box > span
처럼 child 셀렉터를 사용하도록 합니다.
<div class="box">
<span class="box-name"> ... </span>
<span class="box-items"> ... </span>
</div>
.box { ... }
.box-name { ... }
.box-items { ... }
상태 스타일은 툴팁이나 아코디언 같은 요소의 상태 변화를 표현하는 스타일로, 모듈과 레이아웃 둘 다에 적용할 수 있습니다.
주로 Javascript에서 조작되는 클래스에 지정하며, 클래스명은 접두사로 is-
, **s-
**를 사용해야 합니다. 특정 모듈의 경우에는 모듈 이름을 뒤에 붙입니다.
ex) is-hidden
, is-collapsed
/ ex) is-tab-active
또한, 상태 스타일은 필요시 (복잡한 CSS환경에서) **!important
**를 사용할 수 있습니다.
<!-- 레이아웃 요소, 접힌 상태 -->
<div id="header" class="is-collapsed">
<form>
<!-- 모듈, 오류 상태 -->
<div class="msg is-error">
There is an error!
</div>
<!-- 연관된 라벨이 숨겨진 상태 -->
<label for="search" class="is-hidden">Search</label>
<input type="text" id="search">
</form>
</div>
#header
는 레이아웃 요소임을 알 수 있으며, .is-collapsed로 접힌 상태임을 알 수 있다..msg
는 모듈이며 .is-error로 오류 상태임을 알 수 있다.#searchbox
연관된 라벨은 숨겨져 있는 것을 알 수 있다. (.is-hidden
)테마 스타일은 전반적인 표현과 느낌을 결정하는 색깔이나 이미지를 정의합니다.
테마 스타일 규칙만 따로 모아서 분리하면 테마를 쉽게 교체하고 재정의할 수 있습니다.
적용 범위가 넓은 테마의 경우에는 접두사로 **theme-
**를 붙여서 혼란을 피해야 합니다.
/* main.css */
.box {
border: 1px solid;
}
/* theme.css - main.css 뒤에서 읽도록 적용 */
.box {
border-color: blue;
}
SMACSS의 네이밍 규칙을 정리하자면 레이아웃의 경우 .l-*
or .layout
or #layout
이며,
모듈은 .module
, state는 .is-*
or .s-*
, theme는 .theme
or **.theme-*
**입니다.
/* Example Module */
.example {
...
}
/* Callout Module */
.callout {
...
}
/* Callout Module with State */
.callout.is-collapsed {
...
}
/* Form field module */
.field {
...
}
/* Inline layout */
.l-inline {
...
}
5개의 범주화(Base, Layout, Module, State, Theme)를 통해 알아보기 쉽고 재사용 가능한 컴포넌트를 작성할 수 있습니다.
상태스타일(State)을 통해 해당 요소의 상태까지 예측할 수 있으며, 이는 자바스크립트 훅을 추가하여 이벤트를 예측하기 쉽게 도와줍니다.
1. 규칙에 대한 종속성
지금까지 CSS 방법론 중 SMACSS에 대해 알아보았습니다.
읽어주셔서 감사합니다.