Lợi ích của việc sử dụng Thuộc tính tuỳ chỉnh trong hệ thống thiết kế và thư viện thành phần.
Tôi là Dave, một Nhà phát triển giao diện cấp cao tại Nordhealth. Tôi phụ trách việc thiết kế và phát triển hệ thống thiết kế Nord, bao gồm cả việc xây dựng Thành phần web cho thư viện thành phần. Tôi muốn chia sẻ cách chúng tôi giải quyết các vấn đề về việc tạo kiểu cho Thành phần web bằng cách sử dụng Thuộc tính tuỳ chỉnh của CSS, cũng như một số lợi ích khác của việc sử dụng Thuộc tính tuỳ chỉnh trong hệ thống thiết kế và thư viện thành phần.
Cách chúng tôi xây dựng Thành phần web
Để xây dựng Thành phần web, chúng tôi sử dụng Lit, một thư viện cung cấp nhiều mã nguyên mẫu như trạng thái, kiểu theo phạm vi, mẫu tạo mẫu, v.v. Lit không chỉ nhẹ mà còn được xây dựng dựa trên API JavaScript gốc, nghĩa là chúng tôi có thể phân phối một gói mã tinh gọn tận dụng các tính năng mà trình duyệt đã có.
Nhưng điều hấp dẫn nhất về Thành phần web là chúng hoạt động với hầu hết mọi khung JavaScript hiện có, hay thậm chí không sử dụng được bất kỳ khung nào. Sau khi gói JavaScript chính được tham chiếu trong trang, việc sử dụng Thành phần web rất giống với việc sử dụng phần tử HTML gốc. Dấu hiệu duy nhất có thể nhận biết được rằng đó không phải là phần tử HTML gốc chính là dấu gạch nối nhất quán trong các thẻ, đây là tiêu chuẩn để báo hiệu cho trình duyệt rằng đây là một Thành phần web.
Đóng gói kiểu DOM bóng
Tương tự như cách các phần tử HTML gốc có Shadow DOM, các Thành phần web cũng vậy. DOM bóng là cây ẩn các nút trong một phần tử. Cách tốt nhất để hình dung điều này là mở trình kiểm tra web và bật tuỳ chọn "Hiển thị cây DOM bóng". Sau khi hoàn tất việc này, hãy thử xem xét một phần tử đầu vào gốc trong công cụ kiểm tra – giờ đây, bạn sẽ có tuỳ chọn để mở dữ liệu đầu vào đó và xem tất cả các phần tử bên trong nó. Bạn thậm chí có thể thử điều này với một trong các Thành phần web của chúng tôi – hãy thử kiểm tra thành phần đầu vào tuỳ chỉnh của chúng tôi để xem DOM tối tương ứng.
Một trong những ưu điểm (hoặc nhược điểm, tuỳ thuộc vào triển vọng của bạn) đối với DOM bóng là đóng gói kiểu. Nếu bạn viết CSS trong Thành phần web của mình, các kiểu đó không được rò rỉ ra và ảnh hưởng đến trang chính hoặc các phần tử khác; chúng hoàn toàn nằm trong thành phần. Ngoài ra, CSS được viết cho trang chính hoặc Thành phần web mẹ không được rò rỉ vào Thành phần web của bạn.
Việc đóng gói các kiểu này là một lợi ích trong thư viện thành phần của chúng ta. Điều này giúp chúng tôi đảm bảo nhiều hơn rằng khi có người sử dụng một trong các thành phần của chúng tôi, trang đó sẽ trông giống như chúng tôi dự định, bất kể kiểu được áp dụng cho trang mẹ. Và để đảm bảo hơn, chúng ta thêm all: unset;
vào thư mục gốc hoặc "máy chủ" của mọi Thành phần web.
Tuy nhiên, nếu ai đó sử dụng Thành phần web của bạn có lý do chính đáng để thay đổi các kiểu nhất định thì sao? Có thể có một dòng văn bản cần độ tương phản cao hơn do ngữ cảnh hoặc đường viền cần phải dày hơn? Nếu không có kiểu nào có thể vào thành phần của bạn, làm cách nào để bạn có thể mở khoá các tuỳ chọn định kiểu đó?
Chính vì thế, Thuộc tính tuỳ chỉnh CSS đã phát huy tác dụng.
Thuộc tính tuỳ chỉnh CSS
Thuộc tính tuỳ chỉnh được đặt tên rất phù hợp. Đây là các thuộc tính CSS mà bạn hoàn toàn có thể tự đặt tên và áp dụng bất kỳ giá trị nào cần thiết. Yêu cầu duy nhất là bạn thêm hai dấu gạch nối vào tiền tố của chúng. Sau khi khai báo thuộc tính tuỳ chỉnh, bạn có thể dùng giá trị này trong CSS bằng cách dùng hàm var()
.
Về tính kế thừa, tất cả Thuộc tính tuỳ chỉnh đều được kế thừa theo hành vi điển hình của các giá trị và thuộc tính CSS thông thường. Bạn có thể dùng bất kỳ thuộc tính tuỳ chỉnh nào áp dụng cho một phần tử mẹ hoặc chính phần tử đó làm giá trị trên các thuộc tính khác. Chúng tôi tận dụng Thuộc tính tuỳ chỉnh làm mã thông báo thiết kế bằng cách áp dụng chúng vào thành phần gốc thông qua Khung CSS. Tức là tất cả thành phần trên trang đều có thể sử dụng các giá trị mã thông báo này, cho dù đó là Thành phần web, lớp trợ giúp CSS hay nhà phát triển muốn lấy giá trị từ danh sách mã thông báo của chúng tôi.
Khả năng kế thừa Thuộc tính tuỳ chỉnh này (thông qua việc sử dụng hàm var()
) là cách chúng tôi xâm nhập vào DOM tối của Thành phần web và cho phép nhà phát triển kiểm soát chi tiết hơn khi tạo kiểu cho các thành phần.
Thuộc tính tuỳ chỉnh trong một Thành phần Web Bắc
Bất cứ khi nào phát triển một thành phần cho hệ thống thiết kế của mình, chúng tôi đều xem xét kỹ lưỡng CSS của nó. Chúng tôi muốn hướng đến mã tinh gọn nhưng rất dễ bảo trì. Mã thông báo thiết kế mà chúng ta có được xác định là Thuộc tính tuỳ chỉnh trong Khung CSS chính trên phần tử gốc.
Sau đó, các giá trị mã thông báo này được tham chiếu trong các thành phần của chúng tôi. Trong một số trường hợp, chúng tôi sẽ áp dụng giá trị trực tiếp trên thuộc tính CSS, nhưng đối với các trường hợp khác, chúng tôi sẽ thực sự xác định một Thuộc tính tùy chỉnh theo ngữ cảnh mới và áp dụng giá trị đó cho thuộc tính đó.
Chúng tôi cũng sẽ tóm tắt một số giá trị cụ thể cho thành phần nhưng không có trong mã thông báo và chuyển các giá trị đó thành Thuộc tính tùy chỉnh theo ngữ cảnh. Thuộc tính tuỳ chỉnh theo bối cảnh của thành phần mang lại cho chúng tôi hai lợi ích chính. Thứ nhất, điều đó có nghĩa là chúng tôi có thể "không" (có thể) nhiều hơn với CSS vì giá trị đó có thể được áp dụng cho nhiều thuộc tính bên trong thành phần.
Và thứ hai, nó giúp cho các thay đổi về trạng thái thành phần và biến thể thực sự rõ ràng. Đó chỉ là thuộc tính tuỳ chỉnh cần được thay đổi để cập nhật tất cả các thuộc tính đó khi, giả sử bạn đang tạo kiểu cho trạng thái di chuột hay trạng thái hoạt động, hay trong trường hợp này là một biến thể.
Nhưng lợi ích lớn nhất là khi xác định các Thuộc tính tuỳ chỉnh theo ngữ cảnh này trên một thành phần, chúng ta sẽ tạo một loại CSS API tuỳ chỉnh cho từng thành phần để người dùng thành phần đó có thể nhấn vào.
Ví dụ trước cho thấy một trong các Thành phần web có Thuộc tính tùy chỉnh theo ngữ cảnh được thay đổi thông qua bộ chọn. Kết quả của toàn bộ phương pháp này là một thành phần cung cấp đủ tính linh hoạt về định kiểu cho người dùng trong khi vẫn kiểm tra được hầu hết các kiểu thực tế. Ngoài ra, chúng tôi, với tư cách là nhà phát triển thành phần, có khả năng chặn các kiểu đó do người dùng áp dụng. Nếu muốn điều chỉnh hoặc mở rộng một trong các thuộc tính đó, chúng ta có thể thực hiện mà không cần người dùng phải thay đổi bất kỳ mã nào của họ.
Chúng tôi thấy cách tiếp cận này cực kỳ hiệu quả, không chỉ đối với chúng tôi, những người tạo ra các thành phần trong hệ thống thiết kế mà còn đối với nhóm phát triển của chúng tôi khi họ sử dụng các thành phần này trong các sản phẩm của chúng tôi.
Khai thác các Thuộc tính tuỳ chỉnh hơn nữa
Tại thời điểm viết bài này, chúng tôi không thực sự tiết lộ các Thuộc tính tuỳ chỉnh theo bối cảnh này trong tài liệu của mình. Tuy nhiên, chúng tôi dự định làm như vậy để nhóm phát triển chung của mình có thể hiểu được và tận dụng các thuộc tính đó. Các thành phần của chúng ta được đóng gói trên npm với một tệp kê khai, chứa mọi thông tin cần thiết về các thành phần đó. Sau đó, chúng tôi sử dụng tệp kê khai dưới dạng dữ liệu khi trang web tài liệu của chúng tôi được triển khai. Việc này được thực hiện bằng Eleventy và tính năng Dữ liệu toàn cầu của công cụ này. Chúng tôi dự định đưa các Thuộc tính tuỳ chỉnh theo bối cảnh này vào tệp dữ liệu kê khai này.
Một khía cạnh khác mà chúng tôi muốn cải thiện là cách các Thuộc tính tuỳ chỉnh theo bối cảnh này kế thừa giá trị. Ví dụ: hiện tại, nếu muốn điều chỉnh màu của 2 thành phần đường phân chia, bạn cần nhắm mục tiêu cụ thể đến cả 2 thành phần đó bằng bộ chọn hoặc áp dụng thuộc tính tuỳ chỉnh trực tiếp trên phần tử có thuộc tính kiểu. Điều này có vẻ ổn, nhưng sẽ hữu ích hơn nếu nhà phát triển có thể xác định các kiểu đó trên một phần tử chứa hoặc thậm chí ở cấp độ gốc.
Lý do bạn phải đặt giá trị Thuộc tính tùy chỉnh trực tiếp trên thành phần là vì chúng tôi đang xác định chúng trên cùng một phần tử thông qua bộ chọn máy chủ lưu trữ thành phần. Mã thông báo thiết kế chung mà chúng ta sử dụng trực tiếp trong thành phần truyền thẳng qua, không bị ảnh hưởng bởi vấn đề này và thậm chí có thể bị chặn trên các phần tử mẹ. Làm cách nào để chúng ta tận dụng được cả hai thế giới?
Thuộc tính tuỳ chỉnh riêng tư và công khai
Thuộc tính tuỳ chỉnh riêng tư là một thứ do Lea Verou kết hợp. Đây là một Thuộc tính tuỳ chỉnh "riêng tư" theo bối cảnh trên chính thành phần đó nhưng được đặt thành một Thuộc tính tuỳ chỉnh "công khai" có chức năng dự phòng.
Việc xác định Thuộc tính tuỳ chỉnh theo ngữ cảnh theo cách này có nghĩa là chúng ta vẫn có thể làm mọi việc trước đây, chẳng hạn như kế thừa giá trị mã thông báo chung và sử dụng lại các giá trị trong toàn bộ mã thành phần; nhưng thành phần này cũng sẽ dễ dàng kế thừa các định nghĩa mới của thuộc tính đó trên chính nó hoặc trên bất kỳ phần tử mẹ nào.
Mặc dù có thể lập luận rằng phương pháp này không thực sự "riêng tư", nhưng chúng tôi vẫn cho rằng đây là một giải pháp khá tinh tế cho một vấn đề mà chúng tôi lo ngại. Khi có cơ hội, chúng tôi sẽ giải quyết vấn đề này trong các thành phần để nhóm phát triển có nhiều quyền kiểm soát hơn đối với việc sử dụng thành phần trong khi vẫn hưởng lợi từ những biện pháp bảo vệ đang được áp dụng.
Tôi hy vọng bạn thấy thông tin chi tiết này về cách chúng tôi sử dụng Thành phần web với Thuộc tính tuỳ chỉnh CSS hữu ích. Hãy cho chúng tôi biết suy nghĩ của bạn. Nếu bạn quyết định dùng bất kỳ phương pháp nào trong số này trong công việc của mình, bạn có thể tìm thấy tôi trên Twitter @DavidDarnes. Bạn cũng có thể tìm thấy Nordhealth @NordhealthHQ trên Twitter và các thành viên còn lại trong nhóm của tôi. Họ đã nỗ lực kết hợp hệ thống thiết kế này và thực thi các tính năng được đề cập trong bài viết này: @Viljamis, @WickyNilliams và @eric_habich.
Hình ảnh chính của Dan Cristian Pădure Vi,