前端入門5-CSS彈性佈局flex

来源:https://www.cnblogs.com/dasusu/archive/2018/10/31/9886038.html
-Advertisement-
Play Games

聲明 本系列文章內容全部梳理自以下四個來源: 《HTML5權威指南》 《JavaScript權威指南》 "MDN web docs" "Github:smyhvae/web" 作為一個前端小白,入門跟著這四個來源學習,感謝作者的分享,在其基礎上,通過自己的理解,梳理出的知識點,或許有遺漏,或許有些理 ...


本篇文章已授權微信公眾號 dasu_Android(大蘇)獨家發佈

聲明

本系列文章內容全部梳理自以下四個來源:

作為一個前端小白,入門跟著這四個來源學習,感謝作者的分享,在其基礎上,通過自己的理解,梳理出的知識點,或許有遺漏,或許有些理解是錯誤的,如有發現,歡迎指點下。

正文-彈性佈局flex

彈性佈局的作用有點兒類似 Android 中 LinearLayout 和 RelativeLayout 兩者的合成版,即:支持橫向佈局,縱向佈局,start,end,center 佈局,寬高按比例瓜分等等,當然它還有很多其他功能,比如自動換行,按指定 order 排列等。總之有了 Android 基礎,理解彈性佈局 flex 蠻容易的。

可以這麼的理解,傳統的網頁佈局方式是通過 display 和 position 以及 float 三者完成的,藉助塊級元素,行內元素特性,結合 position 指定的相對佈局、絕對佈局、固定佈局方式來實現各種排版效果。如果需要浮動,則藉助 float。

但這種傳統的方式,一來使用較複雜,二來某些排版效果不好實現,如列表、居中、響應式佈局等效果。

而 flex 則能夠很好的完成傳統的佈局工作,而且,它還可以支持響應式佈局。

1.基礎概念

兩根軸線

當使用 flex 佈局時,首先想到的是兩根軸線:主軸和交叉軸。主軸由 flex-direction 定義,另一根軸垂直於它。我們使用 flexbox 的所有屬性都跟這兩根軸線有關, 所以有必要在一開始首先理解它。

flex

理解主軸和交叉軸的概念對於對齊 flexbox 裡面的元素是很重要的;因為 flexbox 的特性是沿著主軸或者交叉軸對齊之中的元素。

佈局空白

佈局空白:available space,大概來說,flex 容器大小扣掉 items 的 flex-basis 指定的占據的空間大小之外剩餘的區域,flex-basis 通常是指 item 本身的大小,當然也可以手動設置。

flex 的一些屬性就是通過改變 flex 容器中的佈局空白分配來達到對齊等效果的。

比如 items 的 flex-grow 拉伸或者 flex 容器的 justify-content 主軸對齊等,其實就是將這些佈局空白按照不同演算法分配給各個 item,分給 item 時,是要直接填充進 item 的內容里達到拉伸效果,還是就簡單的將空白圍繞在 item 周圍達到類似 margin 效果來實現 item 的居中、靠左、靠右、均分等對齊方式。

具體屬性不瞭解沒關係,下麵的章節會講,知道概念即可。

2.flex相關屬性

對任意塊級元素標簽設置 display: flex 即可讓這個元素作為 flex 容器存在,也就可以使用 flex 的相關屬性了。

flex 的屬性並不多,目前只有 13 個,其中有 7 個是 flex 彈性盒子容器本身所使用的屬性,6 個是 flex-item 彈性盒子的子項使用的屬性。其中,有些屬性只是將其他屬性的集中簡化使用,因此,真正具有佈局用途的屬性並不多,很好掌握。

作用於 flex 彈性盒子容器身上的屬性:

flex-direction

語法格式:

flex-direction: row(default) | row-reverse | column | column-reverse

用於設置主軸的方向,flex 分主軸和交叉軸兩個概念,items 佈局時,預設延主軸方向進行,因此通過設置主軸是水平方向還是垂直方向就可以實現 items 的水平或垂直佈局。

  • row:預設值,設置主軸為水平方向
  • column:設置主軸為垂直方向

其他屬性就不介紹了,因為主軸方向就兩個,要麼水平,要麼垂直,其他的區別僅在於水平時是從左到右,還是從右到左,所以這個屬性的影響因素之一的 LTR 和 RTL,但沒必要考慮這麼多,這些場景應該不多,知道這個是用來設置主軸方向就夠了,我覺得。

示例:

flex-direction

flex-wrap

語法格式:

flex-wrap: nowrap(default) | wrap | wrap-reverse

用於設置是否允許換行,預設值 nowrap。

當設置了 wrap 時,允許 items 在主軸方向溢出時自動進行換行佈局,這點可以很好的用來實現響應式佈局,比如當空間逐漸縮小時,原本水平排列的控制項換成垂直方向排版。

示例:

flex-wrap

flex-flow

語法格式:

flex-flow: <'flex-direction'> || <'flex-wrap'>

這個屬性並沒有另外的含義,它只是 flex-direction 和 flex-wrap 的簡寫用法而已。

如果你不想單獨使用上述兩個屬性,可以將它們一起在 flex-flow 使用,如:

flex-flow: row wrap
//等效於
flex-direction: row;
flex-wrap: wrap;

justify-content

語法格式:

justify-content: normal(default) | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]
where 
<content-distribution> = space-between | space-around | space-evenly | stretch
<overflow-position> = unsafe | safe
<content-position> = center | start | end | flex-start | flex-end

用於設置 items 在主軸方向上的對齊方式,可以靠左,靠右,居中或者按比例均分等效果。

需要先明確一點概念,對齊是指 items 在 flex 容器中的排版對齊方式,那麼要想 flex 容器可以控制 items 的對齊方式,那主軸方向上自然就還需要有佈局空白,如果都沒有佈局空白了,不就表明 items 已充滿 flex 容器了,那談何對齊。

那麼,如果存在至少一個 item,它的 flex-grow 屬性不等於 0,justify-content 這個屬性就失效了,因為 flex-grow 表示允許 item 按照比例瓜分佈局空白,這樣一來佈局空白被瓜分完了,flex 容器在主軸方向上已被 items 充滿, 也就沒有對齊一說了。

所以要能夠正確的使用該屬性來控制 items 在主軸方向的對齊方式,那麼就需要註意 item 中會影響佈局空白的屬性,如 flex-grow,flex-basis 這些的使用。

下麵看看各屬性值介紹(下麵的介紹不考慮 RTL 的情況,預設都以 LTR 為主):

  • start:主軸是水平方向的話,左對齊方式排版;主軸是垂直方向的話,上對齊方式排版;
  • end:主軸是水平方向的話,右對齊方式排版;主軸是垂直方向的話,下對齊方式排版;
  • center:居中方式排版;
  • space-between:等比例瓜分佈局空白,每行首元素對齊,末元素對齊,每行各元素間距一致;
  • space-around:與上述的類似效果,區別僅在於,每行首元素並不是在 flex 容器內容區域左邊就開始佈局,它距離 flex 容器左邊的距離等於各個元素之間間距的一半。說白點,就是行首元素和末尾元素的周邊有類型 margin 值存在。

剩餘的屬性值不介紹了,因為我也還沒有搞懂它們的含義和應用場景。

示例:

justify-content

(ps:flex 容器設置了 padding,所以 start 和 end 才沒有貼靠邊界 )

align-items

語法格式:

align-items: normal | stretch | <baseline-position> | [ <overflow-position>? <self-position> ]
where 
<baseline-position> = [ first | last ]? baseline
<overflow-position> = unsafe | safe
<self-position> = center | start | end | self-start | self-end | flex-start | flex-end

用於控制 items 在交叉軸方向上的排版佈局方式,justify-content 是能控制主軸上的排版,而這個屬性則是用於控制交叉軸,通常兩個都會一起使用,相互結合,可以達到一些類似頁面居中效果。

看看屬性值:

  • flex-start:交叉軸方向,從起點開始佈局排版
  • flex-end:交叉軸方向,從末尾開始佈局排版
  • center:交叉軸方向,從中間開始佈局排版
  • stretch:交叉軸方向,如果 items 在交叉軸方向沒有設置大小,那麼讓 items 在交叉軸的方向充滿 flex 容器的高度。

其他屬性不介紹了,不熟悉。

示例:

align-items

(ps:flex 容器設置了 padding,所以 start 和 end 才沒有貼靠邊界 )

stretch 要能夠生效,需要在 items 在交叉軸方向的不設置大小,如上圖中主軸是水平方向,那麼 items 需要不設置 height,此時 stretch 才能夠讓 items 拉伸占據交叉軸的高度。

有一點需要註意,當 flex 容器的 items 在主軸方向上只有一行時,可以很明確的使用這個屬性來控制在交叉軸的排版方式。但,如果 items 在主軸上超過一行,那麼最終的效果可能就不是想要的了,比如下圖:

align-items2

如果是想實現多行的 items 都作為一個整體居中,那麼用 align-items 就無法實現了,針對這種有多行的情況,需要用另外一個屬性來控制:align-content。

align-content

語法格式:

align-content: normal | <baseline-position> | <content-distribution> | <overflow-position>? <content-position>
where 
<baseline-position> = [ first | last ]? baseline
<content-distribution> = space-between | space-around | space-evenly | stretch
<overflow-position> = unsafe | safe
<content-position> = center | start | end | flex-start | flex-end

當 flex 容器的 items 設置了溢出換行屬性,且當前在交叉軸方向上存在多行 item 的情況下,該屬性才會生效。

網上有種翻譯,說這個屬性是用於軸對齊,我不是很理解,我自己粗俗的分兩種情況理解:

當需要進行 start, center, end 這些排版時,是將這些多行的 items 都看成一個整體,然後進行交叉軸方向上的排版控制。此時,將多行 item 看成一行之後,那麼這個 align-content 之後的排版佈局就跟 align-items 一樣的效果了。

其他的 space-around,space-between 究竟是如何計算排版的,不熟悉。

屬性值含義不看了,跟 align-items 一樣的效果,直接看示例:

align-content

(ps:flex 容器設置了 padding,所以 start 和 end 才沒有貼靠邊界 )

place-content

語法格式:

place-content: <'align-content'> <'justify-content'>?

這個屬性並沒有另外的含義,它只是 align-content 和 justify-content 的簡寫用法而已。

如果你不想單獨使用上述兩個屬性,可以將它們一起在 place-content 使用,如:

place-content: center center
//等效於
align-content: center;
justify-content: center;

作用於 flex-item 彈性盒子的子項身上的屬性:

flex-basis

語法格式:

flex-basis: content | <'width'>

where 
<'width'> = [ <length> | <percentage> ] && [ border-box | content-box ]? | available | min-content | max-content | fit-content | auto

用於設置 items 在主軸方向的大小,如果主軸是水平方向,相當於設置 width,此時,該屬性值會覆蓋掉 width 設置的大小。

ps

嘗試了下,在 chorme 瀏覽器上 content 屬性不生效,不清楚,可能不同瀏覽器行為還不一樣,既然這樣,就先暫時不深入瞭解這個屬性了,大概知道用於設置主軸方向上的 item 大小即可。

就算要使用,先直接用指定數值大小的方式好了。

flex-grow

語法格式:

flex-grow: <number>

用於設置 item 在主軸方向上的拉伸因數,即如果 flex 容器還有剩餘空間,會按照各 item 設置的拉伸因數比例關係分配。預設值為 0,即不拉伸。

作用很像 Andorid 中的 LinearLayout 的 child 里設置了 layout_weight 用途一樣。

示例:

flex-grow

flex-shrink

語法格式:

flex-shrink: <number>

用於設置 item 在主軸方向上的收縮因數,跟 flex-grow 剛好反著來。當 flex 容器空間不夠,item 要溢出時,設置次屬性可控制 item 按比例進行相應收縮,以便不讓 item 溢出,預設 1,值越大收縮倍數越大,最後 item 就越小,0 表示不收縮,負值無效。

另外,如果設置了換行屬性,那麼這個就無效了。換行和收縮都是用於解決 item 在主軸方向上溢出的問題,既然是互斥,且換行優先順序高,那麼設置了換行,就不會再對 item 進行收縮了。

示例:

flex-shrink

flex

語法格式:

flex: none | auto | initial | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]

這屬性是 flex-grow,flex-shrink,flex-basis 三個屬性的簡化使用,有三種屬性值:

  • none:元素會根據自身寬高來設置尺寸。它是完全非彈性的:既不會縮短,也不會伸長來適應flex容器。相當於將屬性設置為 flex: 0 0 auto
  • auto:元素會根據自身的寬度與高度來確定尺寸,但是會自行伸長以吸收flex容器中額外的自由空間,也會縮短至自身最小尺寸以適應容器。這相當於將屬性設置為 flex: 1 1 auto.
  • initial:屬性預設值, 元素會根據自身寬高設置尺寸。它會縮短自身以適應容器,但不會伸長並吸收flex容器中的額外自由空間來適應容器 。相當於將屬性設置為"flex: 0 1 auto"。

flex 屬性可以指定 1 個,2 個或 3 個值。

單值語法: 值必須為以下其中之一:

  • 一個無單位數(<number>): 它會被當作 <flex-grow>的值。
  • 一個有效的寬度(width)值: 它會被當作 <flex-basis>的值。
  • 關鍵字 none, auto,或initial.

雙值語法: 第一個值必須為一個無單位數,並且它會被當作<flex-grow>的值。第二個值必須為以下之一:

  • 一個無單位數:它會被當作<flex-shrink>的值。
  • 一個有效的寬度值: 它會被當作<flex-basis>的值。

三值語法:

  • 第一個值必須為一個無單位數,並且它會被當作<flex-grow>的值。
  • 第二個值必須為一個無單位數,並且它會被當作 <flex-shrink>的值。
  • 第三個值必須為一個有效的寬度值, 並且它會被當作<flex-basis>的值。

align-self

語法格式:

align-self: auto | normal | stretch | <baseline-position> | <overflow-position>? <self-position>
where 
<baseline-position> = [ first | last ]? baseline
<overflow-position> = unsafe | safe
<self-position> = center | start | end | self-start | self-end | flex-start | flex-end

用於給單個 item 設置交叉軸方向上的排版佈局方式,屬性值和作用跟 align-items 一樣,區別僅在於 align-items 是 flex 容器的屬性,它會作用於所有的 items 上;而 align-self 允許對單個 item 設置,該值會覆蓋 align-items 設置的屬性值。

這樣就可以實現控制交叉軸上的每個 item 的不同佈局方式,如下:

align-items

order

語法格式:

order: <integer>

用於控制 items 的排版順序,item 將按照 order 屬性值的增序進行佈局。擁有相同 order 屬性值的元素按照它們在源代碼中出現的順序進行佈局。預設值為 0,可設置負值,排序將在預設不設置的 item 前面。

示例:

order

小結

我覺得,這些屬性大體記得每個屬性的主要用途即可,至於每個屬性值如何設置,如何相互結合使用可以達到什麼樣的效果,寫代碼的時候再調就是了。

3.應用場景

以下場景中,如沒有特別指明,flex 容器基本樣式和 item 基本樣式如下:

.flex
{
    width: 200px;
    height: 200px;
    border-radius: 20px;
    background-color: #FFFFFF;
}

.dot {
    width: 50px;
    font-size: 28px;
    line-height: 50px;
    text-align: center;
    color: #FFFFFF;
    height: 50px;
    border-radius: 25px;
    background-color: black;
}

長這個樣子:

基本樣式

白色區域是 flex 容器,黑色圓圈是 item。

場景1:

在頁面中把一個元素居中:item 水平、垂直方向都居中

.flex
{
    display: flex;/* 聲明這個元素作為 flex 容器 */
    flex-direction: row;/*主軸為水平方向*/
    justify-content: center;/*水平居中*/
    align-items: center;/*垂直居中*/
}

場景1

場景2:

前後有固定大小 item,中間區域自動拉伸占據可用空間。

<style >
.flex
{
    display: flex;/* 聲明這個元素作為 flex 容器 */
    flex-direction: row;/*主軸為水平方向*/
}
</style>

<div class="flex">
    <div class="dot" >1</div>
    <div class="dot" style="flex-grow: 1">2</div>
    <div class="dot" >3</div>
</div>

場景2

場景3:

響應式佈局,在屏幕尺寸允許的情況下呈水平佈局,但是在屏幕不允許的情況下可以水平摺疊。

.flex
{
    display: flex;/* 聲明這個元素作為 flex 容器 */
    flex-direction: row;/*主軸為水平方向*/
    flex-wrap: wrap;/*溢出時換行*/
}

場景3

場景4:

水平排列的一組 item 中,前幾個左對齊,後幾個右對齊。

這個需要結合塊級元素的 margin 屬性使用,當設置 margin: auto 時表示,將儘可能占據足夠多的空間。

<style >
.flex
{
    display: flex;/* 聲明這個元素作為 flex 容器 */
    flex-direction: row;/*主軸為水平方向*/
}
</style>

<div class="flex">
    <div class="dot" >1</div>
    <div class="dot" >2</div>
    <div class="dot" margin-left="auto">3</div>
</div>

場景4


大家好,我是 dasu,歡迎關註我的公眾號(dasuAndroidTv),如果你覺得本篇內容有幫助到你,可以轉載但記得要關註,要標明原文哦,謝謝支持~
dasuAndroidTv2.png


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 先展示幾個app效果圖片吧,使用起來非常方便,關聯了機器的快捷鍵操作,操作速度提高了不少,攝像頭車牌自動識別,車牌識別無網路情況下離線也可以使用 再來一張後臺截圖,停車場信息完整顯示,今日數據實時顯示 後臺是支持多設備UI自動響應 最後微信小程式來咯,可以查看今日記錄,歷史數據,還有統計報表 全平臺 ...
  • 這篇文章主要給大家講解一下GCD的平時不太常用的API,以及文末會貼出GCD定時器的一個小例子。 需要學習的朋友可以通過網盤免費下載pdf版 (先點擊普通下載 再選擇普通用戶就能免費下載了)http://putpan.com/fs/cy1i1beebn7s0h4u9/ 1.GCD的API 1.1 D ...
  • 目錄 一、應用開發技術及平臺介紹 ①開發技術: 本系統是採用面向對象的軟體開發方法,基於Android studio開發平臺,以Android作為本系統的開發語言實現音樂播放器預定的需求功能。 ②平臺介紹 硬體平臺 CPU奔騰雙核 (主頻2.0GHz) 記憶體1G以上 64或32位PC機 500G硬碟 ...
  • 又到了公司一年當中最忙的時刻了,為了趕項目,現在居然開啟了996模式,這是我從業多年來第一次遇見的。 一轉眼,一個月又過了,回頭一看,這個月一篇文章都沒有發,上個月忙著一個人做項目,項目忙完了還不忘發篇文章吐槽一下。從明天開始就要去java項目組了,可能做前端,也可能做後端,也可能前後端都要做。Ja ...
  • 系統全面地講解微信小程式的開發技術。開篇創建一個小程式項目並解析體驗,介紹如何由零開始創建一個小程式,全面體驗小程式的開發工具、界面、開發框架、實現過程及其主要代碼框架,瞭解小程式的應用場景及開發要求。接著介紹小程式開發基礎,包括小程式開發的語言與語法、函數方法、模塊、事件交互等。然後詳細介紹了組件 ...
  • export default class HttpUtils { static get(url){ return new Promise((resolve,reject)=>{ fetch(url) .then(response=>response.json()) .then(resu... ...
  • 1.函數都有返回值 而方法的本質也是函數,所以也有返回值。 Document。getElementByLd()返回的是獲取的標簽 getElementsByClassName()和getElemantsByTagName()返回的是一個數組 Document。getElementsByClassNa ...
  • 1. 寫一個函數,實現對數字數組的排序。 function get_order(array){ for(var i = 0; i <array.length-1; i++){ for(var j = 0; j < array.length - 1 -i; j++){ if(array[j] < ar ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...