-
reset
- Tác giả ban đầu sao chép khoảng 200 dòng preflight styles của Tailwind từ
tailwind.css để dùng
- Vì đã quen với reset của Tailwind từ lâu, quy tắc áp dụng
box-sizing: border-box cho mọi phần tử giúp chiều rộng phần tử bao gồm cả padding
* { box-sizing: border-box; }
- Có thể tác giả còn đang vô thức phụ thuộc vào các quy tắc reset khác như
html {line-height: 1.5;}, và nếu viết CSS mà không có các quy tắc đó thì có vẻ sẽ cần một giai đoạn thích nghi khá lớn
-
components
- Phần lớn CSS được sắp xếp vào các file theo từng component, theo cách khá giống với component trong Vue hay React
- Mỗi component có class riêng để CSS của component này không ghi đè lên CSS của component khác
- Trên thực tế, khoảng 80% CSS cần chỉnh sửa nằm trong các file component, nên khi sửa một component dài 100 dòng thì chỉ cần nghĩ về đúng 100 dòng đó
- Ví dụ, component
.zine có thể có HTML như sau
<figure class="zine horizontal">
<img src="whatever.jpg">
</figure>
- CSS gom các trạng thái như
.horizontal, .vertical, :hover vào bên trong component bằng selector lồng nhau
.zine {
...
&.horizontal {
...
}
&.vertical {
...
}
&:hover {
...
}
}
- Dù chưa dùng cách ngăn can nhiễu giữa các component bằng cơ chế lập trình như Web Components hay
@scope, chỉ riêng việc đặt ra và tuân thủ quy ước cũng đã mang lại cảm giác cải thiện rất nhiều
-
colours
colours.css gom các CSS variable có thể dùng khi cần
- Vì màu sắc là phần khó và tác giả không muốn phải xem lại toàn bộ cách dùng màu trong lần refactor này, nên cách làm cũ vẫn được giữ nguyên
- Quy tắc duy nhất là liệt kê toàn bộ màu được dùng trên website trong file này
:root {
--pink: #fea0c2;
--pink-light: #F9B9B9;
--red: #f91a55;
--orange: rgb(222, 117, 31);
...
}
-
font sizes
- Trong Tailwind, chỉ cần chọn một nấc kích thước như
text-lg, xl, 2xl, nên không cần phải nhớ đang dùng em, px hay rem
- Để giữ điều này trong CSS thuần, tác giả định nghĩa các biến kích thước lấy từ Tailwind
--size-xs: 0.75rem;
--line-height-xs: 1rem;
--size-sm: 0.875rem;
--line-height-sm: 1.25rem;
- Kích thước font được chỉ định bằng biến; cách này dài dòng hơn Tailwind một chút nhưng hiện tại vẫn là phương pháp khiến tác giả hài lòng
h3 {
font-size: var(--size-lg);
line-weight: var(--line-weight-lg);
}
-
utilities
- Những phần tử lặp lại ở nhiều component, chẳng hạn như button, được xếp vào nhóm utilities
- Một số utility class như
.sr-only dành cho các phần tử chỉ nên hiển thị với người dùng screen reader được sao chép từ Tailwind
- Tác giả muốn giữ khu vực này nhỏ gọn và cẩn thận mỗi khi thay đổi
-
base
- Style “base” là các style được áp dụng trực tiếp trên toàn bộ website
- Vì tác giả chưa đủ chắc chắn để áp nhiều style lên toàn site, phần này được giữ rất nhỏ
- Hiện tại chỉ có hai quy tắc mà tác giả thấy ổn là cho
<section> và a, trong đó quy tắc cho <section> có thể còn thay đổi về sau
/* put a 950px column in the middle of each <section> */
section {
--inner-width: 950px;
padding: 3rem max(1rem, (100% - var(--inner-width))/2);
}
a {
color: var(--orange);
}
- Với base style, có vẻ dễ nhất là gần như để trống lúc đầu, rồi khi thấy điều gì thực sự muốn dùng chung thì chuyển dần từ component lên base theo cách tiếp cận từ dưới lên
-
spacing
- Cách quản lý padding và margin vẫn chưa được chốt hoàn toàn
- Khi còn dùng Tailwind, tác giả thường thêm padding và margin khá ngẫu hứng ở nhiều chỗ cho đến khi giao diện trông đúng ý, còn bây giờ đang tìm một cách có nguyên tắc hơn
- Hiện tại, tác giả cố gắng để các component layout bên ngoài chịu trách nhiệm về khoảng cách nếu có thể
- Khi muốn tạo khoảng cách đều giữa các phần tử con trong một
<section> có nhiều con, có thể dùng quy tắc sau
section > *+* {
margin-top: 1rem;
}
-
responsive design
- Trong Tailwind, tác giả dùng nhiều cú pháp dựa trên media query như
md:text-xl để áp dụng style text-xl từ một kích thước màn hình trở lên
- Hiện tại, tác giả muốn tạo các layout CSS grid linh hoạt hơn để không cần dùng breakpoint quá nhiều
- Khi dùng
auto-fit, có thể tự động hiển thị 2 cột trên màn hình lớn và 1 cột trên màn hình nhỏ
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 400px), max-content));
justify-content: center;
-
build system
- Trong quá trình phát triển, không cần build system riêng
- CSS có sẵn câu lệnh
@import để tách và nhập file
@import "reset.css";
@import "typography.css";
@import "colors.css";
- CSS cũng hỗ trợ selector lồng nhau
.page {
h2 { ...}
}
- Nếu muốn gộp file CSS cho production thì có thể dùng
esbuild
esbuild style.css --bundle --loader:.svg=dataurl --loader:.woff2=file --outfile=/tmp/out.css
- Tác giả thường tránh dùng build system cho cả CSS lẫn JS, nhưng thấy
esbuild chấp nhận được vì nó dựa trên web standard và là một binary Go tĩnh
- Tác giả từng viết một bài về esbuild và Vue vào năm 2021
3 bình luận
Chẳng phải sau khi chuyển sang zero-config thì tốt hơn một chút sao?
Ý kiến trên Hacker News
Tôi đã dạy HTML ngữ nghĩa và markup có khả năng truy cập trong thời gian dài, cũng từng làm nhiều website và ứng dụng cho trình đọc màn hình, và vấn đề lớn nhất của Tailwind là nó đảo ngược thứ tự cần suy nghĩ về HTML và CSS
HTML dùng để thể hiện ý nghĩa của tài liệu, nên phải bắt đầu từ đó rồi mới dùng CSS để tạo kiểu. Nếu vì kiểu dáng mà cần thêm phần tử thì có thể dùng div hoặc span, nhưng trước tiên nên cân nhắc xem có phần tử nào phù hợp hơn không
Tailwind đẩy lập trình viên vào cách tiếp cận ưu tiên CSS, khiến họ nghĩ tới class Tailwind mình muốn trước, rồi lại thêm một div khác vào DOM chỉ để gán class đó
Năng lực của lập trình viên web trong tương lai vẫn nên bao gồm khả năng tạo ra HTML và CSS dễ đọc về sau, dùng được cho mọi người dùng, và nhìn chung phù hợp với đặc tả HTML/CSS; nhưng Tailwind làm suy giảm kỹ năng đó. Ngay cả ví dụ đầu tiên trên website Tailwind cũng chỉ toàn div và span, tạo thành một bài học tệ cho người mới, và tôi nghĩ nó cũng góp phần vào xu hướng để LLM nhả ra mớ div hỗn độn nếu không có chỉ dẫn riêng
Bất kỳ công cụ nào cũng có thể bị dùng sai, và Tailwind không phải ngoại lệ. Tôi đã dùng CSS khoảng 20 năm, cũng đã thử Less, SASS/SCSS, Stylus, PostCSS, nhưng vài năm gần đây lại gắn bó với Tailwind vì nó giúp tạo kiểu cho ứng dụng vững chắc hơn
Bạn không cần tạo quá nhiều lớp trừu tượng cho style/class, đặt style ngay cạnh markup bị ảnh hưởng giúp giảm gánh nặng nhận thức, giảm việc selector lỏng lẻo vô tình làm đổi style, và cũng dễ debug hơn. Trừ những website/ứng dụng đơn giản, codebase Tailwind thường ít phức tạp và ít mong manh hơn codebase có framework CSS tự chế
Nếu tính cả thang font·màu sắc·kích thước nhất quán, bundle nhỏ hơn, tính nhất quán giữa các lập trình viên biết Tailwind, hệ sinh thái vững chắc và độ thân thiện với LLM, thì đây là lựa chọn rất tốt cho nhiều đội ngũ. Cuối cùng, như hầu hết công cụ khác, dùng tốt hay không vẫn phụ thuộc vào người dùng
Tôi xem sự hỗn độn của HTML/CSS/JS là cái ác cần thiết khi làm việc cho trình duyệt, với tôi đó chỉ là tầng biểu đạt. Trong công việc, tôi tập trung vào tính chính xác của schema cơ sở dữ liệu hay logic nghiệp vụ backend nhiều hơn rất nhiều
Chỉ cần dùng tầng biểu đạt bừa bộn đó ở mức tối thiểu mà vẫn có được code tương đối dễ bảo trì là đủ, và với mục tiêu đó Tailwind rất hợp. LLM viết tốt, người mới hiểu nhanh, và về sau đọc rồi sửa cũng khá dễ
Tôi hoàn toàn đồng ý rằng dự án Tailwind không phải là cách tốt nhất để người mới học HTML/CSS, nhưng tôi vẫn thích người mới tập trung vào schema cơ sở dữ liệu tốt, API trực quan, logic nghiệp vụ có thể kiểm thử, v.v. hơn
Bản thân Tailwind không có gì buộc bạn dùng div và span thay cho các thẻ HTML phù hợp
Tài liệu và giao diện là hai thứ khác nhau, và Tailwind hợp lý hơn nhiều với giao diện. Bạn có thể dùng Tailwind cho giao diện và dùng selector HTML có phạm vi giới hạn cho các nội dung khác
Việc Tailwind nhanh hơn khoảng 4 lần so với tự viết codebase CSS phức tạp và hầu như không có overhead vẫn là một ưu điểm dù đánh giá theo cách nào đi nữa
Tóm lại, đây là cách viết CSS theo thứ tự độ đặc hiệu:
/scss/
├── 1-settings. <- thiết lập toàn cục
├── 2-design-tokens <- font, màu sắc, khoảng cách, v.v.
├── 3-tools <- Sass mixin, hàm CSS, v.v.
├── 4-generic <- reset, box sizing, normalize, v.v.
├── 5-elements <- style mặc định cho tiêu đề, nút, liên kết
├── 6-skeleton <- layout grid, v.v.
├── 7-components <- card, carousel, v.v.
├── 8-utilities <- utility và helper class
├── _shame.scss <- hack để sửa sau
└── main.scss
ITCSS gần như loại bỏ hoàn toàn các cuộc chiến độ đặc hiệu trong codebase CSS. Thường thì nơi duy nhất có
!importantlà tầng utility[1]: https://matthiasott.com/notes/how-i-structure-my-css
Nếu nhìn vào thư viện component thì chúng còn bao gồm cả thuộc tính
aria: https://tailwindcss.com/plus/ui-blocks/marketing/sections/pr...Trừ những thứ gần như brochure số như landing page, tôi luôn bắt đầu từ markup rồi mới thêm class CSS lên trên
Hai điểm hay của Tailwind là đã có rất nhiều thông tin class trong dữ liệu huấn luyện AI, và không có xung đột style
Vì vậy khi AI tạo style mới thì không cần tham chiếu stylesheet hiện có, rất tốt cho việc quản lý ngữ cảnh
Với CSS tùy chỉnh, AI phải đọc stylesheet hiện có thì mới giảm được xung đột hoặc viết trùng, nhưng stylesheet lớn có thể chiếm nhiều không gian bộ nhớ của AI nên thành vấn đề
Tôi thực sự rất thích các bài viết của Julia Evans
Cô ấy viết từ một vị trí dễ tổn thương và chân thành. Nhiều người viết để trông có vẻ thông minh, còn Julia viết với thái độ kiểu như “tôi cũng không biết hết mọi thứ, nhưng có vài điều tôi khám phá ra và muốn chia sẻ”. Nó gần như tạo cảm giác như đang chia sẻ điều gì đó với những người mình yêu quý, dù tôi không trực tiếp biết cô ấy
Ở Strange Loop gần nhất, cô ấy đã trình bày cùng Randall Munroe; sau buổi nói chuyện cũng có người đợi để nói chuyện với anh ấy, nhưng tôi lại đợi để nói chuyện với Julia. Tôi thật sự xin lỗi vì có vẻ cô ấy không hiểu câu đùa của tôi về việc viết lại bash script bằng Perl
Tôi không phải Julia, nhưng gần như có cùng triết lý về các buổi nói chuyện công khai hay thuyết trình, và tôi cũng luôn cố truyền điều đó cho các đồng nghiệp gặp khó khăn với việc trình bày. Có thể truyền lại cho đồng nghiệp và người mình yêu quý những kiến thức mà mình quen thuộc hơn một chút, và có thể hữu ích cho họ, là một đặc ân rất lớn
CSS Modules là một lời giải đơn giản hơn cho vấn đề cascading. Nó tạo ra tên class duy nhất để ngăn xung đột class [1]
Nó cũng không có hai nhược điểm lớn của Tailwind là khả năng đọc [2] và hỗ trợ công cụ. Đặc biệt, tôi thấy hỗ trợ công cụ để debug và thử nghiệm tương tác trong Chrome và FireFox DevTools tốt hơn
[1] https://x.com/efortis/status/1888304658080256099
[2] https://github.com/ericfortis/tailwind-eye
Điều luôn làm tôi ấn tượng ở Tailwind là gần như mọi lập luận của những người ủng hộ cuối cùng đều quy về việc “họ chưa bao giờ học CSS vượt quá trình độ junior”
Người ta hay nói kiểu “nếu không có Tailwind thì sẽ có một file CSS khổng lồ, lộn xộn, phình ra mất kiểm soát, đầy code cũ và
!important”, nhưng CSS cũng là một kỹ năng như bao kỹ năng kỹ thuật khácNếu bạn chỉ học đủ để làm cho nó trông đúng ý rồi vá víu tạm bợ, thì tham vọng sẽ nhanh chóng vượt xa khả năng sắp xếp code của bạn
Thật sự rất bực mình khi đang nói về Tailwind và CSS rồi nhận ra người đối diện không chỉ không biết “cascading” nghĩa là gì, mà còn chưa từng nghĩ rằng khái niệm đó có thể hữu ích trong ngữ cảnh stylesheet
Tôi đã dùng CSS rất nhiều từ thập niên 90, xem xét Tailwind, và sau khi hiểu nó thì phần lớn tránh dùng CSS thuần. Ở một góc độ nào đó, đó là thay một mớ hỗn độn bằng một mớ hỗn độn khác, nhưng cá nhân tôi vẫn thích xử lý mớ class cục bộ hơn là cascade chồng chéo và mâu thuẫn trải trên nhiều file
Cả hai đều có thể được triển khai gọn gàng, nhưng dọn dẹp mớ hỗn độn Tailwind dễ chịu hơn mớ hỗn độn CSS rất nhiều, và toàn bộ quá trình phát triển cũng thấy vui hơn
Tôi cũng đã lập trình hơn 20 năm và làm web gần 15 năm, nhưng rất khó tìm được động lực để học CSS một cách bài bản. Có quá nhiều kỹ năng kỹ thuật phải theo kịp, còn CSS đứng khá thấp trong danh sách ưu tiên của tôi
Tôi muốn giao việc đó cho chuyên gia, nhưng các công ty lại không muốn tuyển lập trình viên frontend chuyên trách
Tôi đang viết một hướng dẫn phát triển web gọn gàng tập trung vào việc viết HTML và CSS mở rộng tốt: https://webdev.bryanhogan.com/
Có lẽ sẽ hữu ích cho mọi người ở đây. Về phần styling, tôi không dùng thứ như Tailwind mà chỉ dùng CSS cùng các framework hiện đại như Astro hay Svelte
Trong mọi dự án, tôi đều có
reset.css,var.css,global.css,util.css, còn các style khác thì giới hạn phạm vi theo component hoặc layout tương ứngBài viết hay
Tôi thích loại bỏ phụ thuộc vào thư viện bên ngoài và tự làm giải pháp từ đầu, nhưng có một lý do rõ ràng khiến tôi không làm vậy với Tailwind. Nó cung cấp tối ưu hóa cho production, bảo đảm rằng chỉ lượng CSS tối thiểu thực sự cần thiết mới được triển khai
Dù bạn có liệt kê sẵn mọi lựa chọn như màu sắc, khoảng cách, v.v. trong
globals.csshay nơi khác, bạn cũng không cần lo liệu trong production có dùng hết tất cả biến thể đó hay không. Nếu làm việc trong framework như Next.js, bước tối thiểu hóa này còn tự động diễn ra khi build, nên chỉ riêng điều đó cũng đã là lý do đủ mạnh để tôi không rời TailwindTôi cũng chưa từng cảm thấy có ràng buộc nào quá khó chịu khi dùng CSS inline trong Tailwind, và cũng không gặp vấn đề lớn khi dùng công cụ grid của Tailwind để triển khai lưới phản hồi tốt theo độ rộng màn hình. Tôi đã giải quyết tất cả các kịch bản nêu trong bài bằng Tailwind hoặc kết hợp Tailwind với CSS, và đúng là
grid-column-areaskhông có sẵn mặc định, nhưng cho tới giờ tôi chưa thấy đó là ràng buộc lớn trong layout grid responsiveVấn đề lớn nhất của Tailwind là mất khá nhiều thời gian để quen với việc đọc nó. Chúng ta được dạy rằng CSS inline là xấu còn CSS phạm vi toàn cục là tốt, và quen với HTML sạch sẽ, nên code Tailwind thực tế, nhất là các dòng dài, ban đầu thật sự rất khó đọc. Dùng lâu rồi tôi hoàn toàn quen với hình thức đó, và cuối cùng đi đến kết luận rằng với tôi Tailwind hiệu quả hơn, dễ bảo trì hơn, thậm chí còn dễ đọc hơn, nhưng cũng mất kha khá thời gian
Cách tiếp cận tôi thực sự thích dạo này là dùng Tailwind cùng style giới hạn phạm vi (trong Svelte và Vue)
Làm vậy vừa giữ được sự tiện lợi của Tailwind vừa giảm tối đa việc làm bẩn template:
+
{{ count }}
Với tôi, Svelte và LLM đã hoàn toàn xóa bỏ nhu cầu cần Tailwind
Hóa ra lý do tôi chủ yếu dùng Tailwind không phải là các ràng buộc tự đặt ra mà là để tránh xung đột CSS, và vì cú pháp của nó có vẻ hợp logic với tôi hơn
Điểm tuyệt nhất của Tailwind là không cần phải nghĩ ra tên class tạm thời nữa. Không còn phải dùng BEM nữa
Ý kiến trên Lobste.rs
Trong các dự án cá nhân, tôi hầu như không còn dùng framework CSS/JavaScript nữa
Vì nếu không có phụ thuộc thì cũng không thể phát sinh lỗ hổng chuỗi cung ứng. Tất nhiên đó không phải là loại lỗ hổng duy nhất, nhưng như vậy cũng giúp ích
Đó là kết quả của việc mệt mỏi với framework, quá tải vì
npm audit, và cả chuyện nhờ LLM mà tôi bớt bận tâm đến đánh giá của người khác về cách triển khai. Ví dụ như những câu hỏi kiểu “tại sao không dùng React và Tailwind?”Đây đơn giản là cách CSS hoạt động
Mỗi khi thấy ai đó mù quáng dùng Tailwind mà không biết điều này, tôi chỉ muốn ra ngoài gào lên với mây trời. Theo tôi, 90% của Tailwind chỉ là inline style với cú pháp khác đi, và có lẽ chỉ khá hơn thẻ
<FONT>đúng một bậcBài blog này giải thích đúng những gì mà bản thân tôi thực sự cần biết
Tailwind vận hành khá khác với inline style, và thực ra giống CSS hơn nhiều. Như bài viết cũng chỉ ra, phần lớn các thói quen tốt giúp dùng Tailwind hiệu quả cũng là những thói quen cần có để viết CSS hiệu quả. Tailwind gần với việc gắn một khối CSS có scope ngầm định vào mỗi phần tử, nhưng dùng một DSL riêng biệt
Tôi hiểu rất rõ cơ chế hoạt động của CSS, nhưng CSS thuần vẫn khiến tôi thấy nặng nề, lại không giỏi thiết kế đồ họa nên tôi vẫn dùng Tailwind. Bài này mang lại những ý tưởng để cấu trúc CSS dựa trên nền tảng Tailwind
Với góc nhìn của một người không theo sát xu hướng gần đây, bài này dường như cho thấy khá rõ các thực hành CSS hiện đại
Tôi cũng thích việc có nhiều liên kết dẫn tới những bài viết đã truyền cảm hứng cho tác giả. Có vẻ rất đáng đọc, dù hiện giờ tôi mới chỉ đọc "no outer margin"
Tuy vậy, tôi hơi hoài nghi về cách tiếp cận thiết lập style mặc định theo kiểu “từ dưới lên”. Tôi cũng không biết nên làm cách nào khác, và nó có vẻ đáng để thử, nhưng style mặc định vốn dĩ luôn khá khó nhằn
Bài này thật sự rất hay
Tôi cũng đã học CSS dần dần trong lúc làm đủ loại website nhỏ, và có lẽ sẽ hữu ích hơn nếu ngay từ đầu tôi suy nghĩ theo hướng có tính hệ thống như thế này. Tôi khá dị ứng với framework, nhưng vì không dùng chúng nên dù biết cách làm mọi thứ theo ý mình, tôi vẫn thường có cảm giác như đang lơ lửng trong khoảng không vô cấu trúc
Tôi thích ở chỗ bài này không nói kiểu “Tailwind dở lắm nên cứ dùng CSS đi”, mà là “Tailwind rất tuyệt, nhưng giờ có thể bạn không còn cần nó nữa”
Tôi luôn gặp khó khăn khi tự tay cấu trúc CSS, và nhờ bài này mà tôi bắt đầu suy nghĩ theo một hướng rất khác
Khi sắp xếp CSS, kỹ thuật cấu trúc này khá hữu ích với tôi: https://rstacruz.github.io/rscss/
Nhìn chung nó rất khớp với những gì jvns mô tả trong bài gốc, đồng thời bổ sung thêm một chút cấu trúc và tính ngăn nắp lên trên đó