你有沒有想過 CSS 中的
flex
屬性如何工作? 它是
flex-grow
,
flex-shrink
和
flex-basis
的簡寫。 開發中最常見的寫法是
flex:1
,它表示 flex 項目擴充并填充可用空間。
接下來,我們來詳細看看它表示是什麼意思。
flex-grow 屬性
flex-grow
屬性定義項目的放大比例,預設為
,即如果存在剩餘空間,也不放大。
flex-grow
的值隻接受一個整數。考慮下面代碼:
<div class="wrapper">
<div class="item item-1"></div>
<div class="item item-2"></div>
<div class="item item-3"></div>
</div>
複制
.wrapper {
display: flex;
flex-wrap: wrap;
}
.item {
flex-grow: 1;
}
複制
注意:會影響寬度或高度,具體取決于
flex-grow
屬性。 對于以下示例,預設的
flex-direction
的值都是
flex-direction
。
row
在不使用
flex-grow
的情況下,flex 項目的寬度将預設為其初始寬度。 但是,使用
flex-grow: 1
時,flex 項目會平均剩餘可用的空間。
你可能想知道,flex 項目之間的空間是如何配置設定的?嗯,這是個好問題,稍後會回答。
在下面的圖中,是沒有使用
flex-grow
情況。換句話說,這是它們的自然大小。
要了解 flex 項目寬度的計算方式,可以參考下面的公式。
我們來計算一下文本是
CSS
的項目寬度。
項目寬度 = (( flex-grow / flex-grow 總個數) * 可用空間)+ 初始項目寬度
多個 flex-grow 值
在前面的示例中,所有flex項目的
flex-grow
值都相同。 現在我們把第一項的
flex-grow
值改為
2
。 這們它又是如何計算? 請注意,本示例的可用空間為498px。
上圖已經解釋的很清楚,這裡就不在啰嗦了,還不懂的,可以多看幾次。
可以用 作為 flex-grow
的值嗎?
flex-grow
當然可以!因為
flex-grow
屬性接受整數值,是以可以使用
,可以防止 flex 項目占用可用空間的一種方式。
這在邊界情況下非常有用,我們希望使 flex 項目保持其初始寬度。
flex-grow 不能讓 flex 項目相等
有一個常見的誤解,使用
flex-grow
會使項目的寬度相等。這是不正确的,
flex-grow
的作用是配置設定可用空間。正如在公式中看到的,每 flex 項目的寬度是基于其初始寬度計算的(應用
flex-grow
之前的寬度)。
如果你想讓項目的寬度相等,可以使用
flex-basis
,這個在接下來的部分會對此進行講解。
flex-shrink 屬性
flex-shrink
屬性定義了項目的縮小比例,預設為
1
,即如果空間不足,該項目将縮小。
考慮下面的例子:中間的項目寬度為
300px
,
flex-shrink
的值為
`
。如果沒有足夠的空間來容納所有的項目,則允許項目縮小寬度。
.item-2 {
width: 300px;
flex-shrink: 1;
}
複制
在下列條件下,浏覽器會保持項目寬度為
300px
:
- 所有項目寬度的總和小于包裝器寬度
- 視窗寬度等于或小于項目
下面是項目在不同視口大小下的行為。
如圖所示,在視口寬度大于
300px
時,寬度為
300px
,少于
300px
,該項目的寬度就被壓縮成跟視口一樣的寬度。
大家都說履歷沒項目寫,我就幫大家找了一個項目,還附贈【搭建教程】。
flex-basis 屬性
flex-basis
屬性定義了在配置設定多餘空間之前,項目占據的主軸空間(main size)。浏覽器根據這個屬性,計算主軸是否有多餘空間。它的預設值為
auto
,即項目的本來大小。
flex-basis
可以設為跟
width
或
height
屬性一樣的值(比如350px,預設值為
auto
),則項目将占據固定空間。
.item-1 {
flex-grow: 0;
flex-shrink: 0;
flex-basis: 50%;
}
複制
在上面的例子中,第一項的寬度為
50%
。這裡需要将
flex-grow
重置為0,以防止項目寬度超過
50%
。
如果将
flex-basis
設定為
100%
,會怎麼樣?該項目單獨占一行,其他項目将換行。
flex 屬性
flex
屬性是
flex-grow
,
flex-shrink
和
flex-basis
的簡寫,預設值為
0 1 auto
。後兩個屬性可選。這也說 flex 項目會根據其内容大小增長
flex 項目相對大小
.item {
/* 預設值,相當于 flex:1 1 auto */
flex: auto;
}
複制
flex 項目的大小取決于内容。是以,内容越多的flex項目就會越大。
flex 項目絕對大小
相反,當
flex-basis
屬性設定為
時,所有
flex
項目大小會保持一緻。
.item {
/* 相當于 flex: 1 1 0% */
flex: 1;
}
複制
我喜歡 flex 屬性的幾個點!
顧名思義,此屬性可以靈活使用其值。 請看下面的例子。
一個值的情況
.item {
flex: 1;
}
複制
上面預設對應的值是
1 1 0
,也就是
flex-grow: 1,flex-shrink:1, flex-basic: 0
。
兩個值的情況
.item {
flex: 1 1;
}
複制
上面對應的值是
1 1 0
,也就是
flex-grow: 1,flex-shrink:1, flex-basic: 0
。
一個長度值
如果 flex 值是一個長度值,這會作用于
flex-basis
。
flex-grow
和
flex-shrink
預設為
1
。
.item {
flex: 100px;
/* flex: 1 1 100px */
}
複制
使用無機關
有時,你想把
felx-basis
設定為
,你可能會這樣寫:
.item {
flex: 0;
}
複制
不建議這樣做,因為讓開發人員和浏覽器感到困惑。 你到底是要把
flex-grow
或者
flex-shirnk
設定為
,還是将 flex-basis 設定為
。
是以,你應該添加一個機關,如
px
或
%
。
.item {
flex: 0%;
/* flex: 1 1 0% */
}
複制
建議使用 flex 簡寫屬性
當你需要設定
grow
、
shrink
和
basis
時,最好使用
flex
屬性來實作這個目的。
根據 CSS 規範:
建議開發者使用 `flex` 簡寫來控制靈活性,而不是直接使用它的普通屬性,因為簡寫的可以正确地重置任何未指定的元件以适應常見情景。
複制
flex 用例
使用者頭像
flexbox 的一個常見用例是使用者元件,頭像和文本内容應該在同一行。
<div class="user">
<img class="user__avatar" src="shadeed.jpg" alt="" />
<div>
<h3>Ahmad Shadeed</h3>
<p>Author of Debugging CSS</p>
</div>
</div>
複制
.user {
display: flex;
flex-wrap: wrap;
align-items: center;
}
.user__avatar {
flex: 0 0 70px;
width: 70px;
height: 70px;
}
複制
上面為
頭像
添加了
flex:0 0 70px
。 如果這裡不這樣設定,在某些舊版浏覽器,圖像看起來像被壓縮的一樣。 除此之外,
flex
的優先級高于
width
屬性(
flex-direction: row
)或
height
(flex-direction:
column
)。
如果我們僅通過調整
flex
屬性來改變頭像的大小,那麼
width
将被浏覽器忽略。
.user__avatar {
/* width 是 100px, 不是 70px */
flex: 0 0 100px;
width: 70px;
height: 70px;
}
複制
大家都說履歷沒項目寫,我就幫大家找了一個項目,還附贈【搭建教程】。
頭部
如果想讓一個标題填滿所有可用的空間,使用
flex: 1
非常适合這種情況。
.page-header {
display: flex;
flex-wrap: wrap;
}
.page-header__title {
flex: 1;
}
複制
輸入框
form {
display: flex;
flex-wrap: wrap;
}
input {
flex: 1;
/* Other styles */
}
複制
在兩張卡片上對齊最後一項
假設CSS grid具有兩列布局。這裡的問題是日期沒有對齊,它們應該在同一條線上(紅色那條)。
我們可以使用flexbox做到這一點。
<div class="card">
<img src="thumb.jpg" alt="">
<h3 class="card__title">Title short</h3>
<time class="card__date"></time>
</div>
複制
通過設定
flex-direction: column
,我們可以在标題上使用
flex-grow
使其填充可用空間,這樣,即使标題很短也将日期保留在末尾。
.card {
display: flex;
flex-direction: column;
}
/* 第一個解決方案 */
.card__title {
flex-grow: 1;
}
複制
同樣,無需使用
flex-grow
也可實作,我們使用
margin-top: auto
/* 第二個解決方案*/
.card__date {
margin-top: auto;
}
複制
用例 - 多個 flex 屬性
這裡的意思是使用
flex-grow
或
flex-shrink
,但值不為
1
。在本節中,我們會探讨一些可以将其合并的想法。
footer
像上面這樣的布局, 我們可以這樣寫:
.actions {
display: flex;
flex-wrap: wrap;
}
.actions__item {
flex: 2;
}
.actions__item.user {
flex: 1;
}
複制
擴充動畫
我們可以做的一件有趣的事情是在懸停時為flex項目設定動畫。 這很有用的,下面是一個簡單的例子:
.palette {
display: flex;
flex-wrap: wrap;
}
.palette__item {
flex: 1;
transition: flex 0.3s ease-out;
}
.palette__item:hover {
flex: 4;
}
複制
增加的使用者體驗
源碼:https://codepen.io/shshaw/pen...
當内容大于其包裝器時
不久前,我收到一個讀者的問題,他的問題如下。 如圖所示,兩個圖像應保留在其包裝的邊界内。
.wrapper {
display: flex;
}
.wrapper img {
flex: 1;
}
複制
這裡,即使 使用了
flex: 1
,圖像仍然會溢出。 根據CSS規範:
預設情況下,flex 項目不會縮小到其最小内容大小(最長的單詞或固定大小的元素的長度)以下。 要更改此設定,請設定或
min-width
屬性。
min-height
上面情況,是由于圖檔太大,
flexbox
不會縮小圖檔。 要更改此行為,我們需要設定以下内容:
.wrapper img {
flex: 1;
min-width: 0;
}
複制
代碼部署後可能存在的BUG沒法實時知道,事後為了解決這些BUG,花了大量的時間進行log 調試,這邊順便給大家推薦一個好用的BUG監控工具 Fundebug。
原文:https://ishadeed.com/article/...