CSS 설계 기법

    반응형

    썸네일

    🚀 CSS 설계 기법


    CSS는 왜 저렇게 쓸까?? 클래스명은 왜 저렇게 쓸까?? 나는 camelCase를 쓰고 싶어!! 등등 개개인의 코드 스타일이 있을 것이다. 하지만 어느 정도 기준은 필요하다 기준이 없다면 그저 대혼란이 올 수도 있기 때문이다. 예를 들어 클래스명을 내 맘대로 s-d_e_w_e_r-r 이런 식으로 작성한다면?? 생각만 해도 끔찍~~ 그래서 CSS는 대표적으로 3가지의 설계 기법이 존재한다.

     

    1. OOCSS(Object Oriented CSS) / ref : https://www.slideshare.net/stubbornella/object-oriented-css

    • OOCSS의 개념은 레고처럼 여러가지 모듈을 만들어서 조합하도록 하는 방법이다.
    • 방법으로는 구조와 스킨을 분리한다. (같은 형태의 ui에 스킨만 다르다면 구조와 스킨을 분리하여 조합)
      • 구조 : width, height, padding, margin 등 레이아웃에 영향을 미치는 속성들
      • 스킨 : font 관련 속성, color, background, border 등 레이아웃에 영향을 미치지는 않지만 시각적인 영향을 주는 속성들 (border는 레이아웃에 영향을 끼칠 수는 있지만 미미하므로 스킨으로 분류)
    • 컨테이너와 콘텐츠를 분리한다.
      • 콘텐츠의 스타일이 컨테이너에 종속되지 않도록한다.
      • 즉 콘텐츠의 스타일 선택자에 컨테이너의 클래스를 배제한다.

    구조와 스킨 분리 예제 코드

    <button type="button" class="btn"></button>
    <button type="button" class="btn btn-close"></button>
    .btn {
        width: 200px;
        height: 80px;
        font-size: 30px;
    }
    
    .btn-close {
        background: black;
        color: #fff;
        border: 3px dotted #fff;
    }

    컨테이너와 콘텐츠 분리 예제 코드

    <main id="main">
        <button type="button" class="btn general">기본 버튼</button>
        <button type="button" class="btn warning">취소 버튼</button>
    </main>
    /* 컨테이너에 스타일이 종속되어 있는 상태 */
    #main .btn {
        width: 300px;
        padding: 20px 10px;
        margin: 10px;
        font-size: 18px;
        line-height: 1.5;
    }
    
    #main .general {
        background-color: aquamarine;
        color: black;
    }
    
    #main .warning {
        background-color: azure;
        color: blue;
    }

    main id가 지워지면 삭제된다.

     

    이제 후에 설명하는 SMACSS, BEM은 OOCSS 기반으로 발전한 내용이다.

     

    2. SMACSS(Scalable and Modular Architecture for CSS) / ref : http://smacss.com

    • CSS 코드를 역할에 따라 분리한다.
      • 베이스 : 폰트 패밀리, 폰트 사이즈, reset 스타일, <img> 공통 스타일
      • 레이아웃 : 헤더, 메인 영역, 푸터, 사이드 바 등 대부분 페이지에 몇 개 존재하지 않기 때문에 ID 선택자를 사용하기도 한다.
      • 모듈 : 레이아웃 안에 배치되는 모든 요소를 의미한다. ID 선택자를 사용하지 않고, 요소 선택자의 사용을 최소화한다. 비슷한 모듈 안에서도 모양이 조금씩 다를 경우 서브클래스를 만든다.
      • 스테이트 : 기존 스타일을 덮어쓰거나 확장하는 데 사용하는 스타일이다. 서브클래스와 다른 점은 레이아웃, 모듈 둘 다 적용 가능하고, 서브클래스가 한 번 적용되면 바뀌지 않는 속성임에 비해 스테이트는 자바스크립트로 필요할 때 넣었다 뺐다 할 수 있다는 점이다. 클래스 이름은 앞에 is라는 접두사를 사용한다. (ex. is-hidden, is-active)
      • 테마 : 사용자에게 사이트의 느낌을 전달하는 background-image, background-color, color 등을 의미한다.

    모듈 예제 코드

    <button type="button" class="btn">그냥 버튼</button>
    <button type="button" class="btn btn-small btn-long">아이디/비밀번호 찾기</button>
    <button type="button" class="btn btn-small">로그인</button>
    .btn {
        display: inline-block;
        width: 300px;
        padding: 20px 10px;
        font-size: 18px;
        text-decoration: none;
        text-align: center;
        vertical-align: top;
        color: #fff;
        background-color: brown;
    }
    
    .btn.btn-small {
        width: 80px;
        padding: 10px 0;
        font-size: 14px;
    }
    
    .btn.btn-long {
        width: 160px;
    }

    스테이트 예제 코드

    <ul class="tabnav">
        <li class="is-active"><a href="">탭1</a></li>
        <li><a href="">탭2</a></li>
        <li><a href="">탭3</a></li>
        <li class="is-hidden"><a href="">탭4</a></li>
    </ul>
    .tabnav {
        display: flex;
        margin: 20px;
    }
    
    .tabnav li {
        border-top: 1px solid black;
        border-right: 1px solid black;
        border-bottom: 1px solid black;
    }
    
    .tabnav li:first-child {
        border-left: 1px solid black;
    }
    
    .tabnav li a {
        display: block;
        padding: 10px 30px;
        text-decoration: none;
    }
    
    .is-active {
        background-color: blanchedalmond;
    }
    
    .is-active a {
        pointer-events: none;
        color: red;
    }
    .is-hidden {
        display: none;
    }

     

    하지만 용도에 따라 적게 되면 예시로 nav 바를  모듈에서 코드를 짜고, 스테이트에서 nav와 관련된 코드를 또 짠다면 나중에 코드가 길어질 경우 코드를 찾아내기에 불편할 것 같기 때문에 사실 좋은 방법이라고 생각이 들진 않는다.

     

    3. BEM (Block, Element, Modifier) / ref : http://getbem.com/ 

    • 얀덱스사가 만든 설계 방법 (하필 러시아 기업임;;). 기본적으로는 OOCSS와 같은 모듈 기반의 방법을 뿌리로 한다.
    • 네이밍의 목숨을 걸음
    • ID 선택자와 요소 선택자를 권장하지 않음 (클래스 선택자만 사용하는 이유는 가중치 계산을 원활히 하기 위해서, z-index를 10 단위로 사용하는 것과 같다.)
    • 사용방법
      • Block
        • 어디에서나 재사용 가능한 부품을 의미한다.
        • 클래스 네이밍은 목적이 명확해야 한다(ex. error, hidden).
        • 소문자를 사용하며 여러 단어가 연결되는 경우는 하이픈 케이스(케밥 케이스)를 사용한다.
      • Element
        • Block을 구성하는 요소들로 block에 종속되어야 한다. 때문에 block 클래스 이름을 상속받고 element의 클래스 이름을 언더바 두 개를 접두사로 하여 사용한다. (ex. error__link)
        • element 안에 또 element를 사용할 경우 클래스 네이밍은 element 끼리 중첩하지 않는다. 서로 종속관계로 보지 않기 때문
      • Modifier
        • block이나 element의 모습이나 상태 또는 움직임을 정의한다.
        • 단독으로 클래스 이름을 사용하지 않고 두 번째 클래스 이름으로 사용한다.
        • 클래스 네이밍은 block이나 element의 이름을 상속 받고 하이픈 두 개로 연결한다.
        • btn-move--size-small (o)

     

    사실 마지막이 가장 중요한 말이다. 요런 위에 있는 설계 기법들은 사실 그대로 사용하지 않는다. 나 같은 경우도 사실,, camel case를 주로 사용하는 편이고 앞으로 회사에 들어간다면 또 그 회사 나름대로의 컨벤션이 있을 것이고!! 또 팀 프로젝트를 하면 다른 유명한 회사들의 컨벤션을 참고해서 프로젝트 팀만의 컨벤션을 만들어서 작성하면 되니까!! 그렇게 연연할 필요는 없다고 본다. 코드에는 늘 그렇듯 최선은 있어도 정답은 없으니까 ㅎㅅㅎ

     

    이번에 설계 기법을 공부하면서 다른 큰 회사들의 컨벤션은 어떨지 한 번 찾아봐야겠다는 생각을 했다. 미리 공부해두면 나중에 그런 큰 회사에 들어갔을 때 적응도 빨라질 테니까 ^^ 아자자~

    반응형

    댓글