CSS3 終極布局指南
我很想寫一些能幫助人們的文章,即使我的水準不夠沒辦法幫助您,我也希望這篇文章不要誤導你。當然人是有極限的,如果文章真的有錯誤,您能幫我指出來,我就非常感謝您了。
對于同一個頁面布局,幾乎每個人的寫法都不一樣,有人喜歡Flex彈性盒子布局,有的人則喜歡Float浮動布局,有些人喜歡Margin負值布局,等等。從來就沒有一種統一的布局方案,現在大夥寫代碼也就放飛自我,隻要能在規定的環境上跑起來,不會亂就行了。但是,身為腦癱正經前端,我們還是有必要分出在不同情況應使用的布局。
這一篇部落格比起作為文章,不如作為工具書。當你對布局迷茫時,不妨打開看看。我們可以不求甚解,隻需要先把所有布局掌握熟練。
文章目錄
- CSS3 終極布局指南
-
- 正常布局(語義化布局)
-
- 正常布局,按照浏覽器的内置CSS渲染
- 應用場景
- 帶來的問題
-
- 挫
- 不相容
- 沒有自适應
- 解決方案
- Float浮動布局
-
- 什麼是浮動?
- 浮動元素的排列
- 浮動解決的布局問題
- 浮動帶來的問題
-
- 父元素高度坍縮
- 不希望浮動時清除浮動
- 總結
- 定位布局
-
- 定位的應用
-
- static
- relative
- absolute
-
- 高度坍縮
- 對比float
- 總結
- fixed
-
- 祖先未使用`transform:none`
- 使用
- sticky 粘性定位
- Flex布局
-
- 浏覽器支援
- Flex使用介紹
-
- Flex容器屬性
-
- flex-direction 排布方向
- flex-wrap 控制換行
- flex-flow [排布方向/控制換行]的簡稱
- justify-content 子項目在主軸上的排布
- align-items 子項目在交叉軸排布
- align-content 定義多根軸線排布
- Flex子項屬性
-
- order 子項排布靠前排名
- flex-grow 子項放大比例
- flex-shrink 子項縮小比例
- flex-basis 預設的寬度
- flex 放大/縮小/預設寬度 簡寫
- align-self 獨自在交叉軸的排布方式
- Flex響應式例子
- Grid 布局
-
- Grid布局的動機
- 浏覽器支援
- Grid概念介紹
- Grid使用
-
- 設定網格容器
- 顯示定義網格
-
- 定義行
-
- 取值
- 定義列
- repeat()
- 網格間隙
- 網格線
- 跨網格的子項目
- 參考
- 聲明
正常布局(語義化布局)
正常布局,按照浏覽器的内置CSS渲染
大道至簡在遠古時代,CSS還有沒被發明,浏覽器渲染HTML的時候,隻是按照規定好的如标題、段落、表格等格式渲染。且不同的浏覽器對于相同元素的渲染也是不同的,現在這項傳統藝能保留到了今天。
不過到了今天,正常布局也稍微被W3C重視了一下。在HTML5的規定中,新增加了不少語義化的元素。所謂語義化元素就是讓大家規定它就是來做這件事的。
新增加的語義化元素。
标簽名稱 | 作用 |
---|---|
hearder | header 标簽定義文檔的頁面組合,通常是一些引導和導航資訊。 |
nav | nav 标簽定義顯示導航連結不是所有的成組的超級連結都需要放在nav标簽裡。nav标簽裡應該放入一些目前頁面的主要導航連結。 例如在頁腳顯示一個站點的導航連結(如首頁,服務資訊頁面,版權資訊頁面等等),就可以使用nav标簽,當然,這不是必須的。 |
article | article标簽裝載顯示一個獨立的文章内容。例如一篇完整的論壇文章,一則網站新聞,一篇部落格文章等等,一個使用者評論等等 artilce可以嵌套,則内層的artilce對外層的article标簽有隸屬的關系。例如,一個部落格文章,可以用article顯示,然後一 些評論可以以article的形式嵌入其中。 |
section | section 标簽定義文檔中的節(section、區段)。比如章節、頁眉、頁腳或文檔中的其他部分。 |
aside | aside 用來裝載非正文類的内容。例如廣告,成組的連結,側邊欄等等。 |
hgroup | hgroup 标簽用于對網頁或區段的标題元素(h1-h6)進行組合。例如,在一個區段中你有連續的h系列的标簽元素,則可以用hgroup将他們括起來。 |
time | time 标簽定義公曆的時間(24 小時制)或日期,時間和時區偏移是可選的。該元素能夠以機器可讀的方式對日期和時間進行編碼,這樣, 舉例說,使用者代理能夠把生日提醒或排定的事件添加到使用者日程表中,搜尋引擎也能夠生成更智能的搜尋結果。 |
mark | mark 标簽定義帶有記号的文本。請在需要突出顯示文本時使用 <mark> 标簽。 |
figure | figure标簽規定獨立的流内容(圖像、圖表、照片、代碼等等)。figure 元素的内容應該與主内容相關,但如果被删除,則不應對文檔流産生影響。 |
可以看到HTML5規定中增加了不少新的标簽,但是這些标簽大部分并不是為了補充正常的文檔布局的,而是服務于搜尋引擎的爬蟲。**不要覺得頁面布局隻是給人看的!**對于布局清晰地頁面,搜尋引擎的爬蟲也會給出更高的分數。
應用場景
- 作為布局的基石。
- 開發較為單一的頁面,比如電子書閱讀頁面,面向視力障礙人士的報紙頁面等。
帶來的問題
挫
使用浏覽器預設的CSS意味着你不可定制自己的頁面,對于像
<ul>
、
<table>
這樣的标簽,你也隻能忍受上世紀的設計風格了。
不相容
先前說了,每個浏覽器對于基礎的HTML節點的渲染都不一樣,也就是說你寫的頁面在IE上是一個風格,換到Safari上又是一種風格。
沒有自适應
有一說一,正常布局(語義化)還是用來當基石比較好,對于響應式、自适應那還得看下面夥計的發揮。
解決方案
解決挫的方法就是使用style屬性,也就是使用CSS美化我們的頁面。解決不相容的問題則需要初始化CSS,大夥應該在不少的頁面的頭部見過一大坨css代碼吧,就像下面Google頁面。(部分)
頁面初始化也是很重要的,它可以使我們的代碼健壯的運作在各個環境的浏覽器上。
Float浮動布局
什麼是浮動?
如果首先要認識一個物品,認識一個東西的最好方式是了解為什麼會産生它,也就是要翻它的曆史。——NaoTan·Ma·Nong
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL1cDO5ADNzUTM2ADMxkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
看上圖,啊,報社最愛的環繞,一堆文字環繞一張圖檔,這樣的布局使得頁面緊湊,并且有較好的閱讀體驗。如果我們要在HTML中實作這樣的布局應當怎麼設定呢?手動設定換行?不行,缺少靈魂。如果能使文字繞過圖檔排列下來就好了。
于是Float屬性出世,它不僅解決了文字環繞問題,并且帶來了新的布局方案。
如上面的布局,我們用代碼實作主要部分。
.side-bar{
float:left;
}
.main-content{
float:left;
}
浮動元素的排列
當一個元素被設定為浮動元素時,首先,它會被移除文檔流,設定
float:left|right
則元素會向設定方向排列,直到遇到父元素邊框(或者說最大寬度)或者另一個浮動元素時停止。
當設定父元素
display:flex
時,子元素的浮動值無效!
浮動解決的布局問題
使用浮動我們可以解決傳統的兩列布局、三列布局的自适應。下面代碼是用浮動實作的兩列布局。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>兩列布局</title>
<style>
body,
html {
margin: 0;
background-color: rgb(228, 228, 228);
}
header {
margin-bottom: 20px;
}
footer {
margin-top: 20px;
}
.layout {
height: 50px;
border: 1px solid black;
}
aside {
width: 25%;
float: left;
border: solid 1px black;
height: 500px;
}
article {
width: 70%;
border: solid 1px black;
height: 500px;
float: right;
}
</style>
</head>
<body>
<header class="layout"></header>
<div style="overflow:auto;">
<aside>
</aside>
<article>
</article>
</div>
<footer class="layout"></footer>
</body>
</html>
效果如下
浮動帶來的問題
父元素高度坍縮
一般來說新手在學習浮動布局之後,遇到的第一個問題就是父元素高度坍縮。什麼是高度坍縮?
看上圖,在父元素的四個子元素均為浮動元素,由于浮動元素的特性浮動元素脫離文檔流,是以父元素不會被撐起高度。
如何解決?答案很簡單,使用BFC塊級格式上下文。當父元素為BFC的時候,内部計算高度會帶上浮動元素的高度。
不希望浮動時清除浮動
使用
clear
屬性可以使元素清除周圍的浮動。
如上圖,對段落文字清除浮動,導緻原本環繞的文字,另起一行。順便解決了高度坍縮的問題。
總結
浮動在帶來友善的同時也引入了新的問題,如果能處理好這些問題那麼浮動也可以當做布局的主力,但是都已經9102年了,我們應該追随CSS3的布局方案,盡量少使用浮動。
定位布局
收拾房子的時候總會把物品按照相應的位置放置,這樣會讓房間看上去更加整潔。是以,我們CSS也是可以這樣做的。
使用
position
屬性,調整元素的位置。
position
一共有四種定位類型:定位元素、相對定位、絕對定位、粘性定位,五種取值:static、relative、absolute、fixed、sticky。
名稱 | 描述 | 定位類型 |
---|---|---|
static | 該關鍵字指定元素使用正常的布局行為,即元素在文檔正常流中目前的布局位置。此時 , , , 和 屬性無效。 | 定位元素 |
relative | 該關鍵字下,元素先放置在未添加定位時的位置,再在不改變頁面布局的前提下調整元素位置(是以會在此元素未添加定位時所在位置留下空白)。position:relative 對 table-*-group, table-row, table-column, table-cell, table-caption 元素無效。 | 相對定位 |
absolute | 不為元素預留白間,通過指定元素相對于最近的非 static 定位祖先元素的偏移,來确定元素位置。絕對定位的元素可以設定外邊距(margins),且不會與其他邊距合并。 | 絕對定位 |
fixed | 不為元素預留白間,而是通過指定元素相對于螢幕視口(viewport)的位置來指定元素位置。元素的位置在螢幕滾動時不會改變。列印時,元素會出現在的每頁的固定位置。 屬性會建立新的層疊上下文。當元素祖先的 屬性非 時,容器由視口改為該祖先。 | 絕對定位 |
sticky | 盒位置根據正常流計算(這稱為正常流動中的位置),然後相對于該元素在流中的 flow root(BFC)和 containing block(最近的塊級祖先元素)定位。在所有情況下(即便被定位元素為 ),該元素定位均不對後續元素造成影響。當元素 B 被粘性定位時,後續元素的位置仍按照 B 未定位時的位置來确定。 對 元素的效果與 相同。 | 粘性定位 |
一般使用
position
屬性時,會使用其相對定位與絕對定位、粘性定位,它們都使用
top
、
bottom
、
left
、
right
來調整自身位置,但是調整的基準不一樣。
定位的應用
static
static是元素正常出現在文檔流中的定位,文檔流中的排列為自上而下,自左至右。一般來說block元素自占一行,inline元素橫向排列。
正常情況下在我們的頁面中大部分元素為
static
定位,對于一些特殊需求我們需要使用其他定位。比如像wiki中的關鍵詞,滑鼠移動上去的時候,關鍵詞下面顯示式卡片。
relative
relative是在實作一些特殊布局的時候經常使用的一種定位方式。設定為relative的元素并不會脫離文檔流,但是可以通過
top
、
bottom
、
left
、
right
調整元素對于預設基準的位置。
.box {
display: inline-block;
width: 100px;
height: 100px;
background: red;
color: white;
}
#two {
position: relative;
top: 20px;
left: 20px;
background: blue;
}
使用相對定位可以實作一些炫酷的效果。
.content{
text-align: center;
margin: 20px;
}
.card{
position: relative;
display: inline-block;
width: 200px;
height: 200px;
background-color: darkgray;
top: 210px;
right: 170px;
visibility: hidden;
}
span:hover+.card{
visibility:visible;
}
<div class="content">
<span>滑鼠移到我身上!</span>
<div class="card">
</div>
</div>
效果
但是,使用相對定位依然會出現一些問題。relative定位并不會脫離文檔流,是以
.content
元素的高度為
200px
。
absolute
與
relative
定位不同的是
absolute
是脫離文檔流的,而且相對基準是position屬性不為static的祖先元素,如果祖先都是static則元素相對body定位。并且,對于absolute元素,如果不設定top/bottom/left/right的話依然排列在正常布局位置。
html,
body {
margin: 0;
}
.content {
position: relative;
/* top: 50px; */
margin-top: 50px;
}
.static {
position: static;
}
.relative {
position: relative;
margin: 20px 0;
}
.absolute {
display: inline-block;
width: 50px;
height: 50px;
background-color: lightcoral;
position: absolute;
}
.non-ab {
display: inline-block;
width: 50px;
height: 50px;
background-color: darkblue;
margin-left: 100px;
}
<div class="content">
<div style="height: 50px;"></div>
<div class="static">
<div class="non-ab">
</div>
<div class="absolute">
</div>
</div>
<div class="relative">
<div class="absolute">
</div>
<div class="non-ab">
</div>
</div>
</div>
上面的代碼很有意思,有興趣的同學可以放在
codepen
上面跑一下子。這個例子驗證了
absolute
的排列方式。當我們知道我們在做什的時候,也就不需要墨守成規(對于absolute元素的父元素統一設定relative屬性)了。
高度坍縮
隻要是脫離了文檔流的元素都會出現高度坍縮,是以在使用
absolute
屬性時,請確定父元素不會是以而改變。
對比float
Float與absolute都會使元素脫離文檔流,但是衆所周知對相同元素設定float與設定absolute會出現不同的效果。這是因為float與absolute本身的排列不一樣。
float:脫離文檔流,排列時以父元素為基準,并且會為占用其他浮動元素的位置。
absolute:脫離文檔流,排列時分情況:第一種情況,對于未設定
left、right、top、bottom
屬性的元素,排列在正常顯示位置,并不占用空間。第二種情況,設定位置屬性的元素,基于非static祖先元素排列。
上面兩者比較顯著的差異為float會影響下一個float元素,但是absolute元素不會。
總結
說absolute為絕對定位也并不貼切,它也是基于祖先元素定位的,隻是脫離了文檔流。我個人還是比較推薦在處理元素相對位置問題上使用absolute屬性的,但前提是您已經深刻了解了absolute的排列方式。
fixed
不為元素預留白間,而是通過指定元素相對于螢幕視口(viewport)的位置來指定元素位置。元素的位置在螢幕滾動時不會改變。列印時,元素會出現在的每頁的固定位置。屬性會建立新的層疊上下文。當元素祖先的
fixed
屬性非
transform
時,容器由視口改為該祖先。
none
fixed元素也會脫離文檔流,并且和absolute元素一樣,當不設定任何
left、top、bottom、right
值的時候,元素依然按照正常定位的位置放置。
祖先未使用 transform:none
transform:none
當祖先元素未使用
transform:none
的時候,fixed元素相對于該祖先元素進行定位。
在上面的圖檔中,我設定小黃塊為fiexd屬性,并讓父元素設定為 使用
transform:matrix(1, 0, 0, 1, 0, 0);
,這時候小黃塊并沒有相對于
body
進行定位,當滾動條下拉時,小黃塊定位固定在父元素左上角。
使用
fiexd元素一般用在如:
to-top
按鈕,或者側邊懸浮面闆,或者懸浮導航欄之中。
sticky 粘性定位
盒位置根據正常流計算(這稱為正常流動中的位置),然後相對于該元素在流中的 flow root(BFC)和 containing block(最近的塊級祖先元素)定位。在所有情況下(即便被定位元素為),該元素定位均不對後續元素造成影響。當元素 B 被粘性定位時,後續元素的位置仍按照 B 未定位時的位置來确定。
table 時
對
position: sticky
元素的效果與
table
相同。
position: relative
上面我們使用了
fiexd
與
transform
,發生了我們意想不到的效果,那就是fixed元素并未相對于body進行移動,也沒有在父元素中進行标準的fixed定位。現在我們使用以下sticky屬性來看一下效果。
<style>
.box{
box-sizing: border-box;
height: 150px;
border:solid 3px black;
margin: 0 0 20px 0;
overflow: auto;
}
.block{
width: 50px;
height: 50px;
background-color: orange;
}
.sticky-1{
position:sticky;
top: 0px;
}
</style>
<div class="box box-1">
<p>下面這個小黃塊設定為sticky</p>
<div class="sticky-1 block">
</div>
<p>
hahah
</p>
<p>
hahah
</p>
<p>hahaha</p>
<p>hahaha</p>
</div>
當我們向下滾動的時候神奇的事情發生了。
小黃塊固定到了父元素的
top:0
位置了,不僅如此,再向上滑動後,小黃塊又回複了當時的位置,而且占用了文檔本身的位置。
使用這個特性我們可以制作浮動的Header元件,當使用者向下滑動至視窗上側的時候,Header元件也跟随視窗滑動。
Flex布局
對于前端工程師來說,最讓人頭疼的莫過于自适應布局。對于不同分辨率的裝置要做到頁面統一,在CSS3出現之前,還是挺不容易的。還有就是前端工程師頭疼的一個布局問題:垂直居中。
CSS3中新出了一種布局技術:CSS彈性盒子布局,我們來看一下MDN是如何介紹的。
CSS 彈性盒子布局是 CSS 的子產品之一,定義了一種針對使用者界面設計而優化的 CSS 盒子模型。在彈性布局模型中,彈性容器的子元素可以在任何方向上排布,也可以“彈性伸縮”其尺寸,既可以增加尺寸以填滿未使用的空間,也可以收縮尺寸以避免父元素溢出。子元素的水準對齊和垂直對齊都能很友善的進行操控。通過嵌套這些框(水準框在垂直框内,或垂直框在水準框内)可以在兩個次元上建構布局。
接下來,我會使用Flex布局技術,設計一些我們常使用頁面布局,并指出優點與缺點。但是,我們首先要來看一下浏覽器的支援程度。
浏覽器支援
特性 | Firefox (Gecko) | Chrome | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
基礎支援 | 20.0 (20.0) | 21.0-webkit 29.0 | 10.0-ms 11.0 | 12.10 | 6.1-webkit |
主流的浏覽器全部支援Flex屬性。注:與社會脫軌的IE9并不支援Flex,如果想寫出相容IE9的頁面,請不要使用Flex。
Flex使用介紹
使用flex務必清楚一些屬性概念。
- Flex容器:對于一個基本元素(不含任何CSS屬性,如
),設定div
,即可建立一個Flex容器。display:flex
- Flex子項:父元素為Flex容器的元素,稱之為Flex子項,其排布受到父元素影響。注:一定是父元素為Flex容器的元素,祖先不算。
- 排布方向:指Flex子項在Flex容器中的排布方向。排布方向有兩種:
、column
。在Flex容器上使用row
即可設定。flex-direction: column|row(預設);
- 主軸:指的Flex容器中是與排列方式相同的方向的軸。如設定Flex容器
則其主軸為豎直方向。direction: column;
- 交叉軸:指的Flex容器中是與排列方式相反的方向的軸。如設定Flex容器
direction: column;
則其主軸為水準方向。
我們一定要清楚上面的基礎概念,這對深入使用Flex有很大的幫助。下面我會介紹一些Flex常用的屬性,主要分為兩部分:對Flex容器、對Flex子項。
Flex容器屬性
flex-direction 排布方向
flex-direction
屬性指定了内部元素是如何在 flex 容器中布局的,定義了主軸的方向(正方向或反方向)。
flex-direction
屬性接受以下值:
- row:子項目在flex容器中橫向,從左至右排列。
-
CSS3 終極布局指南CSS3 終極布局指南
-
- row-reverse:表現和row相同,也是橫向,但是是從右到左。
-
CSS3 終極布局指南CSS3 終極布局指南
-
- column:子項在容器中豎向排列,從上至下。
- 這裡不貼圖了
- column-reverse:表現和
相同,子項在容器中豎向排列,從下至上。column
- 這裡不貼圖了
flex-wrap 控制換行
CSS flex-wrap 指定 flex 元素單行顯示還是多行顯示 。如果允許換行,這個屬性允許你控制行的堆疊方向。
取值:
- nowrap(預設)
- flex 的元素被擺放到到一行,這可能導緻溢出 flex 容器。 cross-start 會根據
的值 相當于 start 或 before。flex-direction
- flex 的元素被擺放到到一行,這可能導緻溢出 flex 容器。 cross-start 會根據
- wrap
- flex 元素 被打斷到多個行中。cross-start 會根據
的值選擇等于start 或before。cross-end 為确定的 cross-start 的另一端。flex-direction
-
CSS3 終極布局指南CSS3 終極布局指南
- flex 元素 被打斷到多個行中。cross-start 會根據
- wrap-reverse
- 和 wrap 的行為一樣,但是 cross-start 和 cross-end 互換。
-
CSS3 終極布局指南CSS3 終極布局指南
flex-flow [排布方向/控制換行]的簡稱
CSS flex-flow 屬性是 flex-direction 和 flex-wrap 的簡寫。
示例:
flex-flow: column-reverse wrap;
justify-content 子項目在主軸上的排布
CSS justify-content 屬性定義了浏覽器如何配置設定順着父容器主軸的彈性元素之間及其周圍的空間。
justify-content同時受到父容器主軸的影響。
取值:
-
從行首開始排列。每行第一個元素與行首對齊,同時所有後續的元素與前一個對齊。start
-
flex-start
(預設)
從行首開始排列。每行第一個彈性元素與行首對齊,同時所有後續的彈性元素與前一個對齊。
-
從行尾開始排列。每行最後一個彈性元素與行尾對齊,其他元素将與後一個對齊。flex-end
-
伸縮元素向每行中點排列。每行第一個元素到行首的距離将與每行最後一個元素到行尾的距離相同。center
-
伸縮元素一個挨一個在對齊容器得左邊緣,如果屬性的軸與内聯軸不平行,則left的行為類似于startleft
-
元素以容器右邊緣為基準, 一個挨着一個對齊,如果屬性軸與内聯軸不平行,則right
的行為類似于right
start.
-
在每行上均勻配置設定彈性元素。相鄰元素間距離相同。每行第一個元素與行首對齊,每行最後一個元素與行尾對齊。space-between
-
space-around
- 在每行上均勻配置設定彈性元素。相鄰元素間距離相同。每行第一個元素到行首的距離和每行最後一個元素到行尾的距離将會是相鄰元素之間距離的一半。
-
CSS3 終極布局指南CSS3 終極布局指南
-
space-evenly
- flex項都沿着主軸均勻分布在指定的對齊容器中。相鄰flex項之間的間距,主軸起始位置到第一個flex項的間距,主軸結束位置到最後一個flex項的間距,都完全一樣。
-
CSS3 終極布局指南CSS3 終極布局指南 - 看上去與
的排布很相似,但其實還是有一些差別的。space-around
會在每一行均勻分布間隙,而space-evenly
是均勻分布項目。space-around
- 借一張圖
CSS3 終極布局指南CSS3 終極布局指南
看上去我們要學的屬性很多,但是其實我們隻需要記住我們常用的幾個屬性就行:
flex-start
、
flex-end
、
space-between
、
center
、
space-around
、
space-evenly
。以上這幾個就是我們常用的屬性值,通過設定主軸方向、設定排列方式,我們可以靈活地組織我們的元素。
align-items 子項目在交叉軸排布
CSS align-items屬性将所有直接子節點上的align-self值設定為一個組。 align-self屬性設定項目在其包含塊中在交叉軸方向上的對齊方式。
取值:
-
這個關鍵字的效果取決于我們處在什麼布局模式中:在絕對定位的布局中,對于被替代的絕對定位盒子,這個效果和normal
的效果的一樣;對于其他所有絕對定位的盒子,這個效果和start
的效果一樣。 在絕對定位布局的靜态位置上,效果和stretch
一樣。對于那些彈性項目而言,效果和stretch
一樣。對于那些網格項目而言,效果和stretch
一樣,除了有部分比例或者一個固定大小的盒子的效果像stretch
。這個屬性不适用于會計盒子和表格。start
-
元素向側軸起點對齊。flex-start
-
元素向側軸終點對齊。flex-end
-
元素在側軸居中。如果元素在側軸上的高度高于其容器,那麼在兩個方向上溢出距離相同。center
因為
align-items
其實和
justify-content
我這裡就不放一些圖檔湊字數了。
align-content 定義多根軸線排布
該屬性對單行彈性盒子模型無效。(即:帶有flex-wrap: nowrap)。
CSS的align-content屬性設定了浏覽器如何沿着伸縮盒子容器(flexbox container)的縱軸和網格容器(Grid Container)的主軸在内容項之間和周圍配置設定空間。
它的取值和
align-items
差不多,經常有人會把他們搞混。
align-content
一般定義多行的交叉軸排列。
絕大多數情況下我們使用
align-items
即可實作我們的需求。
Flex子項屬性
order 子項排布靠前排名
CSS order 屬性規定了彈性容器中的可伸縮項目在布局時的順序。元素按照屬性的值的增序進行布局。擁有相同
order
屬性值的元素按照它們在源代碼中出現的順序進行布局。
order
取值:
-
表示此可伸縮項目所在的次序組。<integer>
flex-grow 子項放大比例
CSS flex-grow 屬性定義彈性盒子項(flex item)的拉伸因子
取值:
-
預設值0,即如果存在剩餘空間,也不放大。負值無效。<number>
flex-shrink 子項縮小比例
CSS flex-shrink 屬性指定了 flex 元素的收縮規則。flex 元素僅在預設寬度之和大于容器的時候才會發生收縮,其收縮的大小是依據 flex-shrink 的值。
總而言之,你定了這個屬性,其他項目會先壓榨你的空間,然後再均勻縮小其他項目。
flex-basis 預設的寬度
屬性定義了在配置設定多餘空間之前,項目占據的主軸空間(main size)。浏覽器根據這個屬性,計算主軸是否有多餘空間。它的預設值為
flex-basis
,即項目的本來大小。
auto
注:配置設定多餘空間之前!!
也就是說你給的
flex-basis
值大于目前配置設定空間時,依然會被壓縮。
flex 放大/縮小/預設寬度 簡寫
flex
屬性是
flex-grow
,
flex-shrink
和
flex-basis
的簡寫,預設值為
0 1 auto
。後兩個屬性可選。
align-self 獨自在交叉軸的排布方式
屬性允許單個項目有與其他項目不一樣的對齊方式,可覆寫
align-self
屬性。預設值為
align-items
,表示繼承父元素的
auto
屬性,如果沒有父元素,則等同于
align-items
。
stretch
這個屬性了不得,它也是我們經常用的子項目屬性之一。
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
就像上面的圖,他可以決定子項目的交叉軸單獨排列方式。
Flex響應式例子
使用我們剛才學到的知識,我們可以輕易設計響應式的布局比如,在大屏上應顯示如下布局
當螢幕分辨率降低時,我們應該在中心保留正文部分,達到下面效果。
這是我們最常用的三欄布局,并且我們考慮到了針對不同螢幕的使用者呈現不同的布局效果。
下面是這個布局的代碼。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Flex例子</title>
<style>
html,
body {
margin: 0;
}
header {
height: 50px;
border: solid 5px black;
box-sizing: border-box;
background-color: gray;
margin-bottom: 20px;
}
.content {
display: flex;
flex-wrap: wrap;
flex-direction: row;
justify-content: space-around;
}
aside {
order: 3;
flex: 1 0 200px;
height: auto;
border: solid 5px black;
box-sizing: border-box;
background-color: gray;
}
article {
text-align: center;
order: 2;
flex: 1 0 800px;
height: 500px;
border: solid 5px black;
box-sizing: border-box;
background-color: gray;
}
.order-1 {
order: 1;
}
footer{
}
</style>
</head>
<body>
<header></header>
<div class="content">
<article>
<h1>我是正文</h1>
<p>我會最先重新整理出來</p>
</article>
<aside class="order-1">
<h1>我是左邊欄</h1>
<p>這裡一般可以放一些文章資訊</p>
<p>比如作者的其他文章、分類、專欄</p>
</aside>
<aside>
<h1>這裡是右邊欄</h1>
<p>頁面制作者可以考慮放一些廣告</p>
<p>我會自動換行到最下面 保證閱讀體驗</p>
</aside>
</div>
<footer></footer>
</body>
</html>
細心的讀者發現我們在html裡面的布局是
<article>
<h1>我是正文</h1>
<p>我會最先重新整理出來</p>
</article>
<aside class="order-1">
</aside>
<aside>
</aside>
我們把正文,寫到了最前面。這樣頁面在加載的的時候會最先加載正文部分。當CSS OM建構完成時,正文就會回到頁面最中心,因為CSS OM的建構速度大部分取決于網速(下載下傳css)是以我們是感受不到這個改變的。
Grid 布局
熟練使用Flex之後,我們确信flex能解決絕大部分的布局難題,剩下一小部分也可以使用定位布局來解決。那麼Grid布局的優勢在哪些地方呢?
Flex布局屬于一維布局,單純控制Flex容器中的一列,或者一行。我們通常不會使用Flex來定義頁面的整體布局,而是更多用它來解決某一個元件中的布局。
Grid布局更多是來定義整體的布局,通過網格線将頁面劃分不同的區域。
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-DU4t4qPs-1570616123211)(%E7%BB%88%E6%9E%81%E5%B8%83%E5%B1%80%E6%8C%87%E5%8D%97.assets/basic-form-1570602316379.png)]
類比一下,Grid就好像一個書架,上面有不同的格子。Flex就是格子中的排布。
Grid布局的動機
使用一些CSS控制頁面布局,搭建響應式頁面。這已經是前端工程師必備技能了,但是使用一些古老的方式,比如浮動、
margin
負值法,建立的布局往往會出現無法預測的行為。也無法直覺的給人布局的美感。有些Web開發人員會使用
display:table
來進行布局,但是這些布局往往在響應式的效果上不佳。
可控制
、
響應式
、
符合直覺
這些問題都需要被解決。
Grid網格布局應運而生。通過我們自定義一些屬性,我們的頁面往往既健壯又符合直覺。
浏覽器支援
雖然現在Grid布局依然隻是處于
CR
階段(w3c的推薦候選标準),但是已經有不少浏覽器完全支援這種布局方案了,而且不少架構的栅格布局,就是使用grid進行實作的。
Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | Android webview | Chrome for Android | Firefox for Android | Opera for Android | Safari on iOS | Samsung Internet | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
| 57 | 16 | 52 | No support | 44 | 10.1 | 57 | 57 | 52 | 43 | 10.3 | 6.0 |
除了IE基本上浏覽器都相容,是以說IE真是個好東西,逼着我們寫相容。
Grid概念介紹
網格容器:我們通過在元素上聲明
display:grid
或
display:inline-grid
來建立一個網格容器。
網格元素:網格容器的直接子元素為網格元素。
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-thm2uX3Q-1570616123212)(assets/1570604160943.png)]
<div class="grid">
<div class="item"><span>1</span></div>
<div class="item"><span>2</span></div>
<div class="item"><span>3</span></div>
<div class="item"><span>4</span></div>
</div>
這裡設定
class="grid"
的
div
為網格容器,而
class="item"
的
div
是網格元素,在最内部的
span
标簽并不是網格元素。
fr
機關:
fr
機關通常與CSS網格布局一起使用。
fr
機關是CSS網格布局規範的一部分,代表網格容器中剩餘空間的一小部分。請把它了解為flex中的
flex:0 1 auto
中數字的機關。
Grid使用
設定網格容器
使用
display:grid
或者
display: inline-grid;
設定容器成為網格容器。
注:設為網格布局以後,容器子元素(項目)的、
float
、
display: inline-block
、
display: table-cell
和
vertical-align
等設定都将失效。
column-*
顯示定義網格
通過使用和
grid-template-columns
屬性建立列和行來顯式設定網格。
grid-template-rows
定義行
在網格容器中使用
grid-template-rows
屬性值可以定義行的高度。
取值
none
:這個關鍵字表示不明确的網格。所有的行和其大小都将由
grid-auto-rows
屬性隐式的指定。
<length>
:長度機關值,如
px
、
em
、
rem
。
<percentage>
:百分比機關。如取值
80%
。
max-content
:是一個用來表示以網格項的最大的内容來占據網格軌道的關鍵字。
min-content
:是一個用來表示以網格項的最大的最小内容來占據網格軌道的關鍵字。
auto
:如果該網格軌道為最大時,該屬性等同于
<max-content>
,為最小時,則等同于
<min-content>
。
minmax(min, max)
:是一個來定義大小範圍的屬性,大于等于min值,并且小于等于max值。如果max值小于min值,則該值會被視為min值。最大值可以設定為網格軌道系數值
<flex>
,但最小值則不行。
使用例:
我們在網格容器中設定
grid-template-rows:100px 80px;
,可以看到第一行的高度變成了
100px
,第二行高度變成了
80px
,我們并沒有設定後面的高度,是以其他的項目按照原本大小顯示。
定義列
在網格容器中使用
grid-template-columns
屬性值可以定義行的高度。
取值和
grid-template-rows
基本相同,這裡不再贅述。
使用例:
grid-template-columns: 90px 150px auto;
看到這裡大夥應該差不多了解了grid的排列了吧,從上至下,從左至右,依次填入設計好的網格中。但是一個一個設計行列寬度,會很費時間,于是css提供給我們一個
repeat()
方法。
repeat()
repeat()
方法接收兩個參數,第一個參數用來表示重複幾次,第二個參數用來表示重複的值。
如:
repeat(10,100px)
,表示重複10次100px。而
repeat(2,50px 80px)
注意中間隻有一個逗号,表示
50px 80px
重複兩次。
用法:
.grid{
display: grid;
grid-template-rows: repeat(2,50px 80px);
grid-template-columns: repeat(3,90px);
}
效果:
網格間隙
在和
grid-column-gap
grid-row-gap
屬性來建立列和行之間的間距。
網格間隙僅在列和行之間建立,而不沿着網格容器的邊緣。
同時設定行列間距。
grid-gap
例:
grid-row-gap: 20px;
grid-column-gap: 5rem;
間隙大小值可以是任意非負,長度值(
px
,
%
,
em
等)。
grid-gap
是
grid-row-gap
和的簡寫
grid-column-gap
。
如果指定了兩個值,則第一個表示
grid-row-gap
,第二個表示
grid-column-gap
。
網格線
網格線從容器的最起始邊到結束邊。如上圖,圖中為2×3的網格。行網格線一共有4條,列網格線一共有三條。網格線對于我們設定子項跨網格起到很大作用。
跨網格的子項目
通過設定
grid-column-start: 2;
grid-column-end: 4;
我們看到第5個
div
占據了兩個格子。
當然我們也可以通過
grid-row-start:1;
grid-row-end: 3;
來使
div
占據豎向網格,效果如下:
每次書寫綁定的兩個css,我們難免會不爽,是以css也為我們這個屬性提供了簡寫。
grid-row: 2 / 5;
grid-column: 2 / 4;
通過這種用法,也可以實作上面的效果。
當然,w3c甚至想到了我們可能連數數都會數錯,是以我們可以用
span
的關鍵字來指定子項目跨越網格線的數目。
grid-row: 2 / span 3;
grid-column: span 2;
效果如下:
關于Grid,我就說這麼多。因為網上教程真的有多又好,我如果隻是在這裡搬運基礎,那麼就有點顯得做無用功了。這裡我推薦大家來https://learncssgrid.com/,這裡學習Grid其他的知識。
參考
- HTML5語義化标簽屬性-HTML5屬性手冊
- All About Floats | CSS-Tricks
- 清除浮動的四種方式及其原理了解
- 【前端Talkking】CSS系列——CSS深入了解之absolute定位
- CSS 彈性盒子布局
- Flex 布局教程:文法篇
- CSS Grid Layout Module Level 1
- grid - CSS(層疊樣式表) | MDN
- CSS Grid 網格布局教程
聲明
腦癱碼農 純靠自學 如有錯誤 望請指正 共同學習 不勝感激