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

1. Intro

(1) 两种分类

  • 固定宽度,一般为960/1000/1024 px
  • 不固定宽度,靠文档流原理布局 -> 用于手机
  • 响应式:PC上固定,手机上不固定

(2) 布局思路

  • 从大到小
  • 从小到大


    用CSS布局.png

(3) 前端底线

必须要先有设计稿才能写代码,手机版给手机版设计图,PC版给PC版设计图

(4) 常用草图工具

  • Balsami
  • Figma
  • 墨刀
  • Adobe XD


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 布局小游戏

  • flex 小游戏


4. Grid 布局

(1) 基本概念

  • 适应新世代浏览器,布局类似表格,常用于不规则布局
  • 一维布局用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;将创建一个具有两行的网格,每一行占据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分区:grid-template-areas
    写成矩阵的形式,用双引号表行,空格分隔表列,不同class自动认领所占区域
    -> 小技巧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"区域*/
}
......
grid分区demo.png

(3) grid布局小游戏

  • 小游戏

你可能感兴趣的:(2020-12-04 CSS 布局:float、flex 和 grid)