假設我有5個300px*300px的卡片,須要根據屏幕寬度自適用平鋪排列,並在換行的時候靠左對齊。css
不能用js實現,用js就太簡單了,並且代碼會比較囉嗦和讓人困擾。 html
justify-content: flex-start
和flex-wrap: wrap
完成自動換行靠左需求justify-content: space-evenly
完成不了需求直覺上,利用這個屬性和wrap就能夠知足,但實際上不能夠,由於會每行各自計算空隙,這樣會致使最後一行對不齊,效果以下瀏覽器
flex-start
和margin-left: calc
實現flex-start
能夠知足咱們靠左對齊的需求。接下來,咱們只要完成間距的需求就能夠了。子項目寬度是固定的300px,那麼根據容器的寬度,確定就能計算出來間距了,例如寬1000px的容器,那確定只能容納3個子項目,剩餘100px空間,一個四個空隙,那每一個空隙就是25px。bash
嗯,貌似是搞定了,咱們轉化成css中calc就是:佈局
margin-left: calc((100% - Math.floor(100% / 300px) * 300px) / Math.floor(100% / 300px))
複製代碼
可是,calc根本不支持這樣:flex
既然沒法經過calc直接計算出來n,那就想辦法跳過這一步。這樣咱們只須要完成左邊的公式就好了。spa
嗯,由於咱們子項目是定寬的300px,那麼:容器少於900px,就只能放2個,少於1200px,就只能放3個。。。。 多寫幾個相似下面的媒體查詢就能夠了3d
@media screen and (max-width: 1200px) and (min-width: 900px) {
item { --n: 3; }
}
複製代碼
而後咱們的margin-left
就能夠簡化成以下calc支持的左邊的公式了code
margin-left: calc((100% - var(--itemWidth) * var(--n)) / (var(--n) + 1));
複製代碼
htmlcdn
<div class="container">
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
/div>
複製代碼
css
.container {
background: gold;
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
}
item {
outline: 1px solid black;
height: 300px;
background: red;
margin-top: 20px;
--itemWidth: 300px; /* 和項目寬度一致 */
width: calc(var(--itemWidth));
margin-left: calc((100% - var(--itemWidth) * var(--n)) / (var(--n) + 1));
}
@media screen and (max-width: 900px) {
item { --n: 2; }
}
@media screen and (max-width: 1200px) and (min-width: 900px) {
item { --n: 3; }
}
@media screen and (max-width: 1500px) and (min-width: 1200px) {
item { --n: 4; }
}
@media screen and (max-width: 8888px) and (min-width: 1500px) {
item { --n: 5; } /* 最多一行顯示五個 */
}
複製代碼
經過縮放瀏覽器觀察,已經實現自適用屏幕寬度了。
思路同樣,可是flex的其餘特性就使用不了了
那就只要把margin-left總體寫到@media 媒體查詢裏便可
若是使用grid佈局,calc都不須要用到了,只要在@media中寫好grid樣式,在不一樣寬度下有不一樣列數便可 請看個人另一篇文章
直接每一個項目寬度 100% / n 便可,可是那樣html代碼就會很囉嗦,每一個子項目都須要再套一層,做爲真正的flex項目使用。