1. 布局基础
各位同学,咱们今天聊聊布局的根基。说实话,我见过太多前端新手,一上来就怼flex、grid,结果页面一变形就崩了。为什么?因为底层的盒模型和文档流没吃透。这就像盖楼不打地基,早晚要塌。
我个人习惯,每接手一个新项目,第一件事就是检查全局的盒模型设置。嗯,这个习惯帮我避过不少坑。咱们今天就把这块硬骨头啃下来。
1.1 CSS盒模型——每个元素都是一只盒子
你想想看,页面上任何一个元素,在浏览器眼里都是什么?就是一个盒子。这个盒子从内到外分四层:内容区(content)、内边距(padding)、边框(border)、外边距(margin)。
核心公式:
元素实际占宽 = width + padding-left + padding-right + border-left + border-right
元素实际占高 = height + padding-top + padding-bottom + border-top + border-bottom
我在项目中遇到过最典型的场景:设计师给了一个卡片,宽300px,带20px内边距和1px边框。新手直接写width:300px,结果实际宽度变成了342px。为什么?因为默认的盒模型是 content-box,width只算内容区。
怎么解决?用 box-sizing: border-box。这个属性一改,width就包含了padding和border。我个人建议,全局统一设置:
* {
box-sizing: border-box;
}
这样一来,你写width:300px,它就是实实在在的300px。省心多了。
1.2 display属性——盒子该怎么摆?
display属性决定了盒子的“性格”。说白了,就是告诉浏览器:这个元素在页面上该怎么表现。常用的就三种:block、inline、inline-block。
| 属性值 | 特点 | 典型元素 | 能否设宽高 | 是否换行 |
|---|---|---|---|---|
| block | 独占一行,默认撑满父容器 | div、p、h1~h6 | 可以 | 是 |
| inline | 多个元素排一行,宽高由内容决定 | span、a、strong | 不可以 | 否 |
| inline-block | 对外像inline,对内像block | img、button | 可以 | 否 |
我记得刚入行时,总搞不清inline为什么设宽高无效。后来才明白:inline元素就像文本里的一个字,你见过哪个字能单独设宽高的?它只能被内容撑大。
那inline-block呢?它是个“两面派”。对外它不换行,可以跟其他元素排一排;对内它又像block,能设宽高、能设margin和padding。我经常用它来做导航菜单的选项:
.nav-item {
display: inline-block;
width: 120px;
height: 40px;
text-align: center;
line-height: 40px;
}
这样每个菜单项就整整齐齐地排成一行,还能单独控制大小。
小技巧:inline-block之间会有4px左右的空白间隙。这是因为HTML中的换行符被解析成了空格。解决办法:父元素设置 font-size: 0,子元素再单独设字体大小。
1.3 标准文档流——页面默认的排版规则
什么叫文档流?说白了,就是浏览器默认的排版方式。元素从上到下、从左到右依次排列。块级元素占一整行,行内元素挨着排。
你想想看,如果不做任何定位和浮动,页面就是按这个规则来的。这就像排队买奶茶,先来后到,谁也别插队。
标准文档流有几个特点:
- 从左到右:行内元素、inline-block元素水平排列,放不下才换行
- 从上到下:块级元素垂直堆叠
- 自动换行:内容超出父容器宽度时,行内元素会自动折行
- 高度塌陷:父元素如果不设高度,会由子元素撑开
这里有个坑,我踩过好几次。当子元素全部浮动或绝对定位后,父元素就“塌陷”了,高度变成0。这就是因为子元素脱离了文档流,父元素“感知”不到它们了。
1.4 脱离文档流——打破默认规则
脱离文档流,就是让元素不再遵循默认的排版规则。常见的三种方式:浮动(float)、绝对定位(position: absolute)、固定定位(position: fixed)。
元素一旦脱离文档流,会发生什么?
- 它不再占据原来的空间
- 后面的元素会“挤”上来,填补它的位置
- 它变成了一个“悬浮”的层,可以随意定位
注意:脱离文档流的元素,其父元素无法感知它的存在。这会导致父元素高度塌陷。我曾经在一个项目中,因为忘记清除浮动,导致整个页面布局错乱,排查了整整一下午。
举个例子,用浮动做两栏布局:
.left {
float: left;
width: 200px;
}
.right {
margin-left: 220px;
}
左边栏浮动了,脱离了文档流。右边栏如果不设margin-left,就会跑到左边栏下面去。这就是脱离文档流带来的影响。
怎么解决父元素高度塌陷?我常用的方法是给父元素加一个 overflow: hidden,或者用伪元素清除浮动:
.clearfix::after {
content: "";
display: block;
clear: both;
}
嗯,这个技巧我用了快十年了,百试百灵。
1.5 知识体系总览
下面这张图,把本章的核心知识点串起来了。你可以把它当作一张“地图”,随时回来查阅。
这张图把本章的三个核心概念串在了一起。盒模型决定元素“长什么样”,display决定它“怎么跟邻居相处”,文档流决定它“站在哪个位置”。三者缺一不可。
我的建议:初学者不要急着学flex和grid。先把盒模型、display、文档流这三个概念玩熟。你可以在浏览器开发者工具里,逐个修改元素的display和box-sizing,观察页面变化。这种“动手实验”比看十遍文档都管用。
好了,布局基础就讲到这里。记住一句话:所有高级布局技巧,都是在这三个基础之上玩花样。底子打牢了,后面学什么都快。