12/08/2018, 15:51

Tạo Menu Hamburger Morphing với CSS mà không cần sử dụng JavaScript

Trong hướng dẫn này tôi sẽ giải thích toàn bộ quá trình tạo Menu Hamburger Morphing với CSS mà không dùng 1 dòng nào JavaScript. Vì vậy, tôi sẽ sử dụng CSS (và SCSS) để tạo ra nó. Đây là CodePen của những gì chúng ta sẽ xây dựng: Cấu trúc HTML Chúng ta sẽ sử dụng cấu trúc HTML dưới đây : ...

Trong hướng dẫn này tôi sẽ giải thích toàn bộ quá trình tạo Menu Hamburger Morphing với CSS mà không dùng 1 dòng nào JavaScript. Vì vậy, tôi sẽ sử dụng CSS (và SCSS) để tạo ra nó. Đây là CodePen của những gì chúng ta sẽ xây dựng:

Cấu trúc HTML

Chúng ta sẽ sử dụng cấu trúc HTML dưới đây :

<div class="container">
    <input id="toggle" type="checkbox">
    <label class="toggle-container" for="toggle">
        <span class="button button-toggle"></span>
    </label>

    <nav class="nav">
        <a class="nav-item" href="">Dashboard</a>
        <a class="nav-item" href="">History</a>
        <a class="nav-item" href="">Statistics</a>
        <a class="nav-item" href="">Settings</a>
    </nav>
</div>

Bắt đầu Style

Bước đầu chúng ta sẽ thêm một số style cơ bản để tạo cảm giác dễ nhìn.

/* Basic styles */

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
}

body {
  font-family: sans-serif;
  background-color: #F6C390;
}

a {
  text-decoration: none;
}

.container {
  position: relative;
  margin: 35px auto 0;
  awidth: 300px;
  height: 534px;
  background-color: #533557;
  overflow: hidden;
}

Toggle

Trước khi bắt đầu xây dựng phần còn lại của giao diện, chúng ta hãy thêm chức năng toggle để dễ dàng thay đổi từ trạng thái này sang trạng thái khác. HTML chúng ta cần đã được áp dụng, và style để làm cho nó hoạt động như thế này:

//  cho ẩn khi chưa checked
#toggle {
  display: none;
}
// Style cho trường hợp checked
#toggle:checked {
  & ~ .nav {
  }
}

Tạo menu đóng

Để tạo được menu đóng chúng ta cần transform các item thành các dòng để tạo nên biểu tượng hamburger menu icon.

và dưới đây là style cho nó hoạt động :

$transition-duration: 0.5s;

// Showing nav items as lines, making up the hamburger menu icon
.nav-item {
  position: relative;
  display: inline-block;
  float: left;
  clear: both;
  color: transparent;
  font-size: 14px;
  letter-spacing: -6.2px;
  height: 7px;
  line-height: 7px;
  text-transform: uppercase;
  white-space: nowrap;
  transform: scaleY(0.2);
  transition: $transition-duration, opacity 1s;

  // Adjusting awidth for the first line
  &:nth-child(1) {
    letter-spacing: -8px;
  }

  // Adjusting awidth for the second line
  &:nth-child(2) {
    letter-spacing: -7px;
  }

  // Adjusting from the fourth element onwards
  &:nth-child(n + 4) {
    letter-spacing: -8px;
    margin-top: -7px;
    opacity: 0;
  }

  // Getting the lines for the hamburger menu icon
  &:before {
    position: absolute;
    content: ';
    top: 50%;
    left: 0;
    awidth: 100%;
    height: 2px;
    background-color: #EC7263;
    transform: translateY(-50%) scaleY(5);
    transition: $transition-duration;
  }
}

Lưu ý rằng ở đây tôi đã đăng chỉ các style chính cho các items nav, đó là phần quan trọng nhất. Bạn có thể vào github lấy đầy đủ nhất mã code.

Tạo menu mở

$transition-duration: 0.5s;

#toggle:checked {

  // Open nav
  & ~ .nav {

    // Restoring nav items from "lines" in the menu icon
    .nav-item {
      color: #EC7263;
      letter-spacing: 0;
      height: 40px;
      line-height: 40px;
      margin-top: 0;
      opacity: 1;
      transform: scaleY(1);
      transition: $transition-duration, opacity 0.1s;

      // Hiding the lines
      &:before {
        opacity: 0;
      }
    }
  }
}

Config delay cho item nav

$items: 4;
$transition-delay: 0.05s;

.nav-item {

  // Setting delays for the nav items in close transition
  @for $i from 1 through $items {
    &:nth-child(#{$i}) {
      $delay: ($i - 1) * $transition-delay;
      transition-delay: $delay;
      &:before {
        transition-delay: $delay;
      }
    }
  }
}

Ở đây chúng ta đang sử dụng vòng lặp. Bạn có thể tìm hiểu thêm về những điều này và các tính năng tuyệt vời khác trong trang tài liệu SASS. Chúng ta cần phải tính toán $$elay hơi khác biệt cho animation mở, để có được transition ngược lại. Chỉ như thế này:

$delay: ($items - $i) * $transition-delay;

0