Bạn sẽ nghĩ rằng ẩn nội dung bằng CSS là một vấn đề đơn giản và dễ giải quyết, nhưng có nhiều giải pháp, mỗi giải pháp là duy nhất
Các nhà phát triển thường sử dụng display: none
để ẩn nội dung trên trang. Thật không may, cách ẩn nội dung này không phải là chống đạn vì hiện tại nội dung đó “không thể truy cập được” đối với trình đọc màn hình. Thật hấp dẫn khi sử dụng nó, nhưng đặc biệt là trong trường hợp thứ gì đó chỉ được dùng để ẩn đi bằng mắt thường, đừng với lấy nó
Thực tế là có nhiều cách để “ẩn” mọi thứ trong CSS, mỗi cách đều có ưu và nhược điểm phụ thuộc rất nhiều vào cách nó được sử dụng. Chúng tôi sẽ xem xét từng kỹ thuật ở đây và tóm tắt mọi thứ bằng một bản tóm tắt giúp chúng tôi quyết định nên sử dụng kỹ thuật nào và khi nào.
Làm thế nào để phát hiện sự khác biệt giữa các kỹ thuật
Để thấy sự khác biệt giữa các cách ẩn nội dung khác nhau, chúng tôi phải giới thiệu một số số liệu. Số liệu mà chúng tôi sẽ sử dụng để so sánh các phương pháp. Tôi quyết định phá vỡ điều đó bằng cách đặt câu hỏi tập trung vào bốn lĩnh vực cụ thể ảnh hưởng đến bố cục, hiệu suất và khả năng truy cập
- khả năng tiếp cận. Nội dung ẩn có được trình đọc màn hình đọc không?
- Luồng tài liệu. Phần tử ẩn có ảnh hưởng đến bố cục tài liệu không?
- kết xuất. Mô hình hộp của phần tử ẩn có được hiển thị không?
- Trình kích hoạt sự kiện. Phần tử có phát hiện các nhấp chuột hoặc tiêu điểm không?
Bây giờ chúng ta đã có các tiêu chí của mình, hãy so sánh các phương pháp. Một lần nữa, chúng ta sẽ kết hợp mọi thứ ở phần cuối theo cách mà chúng ta có thể sử dụng nó làm tài liệu tham khảo để đưa ra quyết định khi ẩn mọi thứ trong CSS
Phương pháp 1. Tài sản .visually-hidden:not[:focus]:not[:active] {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
0
.visually-hidden:not[:focus]:not[:active] {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
Chúng tôi đã bắt đầu bài đăng này với sự thận trọng về việc sử dụng
.visually-hidden:not[:focus]:not[:active] {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
0 để ẩn nội dung. Và như chúng tôi đã thiết lập, sử dụng nó để ẩn một phần tử có nghĩa là phần tử đó hoàn toàn không được tạo. Nó nằm trong DOM, nhưng chưa bao giờ thực sự được hiển thịPhần tử sẽ vẫn hiển thị trong phần đánh dấu, nếu bạn kiểm tra trang, bạn sẽ có thể thấy phần tử đó. Mô hình hộp sẽ không tạo cũng như không xuất hiện trên trang, điều này cũng áp dụng cho tất cả các phần tử con của nó
Và hơn thế nữa, nếu phần tử có bất kỳ trình xử lý sự kiện nào - chẳng hạn như nhấp chuột hoặc di chuột - thì chúng sẽ không đăng ký gì cả. Và như chúng ta đã thảo luận, tất cả nội dung sẽ bị trình đọc màn hình bỏ qua. Ở đây, chúng tôi có hai nút hiển thị và một nút ẩn với display: none
. Cả ba nút đều có các sự kiện nhấp nhưng chỉ có hai nút hiển thị sẽ hiển thị và đăng ký các lần nhấp
Dự phòng nhúng CodePen
Hiển thị là thuộc tính duy nhất sẽ ảnh hưởng đến việc kích hoạt yêu cầu hình ảnh. Nếu thẻ hình ảnh [hoặc phần tử gốc] có thuộc tính
.visually-hidden:not[:focus]:not[:active] {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
0 được đặt thành .visually-hidden:not[:focus]:not[:active] {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
4 thông qua CSS nội tuyến hoặc bằng bộ chọn, thì hình ảnh sẽ được tải xuống. Mặt khác, nếu hình ảnh được áp dụng với thuộc tính .visually-hidden:not[:focus]:not[:active] {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
5, nó sẽ không được tải xuốngTrường hợp này xảy ra do trình phân tích cú pháp chưa áp dụng CSS khi tài liệu HTML được phân tích cú pháp và gặp phải thẻ
.visually-hidden:not[:focus]:not[:active] {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
6. Mặt khác, khi chúng tôi áp dụng hình ảnh cho một phần tử có thuộc tính .visually-hidden:not[:focus]:not[:active] {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
5, hình ảnh sẽ không được tải xuống vì trình phân tích cú pháp chưa áp dụng CSS nơi hình ảnh được gọi. Hành vi này phù hợp trên tất cả các trình duyệt mới nhất. Ngoại lệ duy nhất là IE 11 sẽ tải xuống hình ảnh trong cả hai trường hợpMetricResult Nội dung ẩn có được trình đọc màn hình đọc không?❌Phần tử ẩn có ảnh hưởng đến bố cục tài liệu không?❌Mô hình hộp của phần tử ẩn có được hiển thị không?❌Phần tử có phát hiện nhấp chuột hoặc tiêu điểm không?❌Phương pháp 2. Tài sản .visually-hidden:not[:focus]:not[:active] {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
8
.visually-hidden:not[:focus]:not[:active] {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
Nếu thuộc tính
.visually-hidden:not[:focus]:not[:active] {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
8 của một phần tử được đặt thành .visually-hidden {
position: absolute;
}
0, thì phần tử đó bị “ẩn trực quan. ” Việc “ẩn trực quan” nghe rất giống với những gì mà display: none
làm, nhưng nó cực kỳ khác biệt ở chỗ phần tử được tạo và hiển thị, nhưng vô hình. Điều này có nghĩa là mô hình hộp của phần tử hiện diện, tạo cho nó các kích thước tiếp tục chiếm không gian trên màn hình mặc dù nó dường như không có ở đóHãy tưởng tượng bạn đang mặc một chiếc áo tàng hình khiến bạn vô hình với người khác, nhưng bạn vẫn có thể va vào mọi thứ. Bạn đang ở đó, ngay cả khi bạn vô hình trước mắt người
Nhưng đó là nơi mà sự khác biệt giữa "ẩn trực quan" và "không hiển thị" kết thúc. Trên thực tế, các phần tử ẩn với
.visually-hidden:not[:focus]:not[:active] {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
8 và .visually-hidden:not[:focus]:not[:active] {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
0 hoạt động giống nhau về khả năng truy cập và trình kích hoạt sự kiện. Các phần tử vô hình không thể truy cập được đối với trình đọc màn hình và sẽ không đăng ký các sự kiện, như chúng ta thấy trong bản trình diễn sau đây hoàn toàn giống với ví dụ trước, nhưng chỉ hoán đổi display: none
với .visually-hidden {
position: absolute;
}
5Dự phòng nhúng CodePen
MetricResult Nội dung ẩn có được trình đọc màn hình đọc không?❌Phần tử ẩn có ảnh hưởng đến bố cục tài liệu không?✅Mô hình hộp của phần tử ẩn có được hiển thị không?✅Phần tử có phát hiện nhấp chuột hoặc tiêu điểm không?❌Phương pháp 3. Tài sản .visually-hidden {
position: absolute;
}
6
.visually-hidden {
position: absolute;
}
Thuộc tính
.visually-hidden {
position: absolute;
}
6 chỉ ảnh hưởng đến khía cạnh trực quan của phần tử. Nếu chúng ta đặt .visually-hidden {
position: absolute;
}
6 của một phần tử thành 0, thì phần tử đó sẽ hoàn toàn trong suốt. Một lần nữa, nó rất giống với .visually-hidden {
position: absolute;
}
5 khi chúng ta phủ một chiếc áo choàng vô hình lên phần tử nơi nó vô hình nhưng vẫn hiện diện về mặt vật chấtNói cách khác, những gì chúng ta có là một phần tử rỗng, trong suốt, hoạt động giống như bất kỳ phần tử nào khác, chỉ có điều là vô hình. Nghe rất giống phương pháp
.visually-hidden:not[:focus]:not[:active] {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
8, phải không? Dự phòng nhúng CodePen
MetricResult Nội dung ẩn có được trình đọc màn hình đọc không?✅Phần tử ẩn có ảnh hưởng đến bố cục tài liệu không?✅Mô hình hộp của phần tử ẩn có được hiển thị không?✅Phần tử có phát hiện nhấp chuột hoặc tiêu điểm không?✅Phương pháp 4. Tài sản .visually-hidden {
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
1
.visually-hidden {
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
Đẩy một phần tử ra khỏi màn hình với định vị tuyệt đối là một cách khác mà các nhà phát triển thường giấu mọi thứ. Sử dụng
.visually-hidden {
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
2 và .visually-hidden {
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
3, chúng ta có thể đẩy phần tử ra xa khỏi màn hình đến mức không thể nhìn thấy phần tử đó. Nó giống như giấu lọ bánh quy bên ngoài nhà để bọn trẻ [hoặc có thể bạn. ] không thể tìm thấy chúng“Tuyệt đối” là từ khóa ở đây. Nếu chúng tôi đặt
.visually-hidden {
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
1 thành .visually-hidden {
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
5, một phần tử sẽ bị loại khỏi luồng tài liệu, đây là cách nói rằng phần tử đó không còn tuân theo vị trí tự nhiên của nó trong DOM. Nói cách khác, trang không dành bất kỳ khoảng trống nào cho nó, điều này sẽ loại bỏ phần tử theo thứ tự trực quan, định vị nó thành phần tử được định vị gần nhất nếu có hoặc gốc tài liệu nếu không có gì khácDự phòng nhúng CodePen
Chúng tôi tận dụng vị trí tuyệt đối bằng cách loại bỏ phần tử “ẩn” ra khỏi luồng tài liệu và đặt lệch phần tử đó về phía trên cùng bên trái với các giá trị của
.visually-hidden {
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
6.hidden {
position: absolute;
top: -9999px;
left: -9999px;
}
Dự phòng nhúng CodePen
MetricEffect Nội dung ẩn có được trình đọc màn hình đọc không?✅Phần tử ẩn có ảnh hưởng đến bố cục tài liệu không?❌Mô hình hộp của phần tử ẩn có được hiển thị không?✅Phần tử có phát hiện nhấp chuột hoặc tiêu điểm không?✅Nếu phần tử ẩn chứa nội dung có thể đặt tiêu điểm, trang sẽ cuộn đến phần tử đó khi nó được đặt tiêu điểm, tạo ra một bước nhảy đột ngột
Phương pháp 5. Lớp “ẩn trực quan”
Cho đến nay, phương thức
.visually-hidden {
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
1 là cách gần nhất mà chúng tôi từng thấy đối với cách ẩn nội dung trong CSS thân thiện với khả năng truy cập. Nhưng vấn đề với nội dung có thể lấy tiêu điểm gây ra hiện tượng nhảy trang đột ngột không phải là vấn đề lớn. Một cách tiếp cận khác để ẩn có thể truy cập kết hợp định vị tuyệt đối, thuộc tính .visually-hidden {
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
8 và ẩn tràn. Scott O'Hara đã viết lại nó vào năm 2017.visually-hidden:not[:focus]:not[:active] {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
Hãy phá vỡ điều đó
Chúng ta cần xóa phần tử khỏi luồng tài liệu. Cách tốt nhất để làm điều này là sử dụng
.visually-hidden {
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
9. Thao tác này sẽ xóa phần tử nhưng chúng tôi sẽ không đẩy phần tử đó ra khỏi màn hình.visually-hidden {
position: absolute;
}
Chúng ta có thể ẩn phần tử bằng cách đặt thuộc tính chiều rộng và chiều cao thành 0. Thật không may, điều đó sẽ không hoạt động vì một số trình đọc màn hình sẽ bỏ qua các phần tử có chiều rộng và chiều cao bằng không. Những gì chúng ta có thể làm là đặt nó ở giá trị thấp thứ hai,
.visually-hidden {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
0. Điều đó có nghĩa là nội dung sẽ dễ dàng tràn ra ngoài không gian, vì vậy chúng tôi cũng cần .visually-hidden {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
1 để đảm bảo nội dung không tràn ra ngoài.visually-hidden {
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
Để ẩn hình vuông một pixel đó, chúng ta có thể sử dụng thuộc tính CSS clipping. Nó là hoàn hảo cho tình huống này, vì nó không ảnh hưởng đến trình đọc màn hình. Nội dung ở đó, nhưng, một lần nữa, bị ẩn đi. Điều cần lưu ý là
.visually-hidden {
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
8 không được dùng để thay thế cho .visually-hidden {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
3 nhưng vẫn cần thiết nếu chúng tôi cần hỗ trợ các phiên bản Internet Explorer cũ hơn.visually-hidden {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
Một phần khác của câu đố lớp “ẩn trực quan” là giải quyết văn bản có thể truy cập ngoài màn hình bị nhòe, một điều kỳ lạ loại bỏ khoảng trắng giữa các từ, khiến chúng được đọc to như một chuỗi từ lớn. Ví dụ: “Welcome back home” sẽ được đọc thành “Welcomebackhome. ”
Một giải pháp đơn giản cho vấn đề này là đặt
.visually-hidden {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
4.visually-hidden {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
Và cuối cùng. Điều cuối cùng cần xem xét là cho phép phần tử nhất định có tiêu điểm gốc và trang web đang hoạt động hiển thị khi chúng được đặt tiêu điểm, đồng thời tiếp tục ngăn không cho các phần tử khác, như đoạn văn, hiển thị. Chúng ta có thể sử dụng bộ chọn giả
.visually-hidden {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
5 cho điều đó.visually-hidden:not[:focus]:not[:active] {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
Dự phòng nhúng CodePen
MetricResult Nội dung ẩn có được trình đọc màn hình đọc không?✅Phần tử ẩn có ảnh hưởng đến bố cục tài liệu không?❌Mô hình hộp của phần tử ẩn có được hiển thị không?❌Phần tử có phát hiện nhấp chuột hoặc tiêu điểm không?✅đề cập danh dự
Thậm chí còn có nhiều phương pháp hơn năm phương pháp chúng tôi đã đề cập. Ví dụ: thuộc tính
.visually-hidden {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
6 có thể đẩy văn bản ra khỏi màn hình giống như phương thức .visually-hidden {
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
1.hidden {
text-indent: -9999em;
}
Thật không may, cách tiếp cận này không phù hợp với các chế độ viết RTL. Điều đó làm cho nó ít thích ứng hơn so với các giải pháp khác mà chúng tôi đã đề cập
Một phương pháp khác là sử dụng
.visually-hidden {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
width: 1px;
}
8 để chia tỷ lệ hoặc di chuyển phần tử ra khỏi đường đi. Nó hoạt động giống nhau — chỉ trực quan — như .visually-hidden {
position: absolute;
}
6.hidden {
transform: scale[0];
}
Hãy tập hợp mọi thứ lại với nhau
Chúng tôi đã có một giải pháp giúp ẩn nội dung một cách trực quan nhưng vẫn có thể truy cập được. Sau đó, bạn có nên ngừng sử dụng display: none
?
Điều đó nói rằng, Điều đáng nói là nếu bạn muốn đạt được kết quả ngược lại — ẩn nội dung nào đó khỏi trình đọc màn hình, thuộc tính
.visually-hidden {
clip: rect[0 0 0 0];
clip-path: inset[50%];
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
1 sẽ ẩn nội dung khỏi trình đọc màn hình, nhưng không trực quanCùng với đó, đây là một bảng hoàn chỉnh so sánh tất cả các phương pháp. Sử dụng nó để hướng dẫn các quyết định của bạn về cách ẩn nội dung vào lần tới khi bạn thấy mình trong tình huống đó