2. 其实属性背后是盒模型和层叠规则
我们总说“常用属性”,但为什么是这些属性常用,而不是那些?这就要回到CSS的两个底层机制:盒模型和层叠上下文。你理解了这两个东西,再看任何属性都不会觉得是死记硬背。
2.1 盒模型:所有属性都在围绕content-box做事
盒模型的经典定义是:每个元素都是一个矩形盒子,由content(内容)、padding(内边距)、border(边框)、margin(外边距)四层组成。平时改宽度、高度、内边距、边框,本质上都是在操作这个四层结构的某一部分。
容易踩坑的地方有两个。第一个是box-sizing。默认值是content-box,意味着你设置的width: 300px只作用于content区域,padding和border还要额外加进去。如果你同时设置了width: 300px和padding: 20px,实际占据的宽度是340px。这在写响应式布局时特别容易让人崩溃,所以我会在项目初始就全局设置:
css复制*, *::before, *::after {
box-sizing: border-box;
}
这样width: 300px就是最终渲染宽度,padding和border都被包含在内,心智负担小很多。
第二个是margin的垂直塌陷问题。两个兄弟元素的margin-bottom和margin-top不会叠加,而是取较大值。比如上面元素margin-bottom: 30px,下面元素margin-top: 20px,最后间距只有30px。很多新手以为会得到50px,这是最常见的盒模型误区之一。
2.2 层叠上下文:z-index不生效的真相
很多人遇到z-index设了很大值元素还是被压住,就开始怀疑人生。其实z-index只在同一个层叠上下文里比较才有意义。
触发层叠上下文的方式有很多:position值为relative或absolute且z-index不是auto、opacity小于1、transform不为none、filter不为none、will-change指定了属性,甚至flex容器的子元素设置了z-index也会创建上下文。
我记忆最深的一个例子是:给一个弹窗设置了position: fixed和z-index: 9999,但弹窗的父元素设置了opacity: 0.99(本意是做淡入动画),结果弹窗在父元素内部怎么都盖不住其他内容。原因就是opacity让父元素创建了层叠上下文,弹窗的z-index只能在那个上下文内部有效。
所以排查z-index问题时,我的经验是:沿着DOM树往上找,检查有没有哪个祖先元素创建了层叠上下文。尤其注意opacity、transform、filter这些看起来“人畜无害”的属性。
2.3 继承:不是所有属性都默认继承
另一个让新手困惑的点是CSS继承。color、font-family、font-size、line-height、text-align这些跟文本相关的属性默认会继承,但padding、margin、border、width、height、display这些布局属性不会继承。
有个实用技巧利用继承:在body上设置全局字体、颜色、行高:
css复制body {
font-family: "PingFang SC", "Microsoft YaHei", sans-serif;
font-size: 14px;
line-height: 1.6;
color: #333;
}
子元素只要不覆盖,就自动继承这套样式。用inherit关键字可以强制继承,比如让按钮字体跟父容器一致:font-family: inherit。这在重置表单元素默认样式时特别常用,因为button和input默认不继承父级的font-family,但你通常希望它们跟整体风格统一。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
3. 字体与文本属性:排版美观的核心
字体和文本属性是每个页面都离不开的,不管是阅读型长文还是后台管理系统,文本呈现直接决定第一印象。这一节我会把常用属性、实际场景、坑点一起说。
3.1 font-size单位的选择:px、em、rem怎么权衡
font-size是使用频率最高的字体属性。单位选择直接影响响应式体验,我的建议是优先用rem。
px是绝对单位,固定不变,适合不需要随屏幕变化的场景,比如打印样式或者图表里的数字。em是相对单位,相对父元素字体大小,容易造成“连环放大”问题:外层font-size: 1.2em,内层再1.2em,嵌套几层字号就失控了。
rem只相对根元素(html)的字体大小,避免了嵌套累积。实现响应式时,我通常只改html的字号就能缩放全局:
css复制html {
font-size: 16px;
}
@media (max-width: 768px) {
html {
font-size: 14px;
}
}
.card-title {
font-size: 1.25rem; /* 16 * 1.25 = 20px,小屏下自动变为17.5px */
}
这里要注意,rem在移动端的兼容性很好,基本不用担心。但如果设计稿是px标注,你可以用calc或预处理器换算,或者直接保留px给一些精确的局部样式。我个人的习惯是:正文和标题用rem,边框和间距用px或rem混用,不搞一刀切。
3.2 font-weight与font-style的正确姿势
font-weight用来控制字重,属性值是100到900的倍数,或者normal(400)、bold(700)。但有个现实问题:网页字体文件不一定包含所有字重。如果你设置了font-weight: 600,但字体文件只有Regular(400)和Bold(700),浏览器会通过合成(faux bold)来模拟,效果往往发虚。
我在项目中通常的做法是:用Google Fonts或自家CDN加载字体时,只加载需要的字重。如果系统字体栈,比如"PingFang SC",在macOS上支持font-weight: 500和600的清晰显示,但Windows下的微软雅黑对650以上的字重支持并不好,就会触发合成加粗。所以我会明确设置最接近的字重,避免浏览器自作主张。
font-style常用的是normal和italic。italic在中文排版里用得少,因为中文字体一般没有真正的斜体,浏览器会做倾斜变形。所以中文站点的标题或强调文本,我更推荐用font-weight加粗而不是font-style: italic,或者用text-decoration做下划线,观感更统一。
3.3 line-height与text-align的排版细节
行高(line-height)直接影响阅读舒适度。对正文来说,1.5到1.8是比较舒服的范围。用无单位数字是最推荐的,因为它会按当前字体大小比例计算,继承时父子的缩放也不会乱。例如:
css复制body {
line-height: 1.6;
}
.content {
font-size: 18px;
/* line-height = 18 * 1.6 = 28.8px */
}
如果你用了固定px的line-height,比如line-height: 30px,当字号变化时行高就僵硬了,在小屏缩放时会出现文字重叠或间距异常。
text-align常用值是left、center、right、justify。其中justify两端对齐,适合中文长文,但会产生大量空白间距。如果配合text-align-last属性,可以控制最后一行对齐方式。还有个小技巧:让图片水平居中,可以设置父容器text-align: center,因为img是内联元素。
3.4 字体渐变与金属光泽效果
字体渐变是热词里出现的内容,实现方式其实不复杂。思路是把文字颜色设置为透明,然后让背景渐变穿透显示。核心代码:
css复制.gradient-text {
background: linear-gradient(90deg, #ff8a00, #e52e71);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
这里的background-clip: text是关键属性,它让背景只在文字所在的形状内绘制,配合color: transparent露出背景色。注意兼容性方面-webkit-前缀还是要加,尤其iOS的Safari很依赖前缀。
如果想做“金光闪闪”的效果,核心是让背景位置动起来。常见做法是用一个带光斑的渐变背景,配合background-size放大后做循环移动动画:
css复制@keyframes shine {
0% { background-position: 0% 50%; }
100% { background-position: 200% 50%; }
}
.shine-text {
background: linear-gradient(90deg, #b8860b, #ffd700, #fff8dc, #ffd700, #b8860b);
background-size: 200% auto;
-webkit-background-clip: text;
background-clip: text;
color: transparent;
animation: shine 3s linear infinite;
}
把background-size设为200%后,背景有了可移动的空间,动画让背景位置反复横跳,光感就出来了。需要补充的是,background-clip: text不能和overflow: hidden在同一个元素上搭配使用,有些浏览器会有渲染问题,可以把动画元素包一层父容器。
3.5 字体竖排与溢出省略
竖排文字在某些海报、标签页场景里很实用。CSS提供了writing-mode属性:
css复制
