Việc duy trì các biểu định kiểu lớn thường dẫn đến logic lặp lại, đặc biệt là khi xử lý các mã thông báo của hệ thống thiết kế như dải chuyển màu hoặc mẫu bố cục thích ứng.
Quy tắc at-rule @function của CSS cho phép bạn đóng gói logic này vào các hàm có thể sử dụng lại và có tham số, giúp CSS của bạn dễ bảo trì, nhất quán và DRY (Don't Repeat Yourself – Đừng lặp lại chính mình) hơn.
Cú pháp @function
Hàm tuỳ chỉnh được xác định bằng quy tắc @function, theo sau là tên có dấu gạch ngang và danh sách tham số. Hàm này trả về một giá trị bằng thuộc tính result.
@function --my-function(--input1 <length>, --input2: default-value) returns <length> {
/* Logic goes here */
result: var(--input1);
}
Khái niệm chính
- Tham số: Phải bắt đầu bằng dấu gạch ngang kép (
--). - Giá trị mặc định: Bạn có thể cung cấp giá trị mặc định bằng dấu hai chấm (
:). - Kết quả: Thuộc tính
resultxác định giá trị mà hàm trả về.resultcuối cùng được khai báo trong phần nội dung hàm sẽ được áp dụng. - Phạm vi: Các tham số và biến được xác định bên trong hàm có phạm vi cục bộ.
- Loại: Bạn có thể yêu cầu các tham số và giá trị được trả về phải khớp với một loại CSS có ký hiệu dấu ngoặc vuông (ví dụ:
<color>) và cho phép nhiều loại bằng hàmtype(ví dụ:type(<number> | <percentage>)).
Ví dụ thực tế
1. Mã thông báo hệ thống thiết kế (Chuyển màu)
Đảm bảo độ dốc màu nhất quán trên ứng dụng bằng cách đóng gói logic chuyển màu. --angle cung cấp một giá trị mặc định để đảm bảo tính nhất quán có thể ghi đè.
@function --fancy-gradient(--start-color <color>, --end-color <color>, --angle: 98deg) returns <image>{
result: linear-gradient(in oklab var(--angle), var(--start-color), var(--end-color) );
}
.card {
background: --fancy-gradient(#ed73d7, #5d87e9);
}
2. Logic bố cục có điều kiện
Bạn có thể sử dụng @media hoặc các truy vấn khác ngay bên trong một hàm để trả về các giá trị khác nhau dựa trên môi trường. Khi sử dụng logic có điều kiện trong một hàm, xin lưu ý rằng @function không "trả về" ở giá trị đầu tiên của result, mà tuân theo CSS xếp tầng và phân giải thành giá trị cuối cùng khớp dựa trên kích thước màn hình, kích thước vùng chứa hoặc truy vấn khác.
@function --grid-template(--count <number>){
/* MANDATORY: Put default value first. */
result: 1fr; /* Default: stack */
@media (min-width: 800px) {
result: repeat(var(--count), 1fr); /* Grid on larger screens */
}
}
main {
display: grid;
grid-template-columns: --grid-template(2);
}
Các phương pháp hay nhất
- Sử dụng tên có dấu gạch ngang: Luôn thêm tiền tố
--vào tên và tham số của hàm. - Cung cấp giá trị mặc định: Giúp các hàm của bạn hoạt động hiệu quả hơn bằng cách cung cấp các giá trị mặc định hợp lý.
- Đơn giản: Sử dụng các hàm cho logic thực sự lặp lại hoặc phức tạp. Đừng thiết kế quá phức tạp cho các cặp thuộc tính-giá trị đơn giản.
- Sử dụng các loại: Đảm bảo các tham số và giá trị trả về của bạn thuộc loại dự kiến.
- Cân nhắc các giải pháp thay thế được biên dịch trước: Đối với các hàm không phụ thuộc vào hoạt động đầu vào của người dùng, truy vấn phương tiện hoặc biến thể phía máy khách khác, hãy cân nhắc sử dụng trình biên dịch trước CSS để tránh thực hiện công việc không cần thiết trên máy khách.
Chiến lược dự phòng
Trong các trình duyệt không hỗ trợ Hàm CSS, các giá trị được đặt bằng hàm CSS sẽ không hợp lệ. Để hỗ trợ các trình duyệt khác, trước tiên, hãy cung cấp giá trị dự phòng cho thuộc tính. Giá trị này sẽ bị ghi đè trong các trình duyệt có hỗ trợ hàm CSS.
.card {
/* Provide fallback, in this case a solid color. */
background: #5d87e9;
background: --fancy-gradient(#ed73d7, #5d87e9);
}
main {
/* Provide fallback, in this case a simple stacked default. */
grid-template-columns: 1fr;
grid-template-columns: --grid-template(2);
}
Nếu bạn cần giảm việc lặp lại kiểu trong khi hỗ trợ các trình duyệt khác, hãy cân nhắc sử dụng trình biên dịch trước CSS có các hàm, chẳng hạn như Sass.