Tại sao khoảng cách cột của tôi lại nhỏ hơn khi tôi tăng chiều rộng của vùng chứa?
Tôi đang gặp khó khăn trong việc hiểu logic đằng sau khoảng cách cột trong bố cục nhiều cột. Tôi có HTML / CSS sau trong Fiddle này :
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
</div>
.flex-container {
height: 500px;
width: 300px;
border: 1px solid blue;
columns: 120px;
padding: 10px;
}
.flex-item {
background: OliveDrab;
padding: 5px;
width: 100px;
height: 100px;
line-height: 100px;
color: white;
text-align: center;
break-inside: avoid-column;
}
Bạn sẽ nhận thấy rằng nếu bạn thay đổi vùng width
chứa từ 300px thành 400px, khoảng cách giữa các cột sẽ thực sự thu hẹp lại.
Tại sao nó làm điều này? Có thể căn trái các cột để chúng không di chuyển xung quanh không? Khoảng cách cố định giữa các cột CSS có thể cho thấy điều đó là không thể.
Trả lời
Bố cục cột hơi phức tạp. Nếu bạn đọc thông số kỹ thuật liên quan đến column-width
bạn có thể tìm thấy:
mô tả chiều rộng cột tối ưu. Chiều rộng thực tế của cột có thể rộng hơn (để lấp đầy không gian có sẵn) hoặc hẹp hơn (chỉ khi không gian có sẵn nhỏ hơn chiều rộng cột được chỉ định). ref
Loại bỏ chiều rộng khỏi các phần tử và thay đổi kích thước vùng chứa để nhận thấy điều này:
.flex-container {
width: 400px;
border: 1px solid blue;
columns: 120px;
padding: 10px;
overflow:hidden;
resize:horizontal;
}
.flex-item {
background: OliveDrab;
padding: 5px;
height: 100px;
line-height: 100px;
color: white;
text-align: center;
break-inside: avoid-column;
}
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
</div>
Bạn sẽ nhận thấy rằng khoảng cách thực sự là cố định nhưng chiều rộng của các cột đang thay đổi.
Bạn có thể tìm thêm chi tiết về thuật toán tại đây: https://drafts.csswg.org/css-multicol-1/#pseudo-algorithm
Một giải pháp là xem xét việc sử dụng lưới CSS có chiều rộng cột cố định. Mẹo là xác định chiều rộng của cột lưới bằng khoảng cách + chiều rộng của cột và bạn làm cho vùng chứa của bạn lấp đầy tất cả các cột (chiều rộng của nó sẽ là nhân của khoảng cách + chiều rộng của cột )
Thay đổi kích thước màn hình để xem kết quả:
.container {
display:grid;
grid-template-columns:repeat(auto-fit,140px); /* 120 + 20 */
overflow: hidden;
resize: horizontal;
border: 1px solid blue;
}
.flex-container {
grid-column:1/-1;
column-width: 120px;
column-gap: 20px;
padding: 10px;
}
.flex-item {
background: OliveDrab;
padding: 5px;
height: 100px;
line-height: 100px;
color: white;
text-align: center;
break-inside: avoid-column;
}
<div class="container">
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
<div class="flex-item">9</div>
<div class="flex-item">10</div>
</div>
</div>
Nếu bạn không chỉ định số cột (tham số thứ hai cho các cột) thì hệ thống sẽ tính ra số cột có thể (nghĩa là nó lấy tự động làm tham số đếm cột).
Bạn đã chỉ định chiều rộng cột 'lý tưởng' là 120px và các mục thực tế có chiều rộng nhỏ hơn chiều rộng đó. Do đó, hệ thống tính toán rằng bạn có thể lấy 3 cột vào vùng chứa có chiều rộng 400px và đặt hai cột đầu tiên tương ứng.
Đây là một số thông tin từ https://developer.mozilla.org/en-US/docs/Web/CSS/column-width
Thuộc tính CSS chiều rộng cột đặt chiều rộng cột lý tưởng trong bố cục nhiều cột. Vùng chứa sẽ có nhiều cột phù hợp nhất có thể mà không có cột nào trong số chúng có chiều rộng nhỏ hơn giá trị chiều rộng cột. Nếu chiều rộng của vùng chứa hẹp hơn giá trị được chỉ định, chiều rộng của cột đơn sẽ nhỏ hơn chiều rộng cột đã khai báo.
Nếu bạn muốn đảm bảo chỉ có hai cột thì hãy cung cấp tham số thứ hai:
columns: 120px 2;
.flex-container {
height: 500px;
width: 400px;
border: 1px solid blue;
columns: 120px 2;
padding: 10px;
}
.flex-item {
background: OliveDrab;
padding: 5px;
width: 100px;
height: 100px;
line-height: 100px;
color: white;
text-align: center;
break-inside: avoid-column;
}
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
</div>