Lompat ke konten
dokumentasi.id
Commit 83fc07e
v2
Star3,5 rb

8

Sistem Gaya Less, SCSS, dan SASS

Waves menyimpan aturan gayanya dalam tiga berkas yang isinya setara: src/less/waves.less sebagai sumber utama, src/scss/waves.scss, dan src/sass/waves.sass. Ketiganya mendefinisikan tiga mixin prefix vendor, satu blok induk .waves-effect, dan sekumpulan kelas varian. Halaman ini membahas isi ketiga berkas tersebut; urutan task yang menjalankannya dibahas di Pipeline Build Grunt.

Sumber utama dan dua turunannya

src/less/waves.less adalah berkas acuan. Task less:build mengompilasi berkas itu menjadi dist/waves.css (Gruntfile.js:6-17). Task execute:less2scss membaca berkas Less yang sama, mengganti variabel @ menjadi $, mengubah definisi .nama(...) menjadi @mixin nama(...), mengubah pemanggilan menjadi @include, dan mengubah literal ~'!important' menjadi #{"!important"}, lalu menulis hasilnya ke src/scss/waves.scss (Gruntfile.js:132-151). Berkas src/sass/waves.sass dibuat sass-convert dari src/scss dengan indent: 2 (Gruntfile.js:88-99).

⚠️ src/scss/waves.scss dan src/sass/waves.sass ditulis ulang oleh task build, jadi perubahan manual pada keduanya akan hilang pada grunt build berikutnya. Ubah src/less/waves.less, lalu jalankan build.

Perbedaan ketiganya murni sintaksis. Mixin yang sama dideklarasikan sebagai .waves-transition (@transition) { ... } di Less (src/less/waves.less:9-14), sebagai @mixin waves-transition($transition){ ... } di SCSS (src/scss/waves.scss:9-27), dan sebagai =waves-transition($transition) di SASS (src/sass/waves.sass:9-24). Pemanggilannya juga berbeda: .waves-transition(all 0.5s ease-out); di Less (src/less/waves.less:40-61), @include waves-transition(all 0.5s ease-out); di SCSS (src/scss/waves.scss:54-59), dan +waves-transition(all 0.5s ease-out) di SASS (src/sass/waves.sass:54-61). Escape !important mengikuti pola yang sama: none ~'!important' di Less (src/less/waves.less:81-83) menjadi none #{"!important"} di SCSS (src/scss/waves.scss:82) dan di SASS (src/sass/waves.sass:82).

graph TD
  LESS["src/less/waves.less"]
  TRANS["waves-transition(@transition)"]
  XFORM["waves-transform(@string)"]
  SHADOW["waves-box-shadow(@shadow)"]
  RIPPLE[".waves-ripple"]
  NOTRANS[".waves-notransition"]
  FLOAT[".waves-float"]
  BUTTON[".waves-button / .waves-circle"]
  CSS["dist/waves.css"]

  LESS --> TRANS
  LESS --> XFORM
  LESS --> SHADOW
  TRANS --> RIPPLE
  TRANS --> NOTRANS
  TRANS --> FLOAT
  XFORM --> RIPPLE
  XFORM --> BUTTON
  SHADOW --> FLOAT
  RIPPLE --> CSS
  NOTRANS --> CSS
  FLOAT --> CSS
  BUTTON --> CSS

  style LESS fill:#f59e0b,color:#000
  style TRANS fill:#f59e0b,color:#000
  style XFORM fill:#f59e0b,color:#000
  style SHADOW fill:#f59e0b,color:#000
  style RIPPLE fill:#8b5cf6,color:#fff
  style NOTRANS fill:#8b5cf6,color:#fff
  style FLOAT fill:#8b5cf6,color:#fff
  style BUTTON fill:#8b5cf6,color:#fff
  style CSS fill:#2d7d46,color:#fff
%% fig: Mixin prefix vendor dan titik pakainya
%% desc: Tiga mixin di waves.less menyuplai prefix vendor ke empat blok aturan, lalu kompilasi Less menghasilkan dist/waves.css.
Fig. 1: Mixin prefix vendor dan titik pakainyaTiga mixin di waves.less menyuplai prefix vendor ke empat blok aturan, lalu kompilasi Less menghasilkan dist/waves.css.

Tiga mixin prefix vendor

Setiap mixin membungkus satu properti CSS beserta prefix vendor-nya. Tidak semua prefix disertakan, dan perbedaan itu disengaja: hanya waves-transform yang mengemit -ms-.

MixinProperti yang di-emitPrefix yang disertakanTitik pakai
waves-transition (src/less/waves.less:9-14)transition-webkit-, -moz-, -o-, tanpa prefix.waves-ripple, .waves-notransition, .waves-float
waves-transform (src/less/waves.less:16-22)transform-webkit-, -moz-, -ms-, -o-, tanpa prefix.waves-ripple, .waves-button, .waves-circle
waves-box-shadow (src/less/waves.less:24-27)box-shadow-webkit- dan tanpa prefix saja.waves-float, .waves-float:active

Hasil ekspansi terlihat di berkas hasil kompilasi. .waves-float memuat dua deklarasi box-shadow dan empat deklarasi transition karena memanggil waves-box-shadow dan waves-transition (dist/waves.css:120-132).

Titik pakai mixin

Blok induk .waves-effect menetapkan position: relative, overflow: hidden, dan -webkit-tap-highlight-color: transparent (src/less/waves.less:29-38). overflow: hidden inilah yang memotong ripple agar tidak keluar dari elemen.

.waves-ripple adalah pemakai terberat: waves-transition(all 0.5s ease-out) dan waves-transform(scale(0) translate(0,0)), dengan ukuran width: 100px, height: 100px, margin-top: -50px, margin-left: -50px, dan opacity: 0 (src/less/waves.less:40-61). Nilai margin negatif itu memusatkan lingkaran 100px pada koordinat ripple.

.waves-button dan .waves-circle memakai waves-transform(translateZ(0)) ditambah -webkit-mask-image: -webkit-radial-gradient(circle, white 100%, black 100%) (src/less/waves.less:85-89). Kombinasi ini memaksa elemen ke layer tersendiri dan memotong ripple pada WebKit.

.waves-notransition memanggil waves-transition(none ~'!important') sehingga transisi dimatikan (src/less/waves.less:81-83). JavaScript menambahkan lalu segera melepas kelas ini ketika menempatkan ripple (src/js/waves.js:162-164) agar posisi awal ripple tidak dianimasikan; urutan itu dijelaskan di Siklus Hidup Ripple.

.waves-float memakai waves-box-shadow(0px 1px 1.5px 1px rgba(0, 0, 0, 0.12)) dan waves-transition(all 300ms), lalu menaikkan bayangan menjadi 0px 8px 20px 1px rgba(0, 0, 0, 0.30) saat :active (src/less/waves.less:143-151).

Varian warna ripple: .waves-light dan .waves-classic

Varian dideklarasikan sebagai nested selector di dalam .waves-effect (src/less/waves.less:63-78). Yang menentukan warna akhir bukan urutan deklarasi saja, tetapi juga specificity selector hasil kompilasi.

VarianSelector terkompilasiNilai background akhir pada .waves-ripple
tanpa varian.waves-effect .waves-ripplergba(0,0,0,0.2) lalu gradient hitam radial-gradient
.waves-light.waves-effect.waves-light .waves-ripplergba(255,255,255,0.4) lalu gradient putih
.waves-classic.waves-effect.waves-classic .waves-ripplergba(0,0,0,0.2) datar, gradient hilang
.waves-classic.waves-light.waves-effect.waves-classic.waves-light .waves-ripplergba(255,255,255,0.4) datar

Perhatikan .waves-classic: blok itu hanya menetapkan background: rgba(0,0,0,0.2) (src/less/waves.less:63-78). Karena shorthand background menimpa empat deklarasi radial-gradient di .waves-ripple, ripple versi classic tampil sebagai warna datar, bukan gradien. Selector gabungan .waves-classic.waves-light mengembalikan warna datar putih, dan selector itu berada di urutan terakhir pada CSS hasil kompilasi (dist/waves.css:47-59).

Kelas bentuk: .waves-button, .waves-circle, .waves-float, .waves-block

KelasDeklarasi kunciCatatan
.waves-buttonpadding: 0.85em 1.1em, border-radius: 0.2em (src/less/waves.less:109-112)Gaya tombol semi-rounded
.waves-circlewidth: 2.5em, height: 2.5em, line-height: 2.5em, border-radius: 50% (src/less/waves.less:135-141)Butuh .waves-button untuk aturan mask
.waves-float-webkit-mask-image: none, shadow dan transition 300ms (src/less/waves.less:143-151)mask-image: none membatalkan mask dari .waves-button agar bayangan tidak terpotong
.waves-blockdisplay: block (src/less/waves.less:153-155)Membuat elemen memenuhi lebar induk

.waves-float sengaja mematikan mask karena mask yang sama dipakai .waves-button dan .waves-circle untuk memotong ripple (src/less/waves.less:85-89). Tanpa -webkit-mask-image: none, bayangan 20px di keadaan :active akan ikut terpotong. Kelas waves-* ini dipasang ke elemen lewat Waves.attach; pembungkusan elemen input dan img yang menambahkan .waves-input-wrapper dan .waves-button-input dibahas di Pembungkusan Elemen input dan img.