Home

Awesome

Airbnb CSS / Sass 스타일 가이드

CSS와 Sass에 대한 가장 합리적인 접근 방법

목차

  1. 용어 설명 - 규칙 선언부 - 선택자 - 속성
  2. CSS - 형식 - 주석 - OOCSS와 BEM - ID 선택자 - 자바스크립트 훅 - Border
  3. Sass - 문법 - 순서 - 변수 - 믹스인 - Extend 지시자 - 중첩 선택자
  4. 번역

용어 설명

규칙 선언부

"규칙 선언부(Rule declaration)"는 선택자와 그에 동반되는 속성들을 일컫는 이름입니다. 다음 예시를 참조해주세요:

.listing {
  font-size: 18px;
  line-height: 1.2;
}

선택자

규칙 선언부에서, "선택자(Selectors)"는 DOM 트리의 어떤 요소들이 정의된 속성(Properties)으로 꾸며질지 결정하는 부분들입니다. 선택자는 HTML 요소들, 뿐만 아니라 한 요소의 클래스, ID, 또는 해당 요소의 어느 속성(attributes)들과도 연결될 수 있습니다. 다음은 선택자에 대한 예시들입니다:

.my-element-class {
  /* ... */
}

[aria-hidden] {
  /* ... */
}

속성

마지막으로, "속성(Properties)"은 규칙 선언부의 선택된 요소들이 그들의 스타일을 가지게 하는 것입니다. 속성은 키-값의 쌍으로 구성되며, 규칙 선언부는 하나 이상의 속성 선언부를 가질 수 있습니다. 속성 선언부는 아래와 같은 형태입니다:

/* 특정 선택자 */ {
  background: #f1f1f1;
  color: #333;
}

CSS

형식

잘못된 예시

.avatar{
    border-radius:50%;
    border:2px solid white; }
.no, .nope, .not_good {
    // ...
}
#lol-no {
  // ...
}

올바른 예시

.avatar {
  border-radius: 50%;
  border: 2px solid white;
}

.one,
.selector,
.per-line {
  // ...
}

주석

OOCSS와 BEM

우리는 다음과 같은 이유로 OOCSS와 BEM의 혼용을 권장합니다:

OOCSS, 또는 “Object Oriented CSS”는 당신의 스타일시트를 "객체"의 모음(한 웹사이트에서 독립적으로 사용되는, 재사용 가능하고 반복 가능한 단편들)으로 생각하게 만드는 CSS 작성 방식입니다.

BEM, 또는 “Block-Element-Modifier”는 HTML과 CSS 내부의 클래스에 대한 _명명 협약_입니다. 이것은 원래 대량의 코드베이스와 확장 가능성을 염두에 두고 Yandex에서 개발되었으며, OOCSS 구현을 위한 견고한 가이드라인으로 사용할 수 있습니다.

PascalCase 형태의 블록과 함께 사용하는 BEM의 변형 방식을 권장합니다. 이는 React에서 쓰이는 컴포넌트 등과 결합할 때 효과적입니다. 이 경우에도 _-는 계속 변형자와 자식을 나타내기 위해 사용됩니다.

예시

// ListingCard.jsx
function ListingCard() {
  return (
    <article class="ListingCard ListingCard--featured">

      <h1 class="ListingCard__title">Adorable 2BR in the sunny Mission</h1>

      <div class="ListingCard__content">
        <p>Vestibulum id ligula porta felis euismod semper.</p>
      </div>

    </article>
  );
}
/* ListingCard.css */
.ListingCard { }
.ListingCard--featured { }
.ListingCard__title { }
.ListingCard__content { }

ID 선택자

CSS에서 ID로 요소를 선택하는 것이 가능하긴 하지만, 이것은 안티패턴으로 간주됩니다. ID 선택자는 불필요한 특수성을 초래하며 재사용이 불가능하기 때문입니다.

이 주제에 대해 더 알고 싶으시다면, CSS Wizardry의 글을 읽어보세요.

자바스크립트 훅

CSS 클래스 명에 자바스크립트 훅을 거는 것을 권장하지 않습니다. 한 클래스 명에 두 가지를 혼합시키게 되면 결국 리팩토링할 때 두 경우를 모두 고려해야하기 때문에 시간이 낭비되며, 최악의 경우에는 기능이 작동하지 않을 가능성 때문에 개발자가 코드를 변경시키길 두려워할 수도 있습니다.

자바스크립트에 바인드 할 새로운 클래스(접두어로는 .js-를 추가)를 만드는 것을 권장합니다:

<button class="btn btn-primary js-request-to-book">Request to Book</button>

Border

border가 없을 경우에는 none 대신 0을 사용하세요.

잘못된 예시

.foo {
  border: none;
}

올바른 예시

.foo {
  border: 0;
}

Sass

문법

속성 선언 순서

  1. 속성 선언

    우선 표준 속성 선언을 먼저 작성합니다. @include 혹은 중첩 선택자는 아직 적지 않습니다.

    .btn-green {
      background: green;
      font-weight: bold;
      // ...
    }
    
  2. @include 선언

    @include를 마지막에 모아놓으면 전체 선택자를 쉽게 독해할 수 있습니다.

    .btn-green {
      background: green;
      font-weight: bold;
      @include transition(background 0.5s ease);
      // ...
    }
    
  3. 중첩 선택자

    중첩 선택자는 마지막에 위치합니다. 그리고 그 다음으로는 아무것도 적지 않습니다. 규칙 선언부와 중첩 선택자 사이에는 여백을 추가하며, 중첩 선택자 사이에도 마찬가치입니다. 중첩 선택자 내부 속성들 또한 위의 규칙을 따릅니다.

    .btn {
      background: green;
      font-weight: bold;
      @include transition(background 0.5s ease);
    
      .icon {
        margin-right: 10px;
      }
    }
    

변수

변수 이름을 정할 때는 -를 사용하는 것을 권장합니다. 같은 파일 내에서만 사용될 변수에 한해서는 접두어를 추가해도 괜찮습니다. (예- $_my-variable).

믹스인-Mixins

Mixin은 코드를 DRY하게 하고 명료하게 하며, 복잡성을 줄이기 위해 사용해야 합니다. 인자를 받지 않는 Mixin은 이럴 때 유용합니다. 하지만 만약 당신이 payload를 압축하지 않는다면(예- gzip), 불필요한 코드 중복이 발생하게 됩니다.

Extend 지시자

@extend는 직관적이지 않고 특히 중첩 선택자와 함께 사용할 때 위험성이 있기 때문에 사용하지 않는 것을 권장합니다. 심지어 최상위 placeholder 선택자를 extend해도 선택자들의 순서가 바뀌게 되면 문제가 발생할 수 있습니다. @extend를 사용함으로써 얻을 수 있는 이점은 Gzip을 사용하면 해결될 뿐더러, 스타일시트를 DRY하게 만들기 위해서는 mixin을 사용하면 됩니다.

중첩 선택자

중첩은 최대 3번까지!

.page-container {
  .content {
    .profile {
      // STOP!
    }
  }
}

만약 선택자가 이렇게 길어진다면, 당신은 다음과 같은 CSS를 작성하고 있을 가능성이 높습니다:

강조: 절대로 ID 선택자는 중첩하지 마세요!

어쩔 수 없이 ID 선택자를 사용해야한다면(사용하지 않는 것이 가장 좋습니다.), 절대로 중첩되지 않도록 유의하세요. 만약 중첩시키게 된다면, 왜 그렇게 특수한 케이스가 발생하는지 먼저 고민해보는 것이 좋습니다. 만약 당신이 잘 구성된 HTML과 CSS를 사용한다면 절대로 이렇게 할 필요가 없습니다.

번역

이 스타일 가이드는 여러가지 언어로 번역 돼 있습니다: