nghiên cứu điển hình về :has()

Swetha Gopalakrishnan
Swetha Gopalakrishnan
Saurabh Rajpal
Saurabh Rajpal

CSS nổi tiếng thiếu cách chọn trực tiếp phần tử mẹ dựa trên phần tử con. Đây là yêu cầu hàng đầu của các nhà phát triển trong nhiều năm. Bộ chọn :has() (hiện được tất cả các trình duyệt chính hỗ trợ) sẽ giải quyết vấn đề này. Trước :has(), bạn thường tạo chuỗi các bộ chọn dài hoặc thêm các lớp để tạo kiểu cho các móc. Giờ đây, bạn có thể tạo kiểu dựa trên mối quan hệ của một phần tử với các phần tử con cháu. Đọc thêm về bộ chọn :has() trong CSS Wrapped 20235 đoạn mã CSS mà mọi nhà phát triển giao diện người dùng đều nên biết.

Mặc dù bộ chọn này có vẻ nhỏ, nhưng có thể hỗ trợ rất nhiều trường hợp sử dụng. Bài viết này trình bày một số trường hợp sử dụng mà các công ty thương mại điện tử đã khai thác bằng bộ chọn :has().

:has() là một phần của Baseline Mới có.

Hỗ trợ trình duyệt

  • Chrome: 105.
  • Edge: 105.
  • Firefox: 121.
  • Safari: 15.4.

Nguồn

Hãy xem loạt bài viết đầy đủ mà bài viết này thuộc về. Loạt bài viết này thảo luận về cách các công ty thương mại điện tử nâng cao trang web của họ bằng cách sử dụng các tính năng mới về CSS và giao diện người dùng.

Policybazaar

Với bộ chọn :has(), chúng tôi có thể loại bỏ xác thực dựa trên JavaScript đối với lựa chọn của người dùng và thay thế bằng một giải pháp CSS đang hoạt động liền mạch cho chúng tôi với trải nghiệm tương tự như trước đây. – Aman Soni, Trưởng nhóm kỹ thuật, Policybazaar

Nhóm đầu tư của Policybazaar đã áp dụng bộ chọn :has() một cách khéo léo để cung cấp thông tin trực quan rõ ràng cho người dùng đang so sánh các gói. Hình ảnh sau đây cho thấy hai loại gói trong giao diện người dùng so sánh (vàng và xanh dương). Bạn chỉ có thể so sánh mỗi gói với một loại riêng. Khi sử dụng :has(), khi người dùng chọn một loại gói, họ sẽ không thể chọn loại gói còn lại.

Triển khai :has() để tạo kiểu cho phần tử mẹ và các phần tử con của phần tử mẹ để tạo chức năng lựa chọn liên kết với danh mục.

:has() cho phép bạn tạo kiểu cho các phần tử mẹ và phần tử con. Đoạn mã sau đây sẽ kiểm tra xem vùng chứa mẹ có đặt lớp .disabled-group hay không. Nếu có, thẻ sẽ có màu xám và nút "Add" (Thêm) sẽ không thể phản ứng với các lượt nhấp bằng cách đặt pointer-events thành none.

.plan-group-container:has(.disabled-group) {
  opacity: 0.5;
  filter: grayscale(100%);
}

.plan-group-container:has(.disabled-section) .button {
  pointer-events: none;
  border-color: #B5B5B5;
  color: var(--text-primary-38-color);
  background: var(--input-border-color);
}

Nhóm sức khoẻ tại Policybazaar đã triển khai một trường hợp sử dụng khác một chút. Ứng dụng này có một bài kiểm tra nội tuyến cho người dùng và sử dụng :has() để kiểm tra trạng thái hộp đánh dấu câu hỏi để xem người dùng có trả lời câu hỏi hay không. Nếu có, ảnh động sẽ được áp dụng để chuyển sang câu hỏi tiếp theo.

health.policybazaar.com/

Trong ví dụ so sánh kế hoạch, :has() được dùng để kiểm tra sự hiện diện của một lớp. Bạn cũng có thể kiểm tra trạng thái của một phần tử đầu vào, chẳng hạn như hộp đánh dấu bằng :has(input:checked). Trong hình ảnh hiển thị bài kiểm tra, mỗi câu hỏi trong biểu ngữ màu tím là một hộp đánh dấu. Policybazaar kiểm tra xem câu hỏi đã được trả lời hay chưa bằng :has(input:checked). Nếu câu hỏi đã được trả lời, hãy kích hoạt ảnh động bằng animation: quesSlideOut 0.3s 0.3s linear forwards để chuyển sang câu hỏi tiếp theo. Xem cách hoạt động của chế độ này trong mã sau.

.segment_banner__wrap__questions {
 position: relative;
 animation: quesSlideIn 0.3s linear forwards;
}

.segment_banner__wrap__questions:has(input:checked) {
 animation: quesSlideOut 0.3s 0.3s linear forwards;
}


@keyframes quesSlideIn {
 from {
   transform: translateX(50px);
   opacity: 0;
 }
 to {
   transform: translateX(0px);
   opacity: 1;
 }
}

@keyframes quesSlideOut {
 from {
   transform: translateX(0px);
   opacity: 1;
 }
 to {
   transform: translateX(-50px);
   opacity: 0;
 }
}

Tokopedia

Tokopedia đã sử dụng :has() để tạo hình ảnh lớp phủ nếu hình thu nhỏ sản phẩm chứa video. Nếu hình thu nhỏ sản phẩm chứa lớp .playIcon, thì một lớp phủ CSS sẽ được thêm vào. Ở đây, bộ chọn :has() được sử dụng cùng với bộ chọn lồng ghép & trong lớp .thumbnailWrapper tổng quát áp dụng cho tất cả hình thu nhỏ. Việc này tạo ra CSS theo mô-đun và dễ đọc hơn.

Ảnh chụp màn hình trang Tokopedia trước và sau khi sử dụng bộ chọn có.
Trước và sau khi sử dụng :has().

Mã sau đây sử dụng bộ chọn và bộ kết hợp CSS (&>) và lồng với :has() để tạo kiểu cho hình thu nhỏ. Đối với các trình duyệt không hỗ trợ, quy tắc lớp CSS bổ sung thông thường sẽ được dùng làm phương án dự phòng. Quy tắc @supports selector(:has(*)) cũng được dùng để kiểm tra xem trình duyệt có hỗ trợ hay không. Do đó, trải nghiệm tổng thể trên các phiên bản trình duyệt là như nhau.

export const thumbnailWrapper = css`
  padding: 0;
  margin-right: 7px;
  border: none;
  outline: none;
  background: transparent;

  > div {
    width: 64px;
    height: 64px;
    overflow: hidden;
    cursor: pointer;
    border-color: ;
    position: relative;
    border: 2px solid ${NN0};
    border-radius: 8px;
    transition: border-color 0.25s;

    &.active {
      border-color: ${GN500};
    }

    @supports selector(:has(*)) {
      &:has(.playIcon) {
        &::after {
          content: '';
          display: block;
          background: rgba(0, 0, 0, 0.2);
          position: absolute;
          top: 0;
          left: 0;
          right: 0;
          bottom: 0;
        }
      }
    }

    & > .playIcon {
      position: absolute;
      top: 25%;
      left: 25%;
      width: 50%;
      height: 50%;
      text-align: center;
      z-index: 1;
    }
  }
`;

Những điều cần cân nhắc khi sử dụng :has()

Kết hợp :has() với các bộ chọn khác để tạo một điều kiện phức tạp hơn. Hãy xem một số ví dụ trong has() bộ chọn gia đình.

Tài nguyên:

Khám phá các bài viết khác trong loạt bài này nói về lợi ích của các công ty thương mại điện tử khi sử dụng các tính năng mới về CSS và giao diện người dùng, chẳng hạn như Ảnh động di chuyển, chuyển đổi chế độ xem, cửa sổ bật lên và truy vấn vùng chứa.