float 布局
- float 的设计初衷是为了实现文字环绕图片的效果;
- 当一个元素被设置为浮动时,它会脱离正常的文档流 (Normal Flow),并尽可能地向左或向右移动,直到它的外边缘碰到包含块 (Containing Block) 的边缘或另一个浮动元素的边缘;
- float 的取值:
- left: 元素向左浮动;
- right: 元素向右浮动;
- none: 默认值。元素不浮动,遵循正常的文档流;
- inherit: 元素继承其父元素的 float 值;
核心特性及影响
-
脱离文档流- 正常文档流:元素会按照其在 HTML 中出现的顺序,自上而下、从左到右排列,块级元素独占一行,行内元素共享一行;
- 浮动后:元素会从这个正常的排列中 “跳” 出来,漂浮在文档流之上;它原来在文档流中占据的位置会被后续的元素填补;
-
对周围元素的影响- 块级元素:会无视浮动元素的存在,继续占据整个宽度,并在垂直方向上排列;
- 行内元素 (包括文本):会环绕在浮动元素的周围,这正是 float 被设计出来的初衷;
-
父元素高度塌陷- 问题描述:当一个父元素的所有子元素都是浮动元素时,父元素在计算自身高度时,会忽略这些浮动的子元素;结果就是父元素的高度变为 0,看起来就像 “塌陷” 了一样;
- 原因:因为浮动元素脱离了文档流,父元素无法感知到它们的存在;
解决父元素高度塌陷的方法(清除浮动)
使用 clear 属性(最直接)
-
clear 属性用于指定一个元素是否必须移动到它之前的浮动元素的下方;
- 取值:left、right、both、none;
- 用法:在浮动元素的父元素内部,最后添加一个空的块级元素,并为其设置 clear: both;
- 缺点:会在 HTML 中引入无意义的空标签,造成结构冗余;
-
示例代码:
<head> <style> .parent { border: 2px solid blue; } .child { float: left; width: 100px; height: 100px; background-color: red; margin: 10px; } .clearfix { clear: both; } </style> </head> <body> <div class="parent"> <div class="child"></div> <div class="child"></div> <div class="child"></div> <div class="clearfix"></div> <!-- 关键所在 --> </div> <!-- 现在 .parent 元素的高度会正确地包含所有浮动的 .child 元素 --> </body> -
效果展示:
使用伪元素 ::after (Clearfix Hack) - 推荐
-
这是目前最常用、最优雅的清除浮动方法;它利用 CSS 伪元素在父元素的内容之后自动插入一个清除浮动的元素,而无需修改 HTML 结构;
-
核心代码:
.clearfix::after { content: ""; /* 伪元素必须有 content 属性,空值也可以 */ display: table; /* 或者 block */ clear: both; } /* 为了兼容旧版 IE,有时还会加上 */ .clearfix { *zoom: 1; }
让父元素也浮动
-
给父元素也设置一个 float 值;这样父元素会包裹住其内部的浮动子元素;
-
缺点:这会让父元素也脱离文档流,可能会对父元素的兄弟元素布局产生意料之外的影响,通常需要在更高层级的父元素上再次清除浮动,容易引发连锁反应;
使用 overflow 属性
-
给父元素设置
overflow: hidden或overflow: auto; -
当 overflow 的值不是 visible 时,会触发一个 “块级格式化上下文(Block Formatting Context, BFC)”;BFC 的一个特性就是能够包含内部的浮动元素,计算高度时会将它们也考虑进去;
-
缺点:
overflow: hidden会裁剪掉超出父元素边界的内容,如果子元素的定位或尺寸超出了父元素,可能会被意外隐藏;overflow: auto可能会在不需要滚动条的时候也显示出滚动条;
常见应用场景
-
图文混排:这是 float 最经典、最无可替代的用途; -
创建多列布局:在 Flexbox 和 Grid 普及之前,float 是实现两栏、三栏等多列布局的主要方式; -
创建导航栏:可以将导航项浮动到一行显示;
优缺点
-
优点:
- 实现图文混排非常直观和简单;
- 对于简单的多列布局,实现起来也比较直接;
- 浏览器兼容性非常好,支持所有现代浏览器和旧版浏览器 (如 IE6/7);
-
缺点:
- 高度塌陷问题:需要额外的代码 (如 clearfix) 来修复,增加了复杂性;
- 布局脆弱:浮动元素的位置依赖于其他浮动元素和文档流,一旦某个元素的尺寸发生变化,可能会导致整个布局错乱;
- 脱离文档流:这使得元素的定位和对齐变得不那么直观,尤其是在复杂布局中;
- 不适合垂直居中:使用 float 很难优雅地实现垂直居中对齐;
- 与现代布局方式相比:Flexbox 和 Grid 在处理对齐、分布、响应式等方面提供了更强大、更简洁、更具逻辑性的解决方案;
inline-block 布局
行内块级元素的特性
和块级元素一样,能设置元素的宽高,垂直方向的间距;
宽度如果不指定,则为内部元素的框定;
外部排列方式和行内元素一样,是水平排列的;
常见问题
空白的问题:在设置 inline-block 的元素的父元素设置 font-size: 0;
高度不一样的元素,垂直方向不对齐:在设置 inline-block 的元素上设置 vertical-align: top;
示例代码
<style>
.ly {
width: 100%;
font-size: 0 !important;
text-align: right;
}
.ly__item {
display: inline-block;
vertical-align: top;
font-size: medium;
background: yellow;
width: 100px;
text-align: center;
}
</style>
<div class="ly">
<div class="ly__item">1</div>
<div class="ly__item">2</div>
<div class="ly__item">3</div>
<div class="ly__item">4</div>
</div>
Flex 布局 (专注“轴”)
Flex 是 Flexible Box 的缩写,意为 弹性布局 ,用来为盒状模型提供最大的灵活性,是一维布局;
注意:设为 Flex 布局以后,子元素的 float、clear 和 vertical-align 属性将失效;
基本概念
-
图解

-
采用 Flex 布局的元素,称为 Flex 容器(flex container),它的所有子元素自动成为容器成员(flex item);
-
容器默认存在两根轴:
- 水平的主轴(main axis)和垂直的交叉轴(cross axis);
- 主轴的开始位置(与边框的交叉点)叫做 main start,结束位置叫做 main end;
- 交叉轴的开始位置叫做 cross start,结束位置叫做 cross end;
-
项目默认沿主轴排列,单个项目占据的主轴空间叫做 main size,占据的交叉轴空间叫做 cross size;
容器的属性
-
flex-direction 属性:决定主轴的方向(即项目的排列方向)

-
flex-wrap 属性:如果一条轴线排不下,如何换行;

-
flex-flow 属性:flex-direction 属性和 flex-wrap 属性的简写形式,默认值为 row nowrap;
-
justify-content 属性:定义了项目在主轴上的对齐方式;

-
align-items 属性:定义项目在交叉轴上如何对齐;

-
align-content 属性:定义了多行的对齐方式,如果项目只有一行,该属性不起作用,flex-warp 为 warp 时生效(可以理解成增强了 flex-warp 属性);

项目(容器成员)的属性
-
order 属性:定义项目的排列顺序,数值越小,排列越靠前,默认为 0;
-
flex-grow 属性:定义项目的放大比例,默认为 0,即如果存在剩余空间,也不放大;
-
flex-shrink 属性:定义了项目的缩小比例,默认为 1,即如果空间不足,该项目将缩小;
-
flex-basis 属性:定义了在分配多余空间之前,项目占据的主轴空间(main size),浏览器根据这个属性,计算主轴是否有多余空间,默认值为auto,即项目的本来大小;
-
flex 属性:是 flex-grow、flex-shrink 和 flex-basis 的简写,默认值为 0 1 auto,后两个属性可选;
-
align-self 属性:允许单个项目有与其他项目不一样的对齐方式,可覆盖 align-items 属性,默认值为 auto,表示继承父元素的 align-items 属性,如果没有父元素,则等同于 stretch;
Grid 布局 (专注“网格”)
Grid 布局即网格布局,是一种新的 CSS 布局模型,比较擅长将一个页面划分为几个主要区域,以及定义这些区域的大小、位置、层次等关系;
号称是最强大的的 CSS 布局方案,是目前唯一一种 CSS 二维布局;
基本概念
-
display 属性:当一个 HTML 元素将 display 属性设置为 grid 或 inline-grid 后,它就变成了一个网格容器,这个元素的所有直系子元素将成为网格元素;.grid-container { display: grid; } /* 或 */ .grid-container { display: inline-grid; } -
网格轨道:grid-template-columns 和 grid-template-rows 属性来定义网格中的行和列,容器内部的水平区域称为行,垂直区域称为列;

.grid-container { display: grid; /* 在网格容器中创建三个列 */ grid-template-columns: auto auto auto; /* 网格容器中设置行的高度 */ grid-template-rows: 100px 300px; } /* 或 */ .grid-container { display: grid; /* 等价 grid-template-rows: 100px 300px; grid-template-columns: auto auto auto; */ grid-template: 100px 300px / auto auto auto; } -
fr 单位:网格引入了 fr 单位来创建灵活的网格轨道,一个 fr 单位代表网格容器中可用空间的一等份;.grid-container { display: grid; /* 创建三个相等宽度的轨道,这些轨道会随着可用空间增长和收缩 */ grid-template-columns: 1fr 1fr 1fr; } -
网格单元:一个网格单元是在一个网格元素中最小的单位,从概念上来讲其实它和表格的一个单元格很像;

-
网格区域:网格元素可以向行或着列的方向扩展一个或多个单元,并且会创建一个矩形的网格区域;

-
网格列:网格元素的垂直线方向称为列 (Column);

-
网格行:网格元素的水平线方向称为行 (Row);

-
网格间距:网格间距 (Column Gap) 指的是两个网格单元之间的网格横向间距或网格纵向间距;

.grid-container { display: grid; /* 设置列之间的网格间距 */ grid-column-gap: 50px; }.grid-container { display: grid; /* 设置行之间的网格间距 */ grid-row-gap: 100px; }.grid-container { display: grid; /* grid-row-gap 和 the grid-column-gap 属性的简写 */ grid-gap: 50px 100px; } -
网格线:列与列,行与行之间的交接处就是网格线,下面这个三列两行的网格中,就拥有四条纵向的网格线 (灰色圆圈标记),以及三条横向的网格线 (黑色圆圈标记);

.item1 { /* 该元素 合并了前两列 */ grid-column-start: 1; grid-column-end: 3; }.item1 { /* 该元素 合并了前两行 */ grid-row-start: 1; grid-row-end: 3; }
容器属性
-
justify-content 属性:- 语法:
justify-content: flex-start|flex-end|center|space-between|space-around|initial|inherit; - 属性值:
值 描述 flex-start 默认值,从行首起始位置开始排列 flex-end 从行尾位置开始排列 center 居中排列 space-between 均匀排列每个元素,首个元素放置于起点,末尾元素放置于终点 space-evenly 均匀排列每个元素,每个元素之间的间隔相等 space-around 均匀排列每个元素,每个元素周围分配相同的空间 initial 设置该属性为它的默认值 inherit 从父元素继承该属性
- 语法:
-
align-content 属性- 语法:
align-items: stretch|center|flex-start|flex-end|baseline|initial|inherit; - 属性值:
值 描述 stretch - 默认值,元素被拉伸以适应容器
- 如果指定侧轴大小的属性值为 ‘auto’,则其值会使项目的边距盒的尺寸尽可能接近所在行的尺寸,但同时会遵照
‘min/max-width/height’ 属性的限制center - 元素位于容器的中心
- 弹性盒子元素在该行的侧轴 (纵轴) 上居中放置 (如果该行的尺寸小于弹性盒子元素的尺寸,则会向两个方向溢出
相同的长度)flex-start - 元素位于容器的开头
- 弹性盒子元素的侧轴 (纵轴) 起始位置的边界紧靠住该行的侧轴起始边界flex-end - 元素位于容器的结尾
- 弹性盒子元素的侧轴 (纵轴) 起始位置的边界紧靠住该行的侧轴结束边界baseline - 元素位于容器的基线上
- 如弹性盒子元素的行内轴与侧轴为同一条,则该值与 ‘flex-start’ 等效,其它情况下,该值将参与基线对齐initial 设置该属性为它的默认值 inherit 从父元素继承该属性
- 语法:
-
行间距、列间距- grid-row-gap 属性、grid-column-gap 属性分别设置行间距和列间距;
- grid-gap 属性是两者的简写形式;
-
grid-template-areas 属性:grid-area 属性可以对网格元素进行命名,可以通过容器的 grid-template-areas 属性来引用;.item1 { /* 网格元素命名 */ grid-area: myArea; } .grid-container { /* item1 命名为 "myArea", 并跨越 2 列 */ grid-template-areas: 'myArea myArea . . .'; }.item1 { grid-area: myArea; } .grid-container { /* item1 跨两行两列,.代表没有名字的项目 */ grid-template-areas: 'myArea myArea . . .' 'myArea myArea . . .'; } -
grid-auto-flow 属性:指定自动布局算法怎样运作值 描述 row 默认值,通过填充每一行来放置网格元素,在必要时增加新列 column 通过填充每一列来放置网格元素,在必要时增加新列 dense 如果后面出现了稍小的元素,则会试图去填充网格中前面留下的空白,这样做会填上稍大元素留下的空白,但同时
也可能导致原来出现的次序被打乱row dense 按行来填充网格中前面留下的空白 column dense 按列来填充网格中前面留下的空白 -
grid-auto-columns、grid-auto-rows 属性:设置网格中行、列的默认大小
项目属性
-
跨多个列、行.item1 { /* 第 1 列开始,在第 5 列前 */ grid-column: 1 / 5; /* 第 1 行开始,在第 4 行前 */ grid-row: 1 / 4; /* 等价 */ grid-column-start: 1; grid-column-end: 5; grid-row-start: 1; grid-row-end: 4; }.item1 { /* 跨越 2 列 */ grid-column: 1 / span 2; /* 跨越 2 行 */ grid-row: 1 / span 2; /* 等价 */ grid-column-start: 1; grid-column-end: 3; grid-row-start: 1; grid-row-end: 3; } -
grid-area 属性:grid-row-start, grid-column-start, grid-row-end 以及 grid-column-end 属性的简写.item8 { grid-area: 1 / 2 / 5 / 6; /* 等价 */ grid-row: 1 / 5; grid-column: 2 / 6; /* 等价 */ grid-area: 1 / 2 / span 4 / span 4; } -
justify-self、align-self 属性:设置单元格内容的水平、垂直位置,与 justify-content、align-content 类似;
columns 布局 (专注“列”)
CSS 高级✍️ 精通 CSS 选择符
上一篇