Lập trình · 25/09/2026

CSS prefers-reduced-motion: Giảm hiệu ứng, giữ nguyên trải nghiệm

Một thẻ nội dung trượt vào màn hình có thể tạo cảm giác sinh động, nhưng chuyển động không phải lúc nào cũng cần thiết để đọc thông tin. Khi người dùng chọn giảm chuyển động trên thiết bị, website nên tôn trọng lựa chọn đó mà không làm mất nội dung, trạng thái hay khả năng thao tác.

CSS prefers-reduced-motion: Giảm hiệu ứng, giữ nguyên trải nghiệm

Một thẻ nội dung trượt vào màn hình có thể tạo cảm giác sinh động, nhưng chuyển động không phải lúc nào cũng cần thiết để đọc thông tin. Khi người dùng chọn giảm chuyển động trên thiết bị, website nên tôn trọng lựa chọn đó mà không làm mất nội dung, trạng thái hay khả năng thao tác.

1. Hiểu đúng prefers-reduced-motion

Theo tài liệu MDN, media feature này cho phép CSS nhận biết tùy chọn giảm chuyển động của người dùng. Giá trị reduce thể hiện yêu cầu giảm chuyển động; no-preference nghĩa là chưa có tùy chọn được thông báo, không có nghĩa người dùng muốn mọi hiệu ứng được bật.

Đây là tín hiệu để điều chỉnh thiết kế, không phải một công tắc tự động sửa toàn bộ website. Hiệu ứng từ thư viện, canvas hoặc JavaScript cần được rà soát riêng.

2. Bắt đầu bằng giao diện tĩnh hoạt động đầy đủ

Ví dụ dưới đây giữ thẻ nội dung hiển thị ngay từ đầu. Chỉ khi không có yêu cầu giảm chuyển động, thẻ mới chạy hiệu ứng đi lên nhẹ. Có thể đặt CSS vào stylesheet của trang thử nghiệm và dùng HTML minh họa bên dưới.

<article class="notice">
  <h2>Đã lưu bản nháp</h2>
  <p>Bạn có thể tiếp tục chỉnh sửa trước khi xuất bản.</p>
</article>
.notice {
  padding: 1rem;
  border: 1px solid #64748b;
  border-radius: 0.5rem;
}

@media (prefers-reduced-motion: no-preference) {
  .notice {
    animation: notice-enter 180ms ease-out;
  }
}

@keyframes notice-enter {
  from { transform: translateY(0.5rem); }
  to   { transform: translateY(0); }
}

Kỳ vọng khi kiểm tra: ở chế độ reduce, thẻ xuất hiện tại vị trí cuối mà không trượt; ở no-preference, thẻ có chuyển động ngắn lúc được thêm vào trang. Đây là ví dụ để thử nghiệm, không phải báo cáo kết quả chạy trên mọi trình duyệt.

3. Giảm chuyển động nhưng không xóa phản hồi

Giả sử một thao tác lưu dùng vòng quay để báo đang xử lý. Không nên chỉ ẩn vòng quay rồi để người dùng không biết ứng dụng đang làm gì. Hãy giữ nhãn “Đang lưu…” và cập nhật thành “Đã lưu” hoặc thông báo lỗi khi có kết quả.

Tương tự, menu vẫn phải mở được, hộp thoại vẫn nhận focus đúng và thông báo vẫn đọc được khi bỏ hiệu ứng. Trạng thái nghiệp vụ không nên phụ thuộc vào việc animation đã chạy hết. Nếu mã hiện tại chờ sự kiện animationend để hoàn thành một thao tác, cần kiểm tra lại nhánh không chạy animation.

4. Tránh tắt mọi hiệu ứng bằng một quy tắc toàn cục

Một quy tắc áp dụng animation: none cho mọi phần tử có thể tác động đến thành phần mà đội phát triển chưa kiểm tra. Cách dễ kiểm soát hơn là liệt kê các hiệu ứng thực sự có trong sản phẩm: banner, menu, carousel, cuộn mượt và chuyển trang; sau đó xác định hành vi thay thế cho từng thành phần.

Với thư viện giao diện, kiểm tra tùy chọn giảm chuyển động của chính thư viện. Không mặc định rằng media query trong stylesheet sẽ dừng mọi animation do JavaScript điều khiển.

5. Checklist kiểm tra trước khi phát hành

  1. Mở bảng Rendering trong Chrome DevTools và giả lập prefers-reduced-motion: reduce theo hướng dẫn Chrome DevTools.
  2. Tải lại trang để quan sát hiệu ứng xuất hiện ban đầu, sau đó thử menu, hộp thoại và thao tác lưu.
  3. Chuyển sang no-preference để so sánh; kiểm tra cả trường hợp đổi tùy chọn khi trang đang mở.
  4. Thử điều hướng bằng bàn phím: focus phải nhìn thấy và không bị kẹt vì bỏ hiệu ứng.
  5. Kiểm tra thêm với tùy chọn thật của hệ điều hành; giả lập trong DevTools không thay thế toàn bộ kiểm thử thiết bị.

Tiêu chí hoàn thành không phải là “website hết chuyển động”, mà là người chọn giảm chuyển động vẫn hiểu trạng thái và hoàn thành cùng một công việc. Hãy đưa hai chế độ này vào checklist của từng thành phần ngay từ lúc thiết kế.

Thảo luận

Bình luận 0

Đăng nhập để bình luận

Bạn cần có tài khoản để tham gia thảo luận và trả lời độc giả khác.

Đăng nhậpĐăng ký

Chưa có bình luận. Hãy là người đầu tiên chia sẻ ý kiến.