Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> CSS

Cách bỏ qua Hover/Mouseover events trên element cụ thể với CSS pointer-events property

Tìm hiểu cách remove/ignore mouseover/hover (:hover) event trên HTML element cụ thể bằng property pointer-events.

Tôi gần đây build team gallery page cho client. Mỗi gallery item là UI card dùng overlay đổi màu khi hover chuột. Nhưng gặp vấn đề, dẫn đến tutorial này.

UI Card content & structure

Mỗi gallery card item gồm các element:

  • Ảnh nhân viên - đen/trắng
  • Tên nhân viên - trắng
  • Vai trò nhân viên - trắng
  • Dark background overlay tinh tế

Khi user di chuột qua mỗi card, background overlay transition sang vàng nhạt semi-transparent (brand color).

UI Card example

Vì muốn tập trung giải quyết vấn đề cụ thể, đây là phiên bản giản lược (design-wise) UI Card trông như thế nào. Thử di chuột qua và xem background transition sang vàng nhạt:

Cách bỏ qua Hover/Mouseover events trên element cụ thể với CSS pointer-events property

Employee Name Employee Role

Nhưng có vấn đề. Bạn có thể đã thấy. Thử di chuột qua vùng text, bạn thấy issue không?

Ngay khi chuột di qua text element area, hover event bị cancel — và ngay lập tức quay về trạng thái inactive mặc định, màu xám. Không chấp nhận được!

HTML code:

<div class="card"> <div class="card-overlay"></div> <img class="card-image" src="https://vn.wsxdn.com/UploadFiles_2724/202203/2022033109324298.jpg" /> <div class="card-info"> <div class="card-name">Employee Name</div> <div class="card-role">Employee Role</div> </div> </div>

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; }

Tại sao hover event bị cancel khi di chuột qua text area?

Do stacking order của HTML. Stacking order thường kiểm soát bằng CSS property z-index. Tuy nhiên, có default stacking order xảy ra nếu bạn không address trực tiếp bằng CSS trước.

z-index là CSS property stack order. Element có z-index cao nhất (số) được đặt phía trước các element khác — giả sử position value giống nhau. Default z-index của mọi element trên trang là auto, tương đương 0.

Vì vậy, chúng ta có hai element đều absolute positioned và cả hai đều có default z-index là auto (0), element nào ở trước element kia trong stacking order (một phải thắng)?

Element xuất hiện sau trong HTML thắng.

Trong trường hợp này, container <div class="card-info"> chứa name và role text elements xuất hiện sau element card-overlay:

<div class="card"> <div class="card-overlay"></div> <img class="card-image" src="https://vn.wsxdn.com/UploadFiles_2724/202203/2022033109324298.jpg" /> <div class="card-info"> <div class="card-name">Employee Name</div> <div class="card-role">Employee Role</div> </div> </div>

Trên UI Card example, ngay khi bạn di chuột qua text elements, bạn không còn hover overlay element nữa, mà là element <class="card-info">, element này không có :hover (pseudo class) attached. Chỉ .card có (xem CSS code).

Có thể làm gì?

Nếu bạn di chuyển vật lý element <div class="card-overlay"></div> xuống dưới element <div class="card-info">...</div> như sau:

<div class="card"> <img class="card-image" src="https://vn.wsxdn.com/UploadFiles_2724/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>

Thì stacking order sẽ swap, và điều này xảy ra:

Cách bỏ qua Hover/Mouseover events trên element cụ thể với CSS pointer-events property

Employee Name Employee Role

Tuyệt, giờ overlay transition không còn bị interrupt khi di chuột qua text area (thử đi).

Nhưng đợt đã... Bây giờ stacking order đã swap, text elements bị xám bởi overlay, giờ ở phía trước/đỉnh của nó.

Chúng ta giải quyết vấn đề nhưng tạo ra vấn đề khác.

Hãy không dùng approach đó, và di chuyển element <div class="card-overlay"> về vị trí gốc.

Điều gì nếu chúng ta cho class .card-overlay giá trị z-index là 1?

Bây giờ card-overlay sẽ đặt trước card-info (vẫn z-index: 0) vì stack order cao hơn (z-index: 1) và color change on hover event sẽ lại work uninterrupted — tuyệt, nhưng...

Thật đáng tiếc, làm vậy dẫn đến chính xác điều trước khi di chuyển vật lý element <div class="card-overlay"> xuống dưới <div class="card-info">. Lần này chỉ đổi stacking order trực tiếp bằng CSS. Text elements vẫn bị xám bởi overlay.

Điều này không chấp nhận được!

Pointer events đến giải cứu!

Tôi bỗng nhớ CSS có property pointer-events cho phép quyết định element có phản ứng pointer events hay không.

Pointer events là bất cứ gì liên quan chuột: click, scroll, hoặc di chuột qua (hover) element.

Tôi đơn giản thêm pointer-events: none; vào class .card-info, như sau:

.card-info { position: absolute; bottom: 2rem; left: 2rem; pointer-events: none; /* the fix! */ }

Và bây giờ bạn có thể hover toàn bộ UI Card, kể cả text, không cancel hover event — và text elements giữ 100% màu trắng:

Cách bỏ qua Hover/Mouseover events trên element cụ thể với CSS pointer-events property

Employee Name Employee Role

Xem code CodePen.