CSS 방법론

GOTAEUK·2022년 4월 17일
0
post-thumbnail

1. OOCSS

OOCSS(Object Oriented CSS)는 CSS를 모듈 방식으로 코딩하여 중복을 최소화하는 기법이다.
OOCSS는 두가지 원칙이 있는데 이 두가지 원칙을 지키며 개발을 해야한다.

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

🖋 구조와 외형의 분리

구조와 외형이 어떤 것을 의미할까? 구조(Structure)는 width, height, padding, margin, border 같은 것들이다. 외형(Skin)은 color, border-color, font-color, background-color 같이 구조의 변화 없이 적용할 수 있는 속성들이다.

CSS

/*structure*/
.box{
	width: 200px;
  	height: 50px;
    padding: 10px;
}
.button{
	width: 400px;
 	overflow: hidden;
  	border: solid 1px #ccc;
}
/*skin*/
.common-skin{
	background: linear-gradient(#ccc, #222);
}

HTML

<div class="box common-skin">...</div>
<div class="button common-skin">...</div>

이런 식으로 구조를 포함하는 속성들만 모아 클래스를 생성하고, 외형만 포함하는 css속성들을 모은 클래스를 생성한다. 그 후 원하는 요소에 클래스 이름만 달아줌으로 스타일링한다. 이 방식을 사용하여 구조와 외형들을 결합하면 다양한 결과물을 얻을 수 있다.

🖋 컨테이너와 내용의 분리

어떤 태그를 직접 선택하거나 자손 선택자를 사용하여 스타일링 하는 것은 재사용성을 낮춘다. 따라서 다른 요소들간에 공통적으로 적용되어야 할 속성이 무엇인지 파악하는 것이 중요하다.

.globalwidth{
	position:relative;
    padding:20px;
    margin: 0 auto;
    width:980px;
    overflow:hidden;
}
.header-inside{
	padding-top:20px;
    padding-bottom:20px;
    height:260px;
}

이렇게 globalwidth라는 클래스에 다른 요소에도 사용될 수 있는 속성들을 추출하면 중복된 코드를 줄일 수 있기 때문에 컨테이너와 내용의 분리도 꼭 지켜야 한다.

장점

  • 공통된 부분을 정의하기 때문에 재사용이 가능해진다.
  • 코드를 재사용하기 때문에 코드 양이 줄어들어 CSS파일의 용량이 감소된다. 이는 속도 향상까지 기대할 수 있다.

단점

  • 다중 클래스가 많아짐에 따라 유지보수가 어려워진다.
  • 코드의 가독성이 떨어진다.

2. SMACSS

SMACSS는 Scalable and Modular Architecture CSS의 줄임말로 확장형 모듈식으로 CSS를 구성하는 기법이다. CSS를 Base, Layout, Module, State, Theme 이렇게 다섯가지 카테고리로 나누어 스타일을 정리한다.

🖋 Base

기초 스타일을 지정하는 부분으로 default.css, reset.css를 적용하는 부분이 Base에 포함된다. 아이디나 클래스 선택자를 사용하는 것이 아니라 기본 태그의 스타일을 지정하는 것이다. 이때 !important는 허용되지 않는다.

html, body, form {margin:0;padding:0;}
input[type=text] {border:1px solid #999;}
a {color:#000;}
a:hover {color:#666;}

🖋 Layout

큰 틀의 레이아웃, 다양한 요소들을 구별할 때 사용한다. 주요 컴포넌트에는 header, footer, aside, container, content등이 있고, 하위 컴포넌트에는 list, item, form 등이 있다. 주요 컴포넌트는 id를 사용하고, 하위 컴포넌트는 class를 사용하여 스타일을 지정한다. 클래스 명을 사용할 때는 l- 또는 layout-을 붙인다.

#content {width:80%;float:left;}
#aside {width:20%}

.l-fixed #content {
  width: 600px;
  margin-right: 10px;
}
.l-fixed #aside {
  width: 200px
}

🖋 Module

레이아웃 안의 더 작은 부분을 가리킬 때 module을 사용하는데 이는 재사용을 가능하게 하기 위함이다. 버튼, 위젯, 배너 등이 이 부분에 포함될 수 있다. 각 모듈은 독립적일 수 있도록 설계해야하며 다른 곳에서도 사용할 수 있어야 한다. 재사용을 해야하기 때문에 id선택자와 엘리먼트 선택자는 사용하지 않고, class 선택자를 사용한다. 만약 엘리먼트 선택자를 사용해야 하는 경우에는 child 선택자(>)만 사용한다. 모듈 안에 또 다른 모듈이 들어갈 수 있다.

HTML

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

CSS

.box { ... }
.box-name { ... }
.box-items { ... }

🖋 State

툴팁, 아코디언 등 어떤 요소의 상태가 열리거나 닫히는 등의 상태 변화가 일어나는 경우에 사용하는 스타일이다. 클래스를 사용하며 is- 또는 s- 접두사를 사용한다. 상태 스타일은 복잡한 상황에서 !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

사이트 전체의 look and feel을 제어한다. 색상이나 이미지를 다룰 때 사용하는데 테마 스타일의 규칙만 모아서 분리한다. 이미 스타일링된 요소 뒤에 다시 재선언하여 테마만 입히는 방식이다.

/* main.css */
.box {
  border: 1px solid;
}

/* theme.css - main.css 뒤에서 읽히도록 적용 */
.box {
  border-color: blue;
}

장점

  • 5개의 카테고리로 범주화하기 때문에 알아보기 쉽고 재사용성이 증가하는 동시에 코드가 간결해진다.
  • 또 클래스명을 통해 역할을 쉽게 예측할 수 있다.

단점

  • 규칙에 대한 종속성이 있다.
  • 카테고리의 기준이 모호해질 수 있다.
  • 범주화하기 때문에 CSS를 사용하기 복잡해질 수 있다.

3. BEM

BEM은 Block Element Modifier의 약자로 OOCSS, SMACSS보다 더 많이 사용되는 방법론이다. BEM을 사용한다면 id는 사용하지 않고, class만 사용한해야 한다는 것에 주의하자.

🖋 Block

재사용이 가능한 독립적인 컴포넌트를 block이라고 한다. 로고 같은 경우는 웹 페이지에서 재사용될 일이 많기 때문에 block이라고 할 수 있다. header, aside, content, footer 등 또한 독립적으로 존재해야 하기 때문에 block이 된다. 이 때 block은 환경에 영향을 받으면 안되기 때문에 여백이나 위치를 설정할 수 없다.

만약 block 안에 또 다른 block이 들어간다면 그냥 클래스 이름을 지정하면 된다.

<div class="header">
	<div class="menu">...</div>
	<div class="search">...</div>
</div>

🖋 Element

element는 block을 구성하는 요소 단위로 의존적인 성격을 가진다. 자신이 속한 블록 안에서만 존재하기 때문에 다른 곳에서 재사용할 수 없는 것들을 element라고 한다. 클래스 이름은 block__element이렇게 짓는다. 만약 header안에 있는 title이라면 class명은 header__title가 되겠다. element안에 또 다른 element가 존재할 수 있는데 이 경우에 계속 __를 붙이는 것은 아니다. 자신을 포함하는 block만 __앞에 붙여주면 된다.

❌ BAD

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

위처럼 __ 중첩되는 것이 아니라 아래처럼 사용하면 된다.

⭕ GOOD

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

이때 주의해야 할점은 다른 블록 앨리먼트 요소에 의존하는 선택자를 사용하면 안된다는 것이다. .search-form .search-form__input 이렇게 선택하면 .search-form__input.search-form에 의존하게 된다. 따라서 단순히 .search-form__input 클래스명 하나만 선택하면 된다. 이미 이름 자체가 고유하기 때문에 다른 블록이나 엘리먼트들을 함께 지정하지 않아도 된다.

🖋 Modifier

modifier는 block이나 element의 속성을 나타낼 때 사용한다. block—modifier, block__element—modifier같은 형태로 사용할 수 있다. modifier 앞에 를 붙여주는 것이다. class="block__element—modifier" 이렇게 modifier 혼자 단독으로 사용될 수 없고 class="block__element block__element—modifier" 처럼 기본 블록이나 요소이름을 설정한 후 뒤에 modifier를 추가하는 형태로 사용한다.

modifier에는 boolean 타입과 key-value 타입이 있다.
form__button--focused boolean 타입인데 이름만 봐서 form 블록의 button 엘리먼트가 focused 되었을 때 사용하는 속성들이라는 것을 쉽게 알아차릴 수 있다.

key-value 형식에서는 하이픈으로 키와 값을 연결하여 사용한다. title—color-gray 어떤 태그가 이 클래스를 가진다면 title블록임을 알 수 있고, color는 gray로 설정되리라 알아차릴 수 있다. 하이픈 하나로 key와 value를 구분해 modifier로 사용한 것이다.

장점

  • html문서를 보지 않아도 클래스 명만으로도 구조를 어느 정도 파악할 수 있다.
  • SASS의 & 과 함께 사용할 때 매우 편리하다.
  • block, element, modifier라는 개념을 사용하기 때문에 클래스 명의 중복을 쉽게 방지할 수 있다.

단점

  • 하위 요소로 들어갈수록 클래스명이 지나치게 길어져 복잡할 수 있다.

출처 및 참고

profile
한걸음씩

0개의 댓글