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-171). 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-1512). Berkas src/sass/waves.sass dibuat sass-convert dari src/scss dengan indent: 2 (Gruntfile.js:88-993).
⚠️
src/scss/waves.scssdansrc/sass/waves.sassditulis ulang oleh task build, jadi perubahan manual pada keduanya akan hilang padagrunt buildberikutnya. Ubahsrc/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-144), sebagai @mixin waves-transition($transition){ ... } di SCSS (src/scss/waves.scss:9-275), 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.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-.
| Mixin | Properti yang di-emit | Prefix yang disertakan | Titik pakai |
|---|---|---|---|
waves-transition (src/less/waves.less:9-144) | transition | -webkit-, -moz-, -o-, tanpa prefix | .waves-ripple, .waves-notransition, .waves-float |
waves-transform (src/less/waves.less:16-2213) | transform | -webkit-, -moz-, -ms-, -o-, tanpa prefix | .waves-ripple, .waves-button, .waves-circle |
waves-box-shadow (src/less/waves.less:24-2714) | 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-13215).
Titik pakai mixin
Blok induk .waves-effect menetapkan position: relative, overflow: hidden, dan -webkit-tap-highlight-color: transparent (src/less/waves.less:29-3816). 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-617). 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-8917). 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-8310). JavaScript menambahkan lalu segera melepas kelas ini ketika menempatkan ripple (src/js/waves.js:162-16418) 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-15119).
Varian warna ripple: .waves-light dan .waves-classic
Varian dideklarasikan sebagai nested selector di dalam .waves-effect (src/less/waves.less:63-7820). Yang menentukan warna akhir bukan urutan deklarasi saja, tetapi juga specificity selector hasil kompilasi.
| Varian | Selector terkompilasi | Nilai background akhir pada .waves-ripple |
|---|---|---|
| tanpa varian | .waves-effect .waves-ripple | rgba(0,0,0,0.2) lalu gradient hitam radial-gradient |
.waves-light | .waves-effect.waves-light .waves-ripple | rgba(255,255,255,0.4) lalu gradient putih |
.waves-classic | .waves-effect.waves-classic .waves-ripple | rgba(0,0,0,0.2) datar, gradient hilang |
.waves-classic.waves-light | .waves-effect.waves-classic.waves-light .waves-ripple | rgba(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-7820). 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-5921).
Kelas bentuk: .waves-button, .waves-circle, .waves-float, .waves-block
| Kelas | Deklarasi kunci | Catatan |
|---|---|---|
.waves-button | padding: 0.85em 1.1em, border-radius: 0.2em (src/less/waves.less:109-11222) | Gaya tombol semi-rounded |
.waves-circle | width: 2.5em, height: 2.5em, line-height: 2.5em, border-radius: 50% (src/less/waves.less:135-14123) | Butuh .waves-button untuk aturan mask |
.waves-float | -webkit-mask-image: none, shadow dan transition 300ms (src/less/waves.less:143-15119) | mask-image: none membatalkan mask dari .waves-button agar bayangan tidak terpotong |
.waves-block | display: block (src/less/waves.less:153-15524) | 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-8917). 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.