Trước đây, để áp dụng kiểu riêng biệt cho từng phần tử đồng cấp trong một danh sách, bạn phải dùng vòng lặp :nth-child phức tạp hoặc JavaScript để chèn kiểu cùng dòng. CSS hiện đại cung cấp sibling-index() và sibling-count() để thực hiện các phép tính này ngay trong biểu định kiểu, cho phép bố cục động và hệ thống màu tự động điều chỉnh khi các phần tử được thêm hoặc xoá.
Hệ thống màu động
Bạn có thể tạo một dải màu trên một nhóm thành phần đồng cấp bằng cách tính toán giá trị sắc độ hoặc độ sáng riêng biệt cho từng thành phần con. Điều này đảm bảo hiệu ứng chuyển màu nhất quán bất kể số lượng mục.
.swatch {
/* Calculate hue by dividing the full 360deg circle by total siblings */
/* and multiplying by the current element's 1-based index */
background-color: hsl(
calc(360deg / sibling-count() * sibling-index()),
70%,
50%
);
}
Bố cục đối xứng và hiệu ứng quạt
Để tạo hiệu ứng đối xứng (như "quạt" hoặc căn giữa các mục), hãy sử dụng tổng số để tìm điểm giữa của danh sách.
.card {
/* Find the center index (e.g., 3 if there are 5 siblings) */
--center: calc((sibling-count() + 1) / 2);
/* Rotate items away from the center: negative for left, positive for right */
/* center element gets 0deg rotation */
transform: rotate(calc(10deg * (sibling-index() - var(--center))));
}
Định vị vòng tròn và phức tạp
Bằng cách kết hợp các hàm này với lượng giác CSS (sin(), cos()), bạn có thể đặt các phần tử trong một vòng tròn hoàn hảo mà không cần bất kỳ toạ độ thủ công nào.
.orb {
/* Calculate the angle for this item's position on a 360deg circle */
--angle: calc(360deg / sibling-count() * sibling-index());
--radius: 150px;
/* Set the pre-transformed position for all items to be centered */
position: absolute;
place-self: center;
/* Position each element around the parent center */
transform: translate(
calc(cos(var(--angle)) * var(--radius)),
calc(sin(var(--angle)) * var(--radius))
);
}
Chiến lược dự phòng
Nếu sibling-index() và sibling-count() không được hỗ trợ, hãy cung cấp phương án dự phòng bằng cách chèn các thuộc tính tuỳ chỉnh CSS thông qua JavaScript. BẮT BUỘC: Sử dụng tính năng phát hiện tính năng bằng CSS.supports() để đảm bảo tập lệnh chỉ chạy khi cần thiết.
/* MANDATORY: Check for native support before applying fallback */
if (!CSS.supports('top: calc(sibling-index() * 1px)')) {
const items = document.querySelectorAll('.item');
items.forEach((item, index) => {
/* MANDATORY: Injected index must be 1-based to match native function */
item.style.setProperty('--sibling-index', index + 1);
item.style.setProperty('--sibling-count', items.length);
});
}
Trong CSS, hãy sử dụng các biến này làm cơ sở và ghi đè chúng bằng các hàm gốc bên trong khối @supports. BẮT BUỘC: Bạn PHẢI gói các cơ chế ghi đè hàm gốc trong @supports để đảm bảo các biến vẫn hợp lệ trong các trình duyệt cũ.
.item {
/* 1. Set base values using variables (from JS fallback) */
--index: var(--sibling-index);
--count: var(--sibling-count);
/* 2. Use the computed variables - replace this with your implementation-specific styles */
background-color: hsl(calc(360deg / var(--count) * var(--index)), 70%, 50%);
}
@supports (top: calc(sibling-index() * 1px)) {
.item {
/* 3. Override with native functions ONLY if supported */
--index: sibling-index();
--count: sibling-count();
}
}