Xuất bản: Ngày 11 tháng 12 năm 2025
Vậy là bạn có một trang web mà bạn muốn xây dựng hoặc thiết kế lại. Có thể bạn đã nghĩ đến một vài màu sắc cốt lõi và đang cân nhắc cách nhanh chóng triển khai một giao diện dựa trên những màu sắc đó.
Bạn sẽ cần màu chính, cũng như màu cho các thao tác, trạng thái di chuột, lỗi và màu cho các nhu cầu khác về giao diện người dùng. Vậy còn các lựa chọn chế độ sáng và tối thì sao? Đột nhiên, bạn sẽ cần rất nhiều màu sắc và điều này có thể khiến bạn cảm thấy choáng ngợp.
Tin vui là khi bạn tạo một bảng màu liên quan đến các mã màu xác định trang web của bạn và chuyển đổi giữa các chế độ màu, các tính năng của Baseline có thể giúp bạn thực hiện nhiều thao tác phức tạp. Bạn có thể khám phá một số kỹ thuật này trong bản minh hoạ nổi bật, một danh sách phát theo chủ đề màu sắc trên trang web Baseline Radio hư cấu.
Tạo một cơ sở bằng các màu tương đối
Nếu có ý tưởng về màu chính cho giao diện của mình, cùng với một số kiến thức cơ bản về lý thuyết màu sắc và cú pháp màu tương đối của CSS, bạn có thể nhanh chóng bắt đầu tạo một bảng màu để sử dụng trong giao diện của mình.
Giả sử màu cơ bản của bạn là một sắc thái của màu xanh mòng két, bạn có thể xác định màu này trước tiên theo định dạng màu mà bạn muốn. Sau đó, bạn có thể dùng bất kỳ hàm màu nào để tạo màu mới liên quan đến màu cơ bản:
html {
--base-color: oklch(43.7% 0.075 224);
}
Thuộc tính tuỳ chỉnh --base-color được tạo bằng hàm màu oklch(). OkLCh là dạng hình trụ của hệ màu Oklab và xác định các giá trị cho 3 kênh: L (độ sáng), C (độ bão hoà), H (sắc độ), cộng với một kênh alpha không bắt buộc để kiểm soát độ trong suốt.
OkLCh là một định dạng phù hợp cho loại thao tác màu này, vì định dạng này được thiết kế để mang lại tính đồng nhất về nhận thức. Ví dụ: nếu bạn chỉ điều chỉnh sắc độ của một màu, thì màu kết quả phải có độ sáng và độ bão hoà tương tự như màu gốc. Điều này đặc biệt hữu ích trong việc tránh các vấn đề về độ tương phản không mong muốn.
Giữ nguyên độ sáng và độ bão hoà của --base-color, bạn có thể điều chỉnh sắc độ theo cả hai hướng thêm 120 độ để có một bảng màu gồm 3 màu.
html {
/* ... */
--triadic-color-primary: oklch(from var(--base-color) l c calc(h + 120));
--triadic-color-secondary: oklch(from var(--base-color) l c calc(h - 120));
}
Như minh hoạ ở đây, cú pháp màu tương đối sử dụng một hàm màu tham chiếu đến màu gốc (--base-color trong ví dụ này) bằng từ khoá from và điều chỉnh các kênh tương ứng của không gian màu dựa trên màu đầu ra đã chọn. Trong trường hợp này, màu đầu ra cũng sẽ là OkLCh.
Kết quả đầu ra sẽ cho bạn một màu hồng đậm cho --accent-color và một sắc thái vàng để dùng cho --highlight-color, cả hai đều có cùng độ sáng và độ bão hoà như --base-color ban đầu.
html {
/* ... */
--accent-color: var(--triadic-color-primary);
--highlight-color: var(--triadic-color-secondary);
}
html {
/* Input color in the rgb color space*/
--base-color: teal;
/* Output color in oklch. Computes to oklch(0.543123 0.0927099 314.769) */
--triadic-color-primary: oklch(from var(--base-color) l c calc(h + 120));
}
Màu bổ sung sẽ thêm 180 độ vào góc sắc độ.
html {
/* ... */
--complement-color: oklch(from var(--base-color) l c calc(h + 180));
--border-highlight: var(--complement-color);
}
Đối với trạng thái di chuột trong giao diện người dùng, bạn có thể muốn xuất một phiên bản sáng hơn của một màu cụ thể. Điều này có nghĩa là tăng giá trị của kênh độ sáng. Đối với trạng thái hoạt động, bạn có thể muốn thêm độ trong suốt bằng cách điều chỉnh kênh alpha hoặc làm tối bằng cách giảm giá trị của kênh độ sáng.
html {
/* Darken the --base-color by 15% */
--base-color-darkened: oklch(from var(--base-color) calc(l * 0.85) c h);
/* Assign this color a meaningful variable name */
--action-color: var(--base-color-darkened);
/* Lighten the --action-color by 15% */
--action-color-light: oklch(from var(--action-color) calc(l * 1.15) c h);
/* Darken the --action-color by 10% */
--action-color-dark: oklch(from var(--action-color) calc(l * 0.9) c h);
}
Ở đây, chúng ta đang lấy --action-color từ --base-color và sử dụng nó cho các nút và đường liên kết. --action-color có 2 biến thể (sáng hơn và tối hơn) vẫn sẽ áp dụng ngay cả khi --action-color được thay đổi thành tương ứng với một màu khác ngoài --base-color.
Bạn có thể điều chỉnh các kênh bằng cách sử dụng một hàm toán học như calc() hoặc thay thế hoàn toàn kênh bằng một giá trị mới. Các kênh không thay đổi được biểu thị bằng các chữ cái tương ứng (ví dụ: l cho giá trị độ sáng không thay đổi).
Trộn màu bằng color-mix()
Đối với các biến thể màu khác, bạn có thể áp dụng phương pháp tương tự và điều chỉnh các kênh khác của thuộc tính tuỳ chỉnh --base-color. Hoặc dùng color-mix() để thêm các sắc thái của màu cơ bản vào những khía cạnh khác trong thiết kế của bạn.
--border-color là sự kết hợp giữa màu cơ bản và màu được đặt tên grey, được nội suy trong không gian màu oklab. Khi được dùng làm phương thức nội suy màu, phương thức này sẽ mang lại kết quả đồng nhất về cảm quan.
html {
--base-mix-grey-50: color-mix(in oklab, var(--base-color), grey);
--border-color: var(--base-mix-grey-50);
}
Theo mặc định, tỷ lệ này sẽ là 50% cho mỗi màu, nhưng bạn có thể tăng hoặc giảm độ nổi bật của một màu bằng cách điều chỉnh tỷ lệ phần trăm trọng số của màu đó.
html {
--background-mix-base-80: color-mix(in oklab,
var(--background-color) 80%,
var(--base-color));
--surface-light: var(--background-mix-base-80);
}
Một cách khác để thêm màu cho một phần tử là điều chỉnh kênh sắc độ của phần tử đó bằng cách sử dụng cú pháp màu tương đối. Đường viền của các trường nhập văn bản trong biểu mẫu liên hệ có đường viền nhiều màu hơn một chút khi được lấy tiêu điểm.
[data-input*="text"] {
--focus-ring: transparent;
/* ... */
&:focus {
--focus-ring: oklch(from var(--border-color) l calc(c + 0.1) h);
}
}
Chọn sử dụng chế độ sáng và tối
Sau khi có một bộ màu để sử dụng, bạn sẽ cần một cách hiệu quả để áp dụng các màu khác nhau cho chế độ sáng và tối.
Hỗ trợ tín hiệu cho giao diện sáng và tối bằng thuộc tính color-scheme
Bạn có thể cho trình duyệt biết ngay rằng trang web của bạn có thể xem ở chế độ "sáng", "tối" hoặc cả hai chế độ bằng thuộc tính color-scheme. Thuộc tính này cho trình duyệt biết những bảng phối màu mà một phần tử có thể hiển thị một cách thoải mái.
html {
color-scheme: light dark;
}
Đặt color-scheme: light dark trên phần tử giả :root hoặc phần tử html:
- Cho trình duyệt biết rằng trang của bạn hỗ trợ chế độ sáng hoặc tối.
- Thay đổi màu mặc định của giao diện người dùng trình duyệt cho phù hợp với chế độ cài đặt hệ điều hành tương ứng.
Để thông báo sớm hơn cho các tác nhân người dùng rằng trang của bạn hỗ trợ chế độ sáng và tối, bạn cũng có thể báo hiệu việc hỗ trợ chuyển đổi bảng phối màu bằng cách thêm một phần tử <meta> vào <head> của tài liệu.
<head>
<!-- ... -->
<meta name="color-scheme" content="light dark">
</head>
Đặt các biến thể "light" (sáng) và "dark" (tối) bằng hàm light-dark()
Là tác giả, bạn có thể quen với việc đặt màu của trang bằng truy vấn prefers-color-scheme @media.
@media (prefers-color-scheme: light) {
html {
--background-color: oklch(95.5% 0 162);
--text-color: black;
}
}
@media (prefers-color-scheme: dark) {
html {
--background-color: oklch(22.635% 0.01351 291.83);
--text-color: white;
}
}
Điều này rất hữu ích cho các màu sắc và kiểu do tác giả kiểm soát, nhưng như đã đề cập trong phần trước, bạn vẫn cần color-scheme để cập nhật màu sắc của giao diện người dùng trình duyệt.
Việc thay đổi màu sắc của trang bằng truy vấn prefers-color-scheme cũng có nghĩa là bạn sẽ phải sao chép một số mã vì bạn phải xác định màu sắc cho từng chế độ riêng biệt.
Tuy nhiên, khi đặt color-scheme trên toàn bộ trang (hoặc các phần tử cụ thể), bạn có thể dùng hàm light-dark() để đặt màu cho từng chế độ trong một dòng mã.
Hàm này chấp nhận 2 màu. Màu đầu tiên được dùng khi bảng phối màu được đặt thành "sáng" và màu thứ hai được dùng khi bảng phối màu được đặt thành "tối".
html {
color-scheme: light dark;
/* Color custom property values for both light and dark modes */
--base-color: light-dark(oklch(43.7% 0.075 224), oklch(89.2% 0.069 224));
--background-color: light-dark(oklch(95.5% 0 162), oklch(22.635% 0.01351 291.83));
--accent-color: oklch(from var(--base-color) l c calc(h + 120));
--active-color: light-dark(var(--action-color-light), var(--action-color-dark));
/* ... */
}
Giống như mọi thuộc tính tuỳ chỉnh, bạn có thể đặt chế độ cài đặt light-dark() cho màu sắc trên toàn cầu hoặc trong các thành phần cụ thể, sau đó sử dụng ở nơi khác nếu cần.
/* custom property usage */
body {
background-color: var(--background-color);
/* ... */
}
:any-link {
/* ... */
text-decoration-color: var(--accent-color);
}
Trao quyền kiểm soát cho người dùng bằng trình chuyển đổi giao diện tích hợp
Thật tuyệt vời khi có một giao diện thích ứng với lựa chọn ưu tiên về màu sắc mặc định của hệ thống hoặc trình duyệt của người dùng, nhưng bạn có thể tiến thêm một bước nữa và cho phép người xem trang web của bạn thay thế những lựa chọn ưu tiên về màu sắc mặc định này.
Nếu tạo một nút bật/tắt giao diện cập nhật thuộc tính data-scheme trên phần tử <html>, bạn có thể dùng cùng một thuộc tính để thay đổi color-scheme bằng CSS.
html {
color-scheme: light dark;
&[data-scheme="light"] {
color-scheme: light;
}
&[data-scheme="dark"] {
color-scheme: dark;
}
&[data-scheme="green"] {
--base-color-light: oklch(48.052% 0.11875 151.945);
--base-color-dark: oklch(92.124% 0.13356 151.558);
color-scheme: light dark;
}
}
data-scheme="light" và data-scheme="dark" chỉ hiển thị trang ở chế độ màu tương ứng. data-scheme="green" có thể được xem ở cả hai chế độ và cũng thay đổi --base-color thành một sắc thái của màu xanh lục, mang đến cho bạn một bảng màu hoàn toàn mới vì hầu hết các màu khác đều dựa trên --base-color.
Đăng ký các thuộc tính tuỳ chỉnh bằng @property
Cho đến nay, màu sắc trong bản minh hoạ được đặt làm thuộc tính tuỳ chỉnh tiêu chuẩn. Bạn cũng có thể đăng ký các thuộc tính bằng quy tắc @property để khai thác những lợi ích đi kèm với tính năng kiểm tra kiểu.
Vì --base-color được dùng làm cơ sở của rất nhiều màu khác trong giao diện, nên bạn có thể đảm bảo rằng đây luôn là một màu và có giá trị dự phòng.
@property --base-color-light {
syntax: '<color>';
inherits: false;
initial-value: oklch(43.7% 0.075 224);
}
@property --base-color-dark {
syntax: '<color>';
inherits: false;
initial-value: oklch(89.2% 0.069 224);
}
html {
--base-color: light-dark(var(--base-color-light), var(--base-color-dark));
}
Bằng cách này, nếu --base-color vô tình thay đổi thành một giá trị không hợp lệ, thì giá trị này sẽ luôn quay về initial-value được đặt bằng quy tắc @property.
Việc đăng ký một số thuộc tính theo cách này cũng cho phép tạo hiệu ứng màu sắc mượt mà trong linear-gradient().
.main-heading {
background: linear-gradient(in oklch 90deg, var(--text-color) 50%, oklch(from var(--base-color) l c var(--header-hue)));
background-clip: text;
color: transparent;
animation: header-hue-switch 5s ease-in-out infinite alternate;
}
.main-heading có một nền linear-gradient() xuất hiện thông qua văn bản trong suốt bằng thuộc tính background-clip.
Một phần văn bản cho thấy hue, sử dụng cú pháp màu tương đối, có hiệu ứng chuyển động từ giá trị kênh 26.67 sang 277:
@keyframes header-hue-switch {
from {
--header-hue: 26.67;
}
to {
--header-hue: 277;
}
}
Với một thuộc tính tuỳ chỉnh --header-hue đã đăng ký, ảnh động này có thể diễn ra suôn sẻ vì trình duyệt biết rằng thuộc tính tuỳ chỉnh này là một số.
@property --header-hue {
syntax: '<number>';
inherits: false;
initial-value: 100;
}
Với một thuộc tính tuỳ chỉnh chưa đăng ký, trình duyệt sẽ không biết kiểu dữ liệu của --header-hue, vì vậy, quá trình chuyển đổi sang một số sẽ là một ảnh động rời rạc, tức là ảnh động sẽ chuyển đổi giữa các trạng thái mà không có quá trình nội suy dần.
Tóm tắt
Các công cụ Baseline mới có thể giúp bạn nhanh chóng tạo một bảng màu có thể điều chỉnh và giúp quá trình tạo các biến màu trở nên hiệu quả hơn. Tuy nhiên, bạn vẫn phải tự mình cân nhắc vô số lựa chọn và cách phối màu.
Việc tạo bảng màu một cách linh hoạt như thế này sẽ giúp bạn có nhiều lựa chọn. Nếu cần thay đổi màu cơ bản cho hoạt động xây dựng thương hiệu, bạn chỉ cần cập nhật --base-color và phần còn lại của giao diện sẽ được điều chỉnh theo màu đó. Hoặc nếu thêm chức năng phát nhạc, bạn có thể quyết định thay đổi màu cơ bản một cách linh động cho phù hợp với bài hát đang phát.
Ghi công
Logic của trình chuyển đổi giao diện được điều chỉnh từ Thành phần chuyển đổi giao diện của Adam Argyle.