Thursday, October 8, 2015

[GUIDE] Tạo accordion menu nhiều cấp bằng CSS

Bài viết hướng dẫn tạo một CSS accordion menu đơn giản nhưng hỗ trợ nhiều level của các item bên trong. Cách làm này, có thể chạy trên nhiều trình duyệt khác nhau: IE9+, Safary, Chrome, Firefox.


Trong bài hướng dẫn này, menu chỉ dùng CSS, với việc apply :checked pseudo-class selector của CSS trên các element input checkbox.
Ngoài ra, trong phần demo cũng có một phiên bản sử dụng jQuery, nếu bạn muốn có thêm các hiệu ứng animation để tăng phần sinh động.


DEMO   DOWNLOAD SOURCE

Tạo cấu trúc HTML của menu


Cấu trúc HTML của menu này khá đơn giản: đó là sử dụng 1 list các item. Nếu một item trong list, lại có các item con, thì chúng ta sử dụng một input[type=checkbox] kèm với label của nó để làm top row. Và đồng thời, chúng ta sẽ thêm .has-children class vào item đó trên list. Tất cả các item ở list lớp ngoài cùng, mà không có item con, thì chỉ cần để môt thẻ link a là được.

Chi tiết code như dưới đây:


<ul class="cd-accordion-menu">
<li class="has-children">
<input type="checkbox" name="group-1" id="group-1" checked>
<label for="group-1">Group 1</label>

<ul>
<li class="has-children">
<input type="checkbox" name ="sub-group-1" id="sub-group-1">
<label for="sub-group-1">Sub Group 1</label>

<ul>
<li><a href="#0">Image</a></li>
<li><a href="#0">Image</a></li>
<li><a href="#0">Image</a></li>
</ul>
</li>
<li><a href="#0">Image</a></li>
<li><a href="#0">Image</a></li>
</ul>
</li>

<li><a href="#0">Image</a></li>
<li><a href="#0">Image</a></li>
</ul> <!-- cd-accordion-menu -->


Thêm style CSS

Chúng ta sử dụng một cách khá đơn giản (ngày nay thường làm thế này), để phát hiện ra item được click, và show các item con của nó, chỉ bằng CSS: đó là như đã đã nói ở trên, ta dùng một checkbox input element. Với việc select class :checked của input checkbox đó, ta sẽ bắt được element đó có checked hay chưa, và tiến hành show/hide các item con của nó bằng cách change display từ "none" thành "block" (và ngược lại nếu để hide đi).

Cụ thể step-by-step từng bước một như sau:

1) Đầu tiên, chúng ta phải kiểm tra lại rằng tất cả các item lớn bên ngoài mà có chứa các item con bên trong, thì cần phải có input checkbox như đã làm sample HTML ở trên
2) Chúng ta cũng phải chắc chắn rằng, khi mà chúng ta click vào label của nó, thì checkbox đó cũng tự động được check. Nếu bạn quen thuộc với HTML rồi, thì việc này khá là đơn giản, ở input checkbox bạn cần đặt cho nó một id value, và ở label, bạn cần đặt value id của checkbox vào thuộc tính for của nó.


Dưới đây là code CSS mà chúng ta sẽ sử dụng để hiển thị Menu bằng CSS ở trạng thái ban đầu:


.cd-accordion-menu input[type=checkbox] {
/* hide native checkbox */
position: absolute;
opacity: 0;
}
.cd-accordion-menu label, .cd-accordion-menu a {
position: relative;
display: block;
padding: 18px 18px 18px 64px;
background: #4d5158;
box-shadow: inset 0 -1px #555960;
color: #ffffff;
font-size: 1.6rem;
}


Bây giờ, ta nhận thấy rằng cấu trúc HTML cho input, label, list các item đã được xếp theo thứ tự. Tiếp theo, chúng ta dùng cơ chế select :checked của CSS để thực hiện hiển thị các element con bên trong nó bằng cách thay đổi value display từ "none" thành "block";


.cd-accordion-menu ul {
/* by default hide all sub menus */
display: none;
}

.cd-accordion-menu input[type=checkbox]:checked + label + ul,
.cd-accordion-menu input[type=checkbox]:checked + label:nth-of-type(n) + ul {
/* use label:nth-of-type(n) to fix a bug on safari (<= 8.0.8) with multiple adjacent-sibling selectors*/ /* show children when item is checked */ display: block; }


Như vậy là ta đã hoàn thành một menu accordion chỉ bằng CSS.

Nếu bạn muốn menu có thêm các hiệu ứng chuyển động animation khi cụp xoè (show/hide) item con, thì chỉ việc include thêm javascript vào.

DEMO:



Bài viết được dịch dựa vào nguồn: https://codyhouse.co/gem/css-multi-level-accordion-menu/