- Bài viết đề xuất tự động tạo bảng màu 256 màu từ theme base16 của người dùng, nhằm cải thiện tính nhất quán màu sắc và khả năng đọc trong terminal
- Theme base16 hiện có tuy đơn giản nhưng số lượng màu bị hạn chế, còn truecolor lại gặp vấn đề về độ phức tạp khi cấu hình và khả năng tương thích
- Bảng màu 256 màu mặc định có chất lượng thị giác thấp do mất cân bằng độ sáng, không khớp với theme và nội suy sai
- Nếu dùng nội suy trong không gian màu LAB để tạo bảng màu mở rộng từ các màu base16, có thể giữ được độ sáng và độ tương phản nhất quán, đồng thời biểu đạt màu sắc phong phú hơn
- Nhiều terminal lớn (ví dụ: Ghostty, iTerm2, SwiftTerm) đã bắt đầu triển khai, và tính năng tự động tạo bảng màu được chuẩn hóa có thể giúp nâng chất lượng cho toàn bộ hệ sinh thái terminal
Tổng quan về bảng màu 256 màu
- Bảng màu 256 màu gồm 16 màu cơ bản, khối màu 216 màu và thang xám 24 mức
- 16 màu cơ bản bao gồm đen, trắng, các màu nguyên bản và các biến thể sáng hơn
- Khối màu 216 màu được tính bằng cách dùng 6 mức (0~5) cho mỗi kênh RGB:
16 + (36 * R) + (6 * G) + B
- Thang xám gồm 24 mức giữa đen và trắng:
232 + S (S là 0~23)
- Cấu trúc này là phiên bản đơn giản hóa của RGB 24-bit, giúp giảm số lượng màu nhưng vẫn giữ được khả năng biểu đạt
Các vấn đề của bảng màu 256 màu hiện tại
- Xảy ra xung đột màu do không khớp với theme Base16
- Bảng màu mặc định không hài hòa với phần lớn các theme base16
- Nội suy màu sai làm giảm khả năng đọc trên nền tối
- Sắc độ đầu tiên trong bảng màu mặc định được tính sáng hơn thực tế, làm yếu đi độ tương phản
- Vấn đề độ tương phản không đồng đều
- Việc dùng màu bão hòa hoàn toàn làm mất cân bằng độ sáng, và ở cùng một cấp độ thì màu xanh dương trông tối hơn màu xanh lá
Cách tạo bảng màu
- Giải pháp là tự động tạo bảng màu 256 màu từ các màu base16 của người dùng
- Ánh xạ 8 màu cơ bản của base16 vào 8 đỉnh của khối màu 216 màu
- Dùng màu nền và màu chữ để tạo khối màu bằng nội suy tam tuyến tính (trilinear interpolation)
- Sử dụng không gian màu LAB để giữ độ sáng cảm nhận nhất quán giữa các màu
- Thang xám được tạo bằng nội suy đơn giản từ màu nền đến màu chữ
- Mã Python ví dụ dùng các hàm
rgb_to_lab, lab_to_rgb, lerp_lab để thực hiện chuyển đổi
Tình hình triển khai và áp dụng
- Đoạn mã được đề xuất được phát hành dưới dạng public domain, có thể tự do chỉnh sửa và sử dụng
- Các terminal lớn như Ghostty, iTerm2, SwiftTerm đã triển khai xong
- kitty, Wezterm, Tabby, Windows Terminal cũng đang có yêu cầu áp dụng hoặc đang được phát triển
- Một số nhà phát triển đề xuất dùng không gian màu OKLAB/OKLCH, và dự án dự kiến sẽ thống nhất không gian màu chuẩn theo quyết định của Ghostty
- Có thể áp dụng trực tiếp bảng màu bằng script Python hoặc tự động tạo file cấu hình terminal
Kết luận và đề xuất
- Bảng màu 256 màu mặc định bị các lập trình viên né tránh do làm giảm khả năng đọc và không khớp với theme
- Nếu terminal tự động tạo bảng màu 256 màu dựa trên theme base16, có thể đạt được các lợi ích sau
- Dùng được dải màu rộng mà không cần file cấu hình
- Không cần lập trình viên can thiệp khi chuyển giữa chế độ sáng/tối
- Vẫn giữ được khả năng tương thích rộng với nhiều terminal
- Tác giả nhấn mạnh tính năng này nên được bật mặc định (opt-out) và về lâu dài cần trở thành tính năng tiêu chuẩn
1 bình luận
Ý kiến trên Hacker News
Điểm hay của bảng màu 256 màu là các màu từ 16 đến 255 được cố định
Vì vậy, ví dụ, bạn có thể chắc chắn rằng màu số 146 luôn là một "màu tím dịu"
Điều này rất hữu ích cho các nhà phát triển color theme muốn mang lại trải nghiệm màu sắc nhất quán trên nhiều terminal emulator khác nhau
Nếu bảng màu 256 màu được tạo từ bảng 16 màu có thể thay đổi, thì màu 146 có thể không còn là màu như mong đợi
Biến vùng 16~255 trở nên thiếu ổn định như vùng 0~15 là đi sai hướng
Điều đó làm giảm khả năng đọc đối với người khiếm thị, người mù màu, hoặc những ai thích nền trắng
Rốt cuộc, người dùng sẽ phải chỉnh không chỉ màu mặc định của terminal mà còn cả cài đặt màu của từng ứng dụng riêng lẻ
Terminal được dùng vì hiệu suất, không phải vì giao diện đẹp. Muốn đẹp thì hãy làm web frontend
Chúng ta không muốn một "trải nghiệm nhất quán". Màu sắc nên được dùng tiết chế và tôn trọng thiết lập của người dùng
Nền có thể cũng là màu tím, hoặc có thể là chữ tím trên nền trắng
Tức là nếu ứng dụng không biết cấu hình màu của terminal của tôi, thì đừng nên dùng màu đó
Tôi dùng theme base16 mặc định và không kỳ vọng nó phải khớp với theme do bên thứ ba tạo ra
Tôi nghĩ sự khác biệt giữa cách tiếp cận màu ở cấp terminal và cấp ứng dụng gần như là một vấn đề triết học
Tôi đã tạo ra một trình render Markdown dạng stream tên là Streamdown
Dựa trên HSV, chỉ cần chọn một màu cơ sở, phần còn lại sẽ tự động được điều chỉnh theo bội số của màu đó
Ví dụ, các thành phần tối sẽ giảm độ bão hòa, còn symbol thì sẽ rực hơn
Chỉ cần chỉnh nhẹ HSV trong cấu hình là toàn bộ tông màu thay đổi một cách tự nhiên, nên không cần phải tinh chỉnh từng màu một
Cũng có mã ví dụ
Ngay cả bảng 16 màu mặc định cũng có vấn đề
black,white,bright black,bright whitetrên thực tế nên mang ý nghĩa độ tương phản sáng tối, nhưng tên của chúng lại là tên màuTôi hiểu chúng là "màu gần như không thấy trên nền", "màu có độ tương phản cao", "màu nhìn thấy nhưng yếu", và "màu có độ tương phản mạnh nhất"
Sẽ tốt hơn nếu chúng được định nghĩa theo độ tương phản, chứ không phải tên màu
Màu foreground/background của terminal lại độc lập với chuẩn 16 màu nên còn phức tạp hơn
Khi không biết màu nền, nên tránh màu đen và trắng. Nếu dùng 256 màu thì nên dùng một theme engine cho phép người dùng tùy chỉnh
Tôi nghĩ tính năng này nên được thêm vào mọi terminal
Sẽ còn tốt hơn nếu mở rộng sang màu 24-bit. Tuy nhiên, nó phải được cung cấp dưới dạng tùy chọn
Ví dụ, nếu dùng theme Solarized cho cả terminal lẫn editor, thì việc chuyển đổi màu có thể bị áp dụng trùng lặp
Nếu để nó được điều khiển bằng biến môi trường thay vì để ứng dụng trực tiếp ghi đè cấu hình thì sẽ linh hoạt hơn
Tôi đang dùng tinted-theming/base24 sau khi phát hiện ra nó
Có thể chuyển đổi color theme rất dễ bằng tinted shell. Đây là một giải pháp tạm thời khá ổn
cargo/rustc cũng gặp vấn đề thiếu màu
Nếu chỉ dùng các màu ngữ nghĩa mặc định thì thứ còn lại chỉ là magenta, đen và trắng, mà những màu này có thể nguy hiểm tùy theo theme
Cứ dùng chế độ true color 24-bit thì không cần bảng màu nữa
Theo termstandard/colors, hầu hết terminal hiện đại đều hỗ trợ điều này
Thậm chí nếu xét đến giới hạn vật lý như nguyên lý bất định Heisenberg hay nhiễu lượng tử, có thể sẽ cần dữ liệu ở mức 6000 bit/pixel
Kiểu tưởng tượng này giống như thang đo Kardashev hay các khái niệm thời gian vũ trụ cổ đại: một phép thử tư duy thú vị cho thấy hướng tiến bộ của công nghệ
Không phải người dùng nào cũng cấu hình màu mặc định cho chuẩn
Có terminal có thể ám toàn màu xanh lá hoặc màu cam
Có lẽ cách lấy độ bão hòa của màu mặc định rồi áp dụng cho toàn bộ bảng màu vẫn còn khá hơn
Tôi bị mù màu nên đã gặp rất nhiều khó khăn với color theme
Vì vậy tôi dùng mô hình AI để tự động tạo ra tổ hợp màu có độ dễ đọc cao
Nó tăng độ tương phản dựa trên theme mà tôi vốn thích, nên nhìn dễ chịu hơn hẳn
Tôi nghĩ cách tiếp cận này có thể cũng hữu ích với những người khác
Mỗi ứng dụng dùng màu theo cách khác nhau, nên có theme thì nhìn ổn trong vài CLI nhưng ở chỗ khác lại quá nhạt
Cuối cùng vẫn có bất tiện là phải chỉnh color theme riêng cho từng ứng dụng
Tôi bị protanomaly (suy giảm cảm nhận màu đỏ) nên đang dùng ametameric
Tôi nghĩ nếu dùng cùng với tính năng này thì có thể cho kết quả tốt hơn