[CSS] Snake layout – Làm thế nào để tạo layout dạng con rắn

2 min read

Snake layout là gì?

Snake layout (hay còn gọi là chain layout) là layout mà các block của 1 hàng khi đạt đến số lượng giới hạn nào đó nó sẽ bị wrap xuống nhưng đặc biệt là block của hàng tiếp theo phải ở ngay dưới block của hàng trước đó. Nên các block sẽ uốn lượn như 1 con rắn như cái hình to đùng ở trên.

Xử lý bằng Flex box

Mình nghĩ cách đơn giản nhất là bọc mỗi hàng vào 1 container, hàng lẻ sẽ được sắp xếp theo thứ tự từ trái qua phải như bình thường, hàng chẵn sẽ được sắp xếp theo thứ tự ngược lại.

Vậy ở đây chúng ta sẽ sử dụng flex box cho mỗi container. Chúng ta sẽ select các container ở vị trí chẵn và đảo ngược thứ tự của những element con.

<div class="snakeContainer">
  <div>
    <span>1</span>
    <span>2</span>
    <span>3</span>
    <span>4</span>
  </div>
  <div>
    <span>5</span>
    <span>6</span>
    <span>7</span>
    <span>8</span>
  </div>
  <div>
    <span>9</span>
    <span>10</span>
    <span>11</span>
    <span>12</span>
  </div>
</div>

<style>
.snakeContainer div:nth-child(even){
  display: flex;
  flex-direction: row-reverse; /*đảo chiều*/
  justify-content: flex-end;
}

.snakeContainer div:nth-child(odd){
  display: flex;
}
</style>

Xử lý bằng Grid box

Hmm, có vẻ dùng flex cũng đơn giản nhưng mà cứ mỗi hàng mình phải bọc trong 1 container. Có cách nào mà không cần bọc từng hàng mà vẫn xử lý được trường hợp này không nhỉ?

Câu trả lời là có, mình sẽ sử dụng grid.

  • Đầu tiên, mình xác định 1 hàng có bao nhiêu element. Ví dụ 1 hàng có 4 element.
  • Vậy cứ mỗi 4 element thì mình sẽ đảo chiều 4 element tiếp theo.
  • Chúng ta sẽ sử dụng property grid-column để sắp xếp lại thứ tự của element.
  • Cho n >= 0, Element ở vị trí (8n+5) (element đầu tiên của hàng chẵn) sẽ được đặt ở vị trí cuối cùng từ trái qua phải (grid-column: 4), Element tiếp theo ở vị trí (8n+6) sẽ được đặt ở vị trí áp cuối (grid-column: 4). Cứ như vậy cho đến element (8n+8) (element cuối cùng của hàng chẵn) sẽ ở vị trí đầu tiên (grid-column: 1).

*note: property grid-column sẽ tạo 1 hàng mới cho element đó nên phải dùng grid-auto-flow: dense; để tự động lấp lại những khoảng trống nếu không thì sẽ như hình dưới

<div class="snakeContainer">
    <span>1</span>
    <span>2</span>
    <span>3</span>
    <span>4</span>
    <span>5</span>
    <span>6</span>
    <span>7</span>
    <span>8</span>
    <span>9</span>
    <span>10</span>
    <span>11</span>
    <span>12</span>
</div>

<style>
.snakeContainer {
  display:grid;
  grid-auto-flow: dense; /*Lấp lại những ví trí trống*/
}

.snakeContainer > span:nth-child(8n + 5) { grid-column:4; }
.snakeContainer > span:nth-child(8n + 6) { grid-column:3; }
.snakeContainer > span:nth-child(8n + 7) { grid-column:2; }
.snakeContainer > span:nth-child(8n + 8) { grid-column:1; }
</style>

Ref:

Avatar photo

Dựng front-end bằng Clean Architecture

Khi nhắc đến Clean Architecture, nhiều người thường chỉ nghĩ đến backend – nơi cần cấu trúc rõ ràng để quản lý nghiệp vụ...
Avatar photo Toan Nguyen Thai
5 min read

Khám phá Monorepo: Cách bứt phá quản lý mã…

Trong thế giới phát triển phần mềm hiện đại, việc quản lý mã nguồn đang trở nên phức tạp hơn bao giờ hết. Các...
Avatar photo dan.nguyenhai@ncc.asia
4 min read

Leave a Reply

Your email address will not be published. Required fields are marked *