Tailwind Class Sorter: จัดเรียง Utility Classes ทุกตัวเข้าลำดับมาตรฐานเดียวกัน
จัดเรียง Tailwind class list ใดๆ เข้าสู่ canonical order โดยคง variant, arbitrary value และการจัดการ duplicate ไว้ครบถ้วน — ฟรี, รวดเร็ว และทำงาน 100% client-side
Table of Contents
Tailwind Class Sorter: จัดเรียง Utility Classes ทุกตัวเข้าลำดับมาตรฐานเดียวกัน
ทีมไหนที่ใช้ Tailwind CSS ก็เคยเจอ pull request แบบเดียวกันนี้ทั้งนั้น คนหนึ่งเขียน flex p-4 text-white อีกคนเขียน text-white flex p-4 และอีกคนแทรก hover:bg-blue-600 ไว้กลาง class string สไตล์ที่เรนเดอร์ออกมาเหมือนกันทุกอย่าง แต่ diff ดูรก รีวิวช้าลง และสุดท้ายก็ต้องมีสักคนถามคำถามที่เป็นต้นเหตุของการโต้เถียงทุกครั้งว่า "เราจะตกลงลำดับ class กันได้ไหม" ลำดับ class คือประเด็น code review ของ Tailwind ที่ไม่มีใครอยากเถียงกันสองรอบ และ Tailwind Class Sorter คือวิธีทำให้คุณไม่ต้องเถียงเรื่องนี้อีกเลย
เครื่องมือนี้รับ Tailwind class list แบบไหนก็ได้ — วางตรงๆ จาก className, ไฟล์ template หรือ clipboard — แล้วจัดเรียงเข้าสู่ canonical order ตามแนวคิดเดียวกับ prettier-plugin-tailwindcss variant อย่าง hover:, md: และ dark: จะยังติดอยู่กับ utility ของมันและถูกเรียงเป็นชั้นอย่างสมเหตุสมผล arbitrary value อย่าง w-[37px] ถูกเก็บไว้เป๊ะๆ เหมือนเดิม และมี toggle สำหรับลบ class ที่ซ้ำออกได้ ทุกอย่างทำงานแบบ 100% client-side ใน browser ของคุณ — ไม่ต้องสมัครสมาชิก ไม่ต้องติดตั้งอะไร และข้อมูลที่วางลงไปไม่เคยออกจากเครื่อง
บทความนี้จะพาไปดูว่าทำไม canonical order ถึงสำคัญ, เครื่องมือจัดการ variant และ arbitrary value อย่างไร และวิธีหยิบไปใช้ใน workflow ประจำวันโดยไม่ต้องคิดมาก
ทำไมต้องใช้ Tailwind Class Sorter?
-
จบประเด็นเรื่องลำดับ class ไปตลอด: เมื่อทีมมี canonical order เดียวกัน class string ของทุกคนจะมีรูปแบบเดียวกัน ไม่ต้องเถียงเรื่องความชอบส่วนตัวใน comment ของ review อีก ชี้ที่ผลลัพธ์เดียวกันแล้วไปต่อ
-
Variant อ่านง่ายขึ้น: class ที่มี prefix hover:, md:, dark: จะอยู่คู่กับ utility ที่มันแก้ไข และถูกเรียงเป็นชั้นที่สม่ำเสมอ คุณไม่ต้องไล่หา hover state ที่ซ่อนอยู่กลาง class string ยาวๆ อีก
-
Arbitrary value ถูกเก็บไว้เป๊ะๆ: w-[37px] หรือ bg-[#0f172a] จะไม่ถูกแก้ ไม่ถูกปัด และไม่ถูก "แก้ให้ตรง scale" สิ่งที่วางเข้าไปคือสิ่งที่ได้กลับมา — แค่เรียงใหม่เท่านั้น
-
มีระบบจัดการ duplicate ในตัว: class ที่ซ้ำจากการ merge แบบมีเงื่อนไขเป็นสาเหตุคลาสสิกของปัญหาเงียบๆ toggle ลบ duplicate จะรวมตัวซ้ำให้และบอกด้วยว่าลบไปกี่ตัว
-
ไม่ต้องเซ็ตอัพ: ไม่มี plugin ให้ติดตั้ง ไม่มี config ให้ต่อรอง ไม่มี CLI ให้ต่อเข้า CI เปิดหน้าเว็บ วาง class list copy ผลลัพธ์ ใช้ได้ทั้งกับแก้ไขเล็กๆ สองนาทีและ refactor ใหญ่
-
ปลอดภัยด้วยการออกแบบ: เพราะการเรียงเกิดขึ้นทั้งหมดใน browser ของคุณ class list จากโปรเจกต์เชิงพาณิชย์หรือที่ยังไม่เปิดตัวจะไม่หลุดออกจากเครื่อง
ฟีเจอร์หลัก
| ฟีเจอร์ | รายละเอียด |
|---|---|
| Canonical ordering engine | จัดเรียง utility ตามกลุ่ม property — layout, spacing, typography, visual แล้วจบด้วย state — ตามแนวคิดเดียวกับ prettier-plugin-tailwindcss |
| Variant-aware sorting | เก็บ variant chain อย่าง md:hover: ให้ครบและเรียงชั้น variant อย่างสม่ำเสมอ โดยมี base utility มาก่อน |
| Arbitrary value support | ค่าอย่าง w-[37px] หรือ shadow-[0_4px_6px_rgba(0,0,0,0.1)] ผ่านเข้าออกแบบ byte-for-byte |
| Duplicate removal | toggle สำหรับรวม class ที่ซ้ำ พร้อมรายงานจำนวน duplicates ที่ถูกลบ |
| Unknown class reporting | class ที่ไม่ตรงกับ utility group ที่รู้จักจะไม่ถูกทิ้ง — ถูกเก็บไว้ ถูก flag และถูกนับ |
| Live results | ผลลัพธ์อัปเดตตามที่พิมพ์ พร้อมปุ่ม copy คลิกเดียวและ class list ตัวอย่างในตัว |
| 100% client-side | ทุกอย่างเกิดขึ้นใน browser — ไม่มี upload, ไม่มีบัญชี, ไม่มี network call |
บางฟีเจอร์น่าพูดถึงเป็นพิเศษ การอัปเดตแบบ real-time ทำให้การเรียง class กลายเป็นกิจวัตรแทนที่จะเป็นงานน่าเบื่อ: วาง แวะดู copy และส่วนที่จัดการ class ที่จำไม่ได้อย่างชัดเจนก็สำคัญกว่าที่ฟังดู — sorter ที่เงียบๆ ทิ้ง class ที่มันไม่รู้จักคือ sorter ที่ทำให้ UI พังได้ ที่นี่ class ที่ไม่รู้จักจะถูกเก็บไว้ท้ายผลลัพธ์และแสดงในสถิติ ไม่มีอะไรหายไปโดยคุณไม่รู้ตัว
วิธีใช้งาน
- เปิด Tailwind Class Sorter เครื่องมือโหลดทันที ไม่ต้องสมัคร ไม่ต้องตั้งค่า ถ้าอยากเห็นการทำงานก่อน ให้กดโหลด class list ตัวอย่างที่มีให้
- วาง class list ของคุณ copy เนื้อหาจาก className, string class="..." ใน template หรือ list ของ Tailwind utility ที่คั่นด้วยช่องว่างจากที่ไหนก็ได้
- เปิด toggle ลบ duplicate ถ้าต้องการ ปล่อยปิดไว้เพื่อให้ชุด class เหมือนเดิมทุกตัวอักษร หรือเปิดเพื่อรวมตัวที่ซ้ำและดูว่ามี duplicate กี่ตัว
- ตรวจผลลัพธ์ที่เรียงแล้ว ดูว่า variant อยู่ในชั้นที่คุณคาดหวัง และ class ที่ถูก flag ว่าไม่รู้จักนั้นตั้งใจใช้จริง
- Copy ผลลัพธ์กลับเข้าโค้ด วางทับ string เดิม commit แล้วทำซ้ำกับทุกที่ที่ class เริ่มเละ
Canonical Order คืออะไร และทำไมมันจึงช่วยได้
ตัว sorter จัดกลุ่ม utility ตาม property family โดยอ่านไล่ไปเหมือนตอนที่คุณออกแบบ component ตั้งแต่ต้น: layout → spacing → typography → visual → state class ฝั่ง layout อย่าง flex และ items-center มาก่อนเพราะเป็นตัวกำหนดโครงสร้าง ตามด้วย spacing (p-4, md:px-8), typography (text-white, font-semibold), การตกแต่งภาพ (rounded-lg, bg-blue-500, shadow-lg) และปิดท้ายด้วย state variant อย่าง hover:bg-blue-600 การอ่าน class string ตามลำดับนี้จึงเล่าเรื่องเดียวกับตัว component: มันคืออะไร กินพื้นที่เท่าไร ตัวหนังสือหน้าตาเป็นอย่างไร ทาสีอย่างไร และตอบสนองการ interaction อย่างไร
ชั้นของ variant ถูกเรียงแบบ inside-out ภายใต้โครงสร้างเดียวกัน base utility มาก่อน class ที่มี variant prefix เสมอ และ class อย่าง md:hover:bg-blue-700 จะไปอยู่ข้างๆ class md: ตัวอื่น ไม่ใช่ลอยอยู่ตรงที่มันถูกพิมพ์ไว้ class ที่ variant น้อยกว่ามาก่อน class ที่ prefix เยอะกว่า ดังนั้น p-4 จึงมาก่อน md:px-8 ผลลัพธ์คือลำดับการอ่านที่คาดเดาได้: default ก่อน ตามด้วย hover, responsive override แล้วจึงเป็น dark mode
arbitrary value คือเสาหลักที่สาม sorter ที่พยายามตีความ w-[37px] มักทำพังมันซะมากกว่า ที่นี่ expression ทั้งก้อนในวงเล็บถูกถือว่าเป็น token ทึบ เรียงตาม property family ของมัน แล้วส่งออกแบบต้นฉบับเป๊ะๆ ความกว้าง 37 พิกเซลส่วนตัวของคุณจึงรอดจากการเรียงโดยไม่เปลี่ยนแปลง
สุดท้าย การลบ duplicate และลำดับที่คงที่รวมกันเป็นประโยชน์ที่เงียบแต่ใหญ่: diff ที่เล็กลง เมื่อสองคนแก้ component เดียวกัน canonical order ทำให้บรรทัดที่เปลี่ยนมีเฉพาะบรรทัดที่ styling เปลี่ยนจริงๆ ถ้าไม่มีมัน การเรียงใหม่จากความจำสามารถแตะทุกบรรทัดของ class string แล้วฝังการเปลี่ยนแปลงที่สำคัญเพียงจุดเดียวไว้ในกองเสียงดนตรีที่สับเปลี่ยนไปมา
ลองดู className ที่รกหนึ่งอัน ก่อนและหลัง:
<!-- ก่อน -->
<button
class="text-white hover:bg-blue-600 p-4 flex items-center md:px-8 rounded-lg shadow-lg bg-blue-500 font-semibold"
>
<!-- หลัง -->
<button
class="flex items-center p-4 md:px-8 text-white font-semibold rounded-lg bg-blue-500 shadow-lg hover:bg-blue-600"
></button>
</button>
class เดิมทุกตัว ปุ่มเรนเดอร์เหมือนเดิมทุกอย่าง — แต่ตอนนี้ใครก็อ่านออกทันทีว่าส่วนไหนคือ layout, spacing, typography และ hover state
กรณีใช้งานจริง
1. ความสม่ำเสมอใน code review
ผลตอบแทนที่เห็นไวที่สุดคือใน pull request เมื่อทีมตกลงว่า class string ต้องผ่าน sorter ก่อน commit comment ในการรีวิวจะหยุดพูดเรื่องลำดับและเริ่มพูดเรื่องสาระ reviewer ที่สแกน diff จะเห็นการเปลี่ยนแปลงที่มีความหมายแทนความรกจากการสลับที่ และไม่มีใครต้องพิมพ์ว่า "ช่วยเก็บ class ที่มี hover: ไว้ด้วยกัน" เป็นครั้งที่ห้าแล้ว
2. จัดระเบียบ component ที่กระจัดกระจาย
codebase เก่าๆ จะสะสม class string จากคนละคน เครื่องมือละเครื่อง และ AI ละตัว แต่ละอย่างก็มีนิสัยของตัวเอง การหยิบ class ของ component มาผ่าน sorter เป็นขั้นตอน normalize ที่เร็วและเสี่ยงต่ำระหว่างช่วงเก็บกวาด: สไตล์ไม่เปลี่ยนแน่นอน, diff เป็นแค่งานกลไก และไฟล์กลับมาสม่ำเสมอกับโค้ดส่วนที่เหลือ
3. ไฟล์ template และ starter
boilerplate, email template, snippet ใน README และ starter component ถูก copy ข้ามโปรเจกต์และถูกแก้ทีละจุดเป็นเวลาหลายปี การเรียง class string ของไฟล์พวกนี้สักรอบเปลี่ยนมันเป็นไฟล์อ้างอิงที่เสถียร ทุก copy ถัดไปจึงเริ่มจาก baseline เดียวกัน ไม่ใช่สืบทอดความรกของเมื่อวาน
4. สอน convention การเรียง Tailwind
ถ้าคุณกำลัง onboarding developer ที่เพิ่งเจอ Tailwind canonical order ยังทำหน้าที่เป็นหลักสูตรไปในตัว การเอา component จริงสักสองสามตัวมาเรียงพร้อมกัน แสดงให้เห็นจับต้องได้ว่า utility แต่ละกลุ่มแม็ปกับ property family ไหนและชั้น variant ซ้อนกันอย่างไร — เร็วกว่าเอกสาร style guide ที่ไม่มีใครอ่านหลายเท่า
Best Practices
- เลือกลำดับเดียวแล้วทำให้เป็นอัตโนมัติ: ลำดับไหนสำคัญน้อยกว่าการมีลำดับเดียว ให้ sorter เป็นเครื่องมือกลางของทีม เพื่อให้ class string ทุกอันเบนเข้าหารูปแบบเดียวกันโดยไม่ต้องประชุมหรือบังคับด้วย style guide
- เรียงก่อน commit ไม่ใช่หลัง commit: ฝังการเรียงเร็วๆ ไว้ในนิสัยก่อน commit จะทำให้ diff ทุกอันในอนาคตสะอาด commit เฉพาะกิจสำหรับจัด format ย้อนหลังก็ได้ แต่แยกไว้จากการเปลี่ยน logic เพื่อให้ review อ่านง่าย
- รักษาความอ่านง่ายของ variant: วางใจกับลำดับชั้น base → hover: → md: → dark: ถ้าคุณต้องไล่หา variant ใน string ที่เรียงแล้ว แปลว่า string นั้นยาวเกิน — เป็นสัญญาณให้แตกเป็น component แทน
- แวะดูรายการ unrecognized: ถ้าเครื่องมือ flag class ที่มันไม่รู้จัก ให้เช็กว่าเป็น custom utility หรือพิมพ์ผิด พิมพ์ผิดในชื่อ class มองไม่เห็นใน diff และเงียบที่ runtime sorter ทำให้มันมองเห็น
- ใช้ dedupe อย่างตั้งใจ: ปล่อยปิดไว้เมื่อต้องการชุด class เหมือนเดิมเป๊ะทุก byte และเปิดเมื่อสงสัยว่าการ merge แบบมีเงื่อนไขทิ้งตัวซ้ำไว้
- จับคู่กับเครื่องมือข้างเคียง: เมื่ออยากเห็นว่า class ที่เรียงแล้วคอมไพล์เป็น CSS อะไร ให้ส่งผ่าน converter เมื่อ arbitrary value เริ่มงอกเงย ให้เช็กก่อนว่าตัวเลขแปลงหน่วยได้สวยหรือควรอยู่บน scale
เริ่มจัดเรียง className แรกของคุณวันนี้
เรื่องลำดับ class เป็นประเด็นที่ควรเถียงแค่ครั้งเดียว — งั้นก็จบมันด้วยการเลือกเครื่องมือ ไม่ใช่ด้วยการเขียน manifesto เปิด Tailwind Class Sorter วาง class string ที่รกที่สุดใน codebase ของคุณลงไป แล้ว copy ผลลัพธ์ที่เป็น canonical, ไร้ duplicate และคำนึงถึง variant กลับมาในไม่กี่วินาที reviewer ในอนาคตจะขอบคุณคุณ และ diff ของคุณจะได้สื่อความหมายในที่สุด
Related Tools You Might Like:
- Tailwind to CSS Converter — แปลง Tailwind utility classes กลับเป็น CSS rules
- CSS Custom Properties Generator — สร้างชุด CSS variables สำหรับ design tokens ของคุณ
- CSS Unit Converter — แปลงหน่วย px, rem, em และหน่วย CSS อื่นๆ
Happy sorting!
คำถามที่พบบ่อย
ถ: การเรียง class ใหม่จะเปลี่ยนผลการเรนเดอร์หรือไม่?
ตอบ: ไม่ Tailwind ใช้สไตล์ตามตัวตนของ class ไม่ใช่ตามตำแหน่งใน attribute ดังนั้นการสลับลำดับ class ไม่มีผลต่อ computed styles ทางเลือกเดียวที่มีพฤติกรรมเชิงผลคือการลบ duplicate ซึ่งก็ไม่มีผลทางสายตาเช่นกัน — แค่ตัด class ที่ซ้ำออก
ถ: class list ของฉันถูกอัปโหลดไปเซิร์ฟเวอร์หรือไม่?
ตอบ: ไม่ sorter ทำงานทั้งหมดใน browser ของคุณแบบ 100% client-side class string จากโปรเจกต์ส่วนตัวหรือเชิงพาณิชย์ไม่เคยออกจากเครื่อง และไม่ต้องใช้บัญชีใดๆ
ถ: class ที่ sorter ไม่รู้จักจะถูกจัดการอย่างไร?
ตอบ: จะถูกเก็บไว้ class ที่ไม่รู้จักจะถูกวางท้ายผลลัพธ์ ถูก flag และถูกนับในสถิติ ทำให้ custom utility หรือการพิมพ์ผิดมองเห็นได้ แทนที่จะถูกทิ้งแบบเงียบๆ
ถ: รองรับ variant ซ้อนกันอย่าง md:hover:bg-blue-700 หรือไม่?
ตอบ: รองรับ variant chain จะถูกแยก เก็บลำดับเดิม และเรียงเป็นชุดเดียว variant ซ้อนอย่าง md:hover: จึงไปอยู่ติดกับ class md: ที่เกี่ยวข้องอย่างสม่ำเสมอ ไม่กระจัดกระจายไปทั่ว string
ถ: เรียง class ในไฟล์ HTML ทั้งไฟล์ได้ไหม?
ตอบ: เครื่องมือเรียง class list ทีละ string ไม่ใช่ parse เอกสารทั้งไฟล์ copy className หรือ class attribute เข้ามา แล้ววางผลลัพธ์กลับ — workflow ที่ยังเร็วอยู่แม้จะทำหลายไฟล์