IT/기초 지식

[CSS] CSS 아키텍처

개발자 두더지 2023. 4. 15. 19:16
728x90

일본의 한 블로그 글을 번역한 포스트입니다. 오역 및 의역, 직역이 있을 수 있으며 틀린 내용은 지적해주시면 감사하겠습니다.

 

CSS 아키텍처란?


 CSS는 사양이 단순하기 때문에 배우기 쉽지만, 대규모 사이트나 팀에서 코딩할 때나 장기간 유지 보수하는 등에 있어서는 사양 외에 많은 지식이 요구된다. 

 CSS의 사양을 구석구석 이해하여, 미디어 쿼리나 CSS 애니메이션등을 능숙하게 사용할 수 있다고 해도 그것으로 CSS의 스킬이 높다고는 말할 수 없다.

 CSS의 사양대로 설계할 수 있는 것은 최종 목표가 아닌 기본 능력이다. 코드의 가독성이나 유지보수, 팀 빌딩이 가능한지등은 다른 면으로 굉장히 중요하다.

 CSS에는 이러한 사양 외에의 규약을 제공해주는 아키텍처가 몇 가지가 준비되어 있다.  이 몇 가지 아키텍처에 대해서 가볍게 소개하도록 하겠다.

 

 

BEM


컨셉

  • CSS 셀럭터의 명명 규약이라고 불린다.
  • Block, Element, Modifier의 준말이다.
    • Block
      • 헤더, 네비게이션, 풋터 등의 파츠
      • 독립되어 있다.
    • Element
      • 검색 버튼, 검색 박스등의 부품
      • 기능을 가지고 있다.
    • Modifier
      • 부품의 상태 색 등의 장식

 

사례

명명규약

  • block에 대해서, element와 modifier을 각각 _(언더 스코어 1개), __(언더 스코어 2개), -(하이픈 1개)로 연결하여 셀렉터를 만든다.
  • --(하이픈 2개)를 연결하는 mindBEMding이라는 작성법이 있다.
  • 이러한 것들을 "세퍼레이터"라고 부른다.
    • 세퍼레이터를 사용 구분하는 것으로 Block와 Element의 구분인지, Modifier의 구분인지, 그것도 아니면...과 같은 판별이 가능하게 된다.
    •  Block과 Element의 구분은 __ (언더 스코어 2개)
    • Modifier의 구분은 _ (언더 스코어 1개)
    • 단어의 구분은 - (하이픈 1개) etc...
  • 예 : 블록 안의 세 가지 버튼이 있으며, 중간의 버튼만 빨갛게 하는 경우
<div class="test">
    <button class="test__button">テスト</button>
    <button class="test__button_red"テスト赤色</button>
    <button class="test__button">テスト</button>
</div>
.test {
  border: 1px solid #ccc;
  padding: 16px;
  text-align: center;
  background-color: #fafafa;
}
.test__button {
  width: 200px;
  padding: 8px 0;
  border: 1px solid #ccc;
}
.test__button_red {
  background-color: red;
}

 

장점

  • 기본지식이 있다면 도중에 들어 온 사람이라도 CSS 설계를 이해하기 쉬우므로 금방 작업이 가능하다.
  • 많은 사람이 관여하고 장기적으로 운용되거나 유지 보수가 반복되는 프로젝트에 좋다.
  • 커뮤니케이션 하기 쉽다.

 

단점

  • class명이 장황해진다.
    • Element의 class명으로는 block명을 포함할 필요가 있다.
  • 세퍼레이터의 사용법을 통일하지 않으면 안 된다.

 

 

SMACSS


컨셉

  • Sass를 사용하는 것을 전제로하여 파일을 모듈이나 레이아웃마다 세분화한 후에 모든 style.scss에 @import하여 컴파일하는 것을 권장하고 있다.
  • CSS를 아래 5개에 분할하는 방식이다.
    • 베이스
      • 요소 셀렉터, 속성 셀렉터, 유사 셀럭터등
        • body, a, input 등
      • 레이아웃
        • 구성의 큰 틀을 정의한다.
          • 예 : 헤더, 풋터, 사이드바등
        • 접두사는 .l-, .la-를 붙인다.
      • 모듈
        • 페이지를 구성하는 모든 것
        • 부품마다의 스타일의 지정한다.
          • 예 : .logo, .tabs, .box, .list등
        • 접두사는 붙이지 않는다.
      • 스테이트
        • JavaScript로 상태를 변화시킬 때의 패턴을 분할
          • 클릭하면 어떻게 될지
        • 클래스명의 접두사는 is를 붙인다.
      • 테마
        • 테마의 전환에 관한 것
        • body에 대해서 테마용의 클래스를 준비한다.

 

디렉토리의 구성 예

├── style.scss
│
├── base //베이스에 관련된 것
│   ├── _base.scss 
│   └── _mixins.scss
│
├── layout //레이아웃 관련된 것
│   ├── _top.scss
│   ├── _header.scss
│   └── _footer.scss
│
└── module //모듈에 관련된 것
    ├── _btn.scss 
    ├── _logo.scss
    └── _nav.scsss

 

코드

.l-test {
    width: 500px;
    height: 100px;
}

 

장점

  • 한 개 파일의 코드양이 적어진다.
  • 접두사를 붙이는 것으로 어떤 요소인지, 어디의 요소인지 알기 쉽다.
  • 역할마다 나누는 것으로 코드의 혼재를 방지할 수 있다.

 

단점

  • Sass를 사용하지 않는 경우는 별로 의미없을지도 모른다.
  • 디렉토리에 있는 파일이 많아진다.

 

 

OOCSS


컨셉

  • 오브젝트 지향을 도입했다.
  • 구조(형태를 만드는 것)와 스킨(외관)을 나누는 방식
    • 구조
      • width, height, border등
    • 스킨
      • color, border-color, background-color등

 

예제

안티패턴

  • 동일한 속성, 값을 반복해서 쓴다.
  • 구조에 관련된 것과 외관에 관련된 것을 혼재해서 기재한다. 
    • test.html <div class="box1"> <p>빨간색을 배경으로 한다.</p> </div> <div class="box2"> <p>파란색을 배경으로 한다.</p> </div>
.box1 {
 float: left;
 width: 350px;
 background-color: blue;
 color: white;
 text-align: center;
}

.box2 {
 float: left;
 width: 350px;
 background-color: blue;
 color: white;
 text-align: center;
}

권장되는 작성법

  • 공통 클래스명과 그것과 다른 클래스명을 준비한다.
  • 공통의 클래스에는 구조를 다른 클래스에는 스킨에 관련된 것을 기재한다.
<div class="box red-box">
    <p>빨간색을 배경으로 한다.</p>
</div>
<div class="box blue-box">
    <p>파란색을 배경으로 한다.</p>
</div>
.box { //구조에 관련된 것
 float: left;
 width: 350px;
 text-align: center;
 background-color: white; // 기본값
 color: black; // 기본값
}
.red-box { //외관에 관련된 것
 background-color: blue;
 color: white;
}
.blue-box { //외관에 관련된 것
 background-color: red;
 color: white;
}

 

장점

  • 반복하여 동일한 속성, 값을 쓰지 않으므로 수정해야할 경우 수정할 부분이 적다.
  • 공통화하는 것으로 CSS 코드 양을 줄일 수 있다.

 

단점

  • 코드가 복잡해진다.
  • 설계의도를 이해하기까지 시간이 걸린다.

 

 

ECSS


컨셉

  • OOCSS가 반복을 허용하지 않는데에 반해, ECSS는 반복을 허용하며 적당히 분리하는 것을 목표로 한다.
  • 제일 커더란 것을 찾아서 그 안에 어떤 요소가 필요한지 생각한다.
  • 특정 스코프로 분할한다.
  • 명명규약은 BEM의 것과 동일하다.
    • 이름 공간
      • 접두사로 컨텍스트, 모듈을 나타낸다.
    • 모듈
      • BEM로 말하자면 Block
      • 상위의 DOM
    • 컴포넌틑
      • BEM로 말하자면 Block
      • 부모 DOM에 내포되는 요소
    • 자식 노드
      • BEM로 말하자면 Element
    • 베리언트(변형)
      • BEM로 말하자면 Modifier

 

예시

명명 규약

  • 이름 공간에 - (하이픈 1개)를 더해서 접두사로써 사용한다.
  • 이름공간과 베리언트는 로우 카멜 케이스
    • namespce, vriant
  • 위의 내용 이외에 업퍼 카멜 케이스
    • ModuleName, ChildNode

 모두 작성해보면 다음과 같다.

namespace-ModuleName_ChildNode-variant
namespace-ComponentName_ChildNode-variant

디렉토리 구조

  • 컨텍스트를 스코프로써 파일을 관리한다.
  • css와 js를 병렬로 관리하는 것을 권장한다.
  • Namespace마다 에셋으로 나눠서 관리한다.

 예를 들면 다음과 같다.

├── Top //Namespace
│   ├── css
│   ├── js
│   └── img
├── Page2 //Namespace
│   ├── css
│   ├── js
│   └── img
├── Page3 //Namespace
│   ├── css
│   ├── js
│   └── img
└── Page4 //Namespace
    ├── css
    ├── js
    └── img

 

장점

  • Namespcae마다 관리할 수 있으므로, 불필요할 때 삭제하기 쉬우며, 필요할 때에는 추가하기 쉽다.
  • 새로운 페이지이지만 비슷한 페이지를 만들 때 기존에 존재하는 페이지에 영향을 끼치지 않는다.

 

단점

  • 동일한 CSS를 양산하기 때문에 파일량이 방대해진다.

참고자료

https://rfs.jp/sb/html-css/html-css-guide/css-architecture.html

https://qiita.com/tsugu_maru_san/items/e3c9a8fd64c6500b59b8

728x90