Tooltip Cần Độ Trễ, Nhưng Sau Đó Phải Bỏ Qua Nó

Công nghệ25 tháng 8, 2026·5 phút đọc

Bài viết phân tích một mẫu tương tác UI tinh tế: tooltip cần độ trễ để tránh xuất hiện khi di chuột vô tình, nhưng phải bỏ qua độ trễ này khi người dùng di chuyển giữa các phần tử gần nhau. Tác giả giới thiệu giải pháp 'warm window' 300ms với mã nguồn React cụ thể, cùng một Claude skill để audit codebase của bạn.

Tooltip Cần Độ Trễ, Nhưng Sau Đó Phải Bỏ Qua Nó

Tooltip Cần Độ Trễ, Nhưng Sau Đó Phải Bỏ Qua Nó

Tooltip là một chi tiết nhỏ nhưng ảnh hưởng lớn đến trải nghiệm người dùng. Bài viết này phân tích một mẫu tương tác quen thuộc mà nhiều lập trình viên bỏ qua: tooltip cần độ trễ để tránh hiện ra khi di chuột vô tình, nhưng đồng thời phải bỏ qua độ trễ đó khi người dùng di chuyển giữa các phần tử liền kề. Tác giả đề xuất giải pháp "warm window" với mã nguồn React chi tiết, cùng một Claude skill hữu ích để kiểm tra codebase của bạn.

Khi xây dựng sản phẩm FrontPrep, tác giả Abhishek Jakhar gặp phải một vấn đề khó chịu: tooltip hiện lên ngay lập tức khi di chuột qua logo công ty. Nếu người dùng chỉ lướt chuột qua trang, các tooltip liên tục bật lên một cách khó chịu. Giải pháp ban đầu là thêm độ trễ 200ms, nhưng điều này tạo ra vấn đề mới khi người dùng di chuyển giữa các logo nằm cạnh nhau — họ phải chờ đợi 200ms mỗi lần, khiến trải nghiệm trở nên chậm chạp.

Vấn đề với Tooltip Thông Thường

Tooltip là một trong những thành phần UI phổ biến nhất, xuất hiện trong trình duyệt, website và ứng dụng. Tuy nhiên, ít ai nhận ra rằng việc thiếu độ trễ hoặc độ trễ cố định đều gây ra trải nghiệm kém:

  • Không có độ trễ: Tooltip hiện ngay khi di chuột qua, kể cả khi người dùng chỉ đang lướt chuột ngang qua trang
  • Độ trễ cố định: Người dùng muốn xem tooltip liên tục trên các phần tử gần nhau phải chờ đợi mỗi lần, gây cảm giác chậm chạp

Giải Pháp: Delay và Bỏ Qua Delay

Tác giả chia giải pháp thành ba phần chính:

1. Độ Trễ Mở Tooltip

Khi người dùng hover lên một logo, tooltip sẽ chờ 200ms trước khi mở. Khoảng thời gian này đủ để phân biệt giữa di chuột vô tình và hover có chủ đích.

function handleEnter() {
  if (tooltips.isWarm) {
    show();
    return;
  }
  openTimer.current = setTimeout(show, tooltips.openDelay);
}

2. Cửa Sổ "Warm" 300ms

Khi tooltip đóng, một bộ đếm thời gian 300ms bắt đầu — tác giả gọi đây là "warm window". Nếu người dùng hover lên logo khác trong khoảng thời gian này, tooltip sẽ mở tức thì mà không cần chờ đợi hay animation.

3. Trở Về Trạng Thái "Cold"

Khi hết 300ms, trang trở về trạng thái "cold" — tooltip tiếp theo phải chờ đủ 200ms. Bước này ngăn việc vô hiệu hóa độ trễ vĩnh viễn trên toàn trang.

hover → wait 200ms → tooltip opens (page is now warm)
leave → tooltip closes → 300ms cooldown
    ├─ hover another tooltip before cooldown → opens instantly, page stays warm
    └─ cooldown ends → page is cold, the 200ms wait is back

Cách Code Hoạt Động

Quản Lý Trạng Thái Warm

Trạng thái "warm" được quản lý qua một provider dùng useRef thay vì React state, để tránh re-render toàn bộ tooltip:

const warm = useRef(false);
const cooldownTimer = useRef(null);

const tooltips = useMemo(
  () => ({
    openDelay,
    isWarm: () => skipWhenWarm && warm.current,
    markOpened() {
      warm.current = true;
      clearTimeout(cooldownTimer.current);
    },
    markClosed() {
      clearTimeout(cooldownTimer.current);
      cooldownTimer.current = setTimeout(() => {
        warm.current = false;
      }, warmFor);
    },
  }),
  [openDelay, warmFor, skipWhenWarm]
);

Xử Lý Khi Rời Chuột

Khi người dùng rời khỏi logo, hàm handleLeave kiểm tra xem tooltip có đang mở không. Nếu tooltip chưa từng mở (di chuột qua nhanh), nó hủy timer và thoát. Nếu tooltip đang mở, nó đóng tooltip và khởi động cooldown timer 300ms.

Tại Sao Chọn 200ms?

  • Dưới 150ms: Con trỏ chỉ lướt qua cũng có thể kích hoạt tooltip
  • Trên 250ms: Hover có chủ đích sẽ cảm thấy chậm chạp, gãy gánh
  • 200ms: Là con số cân bằng hoàn hảo

Phán Đoán và Thẩm Mỹ

Tác giả nhấn mạnh rằng AI có thể xây dựng tooltip hoạt động, nhưng để có một tooltip hoàn thiện cần con người phán đoán và thẩm mỹ. Sự khác biệt giữa sản phẩm "hoạt động" và sản phẩm "bóng bẩy" nằm ở những chi tiết nhỏ như thế này. Bạn có thể dùng Claude skills được chia sẻ bởi các kỹ sư khác, nhưng cuối cùng bạn vẫn là người đánh giá và quyết định.

Claude Skill Kiểm Tra Tooltip

Tác giả tạo một Claude skill để tự động audit codebase của bạn:

---
name: tooltip
description: Tooltips need a delay so they don't open up on unintentional mouse travel
---

# Tooltip Timing

A click is always intentional whereas a hover is not intentional. The 200ms is how it finds out.

| Value       | Number | Why                                      |
| ----------- | ------ | ----------------------------------------- |
| Open delay  | 200ms  | Below 150ms cursor passing over opens it. Above 250ms intentional hover feels broken. |
| Warm window | 300ms  | Covers move between triggers. Short enough that a later hover waits again. |
| Close delay | 0ms    | Leaving a trigger should be clear. |

Kết Luận

Mẫu tương tác này có thể áp dụng cho bất kỳ thành phần UI nào có tooltip: trình duyệt, thanh công cụ, biểu mẫu, hay bất kỳ website nào. Ý tưởng cốt lõi rất đơn giản: trì hoãn để lọc tín hiệu vô tình, nhưng sau đó tăng tốc cho các tương tác liên tiếp — một nguyên tắc nhỏ nhưng tạo ra trải nghiệm người dùng mượt mà và chuyên nghiệp.

Logo blog Master.devLogo blog Master.dev

Kết hợp độ trễ thông minh với phản hồi tức thì là chìa khóa tạo nên giao diện tinh tế — hãy áp dụng mẫu này ngay cả vào các ứng dụng React, Vue hay Angular của bạn, và đừng quên dùng Claude skill trên để rà soát codebase hiện tại.

Chia sẻ:FacebookX
Nội dung tổng hợp bằng AI, mang tính tham khảo. Xem bài gốc ↗