Mình cũng đã từng nhiều lần tìm cách tạo mục lục (Table of content) cho các bài viết trong khi thiết kế website, vì thế sau khi tìm nhiều cách thì mình thấy có cách sau là hay nên chia sẽ với các bạn. Cái đặc biệt của code này đó là bạn tạo luôn fixed TOC nhé, nghĩa là sau khi kéo bài xuống dưới để đọc thì cái mục lục sẽ thu gọn và hiển thị biểu tượng để bạn có thể mở lại mục lục bài viết khi cần. Nào cùng đi xem code nó thế nào nhé.
Code sẽ có 3 phần đó là định dạng HTML, CSS và jQuery, sau đây là code của các phần đó.
Đầu tiên là mã HTML
HTML code
<div class="widget-toc">
<div class="toc-title">
<div class="toc_title_inside">Mục lục</div>
<div class="toc_title_inside toc_close">Đóng</div>
</div>
<ol>
<li><a href="#1.+Lịch+sử+ra+đời+của+ô+tô+mui+trần">1. Lịch sử ra đời của ô tô mui trần</a></li>
<li><a href="#2.+Những+mẫu+xe+mui+trần+cổ+điển+trên+thế+giới">2. Những mẫu xe mui trần cổ điển trên thế giới</a>
<ol>
<li><a href="#2.1.+Ford+Model+T+1908">2.1. Ford Model T 1908</a></li>
<li><a href="#2.2.+Peugeot+402+Éclipse+Décapotable+1936">2.2. Peugeot 402 Éclipse Décapotable 1936</a></li>
<li><a href="#2.3.+Mercedes+300SL+1957">2.3. Mercedes 300SL 1957</a></li>
<li><a href="#2.4.+Cadillac+Eldorado+1959">2.4. Cadillac Eldorado 1959</a></li>
<li><a href="#2.5.+Lotus+Elan+1963">2.5. Lotus Elan 1963</a></li>
<li><a href="#2.6.+Ford+Mustang+Convertible+1965">2.6. Ford Mustang Convertible 1965</a></li>
<li><a href="#2.7.+Jaguar+E-Type+Series+1">2.7. Jaguar E-Type Series 1</a></li>
<li><a href="#2.8.+Alfa+Romeo+Spider+1969">2.8. Alfa Romeo Spider 1969</a></li>
<li><a href="#2.9.+Mercury+Cougar+XR-7+Convertible+351+1969">2.9. Mercury Cougar XR-7 Convertible 351 1969</a></li>
<li><a href="#2.10.+Buick+Riviera+Convertible+1982">2.10. Buick Riviera Convertible 1982</a></li>
</ol>
</li>
</ol>
</div>
Tiếp đến là mã CSS
Ví dụ
/* Table of content */
html {
scroll-behavior: smooth;
}
.widget-toc {
display: block;
overflow: hidden;
border: 1px solid #1F2125;
background-color: #ffffff;
width: 100%;
margin: 30px 0 20px 0;
font-size: 95%;
border-radius: 3px;
-webkit-transition: height 0.3s;
-moz-transition: height 0.3s;
-ms-transition: height 0.3s;
-o-transition: height 0.3s;
transition: height 0.3s;
}
.widget-toc>ol {
margin-top: 0;
margin-bottom: 0;
padding-top: 20px;
padding-bottom: 20px;
padding-right: 40px;
background-color: #ffffff;
position: relative;
display: none;
border-radius: 3px;
max-height: 300px;
overflow: auto;
}
.widget-toc>ol>li:not(:last-child) {
margin-bottom: 20px;
}
.widget-toc>ol>li>a {
color: #1F2125;
font-weight: 700;
font-size: 16px;
}
.widget-toc>ol>li>ol,
.widget-toc>ol>li>ol ol {
padding-left: 15px;
}
.widget-toc>ol>li>ol>li>a,
.widget-toc a {
color: #1F2125;
transition: 0.3s;
}
.widget-toc>ol>li>ol>li>ol a {
font-size: 12px;
}
.widget-toc a:hover {
color: #F39F2D;
}
.widget-toc.open {
height: auto;
}
.widget-toc ol li {
display: block;
position: relative;
}
.toc-title {
text-align: center;
font-weight: 700;
margin: 0;
padding: 0;
cursor: pointer;
}
.toc-title .toc_title_inside {
text-align: left;
height: 40px;
display: flex;
align-items: center;
padding: 0 20px 0 50px;
font-size: 13px;
position: relative;
background-color: #ffffff;
color: #1F2125;
}
.toc-title .toc_title_inside.toc_close,
.widget-toc.sticky.open .toc-title .toc_title_inside,
.widget-toc.sticky .toc-title .toc_title_inside.toc_close {
display: none;
}
.widget-toc.sticky.open .toc-title .toc_title_inside.toc_close {
display: flex;
}
.toc-title .toc_title_inside::before {
content: "";
position: absolute;
background-image: url(table_of_content_icon.svg);
background-repeat: no-repeat;
background-size: contain;
background-position: center;
margin-bottom: 5px;
width: 20px;
height: 20px;
left: 20px;
}
.toc-title .toc_title_inside.toc_close::before {
background-image: url(x.svg);
}
.toc-title .toc_title_inside::after {
content: "";
position: absolute;
background-image: url(arrow_down.svg);
background-repeat: no-repeat;
background-size: contain;
width: 14px;
height: 7px;
right: 20px;
-webkit-transition: 0.3s;
-moz-transition: 0.3s;
-ms-transition: 0.3s;
-o-transition: 0.3s;
transition: 0.3s;
}
.widget-toc.open .toc-title .toc_title_inside::after {
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
-ms-transform: rotate(180deg);
-o-transform: rotate(180deg);
transform: rotate(180deg);
}
.widget-toc.sticky {
position: fixed;
top: 152px;
left: 100px;
width: 560px;
max-height: 546px;
background-color: transparent;
padding: 0;
border: 0;
overflow: unset;
margin: 0;
z-index: 1;
-webkit-transition: unset;
-moz-transition: unset;
-ms-transition: unset;
-o-transition: unset;
transition: unset;
}
.widget-toc.sticky.force_none {
height: 0!important;
}
.widget-toc.sticky.open {
background-color: #ffffff;
}
.widget-toc.sticky.open::before {
content: "";
background-color: rgb(0 0 0 / 50%);
position: fixed;
height: 100vh;
width: 100vw;
top: 0;
left: 0;
}
.widget-toc.sticky .toc-title {
position: absolute;
height: 70px;
width: 70px;
left: -80px;
box-shadow: 1px 1px 1px #b2b1b1;
}
.widget-toc.sticky .toc-title .toc_title_inside {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 0;
height: 70px;
width: 70px;
background-color: #ffffff;
border-radius: 3px;
}
.widget-toc.sticky .toc-title .toc_title_inside::after {
display: none;
}
.widget-toc.sticky .toc-title .toc_title_inside::before {
position: relative;
left: unset;
}
@media only screen and (max-width: 1300px) {
.widget-toc.sticky {
left: 20%;
}
}
@media only screen and (max-width: 1024px) {
.widget-toc.sticky {
left: 100px;
}
}
@media only screen and (max-width: 480px) {
.widget-toc.sticky {
left: 15px;
width: calc(100% - 30px);
top: 232px;
}
.widget-toc.sticky .toc-title {
left: 0px;
top: -80px;
}
}
Ảnh trong file CSS này các bạn có thể tải ở đây: table_of_content_icon.svg x.svg arrow_down.svg
Cuối cùng là mã JQuery
Ví dụ
jQuery(document).ready(function () {
// Table of contents
if (jQuery('.widget-toc').length) {
jQuery('.widget-toc .toc-title, .widget-toc a').on('click', function (event) {
if (jQuery('.widget-toc.open').length) {
jQuery('.widget-toc').removeClass('open');
jQuery('.widget-toc > ol').slideUp(300);
} else {
jQuery('.widget-toc').addClass('open');
jQuery('.widget-toc > ol').slideDown(300);
}
});
jQuery(window).scroll(function () {
if (window.pageYOffset > jQuery('.widget-toc').parent().offset().top) {
if (!jQuery('.widget-toc').hasClass('sticky')) {
jQuery('.widget-toc > ol').css('display', 'none');
jQuery('.widget-toc').removeClass('open');
}
jQuery('.widget-toc').addClass('sticky');
} else {
jQuery('.widget-toc').removeClass("sticky");
}
});
}});
Trên đây là toàn bộ mã để tạo mục lục (Fixed TOC) cho bài viết trong khi thiết kế trang web. Hy vọng bài viết đã giúp được bạn!