Vietnamese (Tiếng Việt) translation by Dai Phong (you can also view the original English article)
Bài này sẽ hướng dẫn cho bạn cách tạo và thêm hiệu ứng vào biểu tượng menu hamburger và sau đó gắn kết một event listener thông qua jQuery để kích hoạt menu drop-down.
Tôi sẽ sử dụng Jade (Pug) và Sass thay vì HTML và CSS thuần tuý. Vì vậy, ít nhất bạn nên có một kiến thức cơ bản về những templating engine này.
Tạo Playground
Chúng ta sẽ bắt đầu với việc cài đặt một playground đơn giản. Tôi sẽ cung cấp sẵn template Jade cùng với Sass, vì đây không phải là phạm vi của bài hướng dẫn. Bạn có thể lấy và sử dụng nó hoặc bạn có thể tự mình thiết kế.
Tập tin Jade:
body #container #header #body .content .left .right - for (i=1; i <= 5 ; i++ ) div( id="text" + i ) .content .left .right - for (j=6; j <= 10 ; j++ ) div( id="text" + j ) .content .left .right - for (k=11; k <= 15 ; k++ ) div( id="text" + k )
Tập tin Sass:
=flex() display: -webkit-box display: -moz-box display: -ms-flexbox display: -webkit-flex display: flex =transition($time) -webkit-transition: all $time ease -moz-transition: all $time ease -ms-transition: all $time ease -o-transition: all $time ease transition: all $time ease html, body margin: 0 padding: 20px 0 +flex() justify-content: center //----------------------------------// #container width: 320px height: 550px background-color: #ebebeb overflow: hidden #header height: 45px background-color: #9b9b9b position: relative #body padding: 0 20px padding-top: 40px +flex() flex-direction: column justify-content: flex-start .content +flex() flex-direction: row justify-content: flex-start margin-bottom: 25px .left width: 100px height: 100px margin-right: 15px background-color: #e1e1e1 .right @for $i from 1 through 15 #text#{$i} margin-top: 10px width: 50 + random(100) + px height: 10px background-color: #e1e1e1
Lưu ý: Ở đây tôi đã tạo ra hai mixin có tên là flex
và transition
. Mixin giúp dễ dàng sử dụng lại một số quy tắc CSS bằng cách nhóm chúng lại. Bất cứ khi nào tôi cần thêm display:flex
với tất cả các vendor prefix, tôi chỉ cần sử dụng +flex()
, nhờ vào mixin.
Chúng ta sẽ sử dụng cấu trúc này và xây dựng dựa trên nó cho phần còn lại của hướng dẫn.
Kết quả cuối cùng sẽ giống như sau:

Biểu tượng Menu Hamburger
Bây giờ là lúc để tạo ra một menu hamburger đơn giản nhưng hấp dẫn và thêm hiệu ứng vào nó thông qua CSS.
Thêm một div mới bên trong #header
và đặt tên là #hamburger
. Sau đó tạo hai div con bên trong #hamburger
. Chúng sẽ có một lớp thông thường và ID riêng.
#hamburger .strip#top .strip#bottom
Bây giờ chúng ta cần tạo style cho div cha #hamburger
và các div con với lớp .strip
.
#hamburger height: 100% width: 45 +flex() flex-direction: column justify-content: space-between padding-left: 20px
Chúng ta thiết lập chiều cao của div bằng với div cha của nó, đó là #header
, bằng cách định nghĩa height: 100%
. Ngoài ra, chúng ta thiết lập một giá trị width cho div cha này, sẽ xác định vùng "có thể nhấp" của nó.
Tiếp theo, chúng ta thêm flexbox với tất cả vendor prefix bằng cách sử dụng mixin, cái mà chúng ta đã tạo trước đó.
Vì chúng ta muốn các div .strip
của chúng ta đặt theo chiều dọc, chúng ta thiết lập flex-direction: column
và sau đó sử dụng justify-content: space-between
để đặt khoảng trắng giữa các div .strip
.
Sau đó, chúng ta cần đẩy các div đó vào nhau bằng cách thêm padding top và bottom vào các div tương ứng.
#top margin-top: 17px #bottom margin-bottom: 17px
Chúng ta cũng thêm padding-left: 20px
để di chuyển các div .strip
sang bên phải.
Tiếp theo là style các strip. Việc này là tương đối dễ dàng bằng cách định nghĩa kích thước và màu sắc cho các div.
.strip width: 25px height: 2px background-color: #ffffff
Kết quả cuối cùng, biểu tượng menu hamburger sẽ trông giống như sau:

Tiếp theo là thêm hiệu ứng vào biểu tượng menu để khi nó được nhấp vào, nó sẽ chuyển thành dấu chéo.
Thêm hiệu ứng vào biểu tượng Menu Hamburger
Lúc này, chúng ta sẽ sử dụng jQuery cơ bản để chuyển đổi một số lớp CSS.
Trước tiên hãy tạo các lớp CSS để chuyển đổi.
Chúng ta sẽ sử dụng các thiết lập translate và rotate của thuộc tính transform
của CSS cùng với thuộc tính transition
.
Đầu tiên, thêm transition cho cả div #top
và #bottom
bằng cách sử dụng các mixin với một tham số timing cụ thể.
#top margin-top: 17px +transition(.25s) #bottom margin-bottom: 17px +transition(.25s)
Bây giờ chúng ta cần định nghĩa style của các lớp được chuyển đổi.
Chúng ta sẽ lần lượt rotate và translate từng div .strip
, vì vậy chúng ta cần phải chuyển đổi các lớp khác nhau cho cả div #top
và #bottom
.
#top margin-top: 17px +transition(.25s) &.topRotate transform-origin: center transform: translateY(4px) rotateZ(45deg) #bottom margin-bottom: 17px +transition(.25s) &.bottomRotate transform-origin: center transform: translateY(-5px) rotateZ(-45deg)
Ở đây chúng ta định nghĩa các style cho hai lớp khác nhau có tên là .bottomRotate
và .topRotate
, sẽ được thêm vào và xoá bỏ khỏi các div tham chiếu tương ứng của chúng, #top
và #bottom
.
Lưu ý rằng kích thước khác nhau của lớp .strip
sẽ dẫn đến yêu cầu về các giá trị translateY
và rotateZ
khác nhau để tạo hiệu ứng thành dấu chéo thích hợp.
Chuyển đổi lớp Với jQuery
Chúng ta đã định nghĩa cách mỗi mà div .strip
sẽ hoạt hình khi các lớp topRotate
và bottomRotate
có mặt. Tuy nhiên, chúng ta vẫn chưa đính kèm envent listener để chuyển đổi các lớp đó.
Tạo một tập tin JavaScript mới và sử dụng code sau đây để chuyển đổi các lớp topRotate
và bottomRotate
vào các div có ID #top
và #bottom
tương ứng.
$(document).ready(function(){ $("#hamburger").click(function(){ $("#top").toggleClass("topRotate"); $("#bottom").toggleClass("bottomRotate"); }); })
Chúng ta đặt tất cả các code của chúng ta bên trong $(document).ready(function(){})
để chờ cho toàn bộ trang được tải trước khi thực hiện bất kỳ hành động nào.
Khi chúng ta nhấp vào div #hamburger
, nó sẽ chuyển đổi các lớp cho các div với các ID cụ thể.
Lưu ý: Đừng quên thêm tập tin nguồn jQuery vào dự án của bạn.
Tạo danh sách menu
Bước tiếp theo là tạo một menu với các mục.
Sử dụng cấu trúc sau đây ở bên dưới #header
:
#dropDown #background ul li Home li Blog li Projects li Authors li Jobs li Contact
Vì vậy, ở đây chúng ta sử dụng thẻ ul
làm phần tử cha để nhóm các mục với thẻ li
là phần tử con. Hơn nữa, để tạo hiệu ứng nền mở rộng, chúng ta cũng thêm một div có ID là #background
.
Hãy thêm style cho các phần tử ul
và li
trước.
ul list-style: none padding: 0 margin: 0
Thiết lập list-style
thành none
để loại bỏ các biểu tượng đầu dòng khỏi các phần tử ul
và đồng thời thiết lập padding
và margin
thành 0 để loại bỏ tất cả các giá trị được định nghĩa trước.
Bây giờ hãy thêm style cho các phần tử li
:
li //display: none background-color: #9b9b9b color: #ffffff font-family: 'Quicksand', sans-serif font-weight: lighter font-size: 15px padding: 20px padding-left: 60px &:after position: absolute content: '' left: 60px width: 60% height: 1px bottom: 4px background: rgba(255, 255, 255, 0.25) &:last-child:after width: 0
Ở đây tôi comment display:none
để có thể nhìn thấy kết quả. Tuy nhiên, khi hoạt ảnh, chúng ta sẽ sử dụng nó để ẩn các phần tử danh sách ban đầu.
Tôi cũng đã thêm phần tử giả after
và style nó tương ứng để tách riêng từng phần tử li
với một đường thẳng. :last-child:after
xoá bỏ dòng này cho phần tử li
cuối cùng.
Hoạt hình danh sách menu
Bây giờ chúng ta sẽ sử dụng một số chỉ thị điều khiển của Sass để thêm hoạt ảnh keyframe CSS với các thuộc tính khác nhau vào mỗi phần tử li
.
@keyframes drop 0% opacity: 0 transform: scale(1.3) 100% opacity: 1 transform: scale(1) @keyframes fold 0% opacity: 1 transform: scale(1) 100% opacity: 0 transform: scale(0.7)
Ở đây chúng ta định nghĩa các hoạt ảnh keyframe drop
và fold
.
drop
dành cho hoạt ảnh khi mở danh sách menu. Tỷ lệ ban đầu lớn hơn 30% và quay trở lại kích thước ban đầu cũng như độ trong suốt đi từ 0 đến 1. Hành động ngược lại diễn ra trong fold
.
Bây giờ chúng ta cần gắn các keyframe đó vào các phần tử li
. Đây là nhiệm vụ của Sass.
@for $i from 1 through 6 li:nth-child(#{$i}) animation: name: fold duration: 80ms*(6-$i) + 1ms timing-function: ease-in-out fill-mode: forwards li.anim:nth-child(#{$i}) animation: name: drop duration: 100ms*$i timing-function: ease-in-out fill-mode: forwards
Ở đây tôi sử dụng vòng lặp for từ 1 đến 6 với chỉ số $i
.
Bây giờ chúng ta cần sử dụng chỉ mục này để đính kèm mỗi hoạt ảnh vào các phần tử li
với các khoảng thời gian khác nhau.
Trước tiên, hãy xem dòng li.anim:nth-child(#{$i})
.
Ở đây chúng ta đang lấy con thứ $i
của phần tử li
với lớp anim
.
Chúng ta sẽ chuyển đổi lớp anim
này. Vì vậy, khi nó được thêm vào các phần tử li
, hoạt ảnh keyframe có tên drop
sẽ được áp dụng. Khi nó được xóa, hoạt ảnh fold
sẽ được áp dụng.
Điều quan trọng tiếp theo là thuộc tính duration
.
duration: 100ms*$i
cho hoạt ảnh drop
kéo dài thời lượng của hoạt ảnh cho mỗi số con tăng dần. Vì vậy, khi code này được biên dịch, phần tử li
con đầu tiên sẽ có duration: 100ms
và con cuối cùng sẽ có duration: 600ms
.
Điều này sẽ tạo cảm giác phần tử sau hoạt ảnh sau.
Chúng ta làm điều tương tự cho hoạt ảnh fold
. Lần này, phần tử cuối cùng sẽ hoạt ảnh nhanh hơn, do đó duration: 80ms*(6-$i)+1ms
. 1ms thêm vào duration là do thực tế khi bạn thiết lập duration thành 0, một số vấn đề có khả năng xảy ra, và hiệu ứng của bạn có thể không hoạt động đúng.
Khi chúng ta style phần tử li
, tôi đã đề cập rằng chúng ta cần sử dụng display: none
để tránh hoạt ảnh không mong muốn. Nếu bạn không thiết lập nó thành none
, bạn sẽ thấy rằng hoạt ảnh fold
phát một lần khi trang được tải.
Nếu chúng ta thiết lập thuộc tính display
thành none
, chúng ta sẽ không thấy điều đó, và sau đó chúng ta cần hiển thị phần tử li
trước khi chuyển đổi lớp anim
.
Chúng ta muốn hoạt ảnh được phát khi chúng ta nhấp vào biểu tượng hamburger. Vì vậy, hãy sử dụng một số jQuery để thiết lập thuộc tính display
của từng phần tử li
thành block
và đồng thời chuyển đổi lớp anim
.
$(document).ready(function(){ $("#hamburger").click(function(){ $("#top").toggleClass("topRotate"); $("#bottom").toggleClass("bottomRotate"); $("li").show(); $("li").toggleClass("anim"); }); })
Bạn sẽ thấy rằng chúng ta có thể thấy hoạt ảnh của từng phần tử li
riêng lẻ. Tuy nhiên, chúng ta muốn có một cảm giác menu đang mở rộng.
Để khắc phục điều đó, chúng ta chỉ cần mở rộng chiều cao của div. Div đó là #background
, cái mà ban đầu chúng ta đã thêm khi tạo các phần tử ul
và li
.
#background width: 100% height: 0 background-color: #9b9b9b position: absolute +transition(.45s) &.expand height: 550px
Chúng ta sẽ chuyển đổi lớp expand
để thiết lập thuộc tính height
thành 550px
trong vòng .45s
. Lưu ý rằng tôi sử dụng mixin transition
để định nghĩa transition với một tham số thời gian cụ thể.
Phần kết luận
Trong suốt bài hướng dẫn này, chúng ta đã thực hành cách sử dụng vòng lặp for trong HTML và CSS thông qua các công cụ template Jade và Sass. Trên hết, chúng ta đã tạo ra các keyframe CSS và gắn chúng với thuộc tính duration khác nhau vào các phần tử HTML cụ thể. Sau đó, chúng ta chuyển đổi các lớp với jQuery để kiểm soát các hiệu ứng đó.
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post