布局系统✅
CSS 支持哪些布局方式?
答案
布局方式 | 描述 |
---|---|
文档流(normal flow) | 默认布局方式,基于元素是块级元素还是内联元素。按顺序排布, 可以通过 display:inline-block 使块级元素横向排列。 |
浮动(floating) | 设置 float 属性使元素脱离文档流,向左或向右浮动,允许其他元素环绕。 |
定位(positioning) | 通过 position 属性设置元素的定位方式,如 static 、relative 、absolute 、fixed 、sticky 。 |
弹性布局(Flexbox) | 一维布局模型,通过 display:flex 设置容器,允许子元素在主轴和交叉轴上对齐和分布。 |
网格布局(Grid) | 二维布局模型,通过 display:grid 设置容器,允许精确控制行和列的布局。 |
多列布局(multi-column) | 通过 column-count 、column-width 等属性实现多列文本布局。 |
表格布局(table) | 使用 display:table 、display:table-row 等属性模拟表格布局。 |
响应式布局(responsive) | 结合媒体查询和流式布局技术,实现适应不同屏幕尺寸的布局。 |
- 文档流
- 浮动
- 定位
- 弹性布局
- 网格布局
- 多列布局
- 表格布局
- 响应式布局
内联元素是如何布局的?
答案
参考规范定义 https://drafts.csswg.org/css-text-3/#order 和 chromium LayoutNG Inline Layout 实现
内联元素的布局流程主要分为三个阶段:
- 预布局(Pre-layout):遍历 LayoutObject 树,收集所有非原子内联元素和文本节点,生成拼接后的字符串和 NGInlineItem 列表。此阶段会根据 CSS white-space 规则处理空白字符,并进行文本分段和双向文本(BiDi)处理。
- 换行(Line breaking):测量每个 NGInlineItem,根据可用空间将内容拆分为多行,为每一行生成 NGInlineItemResult 列表。此阶段会计算边框、内边距等的尺寸,确定每行可容纳的内容,并处理溢出和断行点。
- 行盒构建(Line box construction):对每一行的 NGInlineItemResult 进行双向重排序(BiDi),生成 NGPhysicalLineBoxFragment 和对应的 NGPhysicalTextFragment、NGPhysicalBoxFragment,最终构建片段树(fragment tree),并根据 baseline、vertical-align 等属性调整对齐和位置。
整体流程确保内联元素能正确处理文本流、换行、对齐、双向文本等复杂场景,最终生成可渲染的行盒结构。
从使用侧角度需要注意以下几点:
- 字体的宽度是引擎内部决定的取决于字体的渲染方式和浏览器的实现,通常使用
font-size
和font-family
来控制字体大小和样式。但是字形的宽度可能会因浏览器和操作系统的不同而有所差异。CSS Fonts Module Level 5 提供了 font-size-adjust 属性来调整字体的宽度 - 内联元素的行盒高度计算可参考 Line height calculations:行盒高度等于所有内联盒中最上方的 box top 与最下方的 box bottom 之间的距离。空的内联元素会生成空的内联盒,但这些盒子依然具有外边距、内边距、边框和行高,因此会像有内容的元素一样影响行盒高度的计算。这也是为什么有的时候对齐回产生空白的原因
CSS 定位有哪些方式?
答案
position
属性用于指定元素的定位方式,它决定了元素在页面中的定位策略和布局行为。
常见属性值
-
static
:默认值,元素在文档流中正常排列。 -
relative
:元素在文档流中正常排列,但是可以通过设置top
、right
、bottom
、left
属性相对于其正常位置进行偏移,不会影响其它元素的位置。 -
absolute
:元素脱离文档流,相对于最近的非static
定位的祖先元素进行定位,如果没有则相对于<html>
元素进行定位。通过设置top
、right
、bottom
、left
属性进行偏移,如果祖先元素发生位置变化,则元素的位置也会发生相应的变化。 -
fixed
:元素脱离文档流,相对于浏览器窗口进行定位,始终保持在窗口的固定位置,不会随页面滚动而滚动。通过设置top
、right
、bottom
、left
属性进行偏移。 -
sticky
:元素在文档流中正常排列,当元素滚动到指定的位置时,停止滚动并固定在该位置,直到其祖先元素发生滚动时才会取消固定。通过设置top
、right
、bottom
、left
属性和z-index
属性进行设置。通过此属性实现吸顶效果。
延伸阅读
答案
核心概念
CSS定位系统提供了多种方式来控制元素在页面中的位置,每种定位方式都有其特定的应用场景。
定位方式
-
静态定位(static)
- 默认定位方式
- 元素按照正常文档流排列
- 不受
top
、right
、bottom
、left
属性影响
-
相对定位(relative)
- 元素在正常文档流中的位置不变
- 相对于自身原始位置进行偏移
- 不影响其他元素的布局
-
绝对定位(absolute)
- 元素脱离正常文档流
- 相对于最近的定位祖先元素定位
- 如果没有定位祖先,则相对于
<html>
元素
-
固定定位(fixed)
- 元素脱离正常文档流
- 相对于浏览器视口定位
- 不随页面滚动而移动
-
粘性定位(sticky)
- 元素在正常文档流中
- 当滚动到指定位置时,变为固定定位
- 需要设置
top
、right
、bottom
、left
之一
代码示例
/* 静态定位(默认) */
.static {
position: static;
/* top, right, bottom, left 无效 */
}
/* 相对定位 */
.relative {
position: relative;
top: 20px;
left: 30px;
/* 相对于原始位置偏移 */
}
/* 绝对定位 */
.absolute {
position: absolute;
top: 0;
right: 0;
/* 相对于最近的定位祖先 */
}
/* 固定定位 */
.fixed {
position: fixed;
top: 0;
left: 0;
/* 相对于视口,不随滚动移动 */
}
/* 粘性定位 */
.sticky {
position: sticky;
top: 0;
/* 滚动到顶部时固定 */
}
实际应用
/* 模态框定位 */
.modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 1000;
}
/* 导航栏粘性定位 */
.navbar {
position: sticky;
top: 0;
z-index: 100;
background: white;
}
/* 工具提示定位 */
.tooltip {
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
}
什么是 Flexbox 布局?
答案
Flexbox(弹性盒子布局)是CSS3引入的一种布局模式,提供了更高效的方式来排列、分布和对齐容器中的项目,特别适合于一维布局。
核心概念
- Flex 容器:设置了
display: flex
或display: inline-flex
的元素 - Flex 项目:Flex容器的直接子元素
- 主轴 Flex容器的主要轴线,通过
flex-direction
属性定义方向 - 交叉轴 与主轴垂直的轴线
容器属性
flex-direction
:定义主轴方向flex-wrap
:定义是否换行justify-content
:主轴对齐方式align-items
:交叉轴对齐方式align-content
:多行对齐方式, 注意align-content
只在多行时有效gap
:项目间距
项目属性
flex-grow
:放大比例- 默认值为 0,表示项目不会放大
- 如果存在剩余空间,flex-grow 总和大于 1 按比例分配剩余空间,小于 1 则基于数值比例分配
- 无法无限放大,受
max-*
限制
flex-shrink
:缩小比例- 总和大于 1 按比例分配 Flex 容器不足空间,小于 1 则基于数值比例分配
- 无法无限收缩,受
min-*
限制
flex-basis
:基础尺寸- 注意 flex-basis 会受
min-*
和max-*
属性影响, 优先级min-*
/max-*
>flex-basis
>width/height
- 注意 flex-basis 会受
flex
:上述三个属性的简写,顺序依次为flex-grow
、flex-shrink
、flex-basis
**align-self
:单独对齐方式order
:项目顺序
什么是Grid布局?
答案
CSS Grid Layout是一个二维布局系统,允许同时控制行和列,提供了强大的网格布局功能,适合复杂的页面布局。
核心概念
- Grid容器:设置了
display: grid
的元素 - Grid项目:Grid容器的直接子元素
- 网格线:构成网格结构的分界线
- 网格轨道:两条相邻网格线之间的空间
- 网格区域:由四条网格线围成的区域
容器属性
grid-template-columns/rows
:定义网格的列/行grid-gap
:设置网格间距justify-items/align-items
:设置项目对齐方式justify-content/align-content
:设置容器对齐方式
项目属性
grid-column/row
:指定项目位置grid-area
:指定项目区域justify-self/align-self
:单独对齐方式
什么是 CSS 浮动?
答案
核心概念
CSS浮动是一种布局技术,允许元素脱离正常文档流,向左或向右浮动,其他元素会环绕在浮动元素周围。
浮动特性
- 脱离文档流:浮动元素不再占据正常文档流中的空间
- 水平排列:浮动元素会水平排列
- 文字环绕:非浮动元素会环绕在浮动元素周围
- 高度塌陷:父元素可能无法包含浮动子元素
浮动值
float: left
:元素向左浮动float: right
:元素向右浮动float: none
:不浮动(默认值)
代码示例
/* 基本浮动 */
.float-left {
float: left;
width: 200px;
margin-right: 20px;
}
.float-right {
float: right;
width: 200px;
margin-left: 20px;
}
/* 清除浮动 */
.clearfix::after {
content: '';
display: table;
clear: both;
}
/* 使用BFC清除浮动 */
.container {
display: flow-root;
}
实际应用
/* 图片文字环绕 */
.article img {
float: left;
margin: 0 20px 20px 0;
}
/* 导航菜单 */
.nav {
overflow: hidden; /* 创建BFC */
}
.nav-item {
float: left;
margin-right: 20px;
}
/* 多列布局 */
.column {
float: left;
width: 33.33%;
padding: 0 15px;
box-sizing: border-box;
}
面试官视角
- 差:不了解浮动概念,无法处理浮动问题
- 良:理解浮动基本用法,知道如何清除浮动
- 优:深入理解浮动机制,能灵活运用解决布局问题
延伸阅读
- MDN: CSS浮动 - 官方文档
- CSS浮动详解 - 学习指南
-
采用 clear 清除浮动典型代码如下,
<!-- 在父容器添加 clear-float -->
.clear-float::after {
content: '';
clear: both;
display:block;
} -
使浮动元素的父容器为 BFC,元素变为 BFC 的方法参考 mdn bfc
列布局?
答案
Multi-column 用来实现纸质媒体中常见的多列布局。核心属性包括
column-count
:指定列数column-width
:指定列宽column-gap
:指定列间距column-rule
:指定列间分隔线的样式column-span
:指定元素跨越的列数column-fill
:指定列填充方式(如平衡填充)break-inside
:控制列内元素的断行行为break-before
/break-after
:控制列前后断行行为
示例说明
延伸阅读
- css multi-column 多列规范
- https://drafts.csswg.org/css-break/ 断行规范
- LayoutNG block fragmentation 对块分段的说明
- Block fragmentation tutorial 块分隔详解
如何设置表格布局,有哪些特点?
答案
表格布局使用 display: table
、display: table-row
、display: table-cell
等属性模拟表格结构。
核心概念
- 表格容器:使用
display: table
定义 - 表格行:使用
display: table-row
定义 - 表格单元格:使用
display: table-cell
定义 - 表格标题:使用
display: table-caption
定义 - 表格列:使用
display: table-column
定义 - 表格列组:使用
display: table-column-group
定义 - 表格行组:使用
display: table-row-group
定义 - 表格单元格组:使用
display: table-cell-group
定义 - 表格分隔线:使用
display: table-separator
定义 - 表格头部:使用
display: table-header-group
定义 - 表格尾部:使用
display: table-footer-group
定义 - 表格布局:使用
table-layout
属性控制表格布局方式auto
:默认值,浏览器根据内容自动调整列宽fixed
:固定布局,列宽由width
属性决定,不受内容影响
- 表格对齐:使用
text-align
、vertical-align
等属性控制单元格内容对齐方式
示例说明