Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 32 — Time-based Limits & Auto-update

Đã đọc 0/15 mục · còn khoảng 13 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

Mở đầu — vì sao bài này quan trọng

Hãy tưởng tượng bạn đang ngồi ở một cây ATM, chuẩn bị rút tiền để trả tiền nhà. Bạn nhập mật khẩu hơi chậm vì tay run, hoặc vì bạn phải lấy kính lão ra đeo. Đột nhiên màn hình báo "Phiên giao dịch đã hết hạn" và nhả thẻ ra. Bạn phải làm lại từ đầu. Cảm giác đó — bực bội, bị hối thúc, bị loại khỏi cuộc chơi chỉ vì mình thao tác chậm — chính là thứ mà một website vô tình gây ra cho hàng triệu người mỗi ngày khi thiết kế các giới hạn thời gian một cách thiếu suy nghĩ.

Giới hạn thời gian (time limits) và tự động cập nhật (auto-update) là hai trong những rào cản accessibility âm thầm nhưng nghiêm trọng nhất. Chúng không hiện ra như một nút bấm sai màu hay một tấm ảnh thiếu alt text. Chúng ẩn trong logic của sản phẩm: phiên đăng nhập tự hết hạn, giỏ hàng "giữ chỗ" 10 phút, mã OTP chỉ sống 60 giây, carousel tự trượt sau 4 giây, bảng giá chứng khoán nhấp nháy liên tục. Với người dùng bình thường, những thứ này chỉ hơi phiền. Nhưng với người khiếm thị dùng screen reader, người vận động chậm, người mắc chứng rối loạn nhận thức, hay đơn giản là người lớn tuổi, chúng có thể khiến việc hoàn thành một tác vụ trở nên bất khả thi.

Bài này tập trung vào một nhóm tiêu chí WCAG rất cụ thể: những gì xảy ra khi thời gian và sự chuyển động tự động điều khiển giao diện, chứ không phải người dùng. Nắm vững nhóm này, bạn sẽ tránh được những lỗi thiết kế "vô hình" nhưng gây loại trừ nghiêm trọng nhất.

Khái niệm cốt lõi

WCAG 2.2.1 — Timing Adjustable (Cấp A)

Đây là xương sống của bài học. Tiêu chí này quy định: nếu nội dung của bạn đặt ra một giới hạn thời gian, thì bạn PHẢI cung cấp cho người dùng ít nhất một trong các lựa chọn sau:

  • Tắt (Turn off): Người dùng được vô hiệu hóa giới hạn thời gian trước khi nó bắt đầu.
  • Điều chỉnh (Adjust): Người dùng được điều chỉnh giới hạn thành ít nhất 10 lần thời gian mặc định, trước khi nó bắt đầu.
  • Gia hạn (Extend): Người dùng được cảnh báo trước khi hết giờ và được cho ít nhất 20 giây để gia hạn bằng một thao tác đơn giản (ví dụ nhấn phím cách), và có thể gia hạn ít nhất 10 lần.
Nói cách khác, WCAG không cấm bạn đặt giới hạn thời gian. Nó chỉ yêu cầu: đừng khóa cửa mà không đưa chìa cho người dùng.

Các trường hợp ngoại lệ được miễn (rất quan trọng để không "over-engineer"):

  • Real-time event: Đấu giá trực tuyến, sự kiện livestream — bản chất giới hạn thời gian là thật, không thể gia hạn (bạn không thể "gia hạn" một phiên đấu giá cho riêng mình).
  • Essential (thiết yếu): Nếu việc gia hạn sẽ làm mất giá trị của hoạt động. Ví dụ một bài thi có giới hạn thời gian nghiêm ngặt để đánh giá năng lực.
  • 20 giờ: Nếu giới hạn dài hơn 20 giờ, không cần điều chỉnh (vì 20 giờ đủ dài cho mọi nhu cầu thực tế).

WCAG 2.2.4 — Interruptions (Cấp AAA)

Người dùng phải có thể hoãn hoặc tắt các gián đoạn (ví dụ thông báo bật lên tự động, cập nhật nội dung đột ngột), trừ trường hợp khẩn cấp. Điều này bảo vệ người đang tập trung vào một tác vụ khỏi bị nội dung tự động "nhảy vào" làm gián đoạn dòng suy nghĩ — đặc biệt quan trọng với người có rối loạn tập trung.

WCAG 2.2.5 — Re-authenticating (Cấp AAA)

Khi một phiên hết hạn, người dùng phải có thể tiếp tục hoạt động mà không mất dữ liệu sau khi đăng nhập lại. Đây là lý do vì sao một form dài 20 trường mà "văng" hết dữ liệu khi phiên hết hạn là một thảm họa accessibility.

WCAG 2.2.6 — Timeouts (Cấp AAA, thêm ở WCAG 2.1)

Người dùng phải được cảnh báo về khoảng thời gian không hoạt động có thể khiến mất dữ liệu, trừ khi dữ liệu được giữ lâu hơn 20 giờ. Bạn không được để người dùng nhập nửa chừng rồi im lặng xóa mọi thứ.

Liên hệ với auto-update (WCAG 2.2.2 — Pause, Stop, Hide)

Bất kỳ thông tin nào tự động cập nhật, chuyển động, nhấp nháy, hoặc cuộn và bắt đầu tự động, kéo dài hơn 5 giây, và hiển thị song song với nội dung khác — phải có cơ chế để người dùng tạm dừng, dừng hẳn, hoặc ẩn. Carousel tự trượt, ticker giá chứng khoán, bảng tin cập nhật liên tục đều thuộc nhóm này. Auto-update không được phép "cướp" quyền kiểm soát khỏi người dùng.

Điểm mấu chốt cần nhớ xuyên suốt: thời gian và chuyển động phải nằm dưới quyền kiểm soát của con người, không phải của cỗ máy.

Tình huống thực tế

Tình huống 1: Ngân hàng số và phiên đăng nhập 90 giây

Một ngân hàng số tại Việt Nam (giả định tên "VietPay") thiết lập phiên đăng nhập tự động hết hạn sau 90 giây không hoạt động, vì lý do bảo mật. Khi hết giờ, hệ thống lập tức đăng xuất và đưa người dùng về màn hình đăng nhập, xóa toàn bộ nội dung form chuyển khoản đang nhập dở.

Vấn đề nảy sinh khi một khách hàng 68 tuổi cố gắng chuyển tiền cho con. Ông cần thời gian để đọc kỹ số tài khoản người nhận, đối chiếu từng chữ số, và nhập nội dung chuyển khoản bằng cách gõ từng phím. Trung bình ông mất khoảng 3 phút cho một giao dịch. Cứ mỗi lần đang nhập thì phiên hết hạn, ông bị văng ra, mất hết dữ liệu, và phải làm lại. Sau ba lần thất bại, ông bỏ cuộc và gọi điện nhờ con làm hộ.

Diễn giải: Giới hạn 90 giây vi phạm cả 2.2.1 (không có cảnh báo, không có cơ chế gia hạn) lẫn 2.2.5 (mất dữ liệu khi re-authenticate). Nhóm bảo mật đúng khi muốn giới hạn phiên — nhưng cách triển khai đã loại trừ chính nhóm khách hàng lớn tuổi.

Cách sửa: VietPay giữ giới hạn 90 giây vì lý do bảo mật (được phép, vì đây là ngoại lệ "essential" một phần), nhưng thêm một modal cảnh báo bật lên ở giây thứ 70: "Phiên của bạn sắp hết hạn. Bạn có muốn tiếp tục?" với nút "Tiếp tục" cho phép gia hạn thêm. Đồng thời, nếu phiên hết hạn thật, dữ liệu form được giữ tạm trong bộ nhớ để sau khi đăng nhập lại người dùng không phải nhập lại từ đầu. Kết quả: tỷ lệ hoàn thành giao dịch của nhóm khách trên 60 tuổi tăng rõ rệt.

Bài học: Bảo mật và accessibility không đối lập. Bạn có thể giữ giới hạn nhưng phải thêm cảnh báo và bảo toàn dữ liệu.

Tình huống 2: Sàn thương mại điện tử và "giỏ hàng giữ chỗ 5 phút"

Một sàn TMĐT (giả định "ShopFast") tổ chức đợt flash sale. Để chống gian lận và giữ công bằng, họ cho mỗi người 5 phút để hoàn tất thanh toán, nếu không sản phẩm sẽ được trả lại kho. Một đồng hồ đếm ngược 5:00 hiển thị to đùng ở đầu trang, đỏ và nhấp nháy.

Với người dùng screen reader, đây là ác mộng kép. Thứ nhất, đồng hồ đếm ngược liên tục cập nhật khiến screen reader đọc lại "còn 4 phút 59 giây... 4 phút 58 giây..." không ngừng, che lấp mọi thông tin khác. Thứ hai, thao tác điền địa chỉ và thông tin thẻ bằng screen reader vốn đã chậm hơn người sáng mắt 2-3 lần, nên 5 phút là quá ngắn.

Diễn giải: Đồng hồ nhấp nháy vi phạm 2.2.2 (nội dung tự cập nhật không có cơ chế dừng, và nếu nhấp nháy nhanh còn có nguy cơ vi phạm tiêu chí về co giật). Giới hạn 5 phút không thể điều chỉnh vi phạm 2.2.1.

Cách sửa: ShopFast đặt vùng đếm ngược trong một aria-live="off" để screen reader không đọc từng giây, chỉ thông báo tại các mốc quan trọng (còn 2 phút, còn 30 giây) qua aria-live="polite". Họ bỏ hiệu ứng nhấp nháy. Quan trọng nhất, họ thêm nút "Cần thêm thời gian?" cho phép người dùng gia hạn thêm 5 phút. Vì đây gần với "real-time event" (chống gian hàng ảo), họ cân nhắc kỹ, nhưng vẫn cho phép gia hạn có giới hạn để không loại trừ người khuyết tật.

Bài học: Ngay cả khi giới hạn thời gian có lý do kinh doanh chính đáng, cách hiển thị bộ đếm và khả năng gia hạn vẫn phải được thiết kế cho mọi người dùng.

Tình huống 3: Trang tin tức và carousel tự trượt

Một tòa soạn báo điện tử đặt một carousel tin nổi bật ở đầu trang chủ, tự động trượt sang tin tiếp theo mỗi 4 giây. Không có nút tạm dừng.

Một biên tập viên khiếm thị vận động (chỉ dùng bàn phím) muốn đọc tiêu đề tin thứ hai và nhấn Tab để vào link. Nhưng cứ sau 4 giây, carousel trượt đi, tiêu điểm (focus) bị mất, và anh phải bắt đầu lại. Với người mắc chứng khó đọc (dyslexia), 4 giây không đủ để đọc hết một tiêu đề dài.

Diễn giải: Vi phạm rõ ràng 2.2.2. Carousel tự trượt kéo dài hơn 5 giây (nó chạy vô hạn) mà không có cơ chế pause/stop/hide.

Cách sửa: Thêm nút Pause/Play rõ ràng ngay trên carousel. Tự động dừng khi người dùng đưa focus hoặc con trỏ vào carousel (dừng khi hover/focus). Tăng thời gian mỗi slide lên 6-8 giây. Tôn trọng thiết lập prefers-reduced-motion của hệ điều hành — nếu người dùng đã bật, carousel không tự trượt.

Bài học: Auto-update tưởng chừng vô hại lại loại trừ cả người dùng bàn phím lẫn người cần thời gian đọc. Luôn trao nút dừng.

Hướng dẫn từng bước

Đây là quy trình để rà soát và xử lý giới hạn thời gian & auto-update trong sản phẩm của bạn.

Bước 1 — Lập bản đồ mọi giới hạn thời gian. Ngồi lại với team và liệt kê tất cả những nơi có thời gian điều khiển giao diện: phiên đăng nhập, timeout của form, OTP, giỏ hàng giữ chỗ, popup tự đóng, toast tự biến mất, carousel, ticker, auto-refresh dữ liệu. Bạn không thể sửa cái mình chưa nhìn thấy.

Bước 2 — Phân loại theo ngoại lệ. Với mỗi giới hạn, hỏi: đây có phải real-time event không? Có phải essential không (gia hạn làm mất giá trị)? Có dài hơn 20 giờ không? Nếu không rơi vào ngoại lệ nào, giới hạn đó BẮT BUỘC phải tuân thủ 2.2.1.

Bước 3 — Chọn cơ chế: Tắt, Điều chỉnh, hoặc Gia hạn. Với phần lớn timeout phiên, cơ chế "gia hạn có cảnh báo" là thực tế nhất. Với các popup/toast tự đóng, "tắt" (cho tồn tại đến khi người dùng chủ động đóng) thường tốt nhất.

Bước 4 — Thiết kế cảnh báo đúng chuẩn. Nếu chọn gia hạn, cảnh báo phải xuất hiện ít nhất 20 giây trước khi hết giờ, mô tả rõ điều gì sắp xảy ra, và có nút gia hạn thao tác đơn giản. Cảnh báo phải được screen reader thông báo (dùng role="alertdialog" hoặc aria-live).

Bước 5 — Bảo toàn dữ liệu. Đảm bảo nếu phiên hết hạn thật, dữ liệu người dùng đã nhập được giữ lại. Lưu tạm ở client (localStorage/sessionStorage) hoặc server để phục hồi sau khi đăng nhập lại (2.2.5, 2.2.6).

Bước 6 — Xử lý auto-update. Với mọi nội dung tự chuyển động/cập nhật quá 5 giây: thêm nút Pause/Stop/Hide, dừng khi hover/focus, và tôn trọng prefers-reduced-motion.

Bước 7 — Thiết lập vùng live hợp lý. Với bộ đếm ngược, đừng để screen reader đọc từng giây. Dùng aria-live="off" cho phần cập nhật liên tục và chỉ thông báo tại các mốc quan trọng qua vùng aria-live="polite" riêng.

Bước 8 — Kiểm thử với người thật. Nhờ một người dùng screen reader và một người dùng chỉ bàn phím thử hoàn tất tác vụ có giới hạn thời gian. Đây là bước không thể thay thế bằng công cụ tự động.

Lỗi thường gặp & mẹo

Lỗi 1 — Cho rằng "bảo mật nên không thể gia hạn". Rất nhiều team viện lý do bảo mật để từ chối thêm cảnh báo. Thực tế, WCAG không yêu cầu kéo dài phiên vô hạn — chỉ yêu cầu cảnh báo và cho gia hạn có giới hạn. Bạn hoàn toàn giữ được mức bảo mật mong muốn.

Lỗi 2 — Cảnh báo bằng màu sắc hoặc hiệu ứng, không bằng ngữ nghĩa. Một đồng hồ đếm ngược chuyển đỏ không giúp gì cho người khiếm thị. Cảnh báo phải được screen reader đọc lên qua vai trò ARIA phù hợp.

Lỗi 3 — Để aria-live đọc từng giây. Đặt bộ đếm ngược trong aria-live="polite" hoặc assertive sẽ khiến screen reader lải nhải liên tục, che lấp mọi thứ. Chỉ thông báo tại các mốc.

Lỗi 4 — Toast tự biến mất quá nhanh. Một thông báo lỗi hiện lên rồi biến mất sau 3 giây là vô dụng với người đọc chậm. Cho phép toast tồn tại đủ lâu, hoặc để người dùng chủ động đóng.

Lỗi 5 — Quên prefers-reduced-motion. Đây là "chìa khóa vàng": chỉ vài dòng CSS media query có thể tự động tắt auto-slide cho những ai đã khai báo họ cần giảm chuyển động.

Mẹo: Khi phân vân giữa "tự động" và "để người dùng chủ động", hãy luôn nghiêng về phía trao quyền cho người dùng. Auto-play, auto-slide, auto-close — mọi từ bắt đầu bằng "auto" đều cần một cặp mắt accessibility soi kỹ.

Mẹo: Với form dài, hãy tự động lưu nháp (auto-save draft) ở nền. Nó vừa giải quyết 2.2.5/2.2.6 vừa cải thiện trải nghiệm cho tất cả mọi người.

Bài tập thực hành

  • Rà soát sản phẩm của bạn. Mở một sản phẩm hoặc website bạn đang làm. Lập danh sách tất cả nơi có giới hạn thời gian và auto-update. Với mỗi mục, ghi rõ: giới hạn bao lâu, có cảnh báo không, có gia hạn được không, có mất dữ liệu không.
  • Phân loại ngoại lệ. Với từng mục trong danh sách trên, xác định nó có rơi vào ngoại lệ real-time/essential/20 giờ hay không. Đánh dấu những mục BẮT BUỘC phải tuân thủ 2.2.1.
  • Thiết kế modal cảnh báo. Phác thảo (trên giấy hoặc Figma) một modal cảnh báo "phiên sắp hết hạn" cho một form chuyển khoản. Ghi rõ: modal xuất hiện ở giây thứ mấy, nội dung text, các nút, và vai trò ARIA nào được dùng để screen reader thông báo.
  • Thử nghiệm carousel. Tìm một carousel tự trượt trên internet. Dùng chỉ bàn phím (không chuột) thử điều hướng vào các link bên trong. Ghi lại những khó khăn gặp phải và đề xuất cách sửa.
  • Nâng cao — prefers-reduced-motion. Viết một đoạn CSS media query tắt hiệu ứng auto-slide của một carousel khi người dùng bật prefers-reduced-motion: reduce. Kiểm tra bằng cách bật thiết lập "giảm chuyển động" trong hệ điều hành của bạn.

Tóm tắt

Giới hạn thời gian và auto-update là nhóm rào cản accessibility âm thầm nhưng có sức loại trừ lớn, đặc biệt với người lớn tuổi, người dùng screen reader, người vận động chậm và người có khó khăn nhận thức. Nguyên tắc cốt lõi rất đơn giản: thời gian và chuyển động phải nằm dưới quyền kiểm soát của con người.

Những điểm cần nhớ:

  • WCAG 2.2.1 (Cấp A) yêu cầu mọi giới hạn thời gian phải cho phép người dùng tắt, điều chỉnh (ít nhất 10 lần), hoặc gia hạn (cảnh báo trước, ít nhất 20 giây, gia hạn ≥10 lần) — trừ ngoại lệ real-time, essential, hoặc trên 20 giờ.
  • 2.2.5 và 2.2.6 yêu cầu không mất dữ liệu khi phiên hết hạn và phải cảnh báo trước khi mất dữ liệu.
  • 2.2.2 (Pause, Stop, Hide) yêu cầu mọi auto-update kéo dài hơn 5 giây phải có cơ chế tạm dừng, dừng hẳn, hoặc ẩn.
  • Cảnh báo phải mang tính ngữ nghĩa (screen reader đọc được), không chỉ bằng màu sắc.
  • Đừng để aria-live đọc từng giây; chỉ thông báo tại các mốc quan trọng.
  • Bảo mật không phải cái cớ để bỏ qua accessibility — bạn có thể có cả hai.
  • Luôn tôn trọng prefers-reduced-motion và luôn nghiêng về phía trao quyền kiểm soát cho người dùng.
Lần tới khi bạn thấy chữ "auto" hoặc một đồng hồ đếm ngược trong sản phẩm, hãy dừng lại và tự hỏi: người dùng chậm nhất của mình có kịp không? Nếu câu trả lời là không chắc, bạn đã biết cần làm gì.

Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi