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: