Hướng dẫn css timeline vertical

Vietnamese [Tiếng Việt] translation by Dai Phong [you can also view the original English article]

Trong hướng dẫn này, chúng ta sẽ tìm hiểu cách xây dựng một timeline đứng từ đầu cho đến cuối. Trước tiên, chúng ta sẽ tạo cấu trúc cơ bản với mã ít mã html nhất và tận dụng sức mạnh của phần tử giả CSS. Sau đó, chúng ta sẽ sử dụng một số JavaScript để thêm một số hiệu ứng chuyển tiếp như khi chúng ta cuộn trang xuống.

Hãy xem trước những gì chúng ta sẽ xây dựng [kiểm tra phiên bản lớn hơn trên CodePen].

1. Mã đánh dấu HTML

Mã đánh dấu mà chúng ta sẽ sử dụng là khá đơn giản; một danh sách không thứ tự đơn giản với một phần tử div bên trong mỗi mỗi phần tử của danh sách. Khi chúng ta làm việc với các sự kiện dọc theo một timeline, chúng ta sẽ cung cấp cho mỗi phần tử của danh sách một phần tử time để hiển thị năm.

Ngoài ra, chúng ta sẽ bao quanh toàn bộ mọi thứ bên trong một phần tử section với tên lớp là timeline:

  • 1934 Some content here

Điều này cho chúng ta kết quả chưa định hình phong cách như dưới đây:

2. Thêm các phong cách CSS ban đầu

Sau một số màu cơ bản, vân vân [xem phần trên của CSS pen dưới đây], chúng ta sẽ xác định một số thuộc tính cấu trúc CSS cho các phần tử danh sách. Chúng ta cũng sẽ định phong cách cho phần tử giả ::after của các phần tử này:

.timeline ul li {
  list-style-type: none;
  position: relative;
  width: 6px;
  margin: 0 auto;
  padding-top: 50px;
  background: #fff;
}

.timeline ul li::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translateX[-50%];
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: inherit;
}

Tôi đã xoá nội dung trong các phần tử của danh sách để đảm bảo bước này rõ ràng hơn, mang lại cho chúng ta những điều sau đây:

3. Các phong cách cho phần tử Timeline

Bây giờ chúng ta hãy định phong cách phần tử div [chúng ta sẽ gọi chúng là "các phần tử timeline" từ giờ trở đi] là một phần của các phần tử của danh sách. Một lần nữa, chúng ta định phong cách phần tử giả ::before của các phần tử này.

Ngoài ra, như chúng ta sẽ thấy trong một lúc nữa, không phải tất cả phần tử div đều chia sẻ chung một phong cách. Cảm ơn các phần tử giả CSS :nth-child[odd] và :nth-child[even], giúp chúng ta có thể tách riêng các phong cách khác nhau của chúng.

Hãy xem các thuộc tính CSS tương ứng dưới đây:

.timeline ul li div {
  position: relative;
  bottom: 0;
  width: 400px;
  padding: 15px;
  background: #F45B69;
}

.timeline ul li div::before {
  content: '';
  position: absolute;
  bottom: 7px;
  width: 0;
  height: 0;
  border-style: solid;
}

Sau đó một số phong cách cho các phần tử lẻ của chúng ta:

.timeline ul li:nth-child[odd] div {
  left: 45px;
}

.timeline ul li:nth-child[odd] div::before {
  left: -15px;
  border-width: 8px 16px 8px 0;
  border-color: transparent #F45B69 transparent transparent;
}

Sau cùng, là các phong cách cho các phần tử chẵn:

.timeline ul li:nth-child[even] div {
  left: -439px;
}

.timeline ul li:nth-child[even] div::before {
  right: -15px;
  border-width: 8px 0 8px 16px;
  border-color: transparent transparent transparent #F45B69;
}

Với những thuộc tính này đã sẵn sàng [và HTML của chúng ta một lần nữa đã có nội dung] timeline của chúng ta trông như sau:

Sự khác nhau chính giữa các thẻ div "lẻ" và "chẵn" là vị trí của chúng. Những cái đầu tiên có left: 45px; trong khi những cái thứ hai left: -439px;. Để hiểu vị trí của các thẻ div chẵn của chúng ta, hãy làm một số công thức toán học đơn giản:

Chiều rộng của mỗi div + khoảng cách mong muốn - Chiều rộng của mỗi phần tử của danh sách = 400px + 45px -6px = 439px

Sự khác biệt thứ hai, ít quan trọng hơn là tạo mũi tên bằng phần tử giả của chúng. Điều đó có nghĩa là, các phần tử giả của mỗi div "lẻ" có một mũi tên hướng về bên trái, trong khi các phần tử giả của các div "chẵn" sẽ hiển thị như một mũi tên hướng về bên phải.

4. Thêm tương tác

Bây giờ thì cấu trúc cơ bản của timeline đã sẵn sàng, hãy xem xét những yêu cầu mới:

  • Mặc định, các phần tử của timeline [div] sẽ được ẩn.
  • Chúng sẽ xuất hiện khi phần tử cha của chúng [phần tử của dánh sách] đi vào viewport.

Nhiệm vụ đầu tiên là tương đối đơn giản. Dù vậy, cái thứ hai, phức tạp hơn một chút. Chúng ta cần phải xác định nếu các phần tử mục tiêu [các phần tử của danh mục] là hoàn toàn hiển thị trong viewport hiện tại, sau đó nếu điều đó xảy ra chúng ta hiển thị phần tử con của chúng. Để cài đặt tính năng này, chúng ta sẽ không sử dụng bất kỳ thư viện JavaScript bên ngoài nào [ví dụ như WOW.js hoặc ScrollReveal.js] hoặc viết mã riêng của chúng ta, khá phức tạp. Rất may là có một chủ đề rất phổ biến trên StackOverlow về vấn đề này. Vì vậy, trước tiên chúng ta hãy tận dụng lợi thế của câu trả lời được đề xuất để kiểm tra xem một phần tử được nhìn thấy trong viewport hiện tại hay không.

Dưới đây là hàm được đơn giản hoá mà chúng ta sẽ sử dụng:

function isElementInViewport[el] {
  var rect = el.getBoundingClientRect[];
  return [
    rect.top >= 0 &&
    rect.left >= 0 &&
    rect.bottom 

Chủ Đề