CSS之Flex詳解

来源:https://www.cnblogs.com/damocleses/archive/2022/04/27/16198003.html
-Advertisement-
Play Games

想必大部分做頂部導航欄(position: fixed;)的都遇見過導航欄遮住鏈接鏈接對象部分內容這種情況吧,如下圖所示,我的頂部導航欄的高度為9vh,video元素是“本店快遞流程”(錨鏈接)跳轉的元素 當我點擊該鏈接時,video元素被遮去了9vh的高度,這是為什麼呢? 我查看了一下源代碼(vi ...


目錄

flex是什麼

根據規範中的描述可知道,Flexbox 模塊提供了一個有效的佈局方式,即使不知道視窗大小或者未知元素情況之下都可以智能的,靈活的調整和分配元素和空間兩者之關的關係。簡單的理解,就是可以自動調整,計算元素在容器空間中的大小。

flex分為兩個部分,即容器(Container)和項目(item)。一旦將一個元素設置為 flex container,那麼其子元素預設全部變為flex item。然後我們就可以通過在 container 設置一些屬性來控制其 item 的佈局。當然,item 自身也有一些 flex 屬性,是只針對自己的屬性。

要將一個元素設置為容器,只要在其 css 里添加 display:flex 或者 display:flex-inline 即可

在介紹 flex 的屬性前,還有一些基本概念需要介紹,這裡就借用網上的一幅圖來說明
Flex

如圖,其實已經很清晰明瞭了,容器內有兩條軸,分別叫主軸(main axis)和交叉軸(cross axis),一般情況下 item 沿主軸方向排列,flex預設主軸為橫向,交叉軸為縱向。還有 main start、main end、cross start、cross end 這四個分別表示主軸和交叉軸的起始位置和結束位置。

容器的屬性

容器有六個屬性,flex-direction、flex-wrap、flex-flow、justify-content、align-items、align-content。

  1. flex-direction
    flex-direction 有四個值:row、column、row-reverse、column-reverse。這個屬性用於設置主軸方向。row 為預設值,表示主軸為橫軸,方向從左到右;column 表示主軸為縱軸,方向從上到下;後兩個分別表示從右到左和從下到上的主軸。
  2. flex-wrap
    flex-wrap 有三個值:nowrap、wrap、wrap-reverse。這個屬性設置如何換行。nowrap(預設)表示不換行,此時若主軸方向item總長度超過容器長度,則壓縮 item 主軸方向長度。wrap 表示換行,當 item 總長度超過容器長度時就換行。wrap-reverse 表示反向換行,換行後最靠近 cross end 的為第一行、然後是第二行......
  3. flex-flow
    flex-flow 為前面兩個的簡寫版本,即可以同時在此屬性里設置前面兩個屬性的值,如:flex-flow: nowrap row;
  4. justify-content
    justify-content 有五個值:flex-start、flex-end、center、space-between、space-around。此屬性用於調整主軸方向上 item 的對齊方式。flex-start 和 flex-end 分別表示向 main start 和 main end 對齊;center 為主軸方向上的居中對齊;space-between 表示同時向 main start 和 main end 對齊,即兩端對齊,並且兩個 item 之間主軸方向上的間距相等;space-around 表示每個項目兩側之間的距離相等
  5. align-items
    align-items 有五個值:flex-start、flex-end、center、stretch、baseline。此屬性用於調整交叉軸方向上項目的對齊方式。前面三個值和 justify-content 對應的值效果是一樣的,只是方向換成了交叉軸。stretch 為預設值,當 item 交叉軸方向的長度沒有設置或為auto時就會在交叉軸方向填滿容器。baseline 則表示文字對齊,即以 item 中的第一行文字為基準對齊
  6. align-content
    align-content 有六個值:flex-start、flex-end、center、space-around、space-between、stretch。此屬性定義了多根軸線的對齊方式,當只有一根軸線時此屬性無效。此屬性主要針對交叉軸方向,其值在上面都有提到,這裡就不贅述了

item 的屬性

item 有六個屬性:order、flex-grow、flex-shrink、flex-basis、flex、align-self

  1. order。order 設置同一容器里沿主軸方向的排列順序。可以利用此屬性做交換的動畫
  2. flex-grow。此屬性設置該 item 在主軸方向有剩餘空間時的放大比例,預設為0,即不放大。註意:這裡的放大計算原理是先計算主軸上的剩餘空間 rest_space,然後計算這條軸上所有 item 的 flex-grow 之和 grow_sum,最後給每個項目 item[i] 的主軸長度增加 rest_space * ( grow[i] / grow_sum )。即先計算出該 item 放大比例占所有 item 放大比例的百分比,然後該 item 增加 該百分比乘以主軸剩餘長度。需要註意的是,當主軸方向沒有剩餘空間時,該屬性無效
  3. flex-shrink。此屬性和 flex-grow 正好相反,此屬性設置該 item 在主軸方向沒有剩餘空間時的縮小比例,預設值為1,即空間不足時縮小。如果設置為0,則空間不足時會超出容器。我原本以為計算原理和 flex-grow基本相同,後來發現有一點不對。經過網上查詢資料發現,flex- shrink 的計算公式略有區別。flex-shrink 首先要計算權重 TW = E(basis[i] * shrink[i])。也就是所有 item 的 basis * shrink 之和。然後每個 item 的實際長度為 basis[i] - [ (basis[i] * shrink[i] ) / TW ] * need_space。其中,basis 為項目設置長度(見下麵的4),shrink 為縮放值,need_space 為需要所有 item 減少的總長度。需要註意的是:flex-shrink 為0的 item 是不會縮放的,通常這會導致 item 超出容器。
  4. flex-basis。此屬性指示在分配多餘空間前 item 占的長度,預設情況下為 auto,即設置的width。需要註意的是,如果沒有多餘空間的話,會按照上面第3條的規則縮放;是否有多餘空間是根據主軸上所有 item 的flex-basis 之和來計算的,不是按照 width 來計算的!
  5. flex。此屬性為 flex-grow、flex-shrink、flex-basis 三個屬性的簡寫,有兩個快捷值:auto( 1 1 auto) 和 none( 0 0 auto )。
  6. align-self。此屬性可取六個值:flex-start、flex-end、center、baseline、stretch、auto。此屬性設置單獨的排列行為。此屬性的值的含義前面容器屬性部分都有提到,此處不贅述。

一些疑惑和解答

在學習flex的時候,不自覺產生了一些使用方面的疑惑,下麵就是我的一些疑惑和結果

  1. justify-content 是針對主軸方向的排列,一開始想當然認為是多個 item 的情況,後面突然想起,如果是一個 item 的話,其排序規則又是怎樣的呢?
    首先 flex-start、flex-end 和 center 還比較好理解,只有一個項目的時候會貼著 main start、main end 或者在 main start 和 main end 的中間。那麼其值為 space-between 和 space-around的時候呢。前者表示兩端對齊,後者表示等間距對齊,在只有一個項目的情況下會怎麼出現什麼結果呢?結果如下
    result1-1 result1-2
    左邊表示 space-around 的結果,右邊表示 space-between 的結果。可以看出,由於 space-around 要求項目兩側的距離相等,因此只有一個項目時左右距離各占一半,和center的效果是一致的;而 space-between在只有一個項目不能同時對齊左右端的情況下,選擇了左對齊。
    結論:當只有一個項目時,space-around 的效果等同於 center,space-between 的效果等同於 flex-start
  2. align-items值為 stretch 時,假如 item 在交叉軸方向的長度沒有設置,並且在交叉軸方向不止一個 item (即在主軸方向有換行),這時會出現什麼結果呢?
    這個問題的結果非常有趣,我原以為只要交叉軸方向上只有一個 item 的會直接填滿整個容器,而有兩個 item 的就平分容器。然後結果卻如下圖
    result2
    原因大概是因為 stretch 的拉伸針對的是整個軸,而上圖是雙軸線,實際上 stretch 的效果是正確的
    結論:只要交叉軸方向有大於2個 item,即使交叉軸方向只有一個 item,這個 item 依然不會充滿容器,而是和主軸方向上的 item 長度一致
  3. align-items值為 baseline 時,若 item 沒有文字會出現什麼結果?
    這個問題的結果也很有趣,直接上結果
    result3-1 result3-2 result3-3
    可以看出,沒有文字的 item 可以認為是文字在最底部的 item
    結論:沒有文字的 item 可以認為是文字在最底部的 item
  4. align-content 說明為單軸線時無效,那麼什麼時候為單軸線,什麼時候為多軸線?
    經過我的實驗,所謂的單軸線應該就是說沒有換行的情況下,只有一行有 item ,此時 align-content 無效。那麼由此反推,交叉軸方向上 item 的最大個數即主軸數,主軸方向上 item 的最大個數即交叉軸數。如下圖,這就是雙軸線
    result4
  5. justify-content、align-items 和 align-content 似乎差不多?
    首先就他們可以取的值而言, align-content 似乎是 align-items 和 justify-content 的大雜燴,後面兩個屬性可以取得值 align-content 都可以取,更為巧合的是,取 align-items 的 align 和 justify-content 的 content 就組成了 align-content,這倒是挺有趣的。
    但是三者之間還是區別比較明顯的。justify-content 就不說了,它的區別最明顯,它是針對主軸的,而其他兩個是針對交叉軸的。那麼同樣針對交叉軸的 align-content 和 align-items 有什麼區別呢?
    首先看看定義,align-content 相較於 align-items 有一個明顯的不同,那就是它不支持單軸線的操作。下圖是單軸線情況下 align-items 和 align-content 的區別
    result5-1 result5-2 resukt5-3
    可以看出,單軸線情況下 align-content 根本沒起作用,而此時 align-items 就起到了非常關鍵的作用。接下來再看看多軸線情況下會發生什麼
    result5-4 result5-5 result5-6

於是兩者之間的區別已經躍然紙上了。首先,align-content 單軸線無效,而 align-items 單軸線和多軸線都有效(但多線軸情況下其本質還是對單線軸的設置)。當兩者同時使用且發生衝突時,align-content 的優先順序別更高,也就是說,衝突時 align-content 的操作會覆蓋掉 align-items 的操作
結論

  1. justify-content 是針對主軸的,而 align-content 和 align-items 是針對交叉軸的
  2. align-content 不支持單軸線,align-items 本質就是對每條軸線的操作
  3. 操作衝突時,align-items 的操作會被 align-content 覆蓋掉

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

-Advertisement-
Play Games
更多相關文章
  • 本期「OpenHarmony 開源貢獻者計劃」以“戰碼先鋒,PR 徵集令”為主題,圍繞 OpenHarmony 401 個主幹倉,發起獎勵提交 PR(Pull Request)的活動。 ...
  • 4月26日晚上19點,知識賦能第五期第一節課《精益開源——理解設計思維、精益創業、敏捷開發是如何應用到開源項目中》,在OpenHarmony開發者成長計劃社群內成功舉行。 ...
  • 馬蜂窩的首頁是非常正能量,青春的網頁,首頁非常大氣 logo在上一篇我們已經製作好,現在我們開始製作導航條 這個導航條字數不等,寬窄不一致,就是所有的li不一樣寬,字多就寬,字少就窄,需要用padding去撐 pandding:0 10px; 實現如下 1、index.html里body->head ...
  • 實驗環境 軟體版本 操作系統: Fedora35 // on Fedora35 nodejs-16.14.0-2.fc35.x86_64 npm-8.3.1-1.16.14.0.2.fc35.x86_64 yarnpkg-1.22.10-3.fc35.noarch 軟體包說明 nodejs: nod ...
  • 背景 今天突然碰到了一個相容性需求,需要根據不同 macOS 版本,進行不同的相容性處理。 沒想到看似簡單的需求,中間也經歷了一番波折,好在最後解決了問題。 在此記錄一下解決問題的過程,也方便其他有類似需求的同學參考。 獲取系統類型 既然需要針對 mac 系統進行相容性處理,首先需要區分系統類型,好 ...
  • 一.部署到阿裡雲伺服器 既然博客也已經成功在本地部署,然後主題也成功安裝,接下來就可以部署到伺服器上面了,如果你也想要魔改matery主題,可以去各種博客上面找一找大佬的教程,或者聯繫我,也可以讓你少走一些彎路(❁´◡`❁)。 1.部署到伺服器需要做的事情 首先需要在阿裡雲上面購買一臺伺服器,然後購 ...
  • 前言 本篇文章會從本地(Windows 10)搭建-主題更換-部署阿裡雲詳細步驟,如果在搭建過程中,遇到問題,可以通過博客頁腳下的QQ聯繫我,或者在下麵評論留言 一.本地搭建 1.安裝前置 1.1安裝git 在git官網下載最新版本的git即可,因為本地是Windows所以下載Windows版本即可 ...
  • 前言 【筆記內容】 關於JSchallenger中Arrays對象題目的復盤 本人的提交、以及做題時的思路 分析作者答案 涉及的知識快速瞭解,註意:並不深入分析具體知識,只是圍繞題目展開 【筆記目的】 幫助本人進一步瞭解Javascript的Arrays對象以及涉及的方法 對自己做題後的復盤,進一步 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...