:hover
) sự kiện trên các phần tử HTML cụ thể bằng cách sử dụng pointer-events
tài sản. Gần đây tôi đã xây dựng một trang thư viện nhóm cho một trong những khách hàng của mình. Mỗi mục trong thư viện được đại diện bởi một thẻ giao diện người dùng sử dụng lớp phủ thay đổi màu sắc khi bạn di chuột qua nó. Nhưng tôi đã gặp phải một vấn đề, điều này đã truyền cảm hứng cho hướng dẫn này.
Nội dung &cấu trúc Thẻ giao diện người dùng
Mỗi hạng mục thẻ thư viện bao gồm các yếu tố sau:
- Ảnh nhân viên - đen / trắng
- Tên nhân viên - màu trắng
- Vai trò của nhân viên - màu trắng
- Lớp phủ nền tối huyền ảo
Khi người dùng di chuột qua từng thẻ, lớp phủ nền sẽ chuyển sang màu vàng nhạt bán trong suốt (màu thương hiệu).
Ví dụ về thẻ giao diện người dùng
Vì tôi muốn hướng dẫn này tập trung vào việc giải quyết một vấn đề cụ thể, nên đây là cách đơn giản hóa phiên bản (thiết kế khôn ngoan) về giao diện của Thẻ giao diện người dùng. Thử di chuột qua nó và thấy màu nền chuyển sang màu vàng nhạt:
Tên nhân viên Vai trò của nhân viênNhưng có một vấn đề. Bạn có thể đã phát hiện ra nó. Thử di chuột qua vùng văn bản, bạn có thấy vấn đề không?
Ngay sau khi con chuột của bạn di chuyển qua vùng phần tử văn bản, sự kiện di chuột sẽ bị hủy - và ngay lập tức chuyển từ màu vàng, trở lại trạng thái không hoạt động mặc định, với màu xám. Không thể chấp nhận được!
Đây là mã HTML:
<div class="card">
<div class="card-overlay"></div>
<img
class="card-image"
src="/article/uploadfiles/202203/2022033109324298.jpg"
/>
<div class="card-info">
<div class="card-name">Employee Name</div>
<div class="card-role">Employee Role</div>
</div>
</div>
Và CSS:
.card {
max-width: 350px;
position: relative;
}
.card-overlay {
background-image: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.5));
height: 100%;
width: 100%;
position: absolute;
top: 0;
left: 0;
transition: background-color 0.6s;
}
.card-overlay:hover {
background-color: rgba(255, 204, 7, 0.5);
}
.card-image {
max-width: 100%;
display: block;
}
.card-info {
position: absolute;
bottom: 2rem;
left: 2rem;
}
.card-name,
.card-role {
color: white;
font-size: 1.5rem;
line-height: 1.25;
padding: 0.25rem;
}
.card-name {
font-weight: bold;
}
Vậy tại sao sự kiện di chuột lại bị hủy khi bạn di chuyển chuột qua vùng văn bản?
Vì thứ tự xếp chồng của HTML. Thứ tự xếp chồng thường được kiểm soát bởi CSS z-index
bất động sản. Tuy nhiên, có một thứ tự xếp chồng mặc định điều đó xảy ra, nếu bạn không giải quyết vấn đề trực tiếp bằng CSS trước.
z-index
là một thứ tự ngăn xếp Thuộc tính CSS. Phần tử cóz-index
cao nhất giá trị (số) được đặt trước các phần tử khác - giả sử vị tríposition
giá trị là như nhau.z-index
mặc định giá trị của tất cả các phần tử trên trang web làauto
, giống với số không0
.
Vì vậy, vì chúng ta có hai phần tử đều được định vị tuyệt đối và cả hai đều có z-index
mặc định trong tổng số auto
(0) cái nào đứng trước cái nào theo thứ tự xếp chồng (một người phải thắng)?
Cái đến cuối cùng trong HTML của bạn sẽ thắng.
Trong trường hợp này, <div class="card-info">
vùng chứa chứa các phần tử văn bản tên và vai trò đứng sau card-overlay
phần tử:
<div class="card">
<div class="card-overlay"></div>
<img
class="card-image"
src="/article/uploadfiles/202203/2022033109324298.jpg"
/>
<div class="card-info">
<div class="card-name">Employee Name</div>
<div class="card-role">Employee Role</div>
</div>
</div>
Trong ví dụ về Thẻ giao diện người dùng, ngay sau khi bạn di chuột qua các phần tử văn bản, bạn sẽ không di chuột qua phần tử lớp phủ nữa mà là <class="card-info">
phần tử không có :hover
(lớp giả) đính kèm. Chỉ .card
có điều đó (xem mã CSS).
Bạn có thể làm gì?
Nếu bạn di chuyển thực tế <div class="card-overlay"></div>
phần tử xuống bên dưới <div class="card-info>...</div>
phần tử như thế này:
<div class="card">
<img
class="card-image"
src="/article/uploadfiles/202203/2022033109324298.jpg"
/>
<div class="card-info">
<div class="card-name">Employee Name</div>
<div class="card-role">Employee Role</div>
</div>
<div class="card-overlay"></div>
</div>
Sau đó, thứ tự xếp chồng sẽ hoán đổi và điều này xảy ra:
Tên nhân viên Vai trò của nhân viênTuyệt vời, giờ đây, quá trình chuyển đổi lớp phủ không còn bị gián đoạn khi bạn di chuyển chuột qua vùng văn bản (hãy thử).
Nhưng chờ đã ... Bây giờ thứ tự xếp chồng đã được thay đổi, các phần tử văn bản sẽ bị lớp phủ chuyển sang màu xám, hiện nằm ở phía trước / phía trên của nó.
Chúng tôi đã giải quyết một vấn đề trong khi tạo một vấn đề khác.
Hãy không sử dụng phương pháp đó và di chuyển <div class="card-overlay">
phần tử trở lại vị trí ban đầu của nó.
Điều gì sẽ xảy ra nếu thay vào đó chúng tôi cung cấp .card-overlay
lớp a z-index
giá trị của 1
?
Bây giờ card-overlay
sẽ được đặt trước card-info
(vẫn có z-index: 0
) vì nó có thứ tự ngăn xếp cao hơn (z-index: 1
) và bây giờ sự thay đổi màu sắc trên sự kiện di chuột sẽ lại hoạt động không bị gián đoạn - điều đó thật tuyệt, nhưng ...
Thật không may, làm điều này sẽ dẫn đến giống hệt như trước đây khi chúng tôi di chuyển <div class="card-overlay">
bên dưới <div class="card-info">
yếu tố. Lần này chúng tôi chỉ thay đổi thứ tự xếp chồng trực tiếp bằng CSS. Các thành phần văn bản vẫn vẫn bị xám bởi lớp phủ.
Điều này là không thể chấp nhận được!
Sự kiện con trỏ để giải cứu!
Tôi chợt nhớ rằng CSS có thuộc tính là pointer-events
điều này cho phép bạn quyết định xem một phần tử có nên phản ứng hay không tới các sự kiện con trỏ.
Sự kiện con trỏ là bất cứ điều gì bạn phải làm với con chuột của bạn, chẳng hạn như nhấp, cuộn hoặc di chuyển chuột qua (di chuột) một phần tử.
Vì vậy, tôi chỉ cần thêm pointer-events: none;
vào .card-info
của tôi lớp học, như của anh ấy:
.card-info {
position: absolute;
bottom: 2rem;
left: 2rem;
pointer-events: none; /* the fix! */
}
Và bây giờ bạn có thể di chuột qua toàn bộ Thẻ giao diện người dùng, bao gồm cả văn bản, mà không cần hủy sự kiện di chuột - và các phần tử văn bản vẫn giữ nguyên màu trắng 100% của chúng:
Tên nhân viên Vai trò của nhân viênKiểm tra mã CodePen.