Halo! Sudah atau mau mencoba Tailwind CSS? pas banget kesini! saya akan membagikan beberapa hal yang cukup penting seputar Tailwind CSS.
Sebenarnya bukan 'best practices' juga sih. Lebih ke coding style dan beberapa tips yang membuat saya nyaman dalam menggunakan Tailwind CSS.
Opiniated sih jatuhnya, tapi siapa tau ada yang bisa diambil, positifnya, ya kan.
Coding Style
Berikut coding style untuk penulisan Tailwind CSS classes yang sering saya gunakan, dibagi menjadi 3 point penting: sorting, splitting dan grouping.
Sorting
Coba liat dulu contoh komponen Button
berikut, panjang banget classnya 😂
<button
class="inline-flex h-10 items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 text-center text-sm font-bold text-white transition duration-150 hover:bg-purple-700 dark:bg-purple-600 dark:hover:bg-purple-500 md:rounded-xl"
>
Button Text
</button>
Karena berurusan dengan nama class yang akan sangat banyak hanya untuk sebuah element, sorting class cukup penting.
Untungnya, Tailwind CSS sendiri sudah menyiapkan plugin Prettier untuk menghandle urusan ini.
Konsistensi urutan class akan memudahkan dalam proses maintenance kedepannya.
Misal, yang ada dalam contoh, dengan class yang sudah di sortir, kita bisa dengan mudah mengubah border
dan border-transparent
karena saling berdampingan.
Atau dapat dengan mudah mengubah styles hover:
atau breakpoints karena biasanya muncul di bagian akhir class.
Splitting
Untuk membuatnya lebih rapi, kita bisa split classnya jadi beberapa string atau line (agar tidak terlihat terlalu panjang). Kalau saya sih biasa pake clsx.
Contoh sebuah komponen Button
yang sudah menggunakan clsx
:
function Button({ children }) {
return (
<button
className={clsx(
'inline-flex h-10 items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 text-center text-sm font-bold text-white transition duration-150 hover:bg-purple-700 md:rounded-xl',
'dark:bg-purple-600 dark:hover:bg-purple-500'
)}
>
{children}
</button>
);
}
Grouping
Setelah classnya terpisah, kita bisa 'grouping' untuk membuatnya lebih rapi dan juga nyaman dibaca.
Biasanya, pattern yang saya terapkan adalah:
group 1
: default utilitesgroup 2
: breakpoints utilitiesgroup 3
: dark mode utilitesgroup 4
: other variants utilites
Kita implementasikan menggunakan komponen Button
tadi:
function Button({ children }) {
return (
<button
className={clsx(
// group 1
'inline-flex h-10 items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 text-center text-sm font-bold text-white transition duration-150',
// group 2
'md:rounded-xl',
// group 3
'dark:bg-purple-600 dark:hover:bg-purple-500',
// group 4
'hover:bg-purple-700'
)}
>
{children}
</button>
);
}
Sama halnya dengan komponen CSS:
.button {
/* group 1 */
@apply inline-flex h-10 items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 text-center text-sm font-bold text-white transition duration-150;
/* group 2 */
@apply md:rounded-xl;
/* group 3 */
@apply dark:bg-purple-600 dark:hover:bg-purple-500;
/* group 4 */
@apply hover:bg-purple-700;
}
Group 2,3 dan 4 sebenarnya masih bisa di improve atau disesuaikan lagi sesuai keinginan, hanya pastikan untuk membuatnya konsisten di setiap penulisan.
Tips
Gunakan Komponen
Jika dirasa beberapa element mempunyai styles yang sama, bisa di split jadi komponen tersendiri, seperti button yang biasanya memiliki styles yang sama.
Karena saya menggunakan React, saya bisa saja membuat komponen seperti:
function Button({ children }) {
return (
<button
className={clsx(
'inline-flex h-10 items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 text-center text-sm font-bold text-white transition duration-150',
'md:rounded-xl',
'dark:bg-purple-600 dark:hover:bg-purple-500',
'hover:bg-purple-700'
)}
>
{children}
</button>
);
}
Gunakan Class Component
Sama seperti komponen, tapi cara ini digunakan untuk optimasi ukuran atau output file html, khususnya untuk static site.
Karena nama class yang banyak dari Tailwind CSS akan menambahkan beban juga pada HTML.
Coba lihat contoh sederhana, penggunaan set utility yang sama pada button pagination berikut:
<button
class="inline-flex h-10 items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 text-center text-sm font-bold text-white transition duration-150 hover:bg-purple-700 dark:bg-purple-600 dark:hover:bg-purple-500 md:rounded-xl"
>
Previous
</button>
<button
class="inline-flex h-10 items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 text-center text-sm font-bold text-white transition duration-150 hover:bg-purple-700 dark:bg-purple-600 dark:hover:bg-purple-500 md:rounded-xl"
>
1
</button>
<button
class="inline-flex h-10 items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 text-center text-sm font-bold text-white transition duration-150 hover:bg-purple-700 dark:bg-purple-600 dark:hover:bg-purple-500 md:rounded-xl"
>
2
</button>
<button
class="inline-flex h-10 items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 text-center text-sm font-bold text-white transition duration-150 hover:bg-purple-700 dark:bg-purple-600 dark:hover:bg-purple-500 md:rounded-xl"
>
3
</button>
<button
class="inline-flex h-10 items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 text-center text-sm font-bold text-white transition duration-150 hover:bg-purple-700 dark:bg-purple-600 dark:hover:bg-purple-500 md:rounded-xl"
>
4
</button>
<button
class="inline-flex h-10 items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 text-center text-sm font-bold text-white transition duration-150 hover:bg-purple-700 dark:bg-purple-600 dark:hover:bg-purple-500 md:rounded-xl"
>
Next
</button>
Bayangkan jika dalam satu file HTML memiliki beberapa pagination juga, ukuran file HTMLnya pasti akan lebih besar!
Untuk mengurangi ukuran file size dari HTML, kita bisa ubah jadi class component. Kurang lebih penggunaannya seperti ini:
<button class="pagination-button">Previous</button>
<button class="pagination-button">1</button>
<button class="pagination-button">2</button>
<button class="pagination-button">3</button>
<button class="pagination-button">4</button>
<button class="pagination-button">Next</button>
Sudah pernah saya bahas disinidisini (point "Beban ke HTML makin berat").
Penggunaan !important
Layaknya CSS pada umumnya, sebisa mungkin hindari penggunaan !important
.
Di Tailwind CSS, !important
sendiri bisa dengan menambahkan prefix !
pada setiap utility class, contoh !p-2 !px-3
.
Sebisa mungkin hindari! Sekali terjebak menggunakan, mungkin semua utility kita akan berakhir dengan banyaknya !important
dan sangat sulit untuk melakukan perubahan styles kedepannya.
Conditional Class
<div className={`text-black ${dark && 'text-white'}`}>
Hello, World!
</div>
<div className={dark ? 'text-white' : 'text-black'}>
Hello, World!
</div>
Let me explain a bit.
Katakanlah kita pake cara yang pertama dan dark
nilainya true
, maka classnya akan jadi seperti ini text-black text-white
.
Dalam beberapa kasus, mungkin hasilnya ya sesuai harapan. Tapi, ketika beberapa kasus juga, mungkin bisa jadi masalah!
Bisa saja, teks tetap berwarna hitam meski nilai dark
nya true.
Ko bisa? Let the code speak:
<!-- Some elements within the project. -->
<div class="text-white">White!</div>
<div class="text-black">Black!</div>
<!--
The above elements will generate CSS in the following order:
.text-white {
...
}
.text-black {
...
}
-->
<!--
Imagine that "dark" is set to true, and use a class defined as follows for conditional class:
class={`text-black ${dark && 'text-white'}`}
-->
<div class="text-black text-white">Still black? CSS Specificity!</div>
<!--
That's because, in this example, both "text-black" and "text-white" have the same CSS properties and specificity.
On the other hand, the last one defined in the CSS file (in the previously generated CSS) will take precedence!
-->