# Flex 布局与 Grid 布局

  1. flex 布局又称为弹性布局。
  • 当我们给一个容器元素设置 display:flex; 时,这个容器就变成了 flex 容器,容器中所有直接子元素就成了容器成员(flex 项目)。
  • flex 容器默认存在两根轴:水平的主轴和垂直的交叉轴,flex 布局主要是围绕这两根轴来进行布局的。
  • 所以 flex 布局相对于 grid 网格布局来说,他更适合一维布局(单行或单列布局)

父容器属性:flex-direction, justify-content, align-items, align-content
子容器属性:order, flex-grow, flex-shrink, flex-basis, align-self

  1. Grid 布局又称为网格布局。
  • 当我们给一个元素加上 display:grid; 时,我们称这个元素为容器,元素中所有直接子元素称为子项或项目。
  • Grid 布局则是将容器划分成行和列,产生单元格,然后指定项目所在的单元格,可以看作是二维布局。
  • 划分网格的线,称为 "网格线"(grid line)。水平网格线划分出行,垂直网格线划分出列。
  • 设为网格布局以后,容器子元素(项目)的 float、display: inline-block、display: table-cell、vertical-align 和 column-* 等设置都将失效。

父容器属性:grid-template-columns, grid-template-rows, grid-gap, grid-auto-flow, grid-auto-columns, grid-auto-rows, justify-items, align-items, justify-content, align-content
子容器属性:grid-column-start, grid-column-end, grid-row-start, grid-row-end, justify-self, align-self

  1. 经典问题

# 经典问题:

# ask: flex=1 是什么意思

# answer: flex: 1 是 CSS Flexbox 布局中的一个属性值,用于控制弹性容器内子元素的伸缩行为。

具体含义
flex 是 flex-grow、flex-shrink 和 flex-basis 的简写。

flex: 1 等同于 flex: 1 1 0,表示:

flex-grow: 1:子元素会按比例分配剩余空间。

flex-shrink: 1:子元素在空间不足时会缩小。

flex-basis: 0:子元素的初始大小为 0。

效果
子元素会根据 flex-grow 的值分配剩余空间。

如果多个子元素都有 flex: 1,它们将平分剩余空间。

# ask: flex 布局设置水平垂直居中

# answer: 给 flex 容器添加以下三个属性,就可以实现子项水平垂直居中:

display: flex; // 容器为 flex 布局
justify-content: center; // 子项在主轴(水平居中)
align-items: center; // 子项在交叉轴(垂直居中)

# ask: 如何解决 flex 布局 7 个元素使用 space-between 最后一行两边分布的问题?

# answer: 如果我们每一行显示的个数为 n,那我们可以最后一行子项的后面加上 n-2 个 span 元素,span 元素的宽度和其它子项元素宽度一样,但不用设置高度。

为什么是添加 n-2 个 span 元素呢 ?

当最后一行只有 1 个子元素时,他会默认靠左,不用处理
当最后一行子元素正好时,我们就不用关心这个问题。
所以要去掉这两种情况,只需要加 n-2 个 span 元素就好

# ask: flex 实现 8 个元素分两行排列 每行 4 个平均分布 - 自适应

# answer: 给父元素设置 display: flex; flex-wrap: wrap; 子元素设置 flex: 1 0 25%;

给父容器添加如下属性:

display: flex; //flex 布局
flex-wrap: wrap; // 换行
给子项添加如下样式:

flex-basis: 25%; // 项目占据主轴(父容器宽)的空间。
flex-grow: 0; // 不放大
flex-shrink: 0; // 缩小
以上三个属性,也可以简写在 flex: 0 0 25%;

# 当容器为 flex 时,其子元素没有指定高度时,其高度默认为父元素高度。

# ask: 圣杯布局

# answer: 拥有 header 和 footer,中间是主内容行;left 和 right 分别固定了宽度,center 会随着整体布局宽度的变化而进行伸缩

<!DOCTYPE html>
<html>
	<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 type="text/css">
			body {
				min-width: 550px;
			}
			#header {
				background-color: #999999;
			}
			
			#middle{
				/* 2. 把中间部分留出左右元素的宽度 */
				padding-left: 200px;
				padding-right: 150px;
			}
			
			#middle .column{
				float: left;
				height: 200px;
			}
			
			#left{
				width: 200px;
				background-color: #FFFF00;
				/* 4. 向左移动 center 的宽度 */
				margin-left: -100%;
				/* 5. 再向左移动自身宽度,露出被覆盖的 center 块 */
				position: relative;
				right: 200px;
			}
			
			#center{
				width: 100%;
				background-color: pink;
			}
			
			#right{
				/* 3.margin-right 让右方元素覆盖自身,达到消除自身宽度的目的,浮动到 center 上面去 */
				margin-right: -150px;
				width: 150px;
				background-color: #CCCCCC;
			}
			
			#footer {
				background-color: #999999;
			}
			
			.clearfix:after{
				display: table;
				content: '';
				clear: both;
			}
		</style>
	</head>
	<body>
		<div id="header">header</div>
		<div id="middle" class="clearfix">
			<div id="center" class="column">
				center
			</div>
			<div id="left" class="column">
				left
			</div>
			<div id="right" class="column">
				right
			</div>
		</div>
		<div id="footer">footer</div>
	</body>
</html>

# ask: 双飞翼布局

# answer: left 和 right 固定宽度;中间 main 会随着整体布局宽度的变化而伸缩

<!DOCTYPE html>
<html>
<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 type="text/css">
        body {
            min-width: 550px;
        }
        .col {
			/* 1. 设置浮动 */
			float: left;
        }
        #main {
            width: 100%;
            height: 200px;
            background-color: #FFC0CB;
        }
        #main-wrap {
			/* 2. 将 main 左右内边距留出 left 和 right 的宽度 */
			margin: 0 200px 0 150px;
        }
        #left {
            width: 150px;
            height: 200px;
            background-color: #FFFF00;
			/* 3.left 向左偏移 main 的宽度 */
			margin-left: -100%;
        }
        #right {
            width: 200px;
            height: 200px;
            background-color: #cccccc;
			/* 4.right 向左偏移自身宽度 */
			margin-left: -200px;
        }
    </style>
</head>
<body>
    <div id="main" class="col">
        <div id="main-wrap">
            main
        </div>
    </div>
    <div id="left" class="col">
        left
    </div>
    <div id="right" class="col">
        right
    </div>
</body>
</html>

# ask: 圣杯布局与双飞翼布局异同比较

# answer:

维度双飞翼布局圣杯布局
边距控制通过外层 margin 实现通过内层 padding 实现
元素偏移左右均向左偏移左侧左偏移,右侧右偏移
视觉重心主内容居中主内容靠左
适用场景广告位 / 侧边栏固定展示两侧内容灵活布局

双飞翼:均使用 margin-left,左:向左偏移 main 的宽度;右:向左偏移自身宽度

圣杯:左:使用 margin-left(向左偏移 main 的宽度); 右:margin-right(取消自身宽度)

更新于

请我喝[茶]~( ̄▽ ̄)~*

kiyoumiii 微信支付

微信支付

kiyoumiii 支付宝

支付宝

kiyoumiii 贝宝

贝宝