Tạo các thẻ hoạt hình, có thể nhấp bằng Thông minh dữ liệu PlatoBlockchain lớp giả quan hệ :has(). Tìm kiếm dọc. Ái.

Tạo thẻ hoạt hình, có thể nhấp với: has () Relational Pseudo Class

CSS :has() lớp giả đang được triển khai trong nhiều trình duyệt với cơ rômSafari đã hoàn toàn hỗ trợ nó. Nó thường được gọi là “bộ chọn mẹ” - như trong đó, chúng ta có thể chọn kiểu cho phần tử mẹ từ bộ chọn con - nhưng còn nhiều hơn thế nữa :has() có thể giúp chúng tôi giải quyết. Một trong những điều đó là phát minh lại mẫu thẻ có thể nhấp mà nhiều người trong chúng ta yêu thích sử dụng theo thời gian.

Chúng tôi sẽ xem xét cách :has() có thể giúp chúng tôi xử lý các thẻ được liên kết, nhưng trước tiên…

cái gì thế này :has() lớp giả?

Đã có một xăn lên of tuyệt vời bài viết nổi xung quanh làm một công việc xuất sắc giải thích những gì :has() là gì và nó được sử dụng để làm gì, nhưng nó vẫn đủ mới để chúng ta cũng nên nói một vài lời về nó ở đây.

:has() là một lớp giả quan hệ là một phần của Bản thảo làm việc cấp 3 của Bộ chọn W4C. Đó là nội dung của dấu ngoặc đơn: khớp các phần tử có liên quan đến - hoặc chính xác hơn là chứa - một số phần tử con nhất định.

/* Matches an article element that contains an image element */
article:has(img) { }

/* Matches an article element with an image contained immediately within it */
article:has(> img) { }

Vì vậy, bạn có thể thấy lý do tại sao chúng tôi có thể muốn gọi nó là bộ chọn “cha mẹ”. Nhưng chúng ta cũng có thể kết hợp nó với các lớp giả chức năng khác để cụ thể hơn. Giả sử chúng tôi muốn tạo kiểu cho các bài viết không chứa bất kỳ hình ảnh nào. Chúng ta có thể kết hợp các quyền hạn quan hệ của :has() với quyền hạn phủ định của :not() Để làm việc đó:

/* Matches an article without images  */
article:not(:has(img)) { }

Nhưng đó mới chỉ là bước khởi đầu của cách chúng ta có thể kết hợp sức mạnh để làm được nhiều việc hơn với :has(). Trước khi chuyển sang giải quyết câu hỏi hóc búa về thẻ có thể nhấp, hãy xem xét một số cách chúng tôi hiện đang tiếp cận chúng mà không cần sử dụng :has().

Cách chúng tôi hiện xử lý thẻ có thể nhấp

Ngày nay, có ba cách tiếp cận chính về cách mọi người tạo ra một thẻ hoàn toàn có thể nhấp và để hiểu đầy đủ về sức mạnh của lớp giả này, thật tuyệt khi có một chút tổng kết.

Cách tiếp cận này được sử dụng khá thường xuyên. Tôi không bao giờ sử dụng phương pháp này nhưng tôi đã tạo một bản demo nhanh để chứng minh nó:

Có rất nhiều mối quan tâm ở đây, đặc biệt là khi nói đến khả năng tiếp cận. Khi người dùng điều hướng trang web của bạn bằng chức năng rôto, họ sẽ nghe thấy toàn bộ nội dung bên trong phần tử - tiêu đề, văn bản và liên kết. Ai đó có thể không muốn ngồi qua tất cả những điều đó. Chúng ta có thể làm tốt hơn. Kể từ HTML5, chúng ta có thể lồng các phần tử khối vào bên trong yếu tố. Nhưng nó không bao giờ cảm thấy đúng với tôi, đặc biệt là vì lý do này.

Ưu điểm:

  • Nhanh chóng để thực hiện
  • Đúng về mặt ngữ nghĩa

Nhược điểm:

  • Mối quan tâm về khả năng tiếp cận
  • Không thể chọn văn bản
  • Rất nhiều rắc rối khi ghi đè các kiểu mà bạn đã sử dụng trên các liên kết mặc định của mình

Phương pháp JavaScript

Sử dụng JavaScript, chúng tôi có thể đính kèm một liên kết vào thẻ của mình thay vì viết nó trong phần đánh dấu. Tôi đã tìm thấy bản demo CodePen tuyệt vời này bởi costdev người cũng làm cho nội dung thẻ có thể chọn được trong quá trình này:

Cách tiếp cận này có rất nhiều lợi ích. Các liên kết của chúng tôi có thể truy cập vào tiêu điểm và chúng tôi thậm chí có thể chọn văn bản. Nhưng có một số hạn chế khi nói đến kiểu dáng. Ví dụ: nếu chúng ta muốn tạo hoạt ảnh cho những thẻ đó, chúng ta sẽ phải thêm :hover phong cách trên chính của chúng tôi .card trình bao bọc thay vì liên kết chính nó. Chúng tôi cũng sẽ không được hưởng lợi từ các hình ảnh động khi các liên kết nằm trong tiêu điểm từ thao tác tab bàn phím.

Ưu điểm:

  • Có thể được thực hiện một cách hoàn hảo
  • Khả năng chọn văn bản

Nhược điểm:

  • Yêu cầu JavaScript
  • Không thể nhấp chuột phải (mặc dù có thể được khắc phục bằng một số tập lệnh bổ sung)
  • Sẽ yêu cầu nhiều kiểu dáng trên chính thẻ, điều này sẽ không hoạt động khi tập trung vào liên kết

Sản phẩm ::after phương pháp tiếp cận bộ chọn

Phương pháp này yêu cầu chúng ta đặt thẻ có định vị tương đối, sau đó đặt định vị tuyệt đối trên liên kết của ::after bộ chọn giả của một liên kết. Điều này không yêu cầu bất kỳ JavaScript nào và khá dễ thực hiện:

Có một số hạn chế ở đây, đặc biệt là khi nói đến việc chọn văn bản. Trừ khi bạn cung cấp chỉ số z cao hơn trên thân thẻ của mình, bạn sẽ không thể chọn văn bản nhưng nếu làm vậy, hãy lưu ý rằng việc nhấp vào văn bản sẽ không kích hoạt liên kết của bạn. Bạn có muốn văn bản có thể chọn được hay không là tùy thuộc vào bạn. Tôi nghĩ rằng nó có thể là một vấn đề UX, nhưng nó phụ thuộc vào trường hợp sử dụng. Văn bản vẫn có thể truy cập được đối với trình đọc màn hình nhưng vấn đề chính của tôi với phương pháp này là thiếu khả năng hoạt ảnh.

Ưu điểm:

  • Dễ để thực hiện
  • Liên kết có thể truy cập mà không có văn bản cồng kềnh
  • Hoạt động khi di chuột và lấy nét

Nhược điểm:

  • Không thể chọn văn bản
  • Bạn chỉ có thể tạo hoạt ảnh cho liên kết vì đây là phần tử bạn đang di chuột.

Một cách tiếp cận mới: Sử dụng ::after với :has()

Bây giờ chúng tôi đã thiết lập các phương pháp tiếp cận hiện có cho thẻ có thể nhấp, tôi muốn giới thiệu cách giới thiệu :has() hỗn hợp giải quyết hầu hết những thiếu sót đó.

Trên thực tế, chúng ta hãy dựa trên phương pháp này dựa trên phương pháp cuối cùng mà chúng ta đã xem xét bằng cách sử dụng ::after trên phần tử liên kết. Chúng tôi thực sự có thể sử dụng :has() ở đó để khắc phục các hạn chế về hoạt ảnh của cách tiếp cận đó.

Hãy bắt đầu với đánh dấu:

Fluffy gray and white tabby kitten snuggled up in a ball.

Some Heading

Curabitur convallis ac quam vitae laoreet. Nulla mauris ante, euismod sed lacus sit amet, congue bibendum eros. Etiam mattis lobortis porta. Vestibulum ultrices iaculis enim imperdiet egestas.

Tôi sẽ giữ mọi thứ đơn giản nhất có thể bằng cách nhắm mục tiêu các phần tử trong CSS thay vì các lớp.

Đối với bản trình diễn này, chúng tôi sẽ thêm thu phóng hình ảnh và bóng đổ vào thẻ khi di chuột và tạo hoạt ảnh liên kết bằng một mũi tên bật lên và trong khi thay đổi màu văn bản của liên kết. Để làm cho điều này dễ dàng, chúng tôi sẽ thêm một số thuộc tính tùy chỉnh trong phạm vi thẻ của chúng tôi. Đây là kiểu cơ bản:

/* The card element */
article {
  --img-scale: 1.001;
  --title-color: black;
  --link-icon-translate: -20px;
  --link-icon-opacity: 0;

  position: relative;
  border-radius: 16px;
  box-shadow: none;
  background: #fff;
  transform-origin: center;
  transition: all 0.4s ease-in-out;
  overflow: hidden;
}
/* The link's ::after pseudo */
article a::after {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline: 0;
  cursor: pointer;
}

Tuyệt quá! Chúng tôi đã thêm tỷ lệ ban đầu cho hình ảnh (--img-scale: 1.001), màu đầu tiên của tiêu đề thẻ (--title-color: black) và một số thuộc tính bổ sung mà chúng tôi sẽ sử dụng để làm cho mũi tên của chúng tôi bật ra khỏi liên kết. Chúng tôi cũng đã thiết lập trạng thái trống của box-shadow khai báo để tạo hiệu ứng cho nó sau này. Điều này thiết lập những gì chúng ta cần cho thẻ có thể nhấp ngay bây giờ, vì vậy hãy thêm một số đặt lại và tạo kiểu cho nó bằng cách thêm các thuộc tính tùy chỉnh đó vào các phần tử mà chúng ta muốn tạo hoạt ảnh:

article h2 {
  margin: 0 0 18px 0;
  font-family: "Bebas Neue", cursive;
  font-size: 1.9rem;
  letter-spacing: 0.06em;
  color: var(--title-color);
  transition: color 0.3s ease-out;
}
article figure {
  margin: 0;
  padding: 0;
  aspect-ratio: 16 / 9;
  overflow: hidden;
}
article img {
  max-width: 100%;
  transform-origin: center;
  transform: scale(var(--img-scale));
  transition: transform 0.4s ease-in-out;
}
article a {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  color: #28666e;
}
article a:focus {
  outline: 1px dotted #28666e;
}
article a .icon {
  min-width: 24px;
  width: 24px;
  height: 24px;
  margin-left: 5px;
  transform: translateX(var(--link-icon-translate));
  opacity: var(--link-icon-opacity);
  transition: all 0.3s;
}

.article-body {
  padding: 24px;
}

Hãy đối xử tốt với mọi người và cũng thêm một lớp đọc màn hình ẩn đằng sau liên kết:

.sr-only:not(:focus):not(:active) {
  clip: rect(0 0 0 0); 
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap; 
  width: 1px;
}

Thẻ của chúng tôi đang bắt đầu trông khá đẹp. Đã đến lúc thêm một chút ma thuật vào nó. Với :has() lớp giả, giờ đây chúng tôi có thể kiểm tra xem liên kết của chúng tôi có được di chuột qua hoặc tập trung hay không, sau đó cập nhật các thuộc tính tùy chỉnh của chúng tôi và thêm box-shadow. Với đoạn CSS nhỏ này, thẻ của chúng tôi thực sự trở nên sống động:

/* Matches an article element that contains a hover or focus state */
article:has(:hover, :focus) {
  --img-scale: 1.1;
  --title-color: #28666e;
  --link-icon-translate: 0;
  --link-icon-opacity: 1;

  box-shadow: rgba(0, 0, 0, 0.16) 0px 10px 36px 0px, rgba(0, 0, 0, 0.06) 0px 0px 0px 1px;
}

Xem có gì ở đó không? Bây giờ chúng tôi nhận được các kiểu cập nhật nếu bất kì phần tử con trong thẻ được di chuột qua hoặc tập trung. Và mặc dù phần tử liên kết là thứ duy nhất có thể chứa trạng thái di chuột hoặc tiêu điểm trong ::after cách tiếp cận thẻ có thể nhấp, chúng tôi có thể sử dụng cách đó để khớp với phần tử mẹ và áp dụng các chuyển đổi.

Và bạn có nó rồi đấy! Chỉ là một trường hợp sử dụng mạnh mẽ khác cho :has() bộ chọn. Chúng ta không chỉ có thể so khớp một phần tử cha bằng cách khai báo các phần tử khác dưới dạng đối số, mà còn có thể so khớp bằng cách sử dụng các bút danh để so khớp và định kiểu các phần tử cha.

Ưu điểm:

  • Accessible
  • Hoạt hình
  • Không cần JavaScript
  • Sử dụng :hover vào đúng phần tử

Nhược điểm:

  • Không dễ dàng chọn được văn bản.
  • Hỗ trợ trình duyệt được giới hạn cho Chrome và Safari (nó được hỗ trợ trong Firefox sau một lá cờ).

Đây là một bản demo sử dụng kỹ thuật này. Bạn có thể nhận thấy một lớp bao bọc thừa xung quanh thẻ, nhưng đó chỉ là tôi đang chơi với truy vấn vùng chứa, đây chỉ là một trong những điều tuyệt vời khác được triển khai trên tất cả các trình duyệt chính.

Có một ít Những ví dụ khác bạn muốn chia sẻ? Các giải pháp hoặc ý tưởng khác được hoan nghênh hơn trong phần bình luận.

Dấu thời gian:

Thêm từ Thủ thuật CSS