傳統盒模型
文檔流布局
最基本的布局方式,就是按照文檔的順序一個一個顯示出來,塊元素獨占一行,行内元素共享一行
浮動布局
浮動方式布局就是使用 float 屬性,使元素脫離文檔流,浮動起來
什麼情況下需要清除浮動?
父元素沒有高度(指的是不設值,height:0不算)的情況下,裡面的子元素都設定了浮動
隻要浮動在一個有高度的盒子中,那麼這個浮動就不會影響後面的浮動元素。
但是網頁制作中,高度height很少出現。為什麼?因為能被内容撐高!
清除浮動的3種辦法
1、 尾元素清除浮動。給父元素加上clearfix這個類即可
//在類名為clearfix的元素後面加入内容
.clearfix:after{
content:"";
height:;
line-height:;
display:block;
clear:both;
visibility:hidden;
}
.clearfix{
zoom:; //因為IE6不支援:after僞類。它的效果和height:%一樣
}
2、在浮動元素後面加空标簽(設clear:both)
3、給沒有設定高度的父元素設定overflow:hidden
一個父元素不能被自己浮動的子元素,撐出高度。但是,隻要給父元素加上overflow:hidden; 那麼,父元素就能被子元素撐出高了。
定位布局
通過
position
屬性來進行定位
flex 布局
僅僅通過上述的三種布局方式還是有一些缺陷,比如我們不能隻使用一個屬性來實作垂直居中布局,是以就産生了第四種布局方式:flex 布局。
flex是什麼
2009年w3c提出的一種可以簡潔、快速彈性布局的屬性。主要思想是給予容器控制内部元素高度和寬度的能力
Flex 是 Flexible Box 的縮寫,意為”彈性布局”,用來為盒狀模型提供最大的靈活性。
注意其浏覽器的相容性,flex 隻支援 ie 10+,所有還是要根據你的項目情況使用(沒錯,我們要求至少 ie 9)
使用 flex 布局
flex 的使用方法很簡單,隻需要将其
display
屬性設定為
flex
就可以,也可以設定行内的
flex
,記得 Webkit 核心的浏覽器,必須加上
-webkit
字首。注意,設為
Flex
布局以後,子元素的
float
、
clear
和
vertical-align
屬性将失效。
.box {
display: -webkit-box; /* 老版本文法: Safari, iOS, Android browser, older WebKit browsers. */
display: -moz-box; /* 老版本文法: Firefox (buggy) */
display: -ms-flexbox; /* 混合版本文法: IE 10 */
display: -webkit-flex; /* 新版本文法: Chrome 21+ */
display: flex; /* 新版本文法: Opera 12.1, Firefox 22+ */
-webkit-flex-wrap: nowrap;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
}
在 flex 中,最核心的概念就是容器和軸,所有的屬性都是圍繞容器和軸設定的。其中,容器分為父容器和子容器。軸分為主軸和交叉軸(主軸預設為水準方向,方向向右,交叉軸為主軸順時針旋轉 90°)。
在使用 flex 的元素中,預設存在兩根軸:水準的主軸(main axis)和垂直的交叉軸(cross axis)
主軸開始的位置稱為
main start
,主軸結束的位置稱為
main end
。
同理,交叉軸開始的位置稱為
cross start
,交叉軸結束的位置稱為
cross end
。
在使用 flex 的子元素中,占據的主軸空間叫做
main size
,占據的交叉軸空間叫做
cross size
。
父容器屬性
- flex-direction:主軸的方向(即項目的排列方向
- flex-wrap:超出父容器子容器的排列樣式。
- flex-flow:
屬性和flex-direction
屬性的簡寫形式。flex-wrap
- justify-content:子容器在主軸的排列方向。
- align-items:子容器在交叉軸的排列方向。
- align-content:多根軸線的對齊方式。
flex-direction 屬性
flex-direction
屬性決定主軸的方向(主軸的方向不一定是水準的,這個屬性就是設定主軸的方向,主軸預設是水準方向,從左至右,如果主軸方向設定完畢,那麼交叉軸就不需要設定,交叉軸永遠是主軸順時針旋轉 90°)。
.box {
flex-direction: row; //預設值,主軸為水準方向,起點在左端
flex-direction: row-reverse; //主軸為水準方向,起點在右端
flex-direction: column; //主軸為垂直方向,起點在上沿
flex-direction: column-reverse; //主軸為垂直方向,起點在下沿
}
flex-wrap 屬性
flex-wrap
屬性決定子元素如果一條軸線排不下,如何換行
.box {
flex-wrap: nowrap; // 預設,不換行
flex-wrap: wrap; // 換行,第一行在上方。
flex-wrap: wrap-reverse // 換行,第一行在下方。
}
flex-flow 屬性
flex-flow
屬性是flex-direction屬性和flex-wrap屬性的簡寫形式,預設值為row nowrap。
.box {
flex-flow: <flex-direction> || <flex-wrap>;
}
justify-content 屬性
justify-content
屬性定義了子容器在主軸上的對齊方式。
.box{
justify-content: flex-start; // 預設,左對齊
justify-content: flex-end; // 右對齊
justify-content: center; // 居中
justify-content: space-between; // 兩端對齊,項目之間的間隔都相等。
justify-content: space-around; // 每個項目兩側的間隔相等。是以,項目之間的間隔比項目與邊框的間隔大一倍。
}
align-items 屬性
align-items屬性定義子容器在交叉軸上如何對齊。
具體的對齊方式與交叉軸的方向有關,下面假設交叉軸從上到下。
.box{
align-items: flex-start; // 交叉軸的起點對齊。
align-items: flex-end; // 交叉軸的終點對齊。
align-items: center; // 交叉軸的中點對齊。
align-items: baseline; // 項目的第一行文字的基線對齊。
align-items: stretch; // 預設,如果項目未設定高度或設為auto,将占滿整個容器的高度。
}
align-content 屬性
align-content
屬性定義了多根軸線的對齊方式。如果項目隻有一根軸線,該屬性不起作用。
.box{
align-content: flex-start; // 與交叉軸的起點對齊
align-content: flex-end; // 與交叉軸的終點對齊。
align-content: center; // 與交叉軸的中點對齊。
align-content: space-between;// 與交叉軸兩端對齊,軸線之間的間隔平均分布。
align-content: space-around; // 每根軸線兩側的間隔都相等。是以,軸線之間的間隔比軸線與邊框的間隔大一倍。
align-content: stretch; // 預設 軸線占滿整個交叉軸。
}
子容器屬性
子容器也有 6 個屬性:
- order:子容器的排列順序
- flex-grow:子容器剩餘空間的拉伸比例
- flex-shrink:子容器超出空間的壓縮比例
- flex-basis:子容器在不伸縮情況下的原始尺寸
- flex:子元素的 flex 屬性是 flex-grow,flex-shrink 和 flex-basis 的簡寫
- align-self
order屬性
order
屬性定義項目的排列順序。數值越小,排列越靠前,預設為0。
.item {
order: <integer>;
}
flex-grow屬性
flex-grow
屬性定義項目的放大比例,預設為0,即如果存在剩餘空間,也不放大。設定 flex-grow: 1 代表剩餘空間要配置設定給該元素。
.item {
flex-grow: <number>; /* default 0 */
}
flex-shrink屬性
flex-shrink
屬性定義了項目的縮小比例,預設為1,即如果空間不足,該項目将縮小。]
.item {
flex-shrink: <number>; /* default 1 */
}
flex-basis屬性
flex-basis
屬性定義了在配置設定多餘空間之前,項目占據的主軸空間(main size)。浏覽器根據這個屬性,計算主軸是否有多餘空間。它的預設值為auto,即項目的本來大小。
.item {
flex-basis: <length> | auto; /* default auto */
}
flex 屬性
子元素的
flex
屬性是 flex-grow,flex-shrink 和 flex-basis 的簡寫,預設值為 0 1 auto。後兩個屬性可選。
該屬性有兩個快捷值:auto (1 1 auto) 和 none (0 0 auto)。
.item {
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
align-self屬性
align-self
屬性允許單個項目有與其他項目不一樣的對齊方式,可覆寫align-items屬性。預設值為auto,表示繼承父元素的align-items屬性,如果沒有父元素,則等同于stretch。
.box{
align-self: auto; // 繼承父元素的 align-items 屬性
align-self: flex-start; // 交叉軸的起點對齊。
align-self: flex-end; // 交叉軸的終點對齊。
align-self: center; // 交叉軸的中點對齊。
align-self: baseline; // 項目的第一行文字的基線對齊。
align-self: stretch; // 預設,如果項目未設定高度或設為auto,将占滿整個容器的高度。
}
grid布局
flex 布局雖然強大,但是隻能是一維布局,如果要進行二維布局,那麼我們還需要使用 grid。
grid 布局又稱為“網格布局”,可以實作二維布局方式,和之前的 表格
table
布局差不多,然而,這是使用 CSS 控制的,不是使用 HTML 控制的,同時還可以依賴于媒體查詢根據不同的上下文得新定義布局。
沒有 HTML 結構的網格布局有助于使用流體、調整順序等技術管理或更改布局。通過結合 CSS 的媒體查詢屬性,可以控制網格布局容器和他們的子元素,使用頁面的布局根據不同的裝置和可用空間調整元素的顯示風格與定位,而不需要去改變文檔結構的本質内容。
浏覽器相容性
桌面浏覽器
移動端 / 平闆
除了微軟之外,浏覽器制造商在 Grid 規範完全落地以前似乎并沒有放手讓 Gird 野生也長的打算。 這是一件好事,這意味着我們不需要再去學習各種浏覽器相容版本的舊文法。
在生産環境中使用Grid隻是時間問題,但現在是我們該學習的時候了.
grid 網格布局中的基本概念
此部分直接摘自CSS Grid布局:什麼是網格布局
網格線(Grid Lines)
網格線組成了網格,他是網格的水準和垂直的分界線。一個網格線存在行或列的兩側。我們可以引用它的數目或者定義的網格線名稱。
網格軌道(Grid Track)
網格軌道是就是相鄰兩條網格線之間的空間,就好比表格中行或列。所在在網格中其分為grid column和grid row。每個網格軌道可以設定一個大小,用來控制寬度或高度。
網格單元格(Grid Cell)
網格單元格是指四條網格線之間的空間。是以它是最小的機關,就像表格中的單元格。
網格區域(Grid Area)
網格區域是由任意四條網格線組成的空間,是以他可能包含一個或多個單元格。相當于表格中的合并單元格之後的區域。
使用grid布局
使用 grid 布局很簡單,通過display屬性設定屬性值為 grid 或 inline-grid 或者是 subgrid(該元素父元素為網格,繼承父元素的行和列的大小) 就可以了。
網格容器中的所有子元素就會自動變成網格項目(grid item),然後設定列(grid-template-columns)和 行(grid-template-rows)的大小,設定 grid-template-columns 有多少個參數生成的 grid 清單就有多少個列。
注
:當元素設定了網格布局,column、float、clear、vertical-align屬性無效。
.container {
grid-template-columns: <track-size> ... | <line-name> <track-size> ...;
grid-template-rows: <track-size> ... | <line-name> <track-size> ...;
}
如果沒有設定 grid-template-columns,那麼預設隻有一列,寬度為父元素的 100%,例如
為了幫助我們更好的了解,在每個 items(子元素) 加上了單獨的 class :
<div class="wrapper">
<div class="item item1">1</div>
<div class="item item2">2</div>
<div class="item item3">3</div>
<div class="item item4">4</div>
<div class="item item5">5</div>
<div class="item item6">6</div>
</div>
(如果未顯示的給網格線命名),軌道值之間僅僅有空格時,網格線會被自動配置設定數字名稱:
.grid-container{
display: grid;
background:#f0f0f0;
grid-template-rows: px px px;
}
.item{
color: #fff;
text-align: center;
font-size: px;
}
.item1{background: #FF9999;}
.item2{background: #CCFFFF;}
.item3{background: #FFCCCC;}
.item4{background: #99CCCC;}
.item5{background: #FFCC99;}
.item6{background: #99CCFF;;}
顯示如下
設定了 grid-template-columns 的話,設定了幾個參數,就有幾列(不超過 grid item 的個數),然後設定的 grid-template-rows 參數就是每一列的高度(超出列數的高度無效)
.grid-container{
display: grid;
background:#f0f0f0;
grid-template-rows: px px px px;
grid-template-columns: px px px px;
}
.item{
color: #fff;
text-align: center;
font-size: px;
}
雖然我們設定了四個 grid-template-rows,但是因為隻有兩行,是以隻有前兩個值生效。效果如下:
css fr 機關是一個自适應機關,fr機關被用于在一系列長度值中配置設定剩餘空間,如果多個已指定了多個部分,則剩下的空間根據各自的數字按比例配置設定。
“fr”機關允許我們将軌道大小設定為網格容器自由空間的一部分。 例如,下面的代碼會将每個 grid item 為 grid container 寬度的三分之一:
.grid-container{
display: grid;
background:#f0f0f0;
grid-template-rows: px px px px;
grid-template-columns: fr fr fr;
}
效果如下
重複行或者列
repeat()
屬性可以建立重複的網格軌道。這個适用于建立相等尺寸的網格項目和多個網格項目。
repeat()
也接受兩個參數:第一個參數定義網格軌道應該重複的次數,第二個參數定義每個軌道的尺寸。
.grid-container{
display: grid;
grid-template-columns: repeat(,px);
grid-template-rows: repeat(,px);
background: #f0f0f0;
}
效果如下
間距
grid-column-gap
:建立列與列之間的距離。
grid-row-gap
:行與行之間的距離。
顯示如下
或者使用 grid-gap 是 grid-row-gap 和 grid-column-gap兩個屬性的縮寫。
通過網格線定位 grid item
justify-items 屬性
沿着行軸對齊網格内的内容(與之對應的是 align-items, 即沿着列軸對齊),該值适用于容器内的所有的 grid items。
.container {
justify-items: start; //内容與網格區域的左端對齊
justify-items: end; //内容與網格區域的右端對齊
justify-items: center; //内容位于網格區域的中間位置
justify-items: stretch; //預設值,内容寬度占據整個網格區域空間
}
我們可以通過表格線行或者列來定位 grid item。比如:
.grid-container{
display: grid;
grid-template-columns: repeat(,px);
grid-template-rows: repeat(,px);
background: #f0f0f0;
}
.item{
color: #fff;
text-align: center;
font-size: px;
}
.item1{
grid-row-start: ;
grid-row-end: ;
grid-column-start: ;
grid-column-end: ;
background: #fffa90;
color: #000;
}
效果如下
grid-row
是
grid-row-start
和
grid-row-end
的簡寫。
grid-column
是
grid-column-start
和
grid-column-end
的簡寫。
如果隻提供一個值,指定了
grid-row-start
和
grid-column-start
的值。
如果提供兩個值,第一個值是
grid-row-start
或者
grid-column-start
的值,第二個值是
grid-row-end
或者
grid-column-end
的值,兩者之間必須要用/隔開。
grid-row: ;
grid-column: / ;
這四個值可以用
grid-area
縮寫,分别對應
grid-row-start
、
grid-column-start
、
grid-row-end
、
grid-column-end
:
grid-area: / / / ;
合并單元行與合并單元列
初始版
grid-column-start: ;
grid-column-end: ;
grid-row-start: ;
grid-row-end: ;
也可以使用 grid-row 和 grid-column 簡寫的形式,關鍵詞 span 後面緊随數字,表示合并多少個列或行,/ 前面是從第幾行/列開始
grid-row: / span ;
grid-column: span ;
.grid-container{
display: grid;
grid-template-columns: repeat(,px);
grid-template-rows: repeat(,px);
background: #f0f0f0;
}
.item{
color: #fff;
text-align: center;
font-size: px;
}
.item1{
grid-column-start: ;
grid-column-end: ;
grid-row-start: ;
grid-row-end: ;
background: #fffa90;
color: #000;
}
效果如下
自定義網格線名稱
在 grid 中,是可以自定義網格線的名稱的,然後使用定義好的網格線來進行布局,[col1-start] 網格線名稱一定要使用 [] 包覆。
ps: 一個網格線可以有不止一個名字。例如,這裡第2條網格線有兩個名字:row1-end 和 row2-start:
.container {
grid-template-rows: [row1-start] % [row1-end row2-start] % [row2-end];
}
.grid-container{
display: grid;
grid-template-columns: [col1-start] px [col1-end] px [col2-start] px [col2-end] px [col3-start] px [col3-end];
grid-template-rows: [row1-start] px [row1-end] px [row2-start] auto [row2-end] px [row3-start] auto [row3-end];
background: #f0f0f0;
}
.item{
color: #fff;
text-align: center;
font-size: px;
}
.item1{
grid-column: col1-start / col3-start;
grid-row: row1-start;
background: #FF9999;
}
.item2{
grid-column: col3-start / col3-end;
grid-row: row1-start;
background: #CCFFFF;
}
.item3{
grid-column: col1-start;
grid-row: row1-end / row3-end;
background: #FFCCCC;
}
.item4{
grid-column: col1-end / col3-end;
grid-row: row1-end / row2-end;
background: #99CCCC;
}
.item5{
grid-column: col1-end / col2-end;
grid-row: row2-end / row3-end;
background: #FFCC99;
}
.item6{
grid-column: col2-end / col3-end;
grid-row: row2-end / row3-end;
background: #99CCFF;
}
效果如下
通過網格區域命名和定位網格項目
什麼是網格區域:
網格區域(grid-area)是一個邏輯空間,主要用來放置一個或多個網格單元格(Grid Cell)。他是由四條網格線(Grid line),網格區域每邊一條,四邊相交組織的網格軌道(Grid Track)。簡單點了解,網格區域是有四條網格線交織組成的網格空間,這個空間中可能是一個網格單元格,也可能是多個網格單元格
定義網格區域
在CSS Grid Layout中定義網格區域有兩種方式,一種是通過網格線來定義,另一種是通過grid-template-areas來定義。接下來看看兩種定義網格區域的方法在具體使用過程中有何不同。
網格線定義網格區域
使用網格線定義網格區域的方法非常的簡單,首先依賴于
grid-template-columns
和
grid-template-rows
顯式定義網格線,甚至是由浏覽器隐式建立網格線,然後通過
grid-area
屬性通過取網格線,組成網格線交織區域,那麼這個區域就是所講的網格區域。在使用
grid-area
屬性調用網格線,其遵循的規則是
grid-area: row-start
/
column-start
/
row-end
/
column-end
。
grid-template-areas 定義網格區域
通過引用 grid-area屬性指定的網格區域的名稱來定義網格模闆。 重複網格區域的名稱導緻内容擴充到這些單元格。 點号表示一個空單元格。 文法本身提供了網格結構的可視化。
<div class="grid-container">
<div class="header ">header</div>
<div class="content ">content</div>
<div class="sidebar ">sidebar</div>
<div class="footer ">footer</div>
</div>
.grid-container{
text-align: center;
padding: px;
display: grid;
grid-column-gap: px;
grid-row-gap: px;
background: pink;
grid-template-areas: "header header header header header"
"sidebar content content content ."
"footer footer footer footer footer";
grid-template-rows: px px px;
grid-template-columns: px px px;
}
.header { grid-area:header; background: #fff}
.content { grid-area: content; background: #fffa90}
.sidebar { grid-area: sidebar; background: #5bc0de}
.footer { grid-area: footer; background: #ffff00}
效果如下
我發現這樣布局的一個優點,在不設定高度的情況下(父容器和
grid-template-rows
的值,或者
grid-template-rows
設定為 auto 時,
slider
和
content
的高度是一緻的,并且會根據其内的高度自适應)
css常用布局
CSS實作水準居中
一般水準居中還是比較容易的,我一般都是先看子元素是固定寬度還是寬度未知
固定寬度
這種方式是絕對定位居中,除了使用 margin,我們還可以使用 transform
[注意]
IE9-浏覽器不支援
.container{
width: px;
height: px;
background: #09f;
position: relative;
}
.inner{
width: px;
height: px;
position: absolute;
top: %;
left: %;
margin-top: -px;
margin-left: -px;
background: #fff;
text-align: center;
}
.container{
width: px;
height: px;
background: #09f;
position: relative;
}
.inner{
width: px;
height: px;
position: absolute;
top: %;
left: %;
transform: translate(-%, -%);
background: #fff;
text-align: center;
}
也可以使用margin: 0 auto;但是第一種方法全相容哦
寬度未知
将子元素的display為table,使子元素成為塊級元素,同時table還具有包裹性,寬度由内容撐開
.inner{
display: table;
margin: auto;
}
在父元素中設定text-align:center,子元素設定display:inline-block;實作行内元素水準居中
.container{
width: px;
height: px;
background: #09f;
position: relative;
text-align: center;
}
.inner{
display: inline-block;
}
多個塊狀元素
上面的方式即使子元素不止一個也想實作水準居中也是有效的,(寬度固定不固定都可,不固定的話就不需要設定寬度,會被自動撐開,但是要考慮到撐爆的情況)例如:
.container{
width: px;
height: px;
background: #09f;
position: relative;
text-align: center;
padding: px;
}
.inner{
display: inline-block;
width: px;
height: px;
margin: auto;
background: #fff;
}
使用彈性盒模型flex實作水準居中
[注意]
IE9-浏覽器不支援
【1】在伸縮容器上設定主軸對齊方式jusify-content:center
【2】在伸縮項目上設定margin: 0 auto
<style>
.container{
width: px;
height: px;
background: #09f;
position: relative;
display: flex;
jusify-content:center;
}
.inner{
margin: auto;
}
固定高度
單行行内元素
單行行内元素居中,隻需要将子元素的行高等于高度就可以了
.container {
height: px;
background: pink;
}
.inner{
display: inline-block;
height: px;
line-height: px;
}
多行元素
多行元素不能像上面設定line-height了,對于多行的行内元素是處理不了的,可以把一些 div 的顯示方式設定為表格,是以我們可以使用表格的 vertical-align property 屬性
.container {
width: px;
height: px;
background: #09f;
position: relative;
display: table;
}
.inner {
display: table-cell;
vertical-align: middle;
}
table-cell使用
優點:内容可以動态改變高度(不需在 CSS 中定義)。當 container 裡沒有足夠空間時, 内容不會被截斷;
缺點:Internet Explorer(甚至 IE8 beta)中無效,許多嵌套标簽
還有一個方法是設定一個空的行内元素,使其 height:100%,display:inline-block,vertical-align: middle; 并且 font-size:0,要設定一個空元素,高度和父元素相等,并且設定垂直居中的屬性。但是,這隻是用與所有的行内元素的寬度和不超過父元素的寬度的情況
<div class="container">
<img src="test.jpg" width="50px" />
<img src="test.jpg" width="50px" />
<img src="test.jpg" width="50px" />
<p>123</p>
</div>
.container{
width: px;
height: px;
background: #09f;
text-align: center;
}
img{
vertical-align: middle;
}
p{
display: inline-block;
height: %;
line-height: %;
vertical-align: middle;
font-size: ;
}
效果如下:
還有一個方法,在需要居中的content元素前面插入一個div,設定此
div
height:50%; margin-bottom:-contentheight;
content清楚浮動,并顯示在中間
<div class="container">
<div id="floater"></div>
<div id="content">Content here</div>
</div>
.container{
width: px;
height: px;
background: #09f;
text-align: center;
}
#floater {
float: left;
height: %;
margin-bottom: -px;
}
#content {
clear: both;
height: px;
position: relative;
background: gray;
}
優點:适用于所有的浏覽器,沒有足夠空間時(例如:視窗縮小) content 不會被截斷,滾動條出現
缺點:唯一我能想到的就是需要額外的空元素了
效果如下
圖檔與文字居中
經常有看到設計稿是圖檔和文字垂直居中的,那麼怎麼才能讓圖檔和文字垂直居中呢?
隻需要給圖檔一個 vertical-align: middle; 屬性就可以:
<div class="container">
<img src="WechatIMG110.jpg" height="260" />
<p>123456</p>
</div>
.container {
background: #0000ff;
padding: px;
height: px;
}
.container img{
display: inline-block;
vertical-align: middle;
}
.container p{
display: inline-block;
}
效果圖如下:
聖杯布局
聖杯布局的特點
+ 三列布局,中間寬度自适應,兩邊定寬;
+ 中間欄要在浏覽器中優先展示渲染;
+ 允許任意列的高度最高;
效果如下
這個布局方式的關鍵是怎麼樣才能使得在伸縮浏覽器視窗的時候讓中間的子元素寬度改變。可以适應浏覽器的寬度變化使用百分比設定寬度再合适不過,是以我們要将中間子元素的寬度設定為 100%,左邊和右邊的子元素設定為固定的寬度。