Styling di era Component

Are we getting lost or is it just me?

Fondasi untuk membuat sebuah halaman website yakni ada 3; HTML, CSS, dan JavaScript. Sekompleks apapun aplikasi web yang kita buat, yang diakan dilihat oleh user adalah hasil akhir dari pergabungan HTML, CSS, dan JavaScript tersebut.

Wasm/Web Assembly pun hanyalah pseudo-binary yang nantinya dipanggil oleh JavaScript.

Tulisan ini bukan untuk mempengeruh permasalahan tentang JS-JS-JS, namun hanya sebagai refleksi dari seorang Frontend Engineer yang sekarang sedang fokus di engineering User Interface.

Pure CSS

a.k.a CSS in CSS

Sebelum Frontend Development menggunakan teknik Modern, yang perlu dilakukan untuk styling adalah menulis kode CSS. Ya, entah menggunakan nama style.css atau app.css , yang penting it works.

Lalu muncul lah beberapa masalah, seperti override style menggunakan !important yang sangat tidak predictable, atau tidak ada penerapan DRY sama sekali, sehingga kita menulis kode yang sebenarnya sudah ditulis sebelumnya.

Atau, harus mengingat properti apa saja yang harus menggunakan prefix -webkit , atau -moz , dan -o .

Tapi — mungkin waktu dulu — tidak masalah. Sampai ketika masalah mulai muncul.

CSS Preprocessor

a.k.a everything compiled to CSS

Untuk menghindari duplikasi kode, dan juga penerapan styling yang lebih predictable, mulailah kita menggunakan CSS Preprocessor.

Ditambah menggunakan metodologi BEM, atau sekalian menerapkan arsitektur ITCSS agar lebih lengkap. Penerapan ini gue rasa yang paling efektif, semua styling kita pisah dari Settings, Tools, Generic, Elements, Objects, Components, sampai Utilities. Yang mana semakin bawah (di ilustrasi triangle tersebut), maka penerapannya semakin eksplisit.

Tidak ada masalah dari penggunaan CSS Preprocessor + BEM Methodology dalam styling untuk suatu Web App. Untuk penyesuaian dengan state pun kita bisa menggunakan modifier (seperti .c-button--disabled misalnya).

Apa yang menjadi masalah disini?

Hoisting? Dengan BEM kita tidak perlu meribetkan hosting karena sudah ter-scope di Object/Components

DRY? Gue kira sudah bisa menghindari duplikasi disini.

Untuk macro pun rata-rata setiap CSS Preprocessor pasti memilikinya kan?

CSS In JS

Ini adalah tren baru di modern frontend, kita menulis CSS didalam JavaScript. Lebih tepatnya di era component.

Dengan CSS in JS, rata-rata styling sudah ter-scope by default. Gue menggunakan CSS in JS dari era PostCSS (tools untuk transform CSS menggunakan JavaScript) sampai ke sekarang yang pernah mencoba menggunakan Styled Components dan Emotion.

Berdasarkan section Motivation dari Styled Components (no offense), yang gue dapet adalah seperti ini:

Berdasarkan penjelasan diatas yang paling gue dapet adalah Automatic critical CSS (hanya load “CSS” yang digunakan disuatu page saja), Simple dynamic styling (style bisa disesuaikan berdasarkan state), dan Automatic vendor prefixing (yang sebenarnya bisa diterapkan juga menggunakan PostCSS).

Ada beberapa “skeptik” yang gue miliki terhadap CSS in JS ini, antara lain:

Vendor Lock-in.

Ya, dengan menggunakan CSS in JS styling tersebut hanya bisa diterapkan berdasarkan framework yang digunakan (meskipun Emotion adalah Framework agnostic, tapi tetap ada kata Framework, kan?)

Yang artinya, sekali kita menyelam kesana, maka kita akan sulit untuk kembali ke permukaan. Mending kalau yang framework agnostic, kalau yang enggak?

Masih ingat sesimple apa “menggunakan styling” dengan hanya menambahkan <link rel="" /> ? Tanpa memikirkan kita menggunakan framework apa, it just works.

Dengan menulis CSS di JS ini, kita harus menggunakan framework yang didukung oleh CSS in JS library tersebut, framework apapun selagi didukung.

All back to the global

Se-scoped apapun styling yang kita terapkan, maka akan ada saja suatu style yang memang berada di global, utility contohnya. Ketika kita ingin membuat spacing horizontal sebesar 20px, pasti kita menggunakan ‘variable’ yang telah kita buat tersebut (misal $spacing-sm: 20px ). Atau tidak, menggunakan utility khusus (seperti .u-ph-sm untuk menerapkan padding horizontal sebesar 20px).

Apa bedanya dengan menggunakan CSS tanpa JS, kan?

Every byte count

Biasanya dengan menggunakan library CSS in JS, mereka akan merubah className kita dari .c-navbar menjadi misalnya .c34sdfds yang lebih singkat. Terkadang ada yang menggunakan cara “inline styling”, misal bila .c-navbar memiliki property: background-color: white; color: white , maka className untuk masing-masing property tersebut adalah (misalnya): .w23f dab .c2fs .

Apakah ukuran file di CSS benar-benar sangat berpengaruh? Ukuran file Bootstrap 4 saja (minified + gzipped) mencapai 22.6kb, atau tachyons yang hanya 10.6kb. Gue kira beda 10–40kb untuk styling tidak terlalu berpengaruh lah ya?

Static files are cacheable

File CSS “murni” adalah cacheable. Zero runtime. Berdasarkan framework CSS in JS yang gue jumpai rata-rata styling berada di runtime. Tidak tau proses cachingnya seperti apa, intinya non-zero runtime.

Dengan file CSS murni/CSS Preprocessor, paling processor nya berada di build time/compile time. Proses painting dll nya yang dilakukan oleh browser tidak bisa kita kontrol, kan? Mungkin menggunakan CSS in JS bisa membuat prosesnya lebih efisien.

Kesimpulan

Gue hanya sedikit skeptik dengan teknologi CSS in JS ini. Gue rasa proses styling untuk DOM lebih efisien menggunakan CSS Preprocessor. Penamaan class yang panjang pun .enggakMungkinSepanjang__ini--kan ?

Autoprefix bisa dilakukan menggunakan PostCSS yang technically CSS in JS, tapi hanya sebagai transformer, bukan framework/library.

Gue menyinggung topik ini karena sedikit kesel dengan company yang menerapkan teknologi ini, tapi tidak terlalu memikirkan efek sampingnya.

Bagaimana untuk styling suatu DOM yang berbeda framework?

Bagaimana untuk styling suatu DOM yang ternyata tidak menggunakan framework? (Not virtual DOM)

Gue sendiri di kantor sekarang hanya mengandalkan Stylus sebagai CSS Preprocessor, dan menggunakan Vue sebagai stylingnya.

Untuk penggunaan “Scoped CSS” yang ditawarkan Vue, paling hanya dalam proses composing (penataan/pembungkusan component). Ketika gue ingin menggunakan framework lain selain Vue, gue rasa enggak perlu proses yang ribet agar component nya seragam.

Ingin di compile sebagai standalone CSS aja pun bisa.

Jadi, gimana? Mengapa Prisma, InVison, Autodesk, Vogue, Spectrum, Casper, Coinbase, Typeform, dan Patreon menggunakan Styled Components dan Nytimes misalnya menggunakan Emotion yang basically CSS in JS?

Dan mengapa ada yang tidak menggunakan CSS in JS?

I don’t know. Yang gue rasa, gue gak ada masalah dengan penggunaan everything compiled to CSS dalam workflow gue, dalam UX, dan DX.

Atau gue aja yang memang kurang pengalaman?