2020-12-04 CSS 布局:float、flex 和 grid

1. Intro

(1) 兩種分類

  • 固定寬度,一般為960/1000/1024 px
  • 不固定寬度,靠文檔流原理布局 -> 用于手機
  • 響應式:PC上固定,手機上不固定

(2) 布局思路

  • 從大到小
  • 從小到大


    用CSS布局.png

(3) 前端底線

必須要先有設計稿才能寫代碼,手機版給手機版設計圖,PC版給PC版設計圖

(4) 常用草圖工具


2. float布局 - 專為IE布局

(1) 步驟

  • 子元素上加float: left/rightwidth
    ps. 使用float后子元素將脫離文檔流,所以父元素不會包裹他們 -> 設定父元素CSS
  • 父元素上加.clearfix
    父元素加class=clearfix可以包裹所有float子元素,CSS設定為:
.clearfix::after {
  content:'';
  display: block;
  clear: both;
}

(2) 注意

  • 最后一個float元素可以不寫width自適應寬度
  • 使用float布局后不會再響應式布局,flex是專為IE做的布局
  • IE6、7存在bug,margin會變兩倍:可以加上margin數值減半;或加上_margin;或改成display: inline-block;
  • float子元素上下margin不會合并

(3) 實踐運用

  • 外邊框outline: 1px solid green不占像素,可替代border使用
  • 設定了width的塊級元素左右margin auto可以使其居中,如:
.content {
  width: 800px;
  margin-left: auto;
  margin-right: auto;
}
  • 導航欄CSS示例
*{margin: 0; padding: 0; border-sizing: border-box;} /*css reset*/
ul, ol {
  lift-style: none; /*去掉列表樣式*/
}
img {max-width: 100%;}
.clearfix::after {
  content: '';
  display: block;
  clear: both;
}
.logo {
  background: grey;
  display: inline-block; /*使div自動收窄*/
  margin-top: 8px;
}
.logo > img {
  width: 100px;
  vertical-align: middle; /*使圖片溢出div部分消失*/
}
ul > li {
  float: left;
  padding: 4px 0.5em;
  line-height: 32px; 
}
ul {
  display: inline-block; /*自動收窄div*/
}
header {
  background: grey;
  color: white;
}
  • 平均布局
    公式:N x width + (N-1) x margin = total length
    但因為放不下最后一個元素的margin,最后一個元素會被擠到下一行
    -> 解決辦法: 為所有子元素增加一個新的clearfix父元素,里面加上負margin margin-right: -margin;,這樣會為新的父元素向右增加容納的空間


3. flex布局

(1) 容器 container 父元素

  • 使container變成flex: display: flex;
  • 控制item的流動方向(主軸) - 彈性流
    默認:從左到右一字排開 flex-direction: row
    從右往左排:flex-direction: row-reverse
    從上到下排列:flex-direction: column
    從下到上排列:flex-direction: column-reverse
  • 控制item換行
    注意:彈性盒不會折斷,有多少空間就擠多少空間,會把其中的item寬度設置成width/N
    默認不折行 flex-wrap: nowrap
    折行:flex-wrap: wrap
    反向折行: flex-wrap: wrap-reverse
  • 控制item主軸對齊方式
    默認向開始位置擠:justify-content: flex-start;
    向結尾位置擠:justify-content: flex-end;
    居中:justify-content: center;
    把空間放在間隙中(分散對齊):justify-content: space-between; (在兩個item時等價于 第二個item使用margin: auto;
    把空間放在周圍:justify-content: space-around;
    空隙大小一致:justify-content: space-evenly;
主軸對齊.png
  • 控制item次軸對齊方式
    item設定了高度:align-items: flex-start | center | flex-end | baseline,未設置高度可用 stretch (默認)
次軸對齊.png
  • 控制多行item對齊 - align-content
多行對齊.png
  • flex-flow: row wrap <=> flex-direction: row; flex-wrap: wrap;

(2) item 子元素

  • 選擇器:
    .item:first-child 第一個子元素
    .item:nth-child(n) 第n個子元素
    .item:last-child 最后一個子元素
  • order 排序
    默認order都是0,如果改變了order會將子元素按order值從小到大排列,如order: 100;會在order: 1;后面
  • flex-grow 分配多余空間
    默認為0,不分配多余空間
    如下:如果有多余的空間,將其分成4分其中兩份給2號,1份給1號,1份給3號
.item:first-child {
  flex-grow: 1;
}
.item:nth-child(2) {
  flex-grow: 2
}
.item:last-child {
  flex-grow: 1
}

常用導航欄設置flex-grow: 1,多余空間都給導航欄

  • flex-shrink 控制空間不夠時item的縮減比例,越大縮減越多
    默認為1:所有item縮減相同幅度
    設為0:該item不能縮減,由其他item貢獻縮減
  • flex-basis 控制基準寬度,默認為auto
  • flex縮寫:grow shrink basis
    flex: 1 0 100px; <=> flex-grow: 1; flex-shrink: 0; flex-basis: 100px
  • align-self 改變個別item的對齊方式
align-self.png

(3) 實踐

  • 平均布局時也需要負margin
  • 手機一般不把寬度高度寫死,最好用min-width/max-width或用百分數

(4) flex 布局小游戲


4. Grid 布局

(1) 基本概念

  • 適應新世代瀏覽器,布局類似表格,常用于不規(guī)則布局
  • 一維布局用flex,二維布局用grid

(2) Container & Item

  • 成為grid container:display: grid | inline-grid;
  • 設置行和列寬度
    設置各行列寬度,用空格分隔,如:
.container {
  grid-template-columns: 40px 50px auto 50px 40px; /*行*/
  grid-template-rows: 25% 100px auto; /*列*/
}

重復多次可以用 repeat(N, value), 如grid-template-columns: 40 repeat(3, 50);

grid-template是grid-template-rows和grid-template-columns的縮寫形式
比如說,grid-template: 50% 50% / 200px;將創(chuàng)建一個具有兩行的網格,每一行占據50%,以及一個200像素寬的列。

  • 給行列取名
.container {
  grid-template-columns: [col1] 40px [col2] 50px; /*行*/
  grid-template-rows: [row1] 25% [row2] auto; /*列*/
}
Grid行列分布.png
  • 設置item占位

a. 控制item占行占列,row/column 從哪行/哪列到哪行/哪列
正數從左到右從上到下,負數則從右到左從下到上

 .a {
  grid-row-start: 0;
  grid-row-end:3;
  grid-column-start: 0;
  grid-column-end: 3;
}

b. 簡寫為grid-column: n1 / n2;grid-row: n1 / n2;
跨越n1列/行至n2列/行

c. 簡寫為grid-area
grid-area屬性接受4個由'/'分開的值:grid-row-start, grid-column-start, grid-row-end, 最后是grid-column-end
如:grid-area: 1 / 1 / 3 / 6;

grid-area demo.png

d. span 關鍵字用于跨越多行/列

span demo1.png

span demo2.png

  • free space - fr 份 (行列按比例分隔)
.container {
  grid-template-columns: 1fr 2fr 1fr; /*行*/
  grid-template-rows: 1fr 1fr; /*列*/
}
  • grid-gap 設置每個item的上下左右間隔
  • item的order屬性與flex item的order用法一致
  • grd分區(qū):grid-template-areas
    寫成矩陣的形式,用雙引號表行,空格分隔表列,不同class自動認領所占區(qū)域
    -> 小技巧1 表所有item:.container > * {}
    -> 小技巧2 占滿整個屏幕:min-height: 100vh;
.container {
  min-height: 100vh;
  display: grid;
  grid-template-rows: 60px auto 60px;
  grid-template-areas:
  "header header header header"
  "aside main . ad" /*"."點表示空置*/
  "footer footer footer footer";
}
.container > header{
  grid-area: header; /*會自動占滿"header"區(qū)域*/
}
......
grid分區(qū)demo.png

(3) grid布局小游戲

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
禁止轉載,如需轉載請通過簡信或評論聯(lián)系作者。

相關閱讀更多精彩內容

友情鏈接更多精彩內容