Thứ bảy, 02/05/2020 | 00:00 GMT+7

Triển khai một CSS thuần túy có thể thu gọn


Các tiện ích con có thể thu gọn là một cách phổ biến để tạo các phần nội dung có thể thu nhỏ và mở rộng. Có rất nhiều cách triển khai khác nhau trên mạng. Ở đây, nhờ các phần tử đầu vào hộp kiểm, phần tử nhãn và : bộ chọn giả đã kiểm tra , ta sẽ có thể tạo tiện ích con như vậy mà không cần thêm JavaScript.

Đây là giao diện có thể thu gọn của ta :

Xem Bút KKzWqVX của alligatorio ( @alligatorio ) trên CodePen .

Và đây là đánh dấu HTML cho nó:

<div class="wrap-collabsible">
  <input id="collapsible" class="toggle" type="checkbox">
  <label for="collapsible" class="lbl-toggle">More Info</label>
  <div class="collapsible-content">
    <div class="content-inner">
      <p>
        QUnit is by calling one of the object that are embedded in JavaScript, and faster JavaScript program could also used with
        its elegant, well documented, and functional programming using JS, HTML pages Modernizr is a popular browsers without
        plug-ins. Test-Driven Development.
      </p>
    </div>
  </div>
</div>

Nếu bạn muốn có một đóng mở được mở ra theo mặc định, bạn chỉ cần cài đặt các thuộc tính kiểm tra vào hộp kiểm:

<input id="collapsible2" class="toggle" type="checkbox" checked>

Xem Pen qBZrjqG của alligatorio ( @alligatorio ) trên CodePen .

Lưu ý mỗi nhãn phải được liên kết với đúng hộp kiểm, vì vậy mỗi phần tử hộp kiểm cần một id duy nhất và mỗi nhãn thuộc tính for phải trỏ đến id của hộp kiểm tương ứng.

Tạo kiểu có thể thu gọn của ta

Hãy phân tích các phong cách từng chút một…

Đầu tiên, ta đặt phần tử hộp kiểm để display: none . Hộp kiểm sẽ ẩn và thay vào đó, nhãn của nó sẽ được sử dụng để chọn hoặc bỏ chọn. Sau đó, bạn sẽ thấy rằng ta sẽ sử dụng công cụ chọn giả CSS : đã kiểm tra để tạo kiểu khác nhau khi hộp kiểm ẩn được chọn:

input[type='checkbox'] {
  display: none;
}

Tiếp theo, ta tạo kiểu cho nhãn mặc định của bạn . Ở đây không có gì thực sự đặc biệt đang xảy ra, ngoại trừ việc ta làm cho nhãn của bạn hiển thị dưới dạng một phần tử khối với display: block :

.lbl-toggle {
  display: block;

  font-weight: bold;
  font-family: monospace;
  font-size: 1.2rem;
  text-transform: uppercase;
  text-align: center;

  padding: 1rem;

  color: #A77B0E;
  background: #FAE042;

  cursor: pointer;

  border-radius: 7px;
  transition: all 0.25s ease-out;
}

.lbl-toggle:hover {
  color: #7C5A0B;
}

Đối với mũi tên nhỏ, một số cách sử dụng đường viền thông minh sẽ giúp bạn dễ dàng tạo hình tam giác:

.lbl-toggle::before {
  content: ' ';
  display: inline-block;

  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  border-left: 5px solid currentColor;

  vertical-align: middle;
  margin-right: .7rem;
  transform: translateY(-2px);

  transition: transform .2s ease-out;
}

Tham khảo bài đăng này từ CSS-Tricks cho tất cả các nhu cầu về hình tam giác CSS của bạn.

Bạn cũng có thể nhận thấy rằng ta đã sử dụng biến tích hợp sẵn currentColor để tam giác của ta có cùng màu với văn bản nhãn của ta .


Hãy cũng đưa ra một số phong cách cơ bản cho nội dung:

.collapsible-content .content-inner {
  background: rgba(250, 224, 66, .2);
  border-bottom: 1px solid rgba(250, 224, 66, .45);

  border-bottom-left-radius: 7px;
  border-bottom-right-radius: 7px;
  padding: .5rem 1rem;
}

Bây giờ ta có thể bắt đầu với phần thú vị. Theo mặc định, div nội dung có thể thu gọn sẽ có giá trị chiều cao tối đa0px , làm cho nó bị ẩn hoàn toàn:

.collapsible-content {
  max-height: 0px;
  overflow: hidden;

  transition: max-height .25s ease-in-out;
}

Khi hộp kiểm của hộp có thể thu gọn được đánh dấu bằng cách nhấp vào nhãn của nó, ta sẽ đặt div nội dung thành giá trị chiều cao tối đa đủ cao để nó có thể phát triển để hiển thị tất cả nội dung bên trong.

Thay vì cố gắng tìm ra chiều cao tốt theo cách thủ công, bạn cũng có thể chỉ cần sử dụng các đơn vị khung nhìn với thông tin như 100vh. Sử dụng thứ gì đó giống như 100% cũng sẽ hoạt động, nhưng bạn sẽ mất khả năng sử dụng chuyển tiếp. Lưu ý bạn có thể vẫn muốn sử dụng thứ gì đó giống như 100% nếu bạn cho rằng nội dung trong chế độ có thể thu gọn có thể cao hơn chế độ xem.

Ta sử dụng bộ chọn anh chị em kế cận ( + ) để chọn div nội dung của ta khi hộp kiểm được chọn:

.toggle:checked + .lbl-toggle + .collapsible-content {
  max-height: 100vh;
}

Ta sử dụng chiều cao tối đa thay vì chiều cao vì ta muốn tránh sử dụng chiều cao được mã hóa cứng và muốn có thể đặt nội dung có chiều cao tùy ý vào thanh thu gọn của ta .

Và bây giờ ta làm điều gì đó thực sự tương tự bằng cách sử dụng bộ chọn anh chị em liền kề để xoay hình tam giác nhỏ của ta khi mở rộng khả năng thu gọn và để điều chỉnh bán kính dưới cùng bên phải và đường viền bên trái của nhãn:

.toggle:checked + .lbl-toggle::before {
  transform: rotate(90deg) translateX(-3px);
}

.toggle:checked + .lbl-toggle {
  border-bottom-right-radius: 0;
  border-bottom-left-radius: 0;
}

Và bạn có nó rồi đấy! Một cách khá đơn giản để tạo một phần có thể thu gọn mà không cần sử dụng bất kỳ tập lệnh nào.

Lưu ý về khả năng tiếp cận

Như hiện tại, tiện ích con có thể thu gọn của ta không có thể truy cập được. Ta sẽ phải thêm một chút JavaScript để làm cho nó có thể truy cập được. Tôi biết, tôi biết, toàn bộ mọi thứ phải được triển khai bằng không sử dụng JavaScript. Tôi có thể nói gì!

Công nghệ hỗ trợ tiếp cận không ngừng được cải thiện, hãy để lại comment bên dưới nếu có cách tốt hơn để thực hiện việc này.

Trong tập lệnh sau, ta chọn tất cả các nhãn chuyển đổi và lắng nghe các sự kiện keydown. Nếu khóa ép có thể là từ enter hoặc phím spacebar, ta kích hoạt một nhấp chuột trên nhãn.

let myLabels = document.querySelectorAll('.lbl-toggle');

Array.from(myLabels).forEach(label => {
  label.addEventListener('keydown', e => {
    // 32 === spacebar
    // 13 === enter
    if (e.which === 32 || e.which === 13) {
      e.preventDefault();
      label.click();
    };
  });
});

Để làm cho nhãn có thể lấy tiêu điểm, ta thêm tabindex="0" vào nhãn:

<label for="collapsible3" class="lbl-toggle" tabindex="0">With A11y</label>

Xem Pen OJNpgpb của alligatorio ( @alligatorio ) trên CodePen .

Tất cả các phong cách

Dưới đây là toàn bộ kiểu dáng cùng một lúc, để bạn tham khảo:

.wrap-collabsible {
  margin-bottom: 1.2rem 0;
}

input[type='checkbox'] {
  display: none;
}

.lbl-toggle {
  display: block;

  font-weight: bold;
  font-family: monospace;
  font-size: 1.2rem;
  text-transform: uppercase;
  text-align: center;

  padding: 1rem;

  color: #A77B0E;
  background: #FAE042;

  cursor: pointer;

  border-radius: 7px;
  transition: all 0.25s ease-out;
}

.lbl-toggle:hover {
  color: #7C5A0B;
}

.lbl-toggle::before {
  content: ' ';
  display: inline-block;

  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  border-left: 5px solid currentColor;
  vertical-align: middle;
  margin-right: .7rem;
  transform: translateY(-2px);

  transition: transform .2s ease-out;
}

.toggle:checked + .lbl-toggle::before {
  transform: rotate(90deg) translateX(-3px);
}

.collapsible-content {
  max-height: 0px;
  overflow: hidden;
  transition: max-height .25s ease-in-out;
}

.toggle:checked + .lbl-toggle + .collapsible-content {
  max-height: 100vh;
}

.toggle:checked + .lbl-toggle {
  border-bottom-right-radius: 0;
  border-bottom-left-radius: 0;
}

.collapsible-content .content-inner {
  background: rgba(250, 224, 66, .2);
  border-bottom: 1px solid rgba(250, 224, 66, .45);
  border-bottom-left-radius: 7px;
  border-bottom-right-radius: 7px;
  padding: .5rem 1rem;
}

🌈 Tận hưởng khả năng thu gọn gần như chỉ CSS bạn muốn !


Tags:

Các tin liên quan

Căn giữa mọi thứ trong CSS bằng Flexbox
2020-05-02
Tham chiếu phông chữ hệ thống CSS
2020-03-29
Sử dụng Thuộc tính chiều cao dòng CSS để cải thiện khả năng đọc
2020-02-04
Cách sử dụng CSS: root Pseudo-Class Selector
2020-01-15
Khi nào bạn nên sử dụng quy tắc CSS! Important?
2020-01-14
Thủ thuật sử dụng CSS translateZ () và phối cảnh ()
2019-12-13
Cách hiển thị CSS trên server ứng dụng React
2019-12-12
Cách tạo Thư viện ảnh cuộn vô hạn với React và CSS Grid
2019-12-12
Cách tạo node tải xuống với các tương tác nhỏ với CSS, anime.js và segment.js
2019-12-12
Cách giải quyết tắc nghẽn CSS quy mô lớn với ITCSS và BEM
2019-12-12