Hover là một pseudo-class CSS và trạng thái trực quan của phần tử giao diện được kích hoạt khi con trỏ chuột di chuyển qua nó. Cơ chế này cung cấp phản hồi cho người dùng, xác nhận rằng phần tử đã sẵn sàng để tương tác. Theo MDN Web Docs (2026), pseudo-class :hover được hỗ trợ bởi tất cả các trình duyệt hiện đại và là một trong những bộ chọn CSS được sử dụng nhiều nhất để tạo tương tác.
Những điểm chính
Hover (từ tiếng Anh “to hover”) — phản ứng trực quan của phần tử giao diện khi con trỏ chuột ở trên nó. Thuật ngữ này được dùng để chỉ cả pseudo-class CSS :hover và trạng thái của phần tử khi di chuột qua.
Khái niệm hover bắt nguồn từ các giao diện đồ hoạ đầu tiên của Xerox Alto (1973) và được tiêu chuẩn hoá trên web với sự ra đời của CSS2 vào năm 1998. Kể từ đó, hover đã trở thành một phần không thể thiếu của trải nghiệm người dùng trên máy tính để bàn.
Theo CSS Usage Statistics (2025), 94% trang web trong top 1000 sử dụng pseudo-class :hover cho ít nhất một phần tử. Hover được áp dụng phổ biến nhất cho nút (89%), liên kết (85%) và thẻ (62%).
Hover ≠ active. :hover được kích hoạt khi di chuột qua, :active được kích hoạt tại thời điểm nhấp. :focus được kích hoạt khi nhận tiêu điểm qua bàn phím. Mỗi trạng thái phục vụ mục đích riêng. Hover là xem trước, active là xác nhận hành động.
Pseudo-class :hover trong CSS áp dụng kiểu cho phần tử khi người dùng di chuột qua nó. Nó hoạt động với bất kỳ phần tử HTML nào nhưng thường được dùng nhất với các phần tử tương tác.
/* Basic hover implementation */
.button {
background: #4A90D9;
color: white;
padding: 12px 24px;
border: none;
transition: all 0.3s ease;
}
.button:hover {
background: #357ABD;
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(74,144,217,0.4);
}
Tính đặc hiệu của bộ chọn :hover giống như của một lớp (0,1,0). Nếu bạn cần ghi đè hover cho một phần tử cụ thể, hãy sử dụng bộ chọn có tính đặc hiệu cao hơn. Thứ tự khai báo rất quan trọng: nếu :hover được khai báo sau :focus, hover có thể không hoạt động khi có tiêu điểm.
:hover có thể kết hợp với các pseudo-class khác để tạo logic phức tạp. Ví dụ, .card:hover .card__title thay đổi kiểu tiêu đề bên trong thẻ khi di chuột qua toàn bộ thẻ. Điều này cho phép tạo các hiệu ứng với hoạt ảnh lồng nhau.
Hiệu ứng hover được phân loại theo loại thuộc tính được thay đổi. Mỗi loại phù hợp với các kịch bản khác nhau và tạo cảm giác cụ thể cho người dùng.
| Loại hiệu ứng | Thuộc tính CSS | Ví dụ sử dụng |
|---|---|---|
| Màu sắc | background, color | Nút thay đổi màu nền khi di chuột qua |
| Bóng | box-shadow | Thẻ nâng lên với bóng đổ |
| Tỉ lệ | transform: scale | Biểu tượng phóng to khi di chuột qua |
| Dịch chuyển | transform: translate | Phần tử di chuyển lên trên hoặc sang bên |
| Gạch chân | border-bottom, underline | Liên kết có gạch chân khi di chuột qua |
| Bộ lọc | filter: brightness | Hình ảnh trở nên sáng hơn hoặc tối hơn |
| Chuyển màu | background-image | Nền thay đổi khi di chuột qua |
Loại hiệu quả nhất là sự kết hợp giữa hiệu ứng màu sắc và bóng đổ. Material Design khuyến nghị sử dụng thay đổi độ cao (thay đổi chiều cao bóng) là loại phản hồi hover chính.
Theo Google Material Design (2024), hiệu ứng hover phải dễ thấy nhưng không gây mất tập trung. Thời lượng hoạt ảnh được khuyến nghị là 200–300 mili giây. Hiệu ứng quá nhanh (dưới 100 ms) có thể không được chú ý, trong khi hiệu ứng quá chậm (trên 500 ms) gây khó chịu cho người dùng.
Thuộc tính CSS transition làm cho hiệu ứng hover trở nên mượt mà bằng cách tạo hoạt ảnh cho các thay đổi thuộc tính theo thời gian. Không có transition, hover kích hoạt ngay lập tức, trông giật cục và khó chịu.
/* Different transitions per property */
.card {
transition:
box-shadow 0.3s ease-out,
transform 0.2s ease-out,
background 0.15s linear;
}
.card:hover {
box-shadow: 0 8px 30px rgba(0,0,0,0.15);
transform: translateY(-4px);
}
Thời lượng transition phụ thuộc vào ngữ cảnh. Đối với phần tử nhỏ (biểu tượng, liên kết) — 150–200 ms. Đối với phần tử lớn (thẻ, cửa sổ) — 250–350 ms. Hàm easing ease-out làm chậm hoạt ảnh một cách mượt mà về cuối, tạo cảm giác tự nhiên.
Thực hành khuyến nghị — chỉ định transition riêng cho từng thuộc tính được tạo hoạt ảnh. Thuộc tính all thuận tiện trong quá trình phát triển, nhưng trong sản xuất tốt hơn nên xác định các thuộc tính cụ thể cho hoạt ảnh để tránh các hiệu ứng không mong muốn.
Trên thiết bị cảm ứng, khái niệm hover không tồn tại: không có con trỏ nào có thể di chuột qua phần tử. Chạm vào phần tử ngay lập tức kích hoạt nhấp chuột, bỏ qua trạng thái hover. Điều này gây ra vấn đề nếu giao diện chỉ dựa vào hover.
Theo StatCounter (2026), 62% lưu lượng web toàn cầu đến từ thiết bị di động. Bỏ qua sự vắng mặt của hover trên màn hình cảm ứng đồng nghĩa với việc mất kiểm soát UX đối với đa số người dùng.
/* Disable hover on touch devices */
@media (hover: none) and (pointer: coarse) {
.button:hover {
background: initial;
transform: none;
}
}
Media query hover: none cho phép phát hiện thiết bị không hỗ trợ hover. Trên các thiết bị này, hiệu ứng hover bị tắt và tương tác dựa trên trạng thái :active và :focus. Một giải pháp thay thế là hiển thị nội dung hover khi chạm (lần chạm đầu hiển thị hover, lần chạm thứ hai thực hiện hành động), nhưng mẫu này làm giảm UX.
Khả năng tiếp cận hover là một khía cạnh quan trọng thường bị bỏ qua. Người dùng điều hướng giao diện bằng bàn phím không thể kích hoạt :hover. Các chức năng chỉ khả dụng qua hover trở nên không thể tiếp cận được đối với họ.
Quy tắc WCAG 2.2 (Tiêu chí thành công 1.4.13 — Nội dung khi di chuột hoặc tiêu điểm): nội dung xuất hiện khi di chuột cũng phải có sẵn khi có tiêu điểm. Nếu hover hiển thị thông tin bổ sung (chú thích, menu thả xuống), thông tin đó cũng phải có sẵn khi :focus.
/* Hover + focus for accessibility */
.tooltip-trigger:hover .tooltip,
.tooltip-trigger:focus .tooltip {
opacity: 1;
visibility: visible;
}
/* Disable animation for vestibular disorder */
@media (prefers-reduced-motion: reduce) {
*:hover {
transition: none;
}
}
Media query prefers-reduced-motion — tôn trọng cài đặt hệ thống của người dùng. Nếu người dùng đã tắt hoạt ảnh trong hệ thống, hiệu ứng hover phải được áp dụng ngay lập tức, không có transition. Điều này giúp những người bị rối loạn tiền đình.
Các khuyến nghị bổ sung: không sử dụng hover cho các chức năng quan trọng, không chỉ dựa vào màu sắc để truyền tải thông tin khi di chuột (thêm biểu tượng hoặc văn bản) và đảm bảo độ tương phản đầy đủ cho các trạng thái hover.
Các câu hỏi thường gặp
:hover được kích hoạt khi chuột ở trên phần tử. :focus được kích hoạt khi phần tử nhận được tiêu điểm — qua phím Tab hoặc sau khi nhấp. Để đảm bảo khả năng tiếp cận, điều quan trọng là phải sao chép hiệu ứng hover thông qua :focus.
Trên thiết bị cảm ứng, hover hoạt động không ổn định: lần chạm đầu kích hoạt :hover, lần chạm thứ hai kích hoạt nhấp. Điều này gây nhầm lẫn. Nên sử dụng media query @media (hover: none) để tắt hiệu ứng hover trên màn hình cảm ứng.
Sử dụng sự kiện mouseenter (di chuột vào) và mouseleave (di chuột ra). Khác với CSS hover, JavaScript cung cấp khả năng kiểm soát hoàn toàn hoạt ảnh và cho phép tạo các hiệu ứng tuần tự phức tạp với độ trễ.
iOS Safari xử lý :hover đặc biệt. Sau khi chạm, phần tử chuyển sang trạng thái :hover và giữ nguyên cho đến lần chạm tiếp theo. Điều này có thể khiến kiểu hover bị dính. Giải pháp là sử dụng @media (hover: hover) để áp dụng hover chỉ trên các thiết bị hỗ trợ hover.
ease-out (cubic-bezier(0, 0, 0.2, 1)) là lựa chọn tối ưu cho hover: khởi đầu nhanh và giảm tốc mượt mà ở cuối. ease-in-out phù hợp cho hiệu ứng hai giai đoạn (xuất hiện và biến mất). Tránh linear — nó trông không tự nhiên.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm