flex 佈局 自適應 靠左對齊

需求

假設我有5個300px*300px的卡片,須要根據屏幕寬度自適用平鋪排列,並在換行的時候靠左對齊。css

不能用js實現,用js就太簡單了,並且代碼會比較囉嗦和讓人困擾。 html

需求

核心知識

  • 利用flex容器的justify-content: flex-startflex-wrap: wrap完成自動換行靠左需求
  • 利用calc和margin-left完成子項目平鋪需求

單單利用justify-content: space-evenly完成不了需求

直覺上,利用這個屬性和wrap就能夠知足,但實際上不能夠,由於會每行各自計算空隙,這樣會致使最後一行對不齊,效果以下瀏覽器

space-evenly

利用flex-startmargin-left: calc實現

1. 數學公式

flex-start能夠知足咱們靠左對齊的需求。接下來,咱們只要完成間距的需求就能夠了。子項目寬度是固定的300px,那麼根據容器的寬度,確定就能計算出來間距了,例如寬1000px的容器,那確定只能容納3個子項目,剩餘100px空間,一個四個空隙,那每一個空隙就是25px。bash

  • conWidth 容器寬度
  • itemWidth 子項目寬度
  • 每行子項目個數 n = Math.floor(conWidth/itemWidth)
marginLeft
= \frac {conWidth - n \times itemWidth}{n + 1}
= \frac {conWidth - Math.floor(conWidth/itemWidth) \times itemWidth}{Math.floor(conWidth/itemWidth) + 1}

嗯,貌似是搞定了,咱們轉化成css中calc就是:佈局

margin-left: calc((100% - Math.floor(100% / 300px) * 300px) / Math.floor(100% / 300px))
複製代碼

可是,calc根本不支持這樣:flex

  • calc沒有Math.floor方法
  • calc中除法後面必須是數字

2. 利用@media 媒體查詢解決每行個數問題

既然沒法經過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));
複製代碼

3. 最終代碼

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; } /* 最多一行顯示五個 */
}

複製代碼

經過縮放瀏覽器觀察,已經實現自適用屏幕寬度了。

自適用

1. float佈局也能夠這樣解決

思路同樣,可是flex的其餘特性就使用不了了

2. 若是沒法使用css中的var,例如ie瀏覽器

那就只要把margin-left總體寫到@media 媒體查詢裏便可

3. 使用grid佈局更簡單

若是使用grid佈局,calc都不須要用到了,只要在@media中寫好grid樣式,在不一樣寬度下有不一樣列數便可 請看個人另一篇文章

4. 能夠簡化公式

直接每一個項目寬度 100% / n 便可,可是那樣html代碼就會很囉嗦,每一個子項目都須要再套一層,做爲真正的flex項目使用。

相關文章
相關標籤/搜索