Skip to content

一文搞定垂直居中等各种布局

1.实现垂直居中布局的 8 种方式(注意 grid 和 vertical-align)

实现垂直居中布局有多种方式,这里列举几种常用的方法:

1.使用 Flexbox 布局:(好处是不需要知道父元素的宽高)

使用 Flexbox 是一种简单且灵活的方式来实现垂直居中布局。

css
.parent {
  display: flex;
  align-items: center; /* 垂直居中 */
  justify-content: center; /* 水平居中 */
}

2.使用 Grid 布局:place-items(好处是不需要知道父元素的宽高且代码最少)

使用 CSS Grid 布局也可以轻松实现垂直居中布局。

css
.parent {
  display: grid;
  place-items: center; /* 垂直居中和水平居中 */
}

注意:place-items: center 实际上等价于 justify-content: center + align-items: center

如果我只想要水平居中呢?和 flex 一样用 justify-content: center;

如果你只希望实现水平居中而不需要垂直居中,可以使用 CSS Grid 布局的 justify-content 属性来实现。下面是一个示例:

css
.parent {
  display: grid;
  justify-content: center; /* 子元素水平居中 */
}

.child {
  /* 无需设置宽度值 */
}

在上述示例中,将父元素的 display 属性设置为 grid,使用 Grid 布局。然后,设置 justify-content: center,它会将子元素在水平轴上居中对齐,实现水平居中的效果。

grid 与 flex 重合的配置属性有哪些?

CSS Grid 和 Flexbox 的确有一些重叠的配置属性,这些属性在两种布局模型中都可以使用。下面是一些常见的重叠属性:(只有 4 个)

  1. justify-content: 用于在主轴上对齐子元素。在 Flexbox 中,它可以水平对齐子元素;在 Grid 中,它可以水平对齐网格项目。
  2. align-items: 用于在交叉轴上对齐子元素。在 Flexbox 中,它可以垂直对齐子元素;在 Grid 中,它可以垂直对齐网格项目。
  3. align-self: 用于在 Flexbox 和 Grid 布局中单独对齐某个子元素。在 Flexbox 中,它可以单独设置子元素在交叉轴上的对齐方式;在 Grid 中,它可以单独设置网格项目在交叉轴上的对齐方式。
  4. justify-self: 用于在 Grid 布局中单独对齐某个网格项目。它可以单独设置网格项目在主轴上的对齐方式。

这些属性在使用 Flexbox 和 Grid 布局时,可以根据具体的布局需求和场景选择合适的属性进行调整。需要注意的是,这些属性在两种布局模型中的表现和功能可能略有差异,因为它们适用于不同的布局机制。

3.使用绝对定位 absolute 和 transform/margin:(分为两种情况)

这是一个使用绝对定位和 transform 来实现垂直居中的方法。

1.自身尺寸未知的情况下:

css
.parent {
  position: relative;
}

.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(
    -50%,
    -50%
  ); /*直接写-50%就可以,就是自身的50%,不用写具体的数值,但是也可以写具体的数值!*/
}

2.自身尺寸已知的情况下:

css
.parent {
  position: relative;
}

.child {
  width: 100px;
  height: 100px;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -50px; /*-高度的一半px*/
  margin-left: -50px; /*-宽度的一半px*/
}

4.使用 Table 布局 + vertical-align(仅对于 table-cell 元素)

——> 4 和 5 其实本质上都使用了 vertical-align: middle,原理一样

注意:table 默认是块级元素,而 table-cell 默认是行内元素(不是块级-行内元素)!

通过将父元素设置为 display: table,并将子元素设置为 display: table-cell,可以实现垂直居中。

css
.parent {
  display: table; /*父元素必须是table*/
  /*在使用table表格布局时,表格单元格会自动水平居中对齐。所以不需要给子元素设置text-align: center;*/
}

.child {
  display: table-cell; /*table-cell默认是行内元素,等价于inline-block*/
  vertical-align: middle;
}

5.使用 text-align + vertical-align + inline-block(仅对于 inline-block 元素)

在一些特定情况下,也可以使用 vertical-align 属性与 display: inline-block 来实现垂直居中。

css
.parent {
  text-align: center;
}

.child {
  display: inline-block;
  vertical-align: middle; /* 写在父元素里面也可以的,vertical-align也是可以继承的属性,和text-align一样 */
}

这些方法中的每一种都有其适用的场景和限制,你可以根据具体的布局需求选择合适的方法来实现垂直居中布局。

7.使用 text-align 和 line-height(对于文本)

使用 line-height 属性也可以实现一种简单的垂直居中布局方式,特别适用于单行文本的垂直居中(好处是里面不需要嵌套行内元素了)。这种方法的基本思路是将行高设置为容器的高度,从而使文本或内联元素在行框内垂直居中。

以下是使用 line-height 实现垂直居中布局的示例:

css
.parent {
  height: 200px;
  line-height: 200px; /* 与容器高度相同,垂直居中 */
  text-align: center; /* 水平居中 */
  border: 1px solid #ccc;
}

8.使用 margin:auto(仅对于父子宽高固定的情况)

margin: auto; 可以用来实现垂直居中布局,但需要结合一些其他样式属性来使用。

当一个块级元素具有固定的高度,并且它的父容器也有固定的高度时,可以通过将该元素的上下外边距(margin-topmargin-bottom)设置为 auto 来实现垂直居中布局。

css
.container {
  height: 300px; /* 父容器高度必须固定,宽度可以不指定 */
  background-color: #f0f0f0;
}

.content {
  height: 100px; /* 内容元素高度必须固定 */
  width: 100px; /* 内容元素宽度必须固定 */
  margin: auto; /* 实现水平垂直居中布局 */
}

在这个例子中,.container 是父容器,它的高度设置为 300px,而 .content 是内容元素,它的高度设置为 100px。通过将 .content 的上下外边距设置为 auto,它将在 .container 中垂直居中显示。

请注意,这种方法仅在父容器的高度是固定的情况下有效

2.水平实现一栏固定,一栏自适应的布局(两栏布局)

三栏布局如何实现?左右固定,中间自适应

1.BFC 布局

左右 float,中间 bfc 也就是 overflow:hidden(因为 BFC 的区域不会与浮动元素重叠!)

css
.left-column {
  width: 200px; /* 左侧固定宽度 */
  float: left; /* 左浮动 */
}

.middle-column {
  overflow: hidden; /* 创建 BFC */
}

大坑:使用 float: left/right;时浮动元素要在非浮动元素的前面,否则非浮动元素后面的浮动元素一定会换行。

所以这里的 left 必须在 middle 前面!

html
<div class="container">
  <div class="left-column">左侧固定内容</div>
  <div class="middle-column">中间自适应内容</div>
</div>

2.浮动/绝对定位布局

左 float/absolute 浮动,中间设置左的 margin

css
.container {
  width: 100%; /* 可根据需要设置容器宽度 */
}

.left-column {
  width: 200px; /* 左侧固定宽度 */
  float: left; /* 左侧浮动 */
  /*
    	绝对定位也可以:
    	position:absolute;
    	left:0;
    */
}
.middle-column {
  margin-left: 210px;
}

大坑:使用 float: left/right;时浮动元素要在非浮动元素的前面,否则非浮动元素后面的浮动元素一定会换行。

所以这里的 left 必须在 middle 前面!

html
<div class="container">
  <div class="left-column">左侧固定内容</div>
  <div class="middle-column">中间自适应内容</div>
</div>

3.flex 布局

最外层设置 flex,左固定宽度,中间 flex-grow=1

css
.container {
  display: flex;
}

.left-column {
  width: 200px; /* 左侧固定宽度 */
}

.middle-column {
  flex-grow: 1; /* 中间自适应宽度 */
}

4.gird 布局

css
.container {
  display: grid;
  grid-template-columns: 200px auto; /* 左侧、中间的列宽 */
}

5.table 布局

css
.container {
  display: table;
  width: 100%;
}
.container > div {
  display: table-cell;
}
.left {
  width: 100px;
  background: red;
}
.main {
  background: blue;
}

3.水平实现两栏固定,一栏自适应的布局(三栏布局)

三栏布局如何实现?左右固定,中间自适应

1.BFC 布局

左右 float,中间 bfc 也就是 overflow:hidden(因为 BFC 的区域不会与浮动元素重叠!)

css
.left-column {
  width: 200px; /* 左侧固定宽度 */
  float: left; /* 左浮动 */
}

.right-column {
  width: 200px; /* 右侧固定宽度 */
  float: right; /* 右浮动 */
}

.middle-column {
  overflow: hidden; /* 创建 BFC */
}

大坑:使用 float: left/right;时浮动元素要在非浮动元素的前面,否则非浮动元素后面的浮动元素一定会换行。

所以这里的 left 和 right 必须在 middle 前面!

html
<div class="container">
  <div class="left-column">左侧固定内容</div>
  <div class="right-column">右侧固定内容</div>
  <div class="middle-column">中间自适应内容</div>
</div>

BFC 的特点:

设置 overflow:hidden 会触发块级格式化上下文(BFC)。

具有 BFC 特性的元素可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响外面的元素。

触发了 BFC 的元素仍然保持流体特性,也就是说 BFC 元素虽然不与浮动交集,自动退避浮动元素宽度的距离,但本身作为普通元素的流体特性依然存在,反映在布局上就是自动填满除去浮动内容以外的剩余空间

**BFC 具有普通元素没有的特性:**下边距(垂直外边距)不发生折叠;可以清除浮动;可以阻止元素被覆盖。

正因为有了这些特性,所以右边可以用触发 BFC 的元素来清除左边浮动的影响。

注意:BFC(块级格式化上下文)不会自动占满一行,它的行为取决于其内容(如果里面有 div 就可能占满一行)和容器的大小以及其他 CSS 属性和规则的影响。

2.浮动/绝对定位布局

左右 float/absolute 浮动,中间设置左右的 margin

css
.container {
  width: 100%; /* 可根据需要设置容器宽度 */
}

.left-column {
  width: 200px; /* 左侧固定宽度 */
  float: left; /* 左侧浮动 */
  /*
    	绝对定位也可以:
    	position:absolute;
    	left:0;
    */
}
.middle-column {
  margin-left: 210px;
  margin-right: 210px;
}
.right-column {
  width: 200px; /* 右侧固定宽度 */
  float: right; /* 右侧浮动 */
  /*
    	绝对定位也可以:
    	position:absolute;
    	right:0;
    */
}

大坑:使用 float: left/right;时浮动元素要在非浮动元素的前面,否则非浮动元素后面的浮动元素一定会换行。

所以这里的 left 和 right 必须在 middle 前面!

html
<div class="container">
  <div class="left-column">左侧固定内容</div>
  <div class="right-column">右侧固定内容</div>
  <div class="middle-column">中间自适应内容</div>
</div>

**absolute 实现的缺点:**如果中间栏含有最小宽度限制,或是含有宽度的内部元素,当浏览器宽度小到一定程度,会发生层重叠的情况。

absolute 的元素是以最近的父元素还是兄弟元素的定位为基准?

在 CSS 中,使用 position: absolute; 定位的元素是以最近的已定位(非 static)的祖先元素为基准进行定位,而不是以兄弟元素为基准。这意味着它会相对于最近的具有定位属性(如 position: relative;position: absolute;position: fixed;position: sticky;)的祖先元素进行定位。

如果没有找到已定位的祖先元素,那么绝对定位元素将相对于最初的包含块(通常是视口)进行定位。这就是为什么通常需要为绝对定位元素的父元素设置 position: relative; 或其他定位属性,以确保它们按预期进行定位。

兄弟元素的定位与绝对定位元素本身没有直接关系,它们不会作为基准用于绝对定位元素的位置计算。

如果父元素没有 relative,而父元素的父元素有呢?

如果一个元素的直接父元素没有设置 position: relative;,但其父元素的父元素(即祖先元素)设置了 position: relative;,那么该元素会相对于最近的具有 position: relative; 属性的祖先元素进行定位,而不是相对于其直接父元素。

这是因为绝对定位元素(position: absolute;)在寻找定位基准时会向上遍历元素的祖先元素,直到找到具有 position: relative;position: absolute;position: fixed;position: sticky; 的元素,然后相对于这个元素进行定位。

3.flex 布局

最外层设置 flex,左右固定宽度,中间 flex-grow=1

css
.container {
  display: flex;
}

.left-column,
.right-column {
  width: 200px; /* 左侧和右侧固定宽度 */
}

.middle-column {
  flex-grow: 1; /* 中间自适应宽度 */
}

4.gird 布局

css
.container {
  display: grid;
  grid-template-columns: 200px auto 200px; /* 左侧、中间和右侧的列宽 */
}

5.table 布局

css
.container {
  display: table;
  width: 100%;
}
.container > div {
  display: table-cell;
}
.left {
  width: 100px;
  background: red;
}
.main {
  background: blue;
}
.right {
  width: 200px;
  background: red;
}

中间列没有设置宽度,它会自适应剩余的空间,为什么?

如果你没有为中间列设置固定的宽度,同时将其 display 属性设置为 table-cell,浏览器会根据容器的宽度和其他列的宽度,将中间列的宽度分配为剩余的可用空间,以确保所有列水平排列而不重叠。

这种行为类似于 HTML 表格的默认行为,其中表格中的列会自动根据内容和表格的宽度进行调整,以填充可用的空间。

所以,通过将中间列的宽度属性设置为空,它会自动适应容器中剩余的宽度,实现了中间列的自适应。这是一种常见的多列布局技巧,特别适用于需要一个自适应宽度列的情况。

前置知识点:margin 负值对浮动元素的影响

标准盒模型下,盒子总体宽度(真实宽度+margin) = css 设置的 width(内容区域宽度)+ 左右 padding + 左右 border + 左右 margin

一般情况下,这些值都是正值,但当浮动元素的 margin 为负的时候,会有什么效果呢?(注意,padding 和 border 没有负值)

代码及图示如下(已去多余样式),有两个左浮动的盒子,我们尝试给下方绿盒子添加负值 margin。

html
<div class="outer">
  <div class="inner1">上</div>
  <div class="inner2">下</div>
</div>
css
.outer {
  width: 300px;
  height: 300px;
}

.inner1 {
  float: left;
  height: 100px;
  width: 180px;
}

.inner2 {
  float: left;
  height: 100px;
  width: 150px;
}

初始状态

img           img

当 margin-left = -29px 时

此时,绿盒子向左移动了 29px。

img

当 margin-left = -30px 时

此时,绿盒子跑到了第一行,并且与红盒子的右端重合了 30px,为什么呢?

初始状态时,第一行的右边只剩下 120px,已经装不下绿盒子了,所以绿盒子被挤到第二行。

已知,盒子的总体宽度 = 内容宽度 + 左右 padding + 左右 border + 左右 margin,所以当给绿盒子设置 margin-left = -30px 时,绿盒子的总体宽度为 150px + (0 + 0) + (0 + 0)+(- 30px + 0 )= 120px,所以刚刚好能够浮动上第一行的右边。

可以这么理解,就像浮动元素会浮在标准流元素上方以及 z-index 更高的定位元素会覆盖到其他定位元素上。

因为给绿盒子设置了 margin-left = -30px,所以绿盒子的左边 30px 宽度的区域“浮”得更高了,对于红盒子来说,这绿盒子左端这 30px 相当于没有了。或者,还可以想象为绿盒子左端 30px 的 z 坐标轴上的值更大了,这 30px 已经不占这层页面的宽度了,所以我们看到绿盒子与红盒子重叠 30px

img     img

当 margin-left = -180px 时

相当于在 margin-left = -30px 的基础上,再加上 margin-left = -150px,即继续向左移动 150px。

此时绿盒子的左端与红盒子的左端刚刚好重叠。

img     img

当 margin-left = -330px 时

由于现在已经是第一行,所以绿盒子不会继续往上一行走了,只会继续向左移动。

此时,绿盒子刚刚离开父盒子,而且右端与父盒子左端重叠。

img    img

总结

margin 的负值会造成宽度的减小,一旦元素的宽度可以被上一层装上,就会浮动到上一层,客观感觉是基于了右侧进行定位,实际上只是自己浮上去了

并且基于右侧的定位也是有计算规则的:偏移距离 = [margin 负值大小 - 自身宽度大小]

比如设置了 margin-left:-200px,那么就会距离右侧 100px=200px-自身宽度 100px,基于右侧这个右侧指的是内容区域,不包括 padding

注意:如果 margin-left 负的值 > 自身的宽度,那么加和起来的宽度就会小于 0,那么就一定会浮到上面一层,并且形成偏移!

注意:CSS 中负外边距的一个特性,就是可以用于将元素向相反的方向移动

6.圣杯布局

"圣杯布局" 是一种用于创建具有三个列的常见网页布局的 CSS 技术。它通常用于创建具有左侧和右侧固定宽度列以及中间自适应宽度列的布局。圣杯布局的目标是实现以下效果:

  1. 左侧和右侧列具有固定宽度。
  2. 中间列自适应剩余的宽度,以填充中间空间。
  3. 所有列的高度保持一致,以确保背景颜色或边框的连续性。

html

html
<div class="container">
  <div class="middle-column">中间自适应内容</div>
  <div class="left-column">左侧固定内容</div>
  <div class="right-column">右侧固定内容</div>
</div>

css

css
/* 两边定宽,中间自适用 */
.container {
  padding-left: 200px; /* 左侧列宽度 */
  padding-right: 200px; /* 右侧列宽度 */
  overflow: hidden;
}

.middle-column {
  width: 100%; /* 中间列占据剩余宽度 */
  float: left;
}

.left-column {
  width: 200px; /* 左侧列宽度 */
  float: left;
  margin-left: -100%; /* 负外边距将列拉回左侧 */
  position: relative;
  left: -200px; /* 左侧列的位置调整 */
}

.right-column {
  width: 200px; /* 右侧列宽度 */
  float: left;
  margin-left: -200px; /* 负外边距将列拉回左侧 */
  position: relative;
  right: -200px; /* 右侧列的位置调整 */
}

在这个示例中,.container 元素用于包裹所有列,并使用 padding-leftpadding-right 来为左侧和右侧列留出空间。中间列使用 width: 100%; 来占据剩余的宽度,左侧和右侧列使用负外边距和相对定位来移动到适当的位置,以保持三列布局的一致性。

这种布局技巧是一种传统的方法,用于实现具有固定宽度列和自适应列的多列布局,但它有时会涉及到复杂的样式调整。在现代 CSS 布局技术(如 Flexbox 和 Grid)的支持下,通常更推荐使用这些方法来实现多列布局,因为它们更灵活、易于维护,并且不需要使用负外边距和相对定位。

圣杯布局怎么理解?

关键是左侧和右侧列使用负外边距和相对定位来移动到适当的位置!

圣杯布局的代码的核心难点是如何不通过绝对定位来让文档流中后面的元素位于前面元素,这里运用了浮动、负外边距以及相对定位来实现。

css
.left-column {
  width: 200px; /* 左侧列宽度 */
  float: left;
  margin-left: -100%; /* 负外边距将列拉回左侧 */
  position: relative;
  left: -200px; /* 左侧列的位置调整 */
}

这里 margin-left: -100%;由于负外边距-100%计算值是宿主元素内容盒模型的宽度,其宽度大于左侧栏宽度 200px**(会造成元素实际宽度<0)**。所以浮动的左侧栏通过负外边距上浮到上层,以中间栏(#center)的右侧外边缘为基准线,向左侧移动[宿主元素内容盒模型宽度-浮动元素自身宽度]的距离,恰好位于中间栏(#center)的左侧,占据容器(#container)padding-left 的位置。

css
.right-column {
  width: 200px; /* 右侧列宽度 */
  float: left;
  margin-left: -200px; /* 负外边距将列拉回左侧 */
  position: relative;
  right: -200px; /* 右侧列的位置调整 */
}

当左侧栏(#left)由于负外边距上移后,右侧栏(#right)由于左浮动位于容器(#container)的内侧左边缘。同样负外边距 margin-right: -200px; 设置令右侧栏(#right)上移,同样是以中间栏(#center)的右侧外边缘为基准线,形成了正好位于中间栏的右侧的效果。 这样通过对浮动元素左、右负边距的设置,令原本位于中间栏(#center)下方的浮动元素左侧栏(#left)、右侧栏(#right)上移是圣杯布局的理解难点。

自己的个人理解:

由于元素宽度的计算是 width(内容区域宽度)+ 左右 padding + 左右 border + 左右 margin,一旦元素的宽度可以被上一层装上,就会浮动到上一层,<=0 的时候必然浮动到上一层,并且可能发生重叠!

所以左侧元素设置的 margin-left:100% 是让元素距离右侧 [容器 100%-自身 200px] 的距离,看到的效果就是贴着容器左边了!

所以右侧元素设置的 margin-left:-200px 是让元素距离右侧 [200px-自身 200px]=0 的距离,看到的效果就是贴着容器右边了!

本质上由于宽度计算之后<=0,而 center 元素又是 width:100%的,所以就直接重叠了(重叠后左右的会覆盖中间的,因为设置了 margin 负值的元素层级更高),所以接着我们又用 relative 移动元素自身 来解决了重叠问题。

7.双飞翼布局

双飞翼布局是一种用于网页设计的布局技术,旨在实现灵活的三栏布局,其中中间内容栏可以自适应屏幕宽度,而左侧和右侧栏可以固定或自适应宽度。这种布局技术通常使用 HTML 和 CSS 来实现,以下是双飞翼布局的主要组成部分:

  1. 主内容区域(中间内容栏): 这是网页中的主要内容区域,通常包含页面的主要信息。这个区域应该在 HTML 中放在最前面,因为它是页面的主要内容。
  2. 左侧栏(Left Column): 这是位于主内容区域左侧的侧边栏。左侧栏可以包含导航链接、广告、相关链接等。它通常是固定宽度的,但也可以使用百分比来定义宽度,以适应不同屏幕尺寸。
  3. 右侧栏(Right Column): 这是位于主内容区域右侧的侧边栏。右侧栏的特点与左侧栏类似,可以是固定宽度或百分比宽度。

关键的挑战是确保主内容区域能够自适应屏幕宽度,同时使左侧和右侧栏保持相对定位。双飞翼布局通常使用 CSS 技巧来实现,其中包括使用浮动(float)、负边距(negative margins)、相对定位(position:relative)等属性。

以下是一个简单的示例代码,展示了双飞翼布局的实现:

html
<div class="container">
  <div class="main col ">
    <div class="main_inner">Main</div>
  </div>
  <div class="left col ">Left</div>
  <div class="right col ">Right</div>
</div>
css
body,
html,
.container {
  height: 100%;
  padding: 0; /* 没有对container设置padding */
  margin: 0;
}
.col {
  float: left; /* 把left和right定位到左右部分 */
}
.main {
  width: 100%;
  height: 100%;
  background: #659;
}
.main_inner {
  /* 处理中间栏的内容被遮盖问题 ——> 这里是主要改进的地方 */
  margin: 0 200px 0 100px;
}
.left {
  width: 100px;
  height: 100%;
  margin-left: -100%; /* 没有使用relative调整位置 */
  background: #ff69b4;
}
.right {
  height: 100%;
  width: 200px;
  margin-left: -200px;
  background: #ff69b4;
}

通过这些 CSS 规则,左侧和右侧栏会以固定宽度出现在主内容区域的两侧,而主内容区域会自动适应屏幕宽度。这使得双飞翼布局成为一种在网页设计中实现多栏布局的强大技术。

双飞翼布局的好处:

(1)主要的内容先加载的优化。

(2)兼容目前所有的主流浏览器,包括 IE6 在内。

(3)实现不同的布局方式,可以通过调整相关 CSS 属性即可实现。

对比圣杯布局和双飞翼布局:

(1)都是左右栏定宽,中间栏自适应的三栏布局,中间栏都放到文档流前面,保证先行渲染。

(2)解决方案基本相似:都是三栏全部设置左浮动 float:left,然后分别结局中间栏内容被覆盖的问题。

(3)解决中间栏内容被覆盖问题时,圣杯布局设置父元素的 padding,双飞翼布局在中间栏嵌套一个 div,内容放到新的 div 中,并设置 margin,实际上,双飞翼布局就是圣杯布局的改进方案。

即由原来的left/right 去覆盖容器的左右 padding 变成了覆盖 main 里面的 main_inner 的左右 margin了!

自适应到底指的是什么?

主内容区域能够自适应屏幕宽度(不同设备的不同屏幕大小),同时使左侧和右侧栏保持相对定位。

4.垂直方向,两个栏固定,一个自适应?grid-template-rows

除了 flex:1 这种解决方案,我们还可以使用 grid 布局的方式:

可以通过 CSS 的 Grid 布局实现垂直方向上有三个块,其中两个固定高度,一个自适应高度的布局。以下是使用 Grid 布局的示例:

HTML 结构:

html
<div class="container">
  <div class="fixed-block">固定块1</div>
  <div class="flexible-block">自适应块</div>
  <div class="fixed-block">固定块2</div>
</div>

CSS 样式:

css
.container {
  display: grid;
  grid-template-rows: 50px 1fr 50px; /* 父容器的行高设置,两个固定为50px,一个为自适应! */
  height: 300px; /* 父容器的高度 */
  background-color: #f0f0f0;
}

.fixed-block {
  background-color: #ffcccc;
}

.flexible-block {
  background-color: #ccffcc;
}

在上面的例子中,父容器 .container 使用 Grid 布局,并使用 grid-template-rows 属性来设置三个行的高度。.fixed-block 是固定高度的块,没有指定高度值,它会根据行高自动填充高度。.flexible-block 是自适应块,它的行高设置为 1fr,表示它将占据剩余可用空间。

在这种方法中,你可以根据需要调整父容器的高度,Grid 布局会根据 grid-template-rows 属性设置的行高来分配块的高度。

5.实现一个三等分布局,有哪些方式:grid-template-columns

实现一个将容器分为三等份的布局有多种方式,以下是几种常见的方法:

  1. 使用 Flexbox 布局:

使用 Flexbox 是一种简单且强大的方式,可以轻松实现三等分布局。

css
.parent {
  display: flex;
}

.child {
  flex: 1; /* 平均分配剩余空间 */
  border: 1px solid #ccc;
}
  1. 使用 Grid 布局:grid-template-columns ——> 重点

使用 CSS Grid 布局也可以实现三等分布局。

css
.parent {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr; /* 平均分配列宽 */
  /*分配行高:grid-template-rows */
}

.child {
  border: 1px solid #ccc;
}
  1. 使用百分比宽度:(不准确)

通过设置子元素的百分比宽度,可以实现三等分布局。

css
.child {
  width: 33.33%; /* 平均分配宽度,但是这样其实不准确,因为真实的宽度还要加上border,所以需要用 calc计算*/
  border: 1px solid #ccc;
  box-sizing: border-box; /* 包含边框在内的盒模型 */
}
  1. 使用 calc() 函数:

使用 calc() 函数可以根据容器宽度计算子元素的宽度,从而实现三等分布局。

css
.child {
  width: calc(
    33.33% - 2px
  ); /* 减去边框宽度,因为标准盒模型的真实宽度还需要加上border和padding */
  border: 1px solid #ccc;
  box-sizing: border-box;
}

这些方法中的每一种都有其适用的场景和限制,你可以根据具体的布局需求选择合适的方法来实现三等分布局。需要注意的是,有些方法可能受到盒模型、边距、边框等因素的影响,具体情况需要根据布局的具体要求进行调整。