Untuk sistem reka bentuk, ketekalan dan kefahaman adalah segala-galanya. Sistem reka bentuk yang baik memastikan ketekalan pelaksanaan melalui konfigurasi kod yang melaksanakannya. Ia perlu:
Menggunakan tindanan lalai saya React with Tailwind, saya akan menunjukkan kepada anda cara menetapkan lalai anda sendiri untuk tipografi, warna dan jarak bukan sahaja titik permulaan untuk membezakan rupa dan rasa apl anda. Lebih penting lagi, ia secara drastik mengurangkan kod yang perlu kita tulis dan kekalkan, yang mengurangkan beban mental untuk melaksanakan gaya dengan cara yang sistematik, konsisten dan bebas ralat.
Saya akan mulakan dengan kritikan utama yang saya lihat sepanjang masa, dan kemudian pecahkan satu siri langkah konfigurasi yang saya gunakan untuk menyelesaikannya.
Tailwind memudahkan pembangun menulis gaya, yang bagus untuk prototaip pantas. Tetapi kemudahan itu tidak menjamin reka bentuk yang baik atau sistem reka bentuk yang boleh skala dan boleh diselenggara.
Alat lalai dan konfigurasi sifar seperti Tailwind ialah lapisan kelajuan infrastruktur yang menghasilkan lebih banyak masa untuk membina. Tetapi jika anda menskalakan apl yang menggunakan sistem reka bentuk untuk membezakan dirinya, anda tidak boleh bergantung semata-mata pada konfigurasi luar kotak "percuma seperti makan tengah hari".
Jika anda menjalankan dengan konfigurasi Tailwind lalai dan pengurusan gaya tolak ke aplikasi kelas pada komponen, hasilnya selalunya adalah kekacauan kelas yang sukar untuk difikirkan merentas komponen, menyamar sebagai sistem reka bentuk.
Di atas adalah contoh utama. Ia hampir tidak boleh dibaca dan mengambil masa yang lama untuk memahami, apatah lagi memanipulasi. Percubaan untuk berbuat demikian berkemungkinan besar akan membawa kepada pertindihan dan ralat, menjauhkan diri daripada konsistensi reka bentuk di seluruh apl.
Adalah mudah untuk menggabungkan kelas reka bentuk anda menjadi satu Nama kelas. Tetapi tiada kemudahan pengetahuan dalam melakukannya.
Kemudahan penggunaan disertakan dengan pertukaran. Menggunakan standard orang lain bermakna bergantung pada pengetahuan mereka. Ini boleh memberi manfaat, tetapi ia juga boleh menjadi perangkap. Mari kita berundur dan fikirkan tentang apa yang terdiri daripada asas sistem reka bentuk:
Dalam konteks React with Tailwind, ini dan banyak elemen sistem reka bentuk lain ditetapkan dalam konfigurasi Tailwind, yang boleh kami sesuaikan.
{/* lebih cantik-abaikan */}
const config = { theme: { fontSize: { /* ... */ }, colors: { /* ... */ }, spacing: { /* ... */ }, }, };
Pernahkah anda bergelut untuk mengingati jarak huruf yang betul untuk teks kecil anda? Bagaimana jika anda boleh menetapkannya sekali dan melupakannya?
Kami boleh menetapkan pendahuluan (ketinggian garis) dan penjejakan (jarak huruf) sebagai parameter untuk setiap tuple saiz fon secara langsung dalam tailwind.config. Ini bermakna kita tidak perlu menetapkan petunjuk atau penjejakan apabila kita menggunakan kelas saiz fon. Tidak perlu mengingati (atau gagal mencari) apakah jarak huruf teks kecil.
fontSize: { small: [ "13px", { lineHeight: 1.5, letterSpacing: "0.015em" }, ], base: [ "16px", { lineHeight: 1.5, letterSpacing: 0 }, ], }
Menggunakan text-small kini menetapkan saiz fon, ketinggian baris dan jarak huruf. Melampirkan tuple tipografi teras bersama-sama dalam satu kelas memusatkan pelaksanaan nilai ini ke dalam konfigurasi dan bukannya merentas pangkalan kod. Kemenangan besar untuk kebolehselenggaraan.
/* 13px/1.5 with 0.015em letter-spacing */ <div className="text-small" />
Kami boleh menggunakan pembolehubah CSS untuk menetapkan warna responsif di bawah skop :root dan html.dark. Ini bermakna kami menulis dan mengurus satu kelas, seperti bg-canvas, bukannya dua, seperti bg-gray-100 dark:bg-gray-800.
@import "@radix-ui/colors/gray.css"; @import "@radix-ui/colors/gray-dark.css"; :root { --color-gray-base: var(--gray-1); --color-gray-bg: var(--gray-3); --color-gray-line: var(--gray-4); --color-gray-border: var(--gray-5); --color-gray-solid: var(--gray-10); --color-gray-fill: var(--gray-12); }
Oleh kerana saya menggunakan Warna Radix di sini, saya tidak perlu menetapkan skop .dark kerana itu sudah pun dilakukan untuk saya. Jika anda tidak menyukai warna Radix, anda boleh menyesuaikannya, menggunakan perpustakaan lain atau menulis sendiri.
Kemudian tetapkan pembolehubah CSS dalam konfigurasi Tailwind.
colors: { canvas: "var(--color-gray-base)", background: "var(--color-gray-bg)", line: "var(--color-gray-line)", border: "var(--color-gray-border)", solid: "var(--color-gray-solid)", fill: "var(--color-gray-fill-contrast)", }
Menggunakan bg-canvas kini menetapkan warna yang sesuai dalam mod terang atau gelap. Mengalih keluar pertindihan ini merentas pangkalan kod memusatkan pengurusan warna pada konfigurasi kami dan bukannya menyebarkannya merentas pelaksanaan kelas pada komponen. Kemenangan besar untuk kognisi dan kebolehselenggaraan.
/* sets --gray-1 as #fcfcfc on :root or #111111 on html.dark */ <div className="bg-canvas" />
Saya menyokong nama semantik untuk warna dan saiz fon kerana penamaan semantik ialah fungsi memaksa yang mengikat makna untuk digunakan. Melakukannya mengalih keluar kerja tekaan pelaksanaan dan mengurangkan ralat.
Saya telah melihat banyak projek yang tidak konsisten kelabu-50, kelabu-100 atau kelabu-200 semuanya digunakan untuk latar belakang. Ini mudah diselesaikan dengan mentakrifkan warna yang dipanggil latar belakang.
In the same way, it is easier to remember the names for dark and light text colors when they are called fill and solid. It's harder and more error-prone when they're called gray-900 and gray-600 because then you have to remember specifically that it wasn't gray-950 and gray-500, or gray-800 and gray-700.
But naming things—and agreeing on naming—is hard. In the spirit of zero-config, I suggest taking Radix Color's backgrounds, borders, solids & fills paradigm. Or this palette semantics.
And once you've set this in tailwind.config, Typescript will jog your memory at your fingertips with autocomplete.
If you're extending a Tailwind theme and not writing your own, don't use a scale key that's already been used. You may inadvertently overwrite a class that you need to use.
You'll note in the previous colour config example that I set the --color-gray-base var to canvas, not base. If I used base then using this color scale as a text colour (text-base) would clash with the default font-size base value, which is also text-base.
This isn't a downfall of customising the Tailwind config, it's a legacy of its theme naming: setting font-size or color classes in Tailwind both use text-*.1
We can also use CSS variables to set spacings.
:root { --height-nav: 80px; --height-tab: 54px; --space-inset: 20px; --container-text-px: 660px; --container-hero-px: 1000px; }
spacing: { em: "1em", /* relate icon size to parent font-size */ nav: "var(--height-nav)", inset: "var(--space-inset)", text: "var(--container-text)", hero: "var(--container-hero)", }
One could argue this is over-engineering. Except that when it comes time to compute complex interactive layouts like sticky headers, scroll margins and so on, this upfront configuration work makes it straight forward and error-free, to the pixel.
<div className="top-[calc(theme(spacing.nav)+theme(spacing.tab))]"> <div className="scroll-mt-[calc(theme(spacing.nav)+theme(spacing.tab))]"> /* ... */ </div> </div>
Note again the use of semantic naming makes it easy to remember and use.
We have now configured typography, colour and spacing tokens in a manner that is easy to understand and maintain in a single, centralised place. And we don't need to wrire as many classes to implement the system. Winning. And there's further steps we can take to reduce this implementation overhead.
What if I told you there's a way to completely avoid writing text-lg lg:text-xl xl:text-2xl p-2 md:p-4 lg:p-8 everywhere?
We can avoid setting responsive font-size classes by using clamp as a a font-size value in tailwind.config. Here's the simple clamp function I use.
fontSize: { title: [ /* clamp(17px, 14.1429px + 0.5714vw, 21px) */ generateClampSize(500, 1200, 17, 21), { lineHeight: 1.5, letterSpacing: "-0.015em" }, ]; }
So instead of writing text-lg lg:text-xl xl:text-2xl we can just write text-title. Once again, by hoisting font-size responsiveness into a clamp value, we avoid the "implement classes" pitfall again, saving mental effort, errors and debugging time.
Keep in mind, this means we've moved from text-lg lg:text-xl xl:text-2xl leading-none tracking-wide to text-title by properly configuring Tailwind. Winning!
/* 17px at 500px, 21px at 1200, fluidly calculated inbetween */ /* …with default line-height and letter-spacing also specified */ <h2 className="text-title"> Heading copy </h2>
We can also do this for spacing. When extending a theme, I prefix these keys with d for "dynamic" to differentiate it from the default spacing scale.
spacing: { /* lower value is 2/3 of upper value */ d4: generateClampSize(500, 1200, 10.5, 16), d8: generateClampSize(500, 1200, 21, 32), d16: generateClampSize(500, 1200, 43, 64), d24: generateClampSize(500, 1200, 64, 96), d64: generateClampSize(500, 1200, 171, 256), }
This allows us to write py-d24 instead of py-16 md:py-20 lg:py-24. This alleviates the weight of holding a range of website versions for each media-query in our minds. Instead it encourages us to picture fluidly responsive layouts where measurements don't matter as much as consistent relationships.
<main className="pt-d24 pb-d64 space-y-w8"> <header className="container max-w-hero space-y-1"> /* ... */ </header> <article className="container space-y-2"> /* ... */ </article> </main>
Well-crafted UI is your last defense against the coming slopwave of careless AI apps. Here's how customizing Tailwind can save you time and headaches so you can focus on the irrational amount of care it takes to build UI that works in the blink of an eye:
Yes, there's an upfront time cost. But it pays off in spades: less code, fewer errors, greater design consistency, and a team that actually understands the system.
Next up: We'll explore how to use Class Variance Authority to create a bulletproof styling API with semantic props drawn from Tailwind. Stay tuned.
This is also why I dislike using tailwind-merge to remove duplicate Tailwind classes in JSX. More often than not, I find it removing a text-color in favour of a text-fontSize when both are needed. I'm surprised more developers don't raise this issue. ↩
Atas ialah kandungan terperinci Mengkonfigurasi Tailwind sebagai Sistem Reka Bentuk. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!