Airbnb CSS / Sass Styleguide

Sebagian pendekatan yang paling umum untuk CSS dan Sass

Daftar Isi

  1. Terminologi - Rule Declaration - Selectors - Properties
  2. CSS - Formatting - Comments - OOCSS and BEM - ID Selectors - JavaScript hooks - Border
  3. Sass - Syntax - Ordering - Variables - Mixins - Extend directive - Nested selectors
  4. Translation

Terminologi

Rule declaration

“Rule declaration” adalah nama yang diberikan pada suatu selector (atau group dari beberapa selector) dengan properti-properti di yang berada dalamnya. Berikut misalnyanya:

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

Selectors

Di deklarasi rule, “selector” dijelaskan sebagai sebuah aturan yang menjelaskan bagaimana sebuah element di dalam sebuah DOM Tree akan di beri style berdasarkan properti yang dijabarkan di dalamnya. Selector bisa menggunakan HTML Element, class dari HTML element, ID, atau attribute apapun yang terdapat di HTML element tersebut. Berikut beberapa misalnya selectors:

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

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

Properties

Akhirnya, Properti (en :“property”) adalah style apapun yang akan diterapkan pada element terpilih. Properti adalah sebuah pasangan key dan value dengan deklarasi rule yang bisa memuat satu atau lebih deklarasi dari sebuah properti. Deklarasi properti akan terlihat seperti berikut:

/* some selector */ {
  background: #f1f1f1;
  color: #333;
}

CSS

Formatting

  • Gunakan “soft tabs” (2 spasi) untuk indentasi
  • Lebih baik dashes dibandingkan camelCase di dalam nama class.
    • Garis bawah (_) dan PascalCasing tidak mengapa apabila Anda menggunakan BEM (lihat pembahasan OOCSS and BEM dibawah).
  • Jangan gunakan ID selectors
  • Ketika menggunakan “multiple selectors” di deklarasi rule, tambahkan baris baru ke masing-masing selector tersebut.
  • Tambahkan spasi sebelum kurung kurawal (brace) pembuka { di deklarasi rule.
  • Di properti, tambahkan spasi setelahnya, tapi tidak sebelumnya dari karakter :.
  • Tambahkan baris baru pada kurung kurawal (brace) penutup } dari deklarasi rule.
  • Tambahkan baris kosong antara deskripsi rule.

Jangan

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

Sebaiknya

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

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

Comments

  • Lebih baik menggunakan comment sebaris (// di dalam Sass) dibandingkan blok comment.
  • Lebih baik comment di barisnya sendiri. Hindari comments pada baris paling terakhir.
  • Tulis dengan detail comment dari sebuah code yang tidak mempunyai dokumentasi sendiri, misal:
    • Penggunaan z-index
    • Kompatibilitas atau hack dari sebuah browser-specific

OOCSS and BEM

Kami mendorong beberapa kombinasi dari OOCSS dan BEM untuk beberapa alasan berikut:

  • Membantu menulis code dengan lebih jelas, memperjelas hubungan antara CSS dan HTML
  • Membantu kita membuat code reusable, composable components
  • Membuat nesting lebih sedikit dan lebih spesifik
  • Membantu dalam membangun stylesheets yang scalable

OOCSS, atau “Object Oriented CSS”, adalah sebuah pendekatan dalam menulis CSS yang mendorong Anda untuk berpikir mengenai stylesheets sebagai sebuah kumpulan “objects”: reusable, potongan code yang bisa digunakan berulang secara independent didalam sebuah website.

BEM, atau “Block-Element-Modifier”, adalah sebuah naming convention untuk “classes” di HTML dan CSS. Pertama kali dibangun oleh Yandex dengan codebase yang besar dan scalability, dan bisa digunakan sebagai kumpulan panduan dalam meng-implementasi OOCSS.

Kami merekomendasikan variasi dari BEM dengan PascalCased “blocks”, yang bekerja sangat baik bila dikombinasikan dengan components (seperti React). Garis bawah (_ en: underline) dan strip (- en: dashes) tetap digunakan sebagai pembatas untuk modifiers dan anak dibawahnya.

Contoh

// 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 { }
  • .ListingCard adalah “block” dan me-representasikan sebuah component dengan level tertinggi
  • .ListingCard__title adalah “element” dan me-representasikan sebuah anak dari .ListingCard yang membantu membentuk blok secara keseluruhan.
  • .ListingCard--featured adalah “modifier” dan me-representasikan sebuah perubahan state atau variasi di .ListingCard block.

ID selectors

Meskipun memungkinkan untuk memilih element berdasarkan ID dalam CSS, hal tersebut umumnya harus dianggap sebagai anti-pola. ID selector memperkenalkan tingkat yang tidak terlalu tinggi specificity terhadap deklarasi rule Anda, dan itu tidak reusable.

Untuk hal ini, baca lebih lanjut CSS Wizardry's article.

JavaScript hooks

Hindari binding class yang sama di kedua CSS dan JavaScript. Conflating antara keduanya sering menyebabkan paling tidak waktu yang terbuang selama refactoring ketika developer harus cross-reference masing-masing class yang berubah, dan yang paling buruk, developer menjadi takut untuk melakukan perubahan karena takut merusak fungsi.

Kami merekomendasikan membuat JavaScript-specific class untuk melakukan binding, dengan prefix .js-:

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

Border

Gunakan 0 dibandingkan none untuk menjelaskan bahwa style tersebut tidak mempunyai border.

Jangan

.foo {
  border: none;
}

Sebaiknya

.foo {
  border: 0;
}

Sass

Syntax

  • Gunakan .scss syntax, Jangan pernah gunakan .sass syntax asli.
  • Urutkan CSS biasa dan @include logika deklarasi Anda (lihat dibawah)

Mengurutkan deklarasi properti

  1. Deklarasi properti

    Daftar semua deklarasi property standard, sesuatu yang bukan sebuah @include atau nested selector.

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

    Menggabungkan @includes di akhir membuatnya lebih mudah untuk membaca keseluruhan selector.

    .btn-green {
      background: green;
      font-weight: bold;
      @include transition(background 0.5s ease);
      // ...
    }
  3. Nested selectors

    Nested selectors, if necessary, buat di paling akhir, dan jangan buat apapun setelahnya. Tambahkan spasi antara deklarasi rule Anda dan nested selectors, serta antara nested selectors yang berdekatan. Terapkan pedoman yang sama seperti di atas untuk nested selectors Anda.

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

Variables

Lebih baik menggunakan dash-cased untuk nama variabel (misalnya $my-variable) dibandingkan camelCased atau snake_cased. Hal ini dapat diterima sebagai awalan nama variabel yang dimaksudkan untuk digunakan hanya dalam file yang sama dengan garis bawah (en: underscore) (misalnya $_my-variable).

Mixins

Mixin harus digunakan untuk DRY-UP code Anda, menambah kejelasan, atau mengurangi kompleksitas abstrak terlalu dalam sebagaimana juga dengan memberi nama yang baik terhadap function. Mixin yang menerima tanpa argumen dapat berguna untuk ini, tetapi perhatikan bahwa jika Anda tidak mengompresi payload Anda (misalnya gzip), ini dapat berkontribusi terhadap duplikasi code yang tidak perlu dalam style yang dihasilkan.

Extend directive

@extend harus dihindari karena memiliki perilaku unintuitive dan berpotensi berbahaya, terutama bila digunakan dengan nested selectors. Bahkan memperluas selector placeholder pada tingkat atas yang dapat menyebabkan masalah jika urutan selector berubah nantinya (misalnya jika mereka berada di file lain dan urutan load file-file tersebut digeser). Gzip harus menangani sebagian besar penghematan yang akan Anda dapatkan dengan menggunakan @ extend, dan Anda tetap dapat men DRY-UP stylesheet Anda baik menggunakan mixin.

Nested selectors

Jangan gunakan nested selector lebih dari tiga level!

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

Ketika selectors menjadi sebegitu panjang, Anda telah menulis CSS seperti ini:

  • Terlalu berpatokan terhadap HTML (rapuh) —OR—
  • Terlalu spesifik (powerful) —OR—
  • Tidak reusable

Sekali lagi: Jangan pernah nesting ID selectors!

Jika Anda harus menggunakan ID selector di tempat pertama (dan Anda harus benar-benar mencoba untuk tidak melakukannya), mereka tidak boleh nested. Jika Anda menemukan diri Anda melakukan hal ini, Anda perlu untuk meninjau kembali markup Anda, atau mencari tahu mengapa hal tersebut diperlukan. Jika Anda menulis dengan baik HTML dan CSS, Anda seharusnya ** tidak pernah** harus melakukan hal ini.

Translation

Panduan style ini juga tersedia dalam bahasa lain: