Reset CSS trong thiết kế web là gì vậy?

Vài lời của người dịch: tôi bắt đầu chú ý đến file reset.css khi tham khảo một số nhóm hội về front-end trên FB. Rồi thì khi thấy sự khác biệt của các trình duyệt về cách render nội dung qua phần kiểm tra đa trình duyệt (cross browser testing / nhiều nơi dịch là kiểm tra chéo trình duyệt), tôi nghĩ là mình sẽ phải tìm hiểu sâu hơn về chủ đề này. Mục đích chính của file reset.css là tạo ra được định kiểu thống nhất trên càng nhiều trình duyệt khác nhau càng tốt, tính cả phiên bản, lẫn OS mà nó đang vận hành qua đó. Chỉ có thế chúng ta mới nắm chắc được người dùng trải nghiệm như thế nào trên các nền tảng khác nhau ấy. Ý niệm về reset.css thay đổi qua năm tháng, có những người sử dụng 3 dòng mã rất đơn giản dùng selector * cho tất cả các phần tử để thiết lập lại, có những người khác lại thiết kế tỷ mỉ hơn, chỉ chọn những phần tử có sự khác biệt thật sự, và chỉ chú trọng vào các thuộc tính khác biệt của phần tử đó mà thôi, kết hợp với các thay đổi, phát triển của HTML và CSS trong giai đoạn gần đây. Những người khác thậm chí đi xa hơn, không chỉ reset, họ còn bổ sung thêm các style ưa thích của riêng mình, hoặc các style mà họ cho là tốt hơn style mặc định.

OK, giờ đã đến lúc chúng ta vào bài rồi!


Mấy ngày hôm trước, tôi có thấy một bài viết của Nicholas Cerminara nói rằng Bootstrap 4 đã có file reset CSS mới mà họ gọi là Reboot.

Reboot là một tập hợp các chỉ thị, thay đổi các CSS cụ thể của phần tử và được đưa vào một file duy nhất, điều này giúp cho Bootstrap cung cấp được các mã nhất quán, đơn giản được xây dựng dựa trên đó.

Nếu bạn là một người mới trong lĩnh vực phát triển CSS, thì toàn bộ ý tưởng của CSS reset đó là xử lý các mâu thuẫn trong chuyện thiết lập style giữa các trình duyệt. Lấy ví dụ, nếu tôi đưa một button vào trang và không thiết lập style nào cụ thể liên quan đến padding thì theo mặc định trình duyệt Chrome sẽ áp dụng câu lệnh padding: 2px 6px 3px; – trong khi đó trình duyệt FireFox sẽ áp dụng câu lệnh padding: 0 8px;

PS từ người dịch: Hệ quả là chúng ta sẽ có 2 giao diện khác nhau! Và khó lường trước được các rắc rối có thể xảy ra khi người dùng trải nghiệm.

CSS reset sẽ áp dụng padding mới lên phần tử này, vì thế tất cả các trình duyệt sẽ có kết quả render nhất quán, và buộc chúng ta phải tự chủ động điều chỉnh (trong trường hợp này là padding của button), chứ không bị sao nhãng theo mặc định, dẫn đến hệ quả từng trình duyệt sẽ hiển thị khác nhau. Chúng ta sẽ xem xét một vài ví dụ như thế.


Nhìn lại một chút lịch sử nào…

Vào năm 2007, Jeff Starr đã tổng hợp một loạt các thiết lập CSS khác nhau. Phiên bản cũ nhất là của Tantek Çelik, nó đây: undohtml.css (link dẫn trực tiếp đến file). Chúng ta có thể thấy rằng mục đích đằng sau nó là loại bỏ đi các thuộc tính mặc định:

/* undohtml.css */
/* (CC) 2004 Tantek Celik. Some Rights Reserved.             */
/*   http://creativecommons.org/licenses/by/2.0                   */
/* This style sheet is licensed under a Creative Commons License. */

/* Purpose: undo some of the default styling of common (X)HTML browsers */

Ở thời điểm hiện tại, một trong các thiết lập reset phổ biến nhất là của Meyer. Nó có những thứ khác so với những cái mà Tantek đã làm (nó thậm chí cập nhật một số phần tử HTML5), nhưng ý tưởng căn cốt thì vẫn thế thôi: loại bỏ các thiết lập style mặc định. Bạn có thể sẽ để ý đến khối mã nổi tiếng này, tìm thấy nó thông qua DevTools ở khắp mọi nơi:

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%;
	font: inherit;
	vertical-align: baseline;
}

Khi bạn bắt đầu với đoạn mã CSS reset như vậy (tức là tại vị trí trên cùng của file CSS), rồi sau đó bạn viết các đoạn CSS của riêng mình, thế thì bạn sẽ có được các chỉ thị CSS vững chắc, ổn định qua nhiều trình duyệt khác nhau.

Các năm sau đó, khi HTML5 trở thành hiện thực và phổ biến hơn, đoạn mã reset dành cho HTML5 của Richard Clark được biết đến rất nhiều. Nó vẫn là phiên bản điều chỉnh của Meyer, và vẫn giữ nguyên ý tưởng.

article,aside,details,figcaption,figure,
footer,header,hgroup,menu,nav,section { 
    display:block;
}

Trong suốt quá trình trình thay đổi này, có khá nhiều lập trình viên, nhà thiết kế đã tối thiểu hóa công việc trên bằng cách đơn giản chỉ là loại bỏ margin và padding ra khỏi mọi phần tử, và dùng đoạn mã đơn giản thế này thôi:

* {
  padding: 0;
  margin: 0;
}

Tiếp đến là Normalize.css

Normalize.css là đại diện đầu tiên thực hiện bước chuyển trong ý nghĩa của việc file CSS reset nên làm điều gì. Điều này dường như đã tạo ra sự khác biệt rất lớn đối với tôi:

  • Nó là một đánh giá mới về mọi thứ có thể có sự khác biệt về style trong các trình duyệt và nó xác định tất cả các trường hợp đó. Trong đó các CSS cũ hơn được đặt lại với một vài dòng mã, không nén và được định danh là 447;
  • Nó không thực hiện việc loại bỏ các styling từ các phần tử đã có tính ổn định cao trên nhiều trình duyệt (trong phần lớn trường hợp). Ví dụ, không có bất cứ thay đổi nào được thực hiện trong Normalize cho các phần tử từ h2 – h6, chỉ có mã sửa chữa cho thẻ h1. Điều đó có nghĩa là bạn không loại bỏ phân cấp tiêu đề, kiểu mặc định đó sẽ vẫn còn;
  • File reset này phù hợp với ý tưởng thay đổi phần tử hơn là chỉ bao gồm nó. Lấy ví dụ, có một phần chỉ dành cho thẻ <pre> và một dòng trong số đó đặt phông chữ cho nó. Bạn có thể thay đổi điều đó bằng font chữ bạn muốn, và nó sẽ có hiệu quả tương tự như việc đặt lại;

Đoạn mã cũng dễ đọc, vì nó giải thích mục đích của từng dòng mà không quá đi sâu vào chi tiết:

/**
 * 1. Remove the bottom border in Chrome 57- and Firefox 39-.
 * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
 */

abbr[title] {
  border-bottom: none; /* 1 */
  text-decoration: underline; /* 2 */
  text-decoration: underline dotted; /* 2 */
}

Ở thời điểm hiện tại Normalize đang ở phiên bản 7.0.0 và nhận được 30 ngàn sao trên GitHub. Nó quả thực rất phổ biến.


Vì vậy, … chúng ta có thể chọn lựa kiểu reset đúng không?

Chúng ta đã thấy rất nhiều cách khác nhau để reset CSS, và chúng ta cũng thấy những thay đổi nền tảng trong cách tiếp cận, vì thế tôi nghĩ sẽ công bằng khi nói rằng reset CSS có thể có các tùy chọn riêng.

Hãy xem xét một số định hướng nhé…

  • Việc reset có xử lý mọi phần tử có thể không? Hoặc là một tập con của các phần tử? Làm thế nào quyết định được phần tử nào nên động tới, còn cái nào thì không?
  • Những thuộc tính nào cần thay đổi? Chỉ áp dụng với phần tử có sự khác biệt khi test đa trình duyệt (cross browser testing)? Hay có các tiêu chí khác nữa, chẳng hạn như sự tương đồng với các yếu tố khác mà chúng ta cần thay đổi? Có ỔN không khi áp dụng các thuộc tính mới cho các phần tử không gặp vấn đề đa trình duyệt nhân danh tính nhất quán và hiệu quả không?
  • Bạn có cố gắng duy trì tinh thần của style tác nhân người dùng không? Các giá trị mặc định hợp lý là gì?
  • Bạn có áp dụng bất kỳ thuộc tính nào cho các phần tử mà không gặp vấn đề về đa trình duyệt không, chẳng hạn như typographic mặc định hoặc kích cỡ box?
  • Bạn có bao gồm các lớp “hộp công cụ” cho các nhu cầu chung không? Hay để đó cho các dự án khác xử lý?
  • Bạn có đưa vào các lớp “toolbox” cho nhu cầu chung không? Hay để đó cho các dự án khác mà lúc nào cần tới mới xử lý;
  • Bạn có lo lắng về kích thước của file reset không?
  • Bạn có sử dụng bộ tiền xử lý (preprocessor) hay bất kỳ công cụ nào khác không?

Giờ chúng ta hãy nhìn vào Vanilla CSS Un-Reset. Có rất nhiều tùy chọn ở đây, nó bắt đầu với ý tưởng là thiết lập lại style cho phần tử sau khi bạn loại bỏ style của nó thông qua reset. Nó thiết lập font chữ body ở kích cỡ pt, thiết lập ngăn xếp font chữ monospaces rất cụ thể, bao gồm selector ol, một clearfix, và các lớp trợ giúp căn chỉnh. Tôi không phán xét. Mọi người tạo ra cái gì đó để khắc phục các rắc rối cho chính mình, và tôi tin chắc rằng điều này có ích cho sáng tạo. Chúng ta có thể thấy các tùy chọn có vẻ đẹp của riêng nó.

Bây giờ hãy nhìn vào file MiniReset.css. Rất khác nhau! Các ý kiến hoàn toàn khác nhau như vậy đấy.

Jonathan Neal đã tạo một file reset có tên santize.css rất rõ ràng về các tùy chọn ​​của nó. Tìm kiếm từ “opinionated” trong mã nguồn và bạn sẽ thấy nó đến 19 lần. Tất cả các lựa chọn mà Jonathan đưa ra dựa trên nghiên cứu, và điều này dường như là cách thực hành tốt nhất trong thế giới hiện đại. Và không nghi ngờ gì nữa, chúng phản ảnh những gì mà anh ấy cần và muốn reset lại.

/*
 * Remove the text shadow on text selections (opinionated).
 * 1. Restore the coloring undone by defining the text shadow (opinionated).
 */

::-moz-selection {
	background-color: #b3d4fc; /* 1 */
	color: #000000; /* 1 */
	text-shadow: none;
}

::selection {
	background-color: #b3d4fc; /* 1 */
	color: #000000; /* 1 */
	text-shadow: none;
}

Từ “reset”

Cá nhân tôi nghĩ rằng sẽ hữu ích khi nghĩ về tất cả chúng dưới cùng một thuật ngữ chung và chỉ cần nhận thức được sự khác biệt về lý luận. Tuy nhiên, Normalize cố ý tách chính nó ra:

Một giải pháp thay thế hiện đại, sẵn sàng cho HTML5 để thay thế cho reset CSS

Sanizing tự gọi bản thân là một thư viện CSS và không sử dụng từ “reset” ở bất kỳ đâu ngoại trừ phần trích dẫn lại từ Meyer.


Reboot

Reboot rất thú vị, có lẽ là vì nó là tay chơi mới nhất trong lĩnh vực này. Lịch sử của nó bắt đầu từ năm 2015, có thể liên quan đến việc Bootstrap 4 suy giảm sau Bootstrap 3. Reboot không có repo riêng, nó là một phần của Bootstrap. Đây là tệp trực tiếp và tài liệu .

Cách họ nghĩ về nó thật thú vị:

Reboot được xây dựng dựa trên Normalize, cung cấp nhiều phần tử HTML với các phong cách hơi cố chấp bằng cách chỉ sử dụng các bộ chọn phần tử. Tạo kiểu bổ sung chỉ được thực hiện với các lớp. Ví dụ, chúng tôi reboot một số style của thẻ <table> với nền đơn giản và căn bản hơn và sau đó cung cấp .table.table-bordered và một số cái khác nữa

Bạn có thể có một lớp thực hiện tạo kiểu, nhưng nếu bạn sử dụng reset, bạn không phải quá tải lớp đó với các kiểu đặt lại để xử lý các vấn đề về tính nhất quán trên nhiều trình duyệt.

//
// Tables
//

table {
  border-collapse: collapse; // Prevent double borders
}

caption {
  padding-top: $table-cell-padding;
  padding-bottom: $table-cell-padding;
  color: $text-muted;
  text-align: left;
  caption-side: bottom;
}

th {
  // Matches default `<td>` alignment by inheriting from the `<body>`, or the
  // closest parent with a set `text-align`.
  text-align: inherit;
}

Nó chắc chắn là cố chấp, nhưng khi kết hợp với Bootstrap thì lại rất ổn. Thực tế là nó được chôn sâu trong Bootstrap là tín hiệu khá tốt cho thấy reset CSS này được thiết kế cho thế giới đó, chứ không phải là một công cụ thả vào trong bất kỳ dự án nào. 

Nói thêm là, tôi đã cố gắng hết sức để biên dịch một phiên bản CSS đơn giản hơn của nó ở đây.


Tinh chỉnh reset dựa trên hỗ trợ của trình duyệt

Chừng nào chúng ta vẫn nói về quá khứ và tương lai của reset, thì cần phải nhắc lại về Browserlist, đây là một định dạng được tiêu chuẩn hóa để khai báo những trình duyệt / phiên bản nào mà một dự án hỗ trợ.

Reset có thể được xây dựng theo cách mà từng dòng mã ở đó biết vì sao nó nên ở đó. Nó biết chính xác trình duyệt và phiên bản nào cần hỗ trợ. Sau đó, nếu cấu hình danh sách trình duyệt cho thấy rằng một trình duyệt cụ thể không còn được hỗ trợ bởi dự án nữa, CSS đó có thể bị xóa đi.

Đó là những gì mà dự án PostCSS Normalize của Johnathan Neal đang làm.

(Lược dịch từ bài viết Reboot, Resets, and Reasoning của Chris Coyier, trang CSS-TRICKS)

Leave a Comment