深入了解 Flex 屬性

2021-02-08 大遷世界

你有沒有想過 CSS 中的 flex屬性如何工作?它是 flex-grow,flex-shrink和flex-basis的簡寫。開發中最常見的寫法是flex:1,它表示 flex 項目擴展並填充可用空間。

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

flex-grow 屬性

flex-grow屬性定義項目的放大比例,默認為0,即如果存在剩餘空間,也不放大。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

上圖已經解釋的很清楚,這裡就不在囉嗦了,還不懂的,可以多看幾次。

可以用0作為flex-grow的值嗎?

當然可以!因為flex-grow屬性接受整數值,所以可以使用0,可以防止 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屬性設置為0時,所有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 */
}

使用無單位0

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

.item {
    flex: 0;
}

不建議這樣做,因為讓開發人員和瀏覽器感到困惑。你到底是要把 flex-grow 或者 flex-shirnk 設置為 0,還是將 flex-basis 設置為 0。

所以,你應該添加一個單位,如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/EbjvbQ

當內容大於其包裝器時

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

.wrapper {
    display: flex;
}

.wrapper img {
    flex: 1;
}

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

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

上面情況,是由於圖片太大,flexbox不會縮小圖片。要更改此行為,我們需要設置以下內容:

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

作者:Ahmad shaded 譯者:前端小智  來源:sitepoint

原文:https://ishadeed.com/article/css-flex-property/

如果你覺得這篇內容對你挺有啟發,邀請你幫我三個小忙:

點個「在看」,讓更多的人也能看到這篇內容

歡迎關注我的3500+sta文章合集https://github.com/qq449245884/xiaozhi,希望可以帶給你點啟發!

想進前端交流群一起探討技術,請在後臺回復「1」或者加微信「qq449245884」

相關焦點

  • css flex屬性筆記
    flex屬性定義及用法在css中,flex屬性是使用來設置或檢索彈性盒模型對象的子元素如何分配空間,是 flex-grow屬性、flex-shrink屬性和 flex-basis 屬性的簡寫屬性。flex屬性針對的是彈性盒模型對象的子元素,對於其它元素,flex屬性不起任何作用;一些主流瀏覽器還不支持flex屬性,需要在該屬性之前加對應的前綴才能識別該屬性。Internet Explorer 9及更早版本不支持flex屬性,但是可以通過-ms-flex屬性來支持, IE11 及更新版本完全支持flex屬性,不再需要-ms-前綴。
  • Flex布局容器的屬性有哪些?
    {display:flex},行內元素也可以使用Flex布局.box{display:inline-flex;}。當我們將容器設置為Flex布局以後,容器當中的子元素的float、clear等屬性會失效。採用Flex布局的元素,稱為Flex容器,他的所有子元素自動成為容器成員,稱為Flex項目。
  • 在H5開發中flex布局方式的屬性詳解
    我們知道flex布局就是通過給父盒子添加flex屬性,來控制子盒子的位置和排列方式 ,那麼關於flex屬性有哪些 ,又怎麼去用呢?flex的屬性通常分為兩個部分:一是給父盒子添加的屬性也叫父項屬性 , 二是給子盒子添加的屬性也叫子項屬性下面來看看我們常用的flex父子項屬性有哪些?
  • CSS box-flex屬性,然後彈性盒子模型簡介
    一、淡淡的開頭語昨天"多麼痛的領悟"也問了一個關於box-flex的問題。今天我們一起來聊聊box-flex這個傢伙。本文內容敘述撇開以往順流而下的方式,直接以box-flex屬性為切入口,直入大本營,再鋪開敘述。二、box-flex屬性(和諧版)有道桌面詞典顯示,」flex」一詞中文有「收縮」之意。不過,從此屬性實際上產生的效果來看,無論怎樣用「收縮」一詞解釋都顯得很牽強。
  • Vue全家桶之flex布局探秘
    ,不過我們使用webpack打包,所以就不存在這樣的問題,它會為我們自動添加瀏覽器前綴;還有一點,設置了flex布局之後,其子元素的float、clear、vertical-align屬性都將不起作用。
  • 微信小程序CSS之Flex布局
    css相信剛開始學習開發小程序的初學者一定對界面的布局很困擾,不知道怎麼布局,怎麼擺放位置,其原因是不了解CSS樣式的屬性,所以,今天代碼君打算寫一篇關於CSS的教程,給大家普及一下。它的所有子元素自動成為容器成員,稱為 Flex 項目(flex item),簡稱"項目"。Flex總共有6個屬性1. flex-direction屬性flex-direction決定了item裡面排列的方向,有下面四個屬性值row(默認值):橫向排序,從左邊起開始排列item。
  • 3分鐘精通flex布局 - flex布局可視化學習工具
    寫在前面現在大前端中被使用最多的布局方式非flex莫屬,像h5、pc、小程序、rn、甚至native都在使用flex布局,可見掌握好flex布局是多的重要。然而在flex布局興起時,我們學習flex布局的方法大部分就是看一些博客文章的解析,官方文檔說明,然後挨個去看各個屬性的作用和示例,然後再自己手敲實踐幾次。這也是我當初學習flex布局的方法,常規手段,也很有效。如果愣是要說一些不足的地方,應該就是不直觀,效率不太高。
  • 小程序Flex布局
    position:relative,相對布局 相對自己布局 left:50px,top:50px (自己居左居上各50px)position:absolute,絕對布局 找近的一個已定位的父級元素進行定位(父級元素也需要已經定位,使用position屬性
  • Google 開源的 Android 排版庫:FlexboxLayout
    ,這些屬性都是Flexbox布局本身具備的,別著急,下面跟你們介紹下FlexboxLayout的一些具體屬性的用法與意義。默認情況下 Flex 跟 LinearLayout 一樣,都是不帶換行排列的,但是flexWrap屬性可以支持換行排列。
  • 61. flex:1; 表示什麼意思
    CSS 中的 flex 屬性規定了彈性元素如何伸長或縮短以適應 flex 容器中的可用空間,它是 flex-grow
  • CSS的flex布局,看完這篇你就懂了
    今天我們就來了解一下flex布局。flex是Flexible Box的縮寫,意為「彈性布局」,flex布局是w3c在2019年提出一種新的布局方案,它可以簡便、完整、響應式的實現各種頁面布局。現在所有的瀏覽器都支持flex。
  • CSS基礎之Flex布局面面觀
    Flex簡介Flex布局早已在2009年由W3C組織提出,並已經得到幾乎所有瀏覽器的支持,其實用也很簡單,任何容器均可通過設置display屬性為flex變成彈性布局,相應的,一旦一個元素被設置為Flex布局後,該元素本身稱為 Flex 容器(flex container),簡稱」容器」。
  • flex布局 一行3個專題及常見問題 - CSDN
    三、容器的屬性以下6個屬性設置在容器上。flex-directionflex-wrapflex-flowjustify-contentalign-itemsalign-content3.1 flex-direction屬性flex-direction屬性決定主軸的方向(即項目的排列方向)。
  • Flex布局新舊混合寫法詳解(兼容微信)
    flex是個非常好用的屬性,如果說有什麼可以完全代替 float 和 position ,那麼肯定是非它莫屬了(雖然現在還有很多不支持 flex 的瀏覽器)。
  • 2020年了,FLEX布局還搞不定麼
    閱讀本文您將收穫布局的相關概念Flex布局的相關屬性面試中常問的Flex相關知識為啥要Flex布局?因為貪婪!屬性將失效Flex 布局有兩個軸,一個是主軸(默認是水平方向),一個是交叉軸(默認是垂直方向)父容器屬性flex-direction : 決定主軸的方向四個值:row(默認值):主軸為水平方向,起點在左端row-reverse:主軸為水平方向,起點在右端column:主軸為垂直方向,起點在上沿column-reverse:主軸為垂直方向,起點在下沿flex-wrap
  • 【編程】css3 flex 詳解
    先說一下flex一系列屬性:一、flex-direction: (元素排列方向)※ flex-direction:row (橫向從左到右排列==左對齊)          ※ flex-direction:row-reverse (與row 相反)
  • 前端教程:flex布局(攜程網首頁案例製作)
    今日內容flex 布局體驗 flex 布局原理flex 布局父項常見屬性flex布局子項常見屬性>操作方便,布局極其簡單,移動端使用比較廣泛pc端瀏覽器支持情況比較差別名 伸縮布局 彈性布局當我們為父盒子設為 flex 布局以後,子元素的 float、clear 和 vertical-align 屬性將失效
  • flex 多列水平居中 - CSDN
    目錄1.常用居中方法:水平居中,垂直居中,2.單列布局3.二列&三列布局:float+margin,position+margin,聖杯布局(float+負margin),雙飛翼布局(float+負margin),flex布局如果你想學習交流html5css3等web前端技術,想多了解一些前端方面的內容,可以加入我們的QQ
  • 探秘 flex 上下文中神奇的自動 margin
    布局,我們業務中需求中更多的可能是使用 flex 布局,下文將著重圍繞 flex 上下文中自動 margin 的一些表現。使用自動 margin 實現 flex 布局下的 space-between | space-around了解了上面最核心的這一句 :在通過 justify-content 和 align-self 進行對齊之前,任何正處於空閒的空間都會分配到該維度中的自動 margin 中去之後,我們就可以在
  • Web前端html彈性盒子(flex)布局,這些你必須要知道
    作為一名前端程式設計師,彈性盒子的知識,是很常用也是很重要的,我們一起來看一下1.當flex-direction:row時,這時水平軸為主軸,垂直軸為側軸1)justify-content:調整水平軸上的對齊方式;2)align-content:調整垂直軸上各行間的對齊方式(僅在多於一行時有效);3)align-items