Back to Explore
Ranh giới mong manh giữa CSS States và JavaScript Events: Tương lai của Web Development

Ranh giới mong manh giữa CSS States và JavaScript Events: Tương lai của Web Development

Khám phá cách CSS đang dần đảm nhận các tác vụ vốn trước đây chỉ dành cho JavaScript thông qua các pseudo-class hiện đại và đề xuất tương lai đầy hứa hẹn của 'event-trigger'.

Website
Upvote this postSign in to upvote this article.

Giới thiệu

CSS đang ngày càng trở nên "biết lắng nghe" hơn bao giờ hết. Không phải theo nghĩa đen, mà là CSS đang tích hợp ngày càng nhiều các pseudo-class (lớp giả) mạnh mẽ, cho phép chúng ta phản hồi với các sự kiện người dùng mà không cần phải viết JavaScript phức tạp. Mặc dù các pseudo-class theo dõi "trạng thái" (states) chứ không phải "sự kiện" (events), nhưng chúng đang dần xóa nhòa ranh giới giữa hai khái niệm này.

Trong bài viết này, chúng ta sẽ cùng phân tích các pseudo-class hiện có đóng vai trò như các trình lắng nghe sự kiện (event listeners) và khám phá đề xuất tương lai đầy tham vọng: event-trigger.

State Management

Các "Event-listening" Pseudo-classes

:hover và :active

  • :hover: Trạng thái này nắm bắt khoảnh khắc từ khi sự kiện pointerenter kích hoạt cho đến khi pointerleave xảy ra.
  • :active: Khớp với mục tiêu (nút, liên kết) đang được nhấn bởi chuột, ngón tay hoặc bút cảm ứng, tương đương với sự kiện pointerdownpointerup/pointercancel.

Mẹo nhỏ: Bạn có thể sử dụng thuộc tính pointer-events: none trong CSS để ngăn chặn các sự kiện con trỏ kích hoạt trên phần tử đã chọn.

:focus và :focus-visible

Trong khi :focus tương đương với các sự kiện focusblur trong JavaScript, thì :focus-visible thông minh hơn nhiều. Nó sử dụng các thuật toán của trình duyệt để xác định xem liệu chỉ báo focus có nên hiển thị hay không (ví dụ: người dùng đang dùng bàn phím hay chuột?).

Cách tốt nhất để xử lý logic này trong JavaScript là kiểm tra pseudo-class:

element.addEventListener("focus", (event) => {
  if (event.target.matches(":focus-visible")) {
    /* Thực hiện logic khi phần tử được focus qua bàn phím */
  }
});

:focus-within và :has()

CSS hiện đại đã tiến xa hơn với khả năng kiểm tra mối quan hệ cha-con:

  • :focus-within: Khớp nếu bất kỳ phần tử con nào đang có focus.
  • :has(): Khớp nếu một mối quan hệ selector tồn tại.

Ví dụ, hai đoạn code sau có tác dụng tương đương:

form:focus-within { /* Style form khi có con bên trong được focus */ }
form:has(:focus) { /* Style form khi có con bên trong được focus */ }

:checked

Tương đương với sự kiện change trong JavaScript. Khi một ô checkbox hoặc radio được chọn, CSS có thể phản hồi ngay lập tức mà không cần script.

Kiểm soát logic ẩn: :valid, :invalid và :autofill

Thay vì phải gọi checkValidity() trong JavaScript, CSS cung cấp các pseudo-class để xử lý xác thực form:

  • :valid / :invalid: Kiểm tra trạng thái hợp lệ ngay lập tức.
  • :user-valid / :user-invalid: Chỉ kích hoạt sau khi người dùng đã tương tác và rời khỏi phần tử (tương đương với logic của sự kiện change).
  • :autofill: Một tính năng cực kỳ hữu ích mà JavaScript khó có thể phát hiện một cách sạch sẽ.

Các pseudo-class cho Media và UI

  • Media elements: Các pseudo-class mới như :volume-locked sẽ sớm cho phép chúng ta kiểm soát trạng thái audio/video mà không cần lắng nghe sự kiện volumechange.
  • Popover/Dialog: Các pseudo-class như :popover-open, :open, và :modal thay thế hoàn toàn việc phải lắng nghe sự kiện toggle trong JS.
  • :fullscreen: Thay thế cho sự kiện fullscreenchange.
  • :target: Thay thế cho việc lắng nghe hashchange để kiểm tra ID trong URL.

Tương lai: Event-trigger (Đề xuất)

Mặc dù chưa được hỗ trợ rộng rãi, event-trigger là một bước tiến lớn trong đặc tả Animation Triggers. Nó cho phép gắn sự kiện trực tiếp vào CSS.

Cấu trúc cơ bản:

button {    
  event-trigger: --event click;
}

div {
  animation-trigger: --event play-forwards;
  animation: fade-in 300ms both;
}

Với event-trigger, chúng ta có thể tạo ra các hiệu ứng phức tạp chỉ bằng CSS, ví dụ như kích hoạt animation của phần tử B khi phần tử A được click. Các hành động animation được hỗ trợ bao gồm: play-once, play-forwards, play-backwards, và replay.

Kết luận

Việc CSS đảm nhận nhiều logic hơn không có nghĩa là JavaScript "tệ đi", mà là chúng ta có thêm công cụ để tối ưu hóa hiệu năng và đơn giản hóa mã nguồn. Sự chuyển dịch này giúp giao diện web trở nên phản hồi nhanh hơn và giảm bớt gánh nặng cho luồng thực thi chính (main thread) của JavaScript.

Discussion (0)

You need to log in to post comments. Log In

No comments yet. Start the discussion!

Do you like this post?

Upvote to push this post higher on the community feed

Details

Posted by: @admin
Categories: Libraries & Frameworks
Date posted: 8 tháng 7, 2026