深刻了解 Flex 屬性

做者:Ahmad shaded
譯者:前端小智
來源:sitepoint
移動端閱讀: https://mp.weixin.qq.com/s/Tw...
點贊再看,微信搜索 【大遷世界】 關注這個沒有大廠背景,但有着一股向上積極心態人。本文 GitHub https://github.com/qq44924588... 上已經收錄,文章的已分類,也整理了不少個人文檔,和教程資料。

你們都說簡歷沒項目寫,我就幫你們找了一個項目,還附贈【搭建教程】css

你有沒有想過 CSS 中的 flex屬性如何工做? 它是 flex-growflex-shrinkflex-basis的簡寫。 開發中最多見的寫法是flex:1,它表示 flex 項目擴展並填充可用空間。前端

接下來,咱們來詳細看看它表示是什麼意思。git

flex-grow 屬性

flex-grow屬性定義項目的放大比例,默認爲0,即若是存在剩餘空間,也不放大。flex-grow的值只接受一個整數。考慮下面代碼:github

<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 項目會平均剩餘可用的空間。瀏覽器

clipboard.png

你可能想知道,flex 項目之間的空間是如何分配的?嗯,這是個好問題,稍後會回答。微信

在下面的圖中,是沒有使用flex-grow狀況。換句話說,這是它們的天然大小。app

clipboard.png

要了解 flex 項目寬度的計算方式,能夠參考下面的公式。工具

咱們來計算一下文本是 CSS 的項目寬度。佈局

clipboard.png

項目寬度 = (( flex-grow / flex-grow 總個數) * 可用空間)+ 初始項目寬度flex

多個 flex-grow 值

在前面的示例中,全部flex項目的flex-grow值都相同。 如今咱們把第一項的flex-grow值改成2。 這們它又是如何計算? 請注意,本示例的可用空間爲498px

clipboard.png

上圖已經解釋的很清楚,這裏就不在囉嗦了,還不懂的,能夠多看幾回。

能夠用0做爲flex-grow的值嗎?

固然能夠!由於flex-grow屬性接受整數值,因此可使用0,能夠防止 flex 項目佔用可用空間的一種方式。

clipboard.png

這在邊界狀況下很是有用,咱們但願使 flex 項目保持其初始寬度。

flex-grow 不能讓 flex 項目相等

有一個常見的誤解,使用flex-grow會使項目的寬度相等。這是不正確的,flex-grow的做用是分配可用空間。正如在公式中看到的,每 flex 項目的寬度是基於其初始寬度計算的(應用flex-grow以前的寬度)。

若是你想讓項目的寬度相等,可使用flex-basis,這個在接下來的部分會對此進行講解。

flex-shrink 屬性

flex-shrink屬性定義了項目的縮小比例,默認爲1,即若是空間不足,該項目將縮小。

考慮下面的例子:中間的項目寬度爲300pxflex-shrink的值爲`。若是沒有足夠的空間來容納全部的項目,則容許項目縮小寬度。

clipboard.png

.item-2 {
    width: 300px;
    flex-shrink: 1;
}

在下列條件下,瀏覽器會保持項目寬度爲300px:

  • 全部項目寬度的總和小於包裝器寬度
  • 視窗寬度等於或小於項目

下面是項目在不一樣視口大小下的行爲。

clipboard.png

如圖所示,在視口寬度大於300px時,寬度爲300px,少於 300px,該項目的寬度就被壓縮成跟視口同樣的寬度。

你們都說簡歷沒項目寫,我就幫你們找了一個項目,還附贈【搭建教程】

flex-basis 屬性

flex-basis屬性定義了在分配多餘空間以前,項目佔據的主軸空間(main size)。瀏覽器根據這個屬性,計算主軸是否有多餘空間。它的默認值爲auto,即項目的原本大小。

flex-basis能夠設爲跟widthheight屬性同樣的值(好比350px,默認值爲 auto),則項目將佔據固定空間。

.item-1 {
    flex-grow: 0;
    flex-shrink: 0;
    flex-basis: 50%;
}

clipboard.png

在上面的例子中,第一項的寬度爲50%。這裏須要將flex-grow重置爲0,以防止項目寬度超過50%

若是將 flex-basis 設置爲 100%,會怎麼樣?該項目單獨佔一行,其餘項目將換行。

clipboard.png

flex 屬性

flex屬性是flex-grow, flex-shrinkflex-basis的簡寫,默認值爲0 1 auto。後兩個屬性可選。這也說 flex 項目會根據其內容大小增加

flex 項目相對大小

.item {
    /* 默認值,至關於 flex:1 1 auto */
    flex: auto;
}

flex 項目的大小取決於內容。所以,內容越多的flex項目就會越大。

clipboard.png

flex 項目絕對大小

相反,當flex-basis屬性設置爲0時,全部flex項目大小會保持一致。

.item {
    /* 至關於  flex: 1 1 0% */
    flex: 1;
}

clipboard.png

我喜歡 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-basisflex-growflex-shrink默認爲1

.item {
    flex: 100px;
    /* flex: 1 1 100px */
}

使用無單位0

有時,你想把 felx-basis 設置爲 0,你可能會這樣寫:

.item {
    flex: 0;
}

不建議這樣作,由於讓開發人員和瀏覽器感到困惑。 你究竟是要把 flex-grow 或者 flex-shirnk 設置爲 0,仍是將 flex-basis 設置爲 0

因此,你應該添加一個單位,如px%

.item {
    flex: 0%;
    /* flex: 1 1 0% */
}

建議使用 flex 簡寫屬性

當你須要設置growshrinkbasis時,最好使用flex屬性來實現這個目的。

根據 CSS 規範:

建議開發者使用 `flex` 簡寫來控制靈活性,而不是直接使用它的普通屬性,由於簡寫的能夠正確地重置任何未指定的組件以適應常見情景。

flex 用例

用戶頭像

clipboard.png

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;
}

你們都說簡歷沒項目寫,我就幫你們找了一個項目,還附贈【搭建教程】

頭部

clipboard.png

若是想讓一個標題填滿全部可用的空間,使用flex: 1很是適合這種狀況。

.page-header {
    display: flex;
    flex-wrap: wrap;    
}

.page-header__title {
    flex: 1;
}

輸入框

clipboard.png

form {
    display: flex;
    flex-wrap: wrap;    
}

input {
    flex: 1;
    /* Other styles */
}

在兩張卡片上對齊最後一項

clipboard.png

假設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-growflex-shrink,但值不爲1。在本節中,咱們會探討一些能夠將其合併的想法。

footer

clipboard.png

像上面這樣的佈局, 咱們能夠這樣寫:

.actions {
    display: flex;
    flex-wrap: wrap;
}

.actions__item {
    flex: 2;
}

.actions__item.user {
    flex: 1;
}

擴展動畫

clipboard.png

咱們能夠作的一件有趣的事情是在懸停時爲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...

當內容大於其包裝器時

clipboard.png

不久前,我收到一個讀者的問題,他的問題以下。 如圖所示,兩個圖像應保留在其包裝的邊界內。

.wrapper {
    display: flex;
}

.wrapper img {
    flex: 1;
}

這裏,即便 使用了 flex: 1,圖像仍然會溢出。 根據CSS規範:

默認狀況下,flex 項目不會縮小到其最小內容大小(最長的單詞或固定大小的元素的長度)如下。 要更改此設置,請設置 min-widthmin-height屬性。

上面狀況,是因爲圖片太大,flexbox不會縮小圖片。 要更改此行爲,咱們須要設置如下內容:

.wrapper img {
    flex: 1;
    min-width: 0;
}

代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug

原文:https://ishadeed.com/article/...

交流

文章每週持續更新,能夠微信搜索【大遷世界 】第一時間閱讀,回覆【福利】有多份前端視頻等着你,本文 GitHub https://github.com/qq449245884/xiaozhi 已經收錄,歡迎Star。

相關文章
相關標籤/搜索