CSS: Những phần tệ không thể tránh khỏi
(matklad.github.io)- Việc tạo kiểu cho trang web chỉ cần một tập con nhỏ có thể học được đối với blog đơn giản hay GUI, nhưng những cái bẫy như giá trị mặc định của trình duyệt và bố cục có thể dẫn tới nhiều ngày debug
- Nếu dùng các thẻ HTML5 có ngữ nghĩa trước và giảm bớt wrapper, sẽ dễ hơn để làm cho CSS hoạt động theo đúng markup sẵn có
- Không có một thuật toán duy nhất mang tính phổ quát cho bố cục CSS; cần tiếp cận bằng cách hiểu kiểu sắp đặt mà từng hệ thống cho phép
box-sizing,margin,font-size,line-height,word-breakhoạt động khác với trực giác, nên một thay đổi nhỏ có thể lan thành vấn đề về toàn bộ bố cục hoặc khả năng đọc- Với các trang đơn giản, CSS reset, classless CSS, flexbox và các quy tắc responsive không quá mức có thể là điểm khởi đầu thực dụng
Phạm vi học CSS và góc nhìn cơ bản
- CSS, HTML và Web API rất rộng và đòi hỏi tính chuyên môn, nhưng với những việc như blog lập trình hay GUI đơn giản thì một tập con phù hợp của web hiện đại là đủ
- Chưa từng thấy tài liệu nào chỉ dạy riêng tập con cần thiết cho các công việc đơn giản, nhưng có thể nắm được phần nào bằng cách đi theo MDN
- Vấn đề là những cái bẫy không ngờ tới có thể phá hỏng trang và mất nhiều ngày mới tìm ra nguyên nhân
- Phần styling của trang này gồm khoảng 200 dòng CSS dễ đọc
Phần tốt: HTML có ngữ nghĩa và classless CSS
-
Thẻ ngữ nghĩa HTML5
- Đáng để lướt qua Elements Reference trên MDN, và số lượng phần tử HTML thực ra không quá nhiều
- Các thẻ như
main,article,nav,kbdcó thể giúp việc tạo cấu trúc trang trở nên dễ hơn ulcó thể dùng cho mọi kiểu danh sách, chẳng hạn các mục của website bên trongheader > navdetailscó thể dùng cho mục lục, và có thể xem mã nguồn của MDNdlvàdtcó thể dùng cho các danh sách theo cặp
-
Cách tiếp cận giảm wrapper
- Khi xem mã nguồn của các website thực tế, có thể thấy rất nhiều phần tử wrapper lồng nhiều lớp, khiến người ta tưởng rằng vấn đề bố cục được giải bằng wrapper
- Tạm không phán xét về kinh nghiệm CSS production, nhưng việc tự giới hạn chỉ dùng các thẻ semantic có ý nghĩa rồi tìm CSS phù hợp với markup đó dễ hiểu hơn
-
Classless CSS
- Không thể reset style về trạng thái hoàn toàn trung tính kiểu “không có gì”; văn bản màu trắng hay trong suốt vẫn là một kiểu style
- Sau bước reset, có thể trực tiếp tạo style cho các phần tử HTML phổ biến
- Nếu dùng các thẻ
main,header,footer,navthì có thể thiết lập bố cục tổng thể của trang mà không cần nhiều selector CSS - Cách này khiến CSS giả định cấu trúc HTML, nhưng nếu đó là HTML và CSS của chính mình thì khi không ưng ý kết quả, bạn có thể đổi
Phần tệ: bố cục, giá trị mặc định của trình duyệt, selector
-
Bố cục
- Vấn đề bố cục không chỉ là chuyện riêng của web; đây là bài toán khó trong nhiều framework GUI
- Có nhiều cách để đặt một ảnh raster kích thước cố định cùng đoạn văn bản mô tả nó vào trong một hình chữ nhật màn hình
- GUI nói chung là một cấu trúc phân cấp của các hộp có nhiều “bậc tự do bố cục”
- Bố cục của mỗi hộp ảnh hưởng tới bố cục của mọi hộp khác, và thông thường tất cả các hộp phải khớp chính xác với nhau, không có khoảng hở hay chồng lấn
- Không tồn tại một thuật toán bố cục duy nhất mang tính phổ quát; từ RectCut tới constraint solvers, và cả vùng ở giữa, mỗi hệ thống dùng heuristic khác nhau
- Tốt hơn nên nghĩ “hệ thống này cho phép những bố cục nào” thay vì “làm thế nào để tạo bố cục trong hệ thống này”
-
Giá trị mặc định của trình duyệt và CSS reset
- Ngay cả HTML có ngữ nghĩa mà không có CSS vẫn được trình duyệt áp style mặc định như màu sắc, phông chữ, cỡ chữ, tiêu đề lớn, liên kết có gạch chân...
- Các style mặc định này hữu ích, nhưng khác nhau giữa các trình duyệt; nếu dựa vào những giá trị mặc định mình không viết ra, kết quả có thể khác ở trình duyệt khác
- Cách giải quyết phổ biến là dùng CSS reset hoặc normalization, tức ghi đè các giá trị mặc định bằng những rule tường minh ở đầu file CSS
- Bản thân giá trị mặc định không xấu; vấn đề là chúng không nhất quán với nhau
- Trên thực tế, muốn biết nên ghi đè những rule nào thì tốt hơn là so sánh nhiều CSS reset có sẵn
-
Có nên tạo style cho trang web không
- Nền tảng web đồng thời tồn tại quan điểm xem nó là một phương tiện thị giác linh hoạt, thích ứng, và quan điểm tập trung vào việc truyền tải nội dung để người dùng tự tùy biến cách hiển thị
- Một trang mặc định không có style thường kém thân thiện và không đẹp mắt
- Sẽ tốt hơn nếu thế giới mà trang không có CSS vẫn dễ đọc, nhưng trong môi trường hiện tại thì việc áp style cho nội dung là có ích
- Nên cho phép người dùng nâng cao mang CSS riêng của họ vào
- Markup HTML cần hợp lý, không nên overfit HTML cho CSS, và trang nên hoạt động được trong reader mode
-
Selector CSS
- CSS cơ bản hoạt động giống một cơ chế kế thừa mạnh mẽ, nơi mỗi yếu tố thiết kế trên trang bị ảnh hưởng bởi nhiều rule khác nhau
- Có thể “monkey patch” các phần tử hiện có bất cứ lúc nào bằng cách nối thêm vào file CSS
- Có thể xem selector CSS là một kiểu trừu tượng hóa làm tăng năng lực theo sai trục, và chọn cách dùng classless CSS cùng inline style
- Những công cụ như Tailwind giúp giảm sự bất tiện khi viết inline, còn JSX hay các template engine hỗ trợ composition giúp giảm lặp HTML
- Dùng CSS nesting có thể giảm các selector vươn quá xa và tạo style theo đơn vị component
Box model và sắp đặt: box-sizing, margin, flow mặc định, flexbox
-
box-sizing- UI là các hình chữ nhật đệ quy, và bố cục là quá trình quyết định từng hình chữ nhật được đặt ở đâu
- Theo mặc định của HTML,
widthvàheightcủa một phần tử không bao gồm border và padding, điều này không trực quan - Chỉ cần tăng padding ở một chỗ, toàn bộ bố cục vốn nhìn có vẻ hoàn hảo ban đầu có thể bị xô lệch ngoài dự tính
* { box-sizing: border-box; }xứng đáng là dòng đầu tiên của CSS reset, vì nó biến việc thêm border thành thay đổi cục bộ
-
Margin collapsing
- Nếu muốn khoảng cách
8pxquanh một phần tử mà dùng padding, thì khoảng cách giữa hai phần tử liền kề có thể thành16px marginhoạt động bằng cách kết hợp margin của hai phần tử hàng xóm theomaxchứ không phải cộng dồn- Margin collapsing rất hữu ích nhưng có thể tạo ra hành vi gây bất ngờ
- Có thể xem nó như việc margin của phần tử con tràn ra ngoài phần tử cha, nhưng trực giác về margin vẫn chưa thật sự đủ chắc
- Bài viết của Julia Evans Moving away from Tailwind, and learning to structure my CSS bàn về cách dùng owl selector để phần tử cha kiểm soát margin giữa các phần tử con thay vì thường xuyên gán margin cho chính phần tử đó
- Cách thêm margin cho mọi phần tử con của
sectiontrừ phần tử đầu tiên được hiểu là một ý tưởng giúp giảm các vấn đề về margin - Điều khó chịu là những kiến thức kiểu này rất khó học nếu không trở thành lập trình viên web chuyên nghiệp hoặc đi reverse-engineer framework CSS của người khác
- Nếu muốn khoảng cách
-
Bố cục flow mặc định
- Thuật toán bố cục mặc định gắn với nguồn gốc của HTML như một ngôn ngữ tài liệu, và có vẻ được tối ưu cho trường hợp tạo tài liệu giấy xoay quanh văn bản và hình ảnh
- Với phần thân văn bản, flow mặc định thực sự hoạt động khá gần với điều ta mong muốn
- Nếu muốn trực tiếp kiểm soát việc sắp đặt không gian của các phần tử trên trang, cần một cách khác ngoài flow mặc định
-
Flexbox
- flexbox là kiểu bố cục để sắp một chuỗi phần tử theo chiều dọc hoặc ngang, rồi điều chỉnh theo không gian khả dụng
- Trước đây, ngay cả kiểu sắp đặt như “cái này bên trái, cái kia bên phải” cũng đòi hỏi hiểu biết CSS sâu hoặc một framework CSS khó đoán
- Flexbox khá phức tạp nên vẫn phải liên tục tra MDN, nhưng nhìn chung nó cho phép hoàn thành phần lớn công việc mong muốn
-
Thiết kế responsive
- CSS hiện đại có thể truy vấn kích thước màn hình và triển khai logic có điều kiện theo các ràng buộc của user agent
- HTML về bản chất đã là responsive; không giống PostScript hay PDF, khi kích thước cửa sổ thay đổi thì đoạn văn tự động reflow
- Tốt hơn là tránh các rule responsive tường minh và để bố cục tự hoạt động một cách hợp lý
- Blog này nhìn vẫn ổn trên di động, tablet và desktop mà không cần
@mediaquery tường minh - Chỉ cần đặt
max-widthvô điều kiện cho cột nội dung chính là đủ
Kích thước và văn bản: pixel, phông chữ, chiều cao dòng, ngắt dòng
-
Pixel
1pxlàm đúng việc người ta mong muốn, nhưng không có nghĩa là một pixel vật lý trên màn hình1pxtrong CSS là một đơn vị góc nhìn, được thiết kế để trông tương tự nhau về mặt cảm nhận trên mọi màn hình- Nó được chuyển đổi thành số pixel vật lý khác nhau tùy kích thước màn hình, mật độ điểm ảnh và khoảng cách xem thông thường
- Vì vậy có thể chỉ định mọi kích thước bằng pixel mà không cần suy nghĩ riêng về mật độ pixel của các màn hình khác nhau
- Các đơn vị “thực” như centimet và inch trong CSS cũng được định nghĩa dựa trên pixel, nên chúng cũng hoạt động giống đơn vị góc
-
font-size- Trong
font-size: 16px,16pxkhông phải kích thước của một glyph cụ thể mà là kích thước của hộp ảo bao quanh glyph - Hộp này không khít với glyph, và kích thước glyph thực tế thay đổi theo từng phông chữ
font-size-adjustcó thể giúpfont-sizenhất quán hơn giữa các phông chữ- Hiện tại
font-size-adjustcó vẻ là một tính năng rất ngách; cá nhân tác giả muốn đặtfont-size-adjust: ex-height 0.53;bên cạnhbox-sizing, nhưng rất ít trang làm vậy - Giá trị mặc định của
font-sizekhá nhất quán giữa các trình duyệt, và16pxlà mặc định áp đảo - Tùy phông chữ mà
16pxcó thể trông nhỏ, và một số phông mặc định đặc biệt nhỏ - Trên Apple,
font-family: seriftrông nhỏ hơn rất nhiều so vớisans-serif, và ở16pxgần như khó đọc - Khi đặt
font-sizetrong CSS, bạn làm vô hiệu hóa cách trình duyệt thay đổi cỡ chữ mặc định - Đừng giả định rằng văn bản mặc định sẽ dễ đọc; cần kiểm tra trong các thiết lập khác nhau
- Khi dùng
font-size-adjustđể giảm bớt bậc tự do và cố định ý nghĩa củafont-size, nếu ở cỡ chữ mặc định16pxmà nhìn ổn thì coi như xong - Nếu không, hãy đặt
font-sizethành một giá trị lớn hơn, rồi kiểm tra sau đó xem trong reader mode còn dễ đọc không
- Trong
-
line-height- Trái với tên gọi,
line-heightkhông thiết lập chiều cao của một dòng line-heightlà chiều cao của một cụm glyph được đặt bằng cùng một phông chữ- Khi toàn bộ văn bản dùng cùng một phông chữ, chiều cao dòng và chiều cao cụm glyph trùng nhau
- Nếu một số từ được đặt bằng phông
monospace, có thể xuất hiện kết quả ngoài dự tính font-size-adjustsửa kích thước glyph trong hộp, nhưng không quy định luôn cả vị trí tương đối của chúng- Khi các cụm văn bản từ những phông khác nhau được căn dọc để cùng chia sẻ baseline, các line-box theo
line-heightcủa chúng bị lệch nhau - Tổng chiều cao của dòng có thể được tạo thành như một phép hợp, và lớn hơn dự đoán
- Hiệu ứng này được phân tích kỹ trong Deep dive CSS: font metrics, line-height and vertical-align
- Trái với tên gọi,
-
Vertical rhythm
- Vertical rhythm là ý tưởng căn cho vị trí các dòng giữa các đoạn vẫn ở cùng một vị trí tương đối, kể cả khi có tiêu đề, hình ảnh, v.v.
- Nó thường được giải thích như việc căn nội dung theo những dòng kẻ vô hình phía sau trang web
- Với bố cục một cột, điều này được xem là không hữu ích
- Với bố cục hai cột, có thể bạn sẽ muốn căn dòng ở hai bên cho khớp nhau
- Nhưng bỏ nhiều công sức phức tạp để làm việc đó trong bố cục một cột thì không hợp lý
-
word-break- Điểm mạnh của bố cục flow là hành vi động: khi cửa sổ hẹp lại, văn bản tự chia thành các dòng gọn gàng
- Dòng chỉ có thể bị ngắt tại khoảng trắng hoặc vị trí có thể chèn dấu gạch nối
- Những đoạn dài như
inline codehay URL có thể không bị ngắt - Vấn đề này gây tràn ngang trên thiết bị di động, và thường chỉ bị phát hiện sau khi đã đăng
- Không có một mẹo duy nhất để sửa, nhưng Against Horizontal Scroll có một số gợi ý
Kết luận thực dụng
- Để làm một blog đơn giản, cần có tài liệu giải thích ngắn gọn nhưng đủ dùng về HTML và CSS
- Bài viết kết lại bằng mong muốn có một cuốn sách ngắn khoảng 100 trang, giải thích HTML và CSS đủ để làm blog đơn giản mà không gục ngã trước những vấn đề như margin collapsing
1 bình luận
Ý kiến trên Lobste.rs
Một góp ý nhỏ thôi, nhưng định nghĩa của responsive design là “được render tốt trên nhiều thiết bị và nhiều kích thước cửa sổ/màn hình khác nhau để đảm bảo tính khả dụng và sự hài lòng”
Media query hay container query chỉ là một trong những công cụ để hiện thực hóa điều đó, và responsive design gần với một cách tư duy hơn là kiểu “hãy dùng media query cho mọi thứ”
Vì vậy, có lẽ thứ “tệ” không phải bản thân responsive design mà là media query hoặc lạm dụng breakpoint
Phần “Browser defaults” khá dễ gây hiểu nhầm. Reset stylesheet và normalize stylesheet rất khác nhau về mục đích lẫn cách hoạt động, nhưng bài viết lại đang trộn chúng với nhau
Reset không nhằm xóa khác biệt giữa các trình duyệt mà là xóa khác biệt mặc định giữa các phần tử, như
padding-inline-startcủaolhay giao diện mặc định củabutton, để bạn xây style từ một trang giấy trắng thay vì từ trên user agent stylesheetNormalize là một cách tiếp cận muốn phối hợp với user agent stylesheet, và trong đó có lẫn cả phần căn chỉnh khác biệt giữa các trình duyệt lẫn phần đổi sang những giá trị mặc định được xem là “hợp lý hơn”
Hiện nay, không còn nhiều trường hợp mà giá trị mặc định của trình duyệt khác nhau một cách đáng kể, nên người viết nội dung web thông thường gần như có thể bỏ qua. Ngoại lệ còn lại gồm Chromium has the wrong
tableborder-color, WebKit fixed theirs 1½ years ago, khác biệt về margin/kích thước của một số form control,appearance, và việc style<summary>::markercủa WebKitTôi cũng phản đối
box-sizing: border-box.border-boxthiên về layout còncontent-boxthiên về content, nên tôi thấy tốt hơn nếu để phần tử cha lo layout và thiết kế dựa trên nội dung. Khi xử lý tỷ lệ thì cầncontent-box, còn trường hợpborder-boxthực sự hữu ích thì chủ yếu là làm chobodylấp đầy viewportTôi cũng hoài nghi về
font-size-adjust. Nó thay một vấn đề đã được biết rõ bằng một vấn đề ít được kiểm chứng hơn; với người này có thể tốt hơn một chút nhưng với người khác lại tệ hơn một chút. Nó không giải quyết được vấn đề gốc, mà còn buộc phải đưa ra những giả định không có cơ sở về tỷ lệ và metric font của người dùngline-heightvà cách nói “đặt cùng một font” cũng không đủ chặt chẽ. Thực tế ở đây còn đan xen cả cỡ chữ, chuyển đổi ngôn ngữ,font-family: monospace,vertical-align,<sup>,<sub>, và metric font, nên khó coi đó đơn thuần là vấn đề cùng một fontMargin collapsing phức tạp hơn bài viết mô tả, nhưng cũng khá thực dụng. Nếu dùng
flexhaygridcho nội dung thông thường, bạn thường phải liên tục chỉnhgaphoặc margin nên rất dễ trở nên mong manh. Dùngdisplay: flow-rootcó thể ngăn margin của phần tử con bị gộp với margin của phần tử chaTôi không đồng ý với bức tranh tổng thể về responsive design, nhưng hướng giảm bớt media query không cần thiết và đừng “đánh nhau” với trình duyệt thì là đúng. Nếu có thể biểu đạt thay đổi layout dựa trên nội dung thì nhìn chung cách đó tốt hơn
Gần đây tôi dùng khá nhiều nội suy tuyến tính bằng clamp với đơn vị viewport:
margin-inline: --vw-lerp(1rem at 20rem, 2.5rem at 60rem);rồi bung ra thànhmargin-inline: clamp(1rem,1rem + ((2.5 - 1)/(60 - 20)*(100vw - 20rem)),2.5rem);Năm ngoái tôi đã implemented this as a LightningCSS visitor, và kết quả là khi viewport từ 20rem trở xuống thì là 1rem, sau đó tăng mượt đến 2.5rem ở 60rem rồi dừng lại, nên tạo cảm giác tốt vì không cần breakpoint mà vẫn thích ứng được với cỡ font của người dùng
font-size-adjustcó hoạt động như vậy không. Tên gọi của nó dễ gây nhầm, nhưng tôi hiểu làfont-sizethay đổi kích thước em box, cònfont-size-adjustthay đổi kích thước glyph bên trong em boxVì vậy
emvàremvẫn giữ nguyên, cònchthì thay đổi. Nhưngchvốn dĩ phụ thuộc vào font nên việc nó thay đổi là hợp lýTôi muốn có ai đó viết về
font-size-adjust. Tôi không phải chuyên gia nên độ chắc chắn không cao, nhưng đến giờ nó trông như một cải tiến cực lớn mà hầu như chưa ai biết tới. Không thể tự động làm khớp mọi cặp font trong mọi ngữ cảnh, nhưng chỉ riêng việc căn theo kích thướcxthay vì em box thôi cũng có thể bao phủ 90% trường hợp về font/ngữ cảnhÝ chính của bài viết là tốt, và góc nhìn từ những người không đắm hoàn toàn vào HTML/CSS cũng quan trọng, nhưng khá nhiều thứ bị gọi là “tệ” thật ra lại có thể tốt tùy ngữ cảnh
CSS selector rất dễ bị lạm dụng, nhưng không phải vì thế mà nó vốn dĩ xấu. Thay vì đi đến kết luận A hoặc B, bạn có thể dùng các quy tắc/selector tổng quát rồi rải class ngoại lệ hoặc utility class khi cần
Trong bài cũng có một ví dụ selector khá ổn:
Media query cũng có thể là không cần nếu container queries giải quyết được bài toán
CSS có thể tạo cảm giác bề mặt rất rộng, nhưng vì nó được dùng phổ biến và có thể làm nhiều việc nên xung đột quan điểm cũng xảy ra thường xuyên. Dù vậy, cũng nên nhìn vào việc CSS đã tiến xa đến đâu, và khi đã nắm được các khái niệm thì có thể làm được những gì chỉ với lượng code tương đối ít
Nếu muốn học thêm, https://every-layout.dev/ đã giúp tôi khá nhiều trong việc hiểu các thành phần khác nhau trong CSS ăn khớp với nhau ra sao
Điều giúp tôi bắt đầu hiểu web layout là khi nhận ra rằng một website tốt về cơ bản là được thiết kế theo chiều dọc. Các phần tử mặc định nên xếp chồng từ trên xuống dưới, và bạn nên thiết kế cho màn hình mobile trước, rồi coi việc mở rộng ra màn hình lớn là phần thưởng thêm
Khó mà đồng ý với lập luận này. CSS nesting chỉ là đường cú pháp rút gọn, và không thực sự giúp tránh vấn đề selector quá cụ thể một cách có ý nghĩa
15 năm trước người ta cũng đã dùng lồng selector rất nhiều với Sass, và rồi lần lượt đi đến cùng một kết luận rằng như thế là tự trói tay mình bằng cách buộc CSS selector quá chặt vào cấu trúc HTML
Cái bẫy của nesting không lộ ra rõ ở giai đoạn đầu của dự án. Ở giai đoạn greenfield, khi chủ yếu đang làm tính năng mới, viết CSS kiểu này trông có vẻ rất ổn
Nhưng vài tháng sau, khi bắt đầu chỉnh sửa layout lớn và làm mới thiết kế, các phần tử wrapper trong HTML đổi chỗ, và việc sửa CSS cho khớp với chúng có cảm giác như vừa dùng LSD vừa giải khối Rubik
Việc quản lý specificity của selector có lẽ đạt đỉnh ở cách giữ phần lớn selector thật đơn giản, tức là chỉ một class, và chỉ dùng một số ít selector tổ hợp cùng các selector kết hợp như
a:hover. Đó là dòng BEM, OOCSS, rồi sau đó sự quan tâm nhanh chóng chuyển mạnh sang các công cụ lấy JS làm trung tâmBài viết thú vị, nhưng có vẻ tác giả đang dùng nested selector ở một vị trí chẳng mang lại tác dụng gì
&là một sai lầm và vì thế luôn viết&. Tôi thấy đó là một quan điểm khá hợp lýCá nhân tôi vẫn còn phân vân. Ban đầu tôi cũng nghĩ đó là một sai lầm, nhưng trong những tình huống chỉ cần bọc cả đống style đã viết vào
header { … }là có thể thu hẹp phạm vi, thì nó lại khá tiện. Sẽ còn hay hơn nếu các at-rule không dựa trên selector như@keyframescũng có thể viết bên trong đóNói thật thì đây là lời khuyên rất tệ. Tôi thích các bài của Maklad, nhưng bài này rõ ràng trông như được viết bởi người chưa từng dùng CSS ở mức chuyên nghiệp
Gần như toàn bộ nội dung đều là những thói quen xấu kiểu nghiệp dư mà người viết CSS chuyên nghiệp tránh dùng
Vì phải style chúng mà không có selector class, họ cũng sẽ style cả
<main>hay<nav>mà không có selector classNgược lại, trong môi trường chuyên nghiệp, thời gian dành cho việc thiết kế hộp nội dung là rất ít. Làm một lần vào đầu dự án, rồi về sau chỉ từ từ sửa các lỗi nhỏ
Phần lớn thời gian là để tạo component tùy biến hoặc component tái sử dụng. Component tái sử dụng khó hơn, và thực chất thường dẫn tới việc làm ra một bản sao Bootstrap dành riêng cho site
Component tùy biến thì dễ hơn nhưng làm mã nguồn phình to, và cần các chiến lược như BEM, OOCSS, hay utility class kiểu Tailwind để tránh việc vô tình can thiệp sang component khác
Kết luận là mỗi kỹ thuật phù hợp với một quy mô khác nhau. Nếu cách viết CSS chuyên nghiệp có vẻ vô dụng, có lẽ là vì bạn đang giải một bài toán ở quy mô khác
Dù vậy tôi đồng ý với
Bad: Wrappers. Tôi từng thấy những chuyên gia CSS viết toàn bộ site chỉ trong một hai file, và cũng từng thấy những người dùng CSS cực nhiềuCon đường thứ hai cuối cùng rất dễ dẫn tới những cách tiếp cận sai như BEM để quản lý lượng CSS khổng lồ đó
Có vẻ trong bài có những lời khuyên tự mâu thuẫn nhau
Good: Classless CSSvàBad: CSS selectorslại xuất hiện cùng lúc, trong khi muốn dùng CSS không class thì ngược lại phải phụ thuộc nhiều hơn vào CSS selectorTham khảo: https://www.keithcirkel.co.uk/css-classes-considered-harmful/
Kiểu vertical rhythm như “thể như có một quyển vở kẻ dòng vô hình nằm phía sau trang web” hoàn toàn có thể làm được chỉ bằng các giá trị EM
Nếu trộn nhiều font khác nhau thì có thể hơi lệch do khác biệt về metrics, nhưng ngay cả khi đó vẫn có thể dùng
align-items: baselinecủa flex