- 教程
- 前端
【免费下载链接】css-protips
A collection of tips to help take your CSS skills pro. 🕹
本文以 css-protips 仓库的葡萄牙语(欧洲)翻译版 README(translations/pt-PT/README.md)为绝对主线,系统讲解其中收录的 25 条 CSS 实战技巧,覆盖样式重置、选择器进阶、排版字体、布局方案与表单/组件细节等场景,并结合仓库主 README.md 与 CONTRIBUTING.md 进行原理深化与交叉印证。读完本文,你将获得一批可复制、可运行、带浏览器兼容性说明的 CSS 代码片段,并理解它们背后的盒模型、选择器优先级与响应式机制。
一、项目与文档背景
css-protips 是一个精选 CSS 技巧集合,仓库根目录 README.md 的定位是"A collection of tips to help take your CSS skills pro"(一个帮你把 CSS 技能提升到专业水准的技巧集合)。仓库将主 README 翻译为 15 种语言,存放在 translations 目录下,本篇文章的主体即其中的欧洲葡萄牙语版本 translations/pt-PT/README.md。
需要说明的是,主 README 在 Translations 一节中明确提示:翻译文件可能不会包含主 README 的全部技巧——因为每新增一条技巧都需要同步十几种语言,维护成本很高。因此本文以 pt-PT 版 README 收录的 25 条技巧为骨架展开,并在最后一节补充主 README 中尚未同步进该翻译的 4 条扩展技巧,供读者对照学习。
根据 pt-PT 版 README 末尾的"Suporte(支持)"声明,本集合中的技巧面向Chrome、Firefox、Safari、Edge 的当前版本,编写时不必为这些主流浏览器的现代实现做过多降级处理。
二、从零开始:样式重置的三条思路
1. 使用 CSS Reset(重置样式)
不同浏览器对元素的默认样式(margin、padding、字体等)各不相同,重置样式可以"抹平"差异,为后续样式编写提供一个干净一致的起点。pt-PT 版 README 给出的最简化方案如下:
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }该规则同时作用于元素本身及其::before/::after伪元素,将它们的外边距、内边距全部清零,并把盒模型统一为border-box。从仓库根 README.md 可以看到同样的写法,说明这是项目推荐的基础模板。
注意:如果你采用了下面第 2 条"继承box-sizing"的技巧,可以在 Reset 中省略box-sizing声明,避免重复设置。
2. 让box-sizing从html继承
与其在每个元素上直接写box-sizing: border-box,不如让该属性从根元素继承:
html { box-sizing: border-box; } *, *::before, *::after { box-sizing: inherit; }这样做的价值在于可覆写性:默认情况下所有元素都是border-box,但当你引入某个插件或第三方组件、其内部元素需要改用content-box计算尺寸时,只需在该组件根节点上设置box-sizing: content-box,其内部后代便会因继承机制自动跟随,无需逐个覆盖。这正是 README.md 中所述"让插件或其他行为不同的组件更容易改变box-sizing"的原因。
3. 用unset代替逐条重置属性
重置一个元素(例如<button>)时,传统做法是逐条清零:
button { background: none; border: none; color: inherit; font: inherit; outline: none; padding: 0; }而 CSS 提供了all简写属性,配合关键字unset,一行即可完成等效重置:
button { all: unset; }原理是:unset对继承属性等价于inherit(恢复为父元素的计算值),对非继承属性等价于initial(恢复为规范定义的初始值)。因此all: unset会把按钮的背景、边框、字体、内边距等一次性"打回原形",之后再按需重新声明样式。这一技巧在 README.md 中同样收录,是项目认可的高效写法。
三、选择器进阶:更精准、更简洁地命中元素
4. 用:not()应用/移除导航边框
为导航项加分隔边框时,常见做法是先给所有li加边框、再单独去掉最后一项:
/* 先加边框 */ .nav li { border-right: 1px solid #666; } /* 再移除最后一项的边框 */ .nav li:last-child { border-right: none; }两条规则互相"打架"、且需要额外的覆盖声明。改用:not()伪类后,一条规则即可表达完整意图:
.nav li:not(:last-child) { border-right: 1px solid #666; }正如 pt-PT 版 README 所言,"这个选择器的写法就像人类描述需求一样直观":给"不是最后一项"的元素加边框。:not()是函数式伪类,可以嵌套其他选择器,在本集合中被反复使用(见第 6、10、12、18、19 节)。
5. 用负nth-child选取第 1 到第 n 项
:nth-child()接受An+B形式的公式,当A为负数时,匹配范围变为"从第 1 项到第 B 项"。例如选取前 3 项并显示:
li { display: none; } /* 显示第 1 到第 3 项 */ li:nth-child(-n + 3) { display: block; }结合已学的:not(),还可以反选:
/* 选取除前 3 项以外的所有项 */ li:not(:nth-child(-n + 3)) { display: none; }仓库证据对照:pt-PT 版 README 中该反选示例的代码为display: none,而其注释文字("选取除前 3 项外的所有项并显示")与代码存在出入;对照主 README.md 可发现,主版本已将该规则修正为display: block。阅读翻译版时请以主 README 的修正为准。
6. 使用 "Lobotomized Owl"(裂脑猫头鹰)选择器
这个名字听起来很怪,但它由通配选择器*与相邻兄弟选择器+组合而成,能力非常强大:
* + * { margin-top: 1.5em; }* + *匹配"文档流中紧跟在其他元素之后的元素",即除了第一个元素外的所有元素。因此一条规则就能为列表、段落、标题等所有相邻元素统一设置margin-top,实现均匀的垂直间距,无需为每种标签分别写规则。这在排版类页面上尤其省事。
7. 用属性选择器展示空链接
当一个<a>标签没有文本内容、但带有href属性时,页面上会出现一个不可见的死链接。可以用属性选择器 +:empty伪类让它"现形":
a[href^="http"]:empty::before { content: attr(href); }a[href^="http"]选取href以http开头的链接,:empty匹配无任何内容的元素,attr(href)则把href属性的值作为content显示出来。这样空链接会自动展示其目标地址,便于用户识别。需要提醒的是(原文档的注意事项):此类技巧对屏幕阅读器可能不够友好,且 CSS 生成的内容无法被浏览器复制粘贴,请谨慎使用。
8. 为"默认"链接定义样式
CMS(内容管理系统)自动插入的链接往往不带class属性,可以通过"无 class 的有href链接"这一特征为它们单独定义样式,而不影响其他受控链接:
a[href]:not([class]) { color: #008000; text-decoration: underline; }:not([class])表示"没有 class 属性的元素",与a[href]组合后,恰好命中"默认裸链接"。这样来自 CMS 的链接获得统一的绿色下划线样式,又不会通过级联污染页面中其他链接。
四、字体与排版:从加载到度量
9. 先检查字体是否已本地安装
使用@font-face加载自定义字体时,可以先检查系统是否已安装该字体,命中则跳过远程下载,这既是性能优化,也能避免网络字体闪烁:
@font-face { font-family: "Dank Mono"; src: /* 字体全名 */ local("Dank Mono"), /* PostScript 名称 */ local("Dank-Mono"), /* 均未命中时,再从服务器下载 */ url("//...a.server/fonts/DankMono.woff"); } code { font-family: "Dank Mono", system-ui-monospace; }src中local()依次尝试字体的全名与 PostScript 名(两者在不同系统上可能不一致,所以都列出),全部未命中时才回退到url()下载。示例同时展示了字体栈兜底:system-ui-monospace作为通用后备,保证code元素在任意环境下都有等宽字体可用。
10. 把line-height写在body上
无需为每个<p>、<h1>~<h6>分别设置行高,只需在body上声明一次:
body { line-height: 1.5; }line-height是继承属性,所有文本元素都会从body继承该值,正文因此获得一致的阅读节奏,也便于全局统一调整。
11. 全局尺寸用rem,局部尺寸用em
在根元素设定基准字号(html { font-size: 100%; })后,正文文本元素使用相对自身的em:
h2 { font-size: 2em; } p { font-size: 1em; }而模块级(组件级)字号使用相对根元素的rem:
article { font-size: 1.25rem; } aside .module { font-size: 0.9rem; }这样的分工逻辑是:em随父级字号缩放,适合"与上下文联动"的文本元素;rem始终相对根字号,适合"模块自包含、不受嵌套影响"的组件尺寸。模块之间相互隔离,维护与调整都更灵活。
12. 用:root实现随视口缩放的灵活排版
响应式布局中,字号应能随视口大小自适应。可以在:root上用calc()把视口宽高纳入字号计算:
:root { font-size: calc(1vw + 1vh + 0.5vmin); }1vw为视口宽度的 1%,1vh为视口高度的 1%,0.5vmin为视口较小边的 0.5%。三者相加得到一个随视口变化的基准字号。之后正文即可用rem单位引用它:
body { font: 1rem/1.6 sans-serif; }由于rem始终相对:root的字号,只要根字号随视口变化,整棵文档树中所有rem尺寸都会联动缩放,实现"一行代码驱动的流式排版"。
五、布局实战:居中、等宽与比例
13. 垂直居中(Flexbox 与 Grid 两种方案)
垂直居中不是"黑魔法"。用 Flexbox 时,先让html、body撑满视口高度,再让body成为弹性容器并开启交叉轴居中:
html, body { height: 100%; margin: 0; } body { -webkit-align-items: center; -ms-flex-align: center; align-items: center; display: -webkit-flex; display: flex; }pt-PT 版保留了-webkit-/-ms-前缀写法以便兼容旧引擎;对照主 README.md 可看到现代写法还补充了justify-content: center,可同时实现水平居中。用 CSS Grid 则更简洁:
body { display: grid; height: 100vh; margin: 0; place-items: center center; }place-items: center center是align-items与justify-items的简写,一行同时完成主轴与交叉轴居中(主 README 中写作place-items: center,效果相同)。
14. 纯 CSS 滑块:max-height+overflow
不借助 JavaScript,仅用max-height与溢出控制即可实现展开式滑块:
.slider { max-height: 200px; overflow-y: hidden; width: 300px; } .slider:hover { max-height: 600px; overflow-y: scroll; }默认状态下内容被max-height: 200px截断并隐藏溢出部分;悬停时max-height增大到 600px,内容展开,配合overflow-y: scroll呈现可滚动滑块效果。注意max-height的动画过渡只对"不超过该值的部分"平滑,且该技巧是"尽力展开",内容超出上限时仍需滚动查看。
15. 表格等宽单元格:table-layout: fixed
表格布局难缠?为表格设置table-layout: fixed即可让所有单元格保持相同宽度:
.calendar { table-layout: fixed; }table-layout: auto(默认值)会让浏览器根据内容自动分配列宽,同一列可能忽宽忽窄;fixed则忽略内容、按既定宽度均分列,列宽由此可预测、稳定,非常适合日历、数据网格等需要等宽对齐的场景。
16. 告别 margin hack,用 Flexbox 的space-between
为多列布局留出等宽 gutter 时,传统做法依赖nth-、first-、last-child各种 hack;改用 Flexbox 后一条属性即可搞定:
.list { display: flex; justify-content: space-between; } .list .person { flex-basis: 23%; }justify-content: space-between会把第一项贴左、最后一项贴右,中间项目均匀分布,剩余空间自动成为列间距;配合flex-basis: 23%控制每项基础宽度。无论项目数量如何变化,gutter 始终保持均匀,无需再写条件选择器。
17. 固定宽高比的盒子(内联比例技巧)
要创建一个宽高比固定的容器,只需在父 div 上设置padding-bottom(或padding-top),因为百分比 padding 是相对包含块宽度计算的:
.container { height: 0; padding-bottom: 20%; position: relative; } .container div { border: 2px dashed #ddd; height: 100%; left: 0; position: absolute; top: 0; width: 100%; }padding-bottom: 20%意味着内边距高度恒等于容器宽度的 20%,而height: 0使容器总高就是该 padding 值。子元素通过绝对定位铺满容器,其实际高度即为宽度的 20%,宽高比恒为 100% / 20% =5:1,且与视口宽度无关。这是经典"内联比例盒子"(Intrinsic Ratio Box)实现,常用于嵌入视频、图片占位等场景。
六、组件细节:列表、图标、表单与多媒体
18. 逗号分隔列表
把普通<ul>变成"真·逗号分隔列表":
ul > li:not(:last-child)::after { content: ","; }:not(:last-child)保证最后一个li不加逗号,:after伪元素在其余每项末尾插入逗号字符。可访问性警告(原文档明确标注):此技巧对屏幕阅读器可能不友好,且 CSS 生成的内容无法被浏览器复制粘贴,请谨慎用于正式内容。
19. 图标优先使用 SVG
SVG 矢量图标在任何分辨率下都清晰锐利,浏览器支持可回溯到 IE9,完全有理由取代.png、.jpg乃至.gif位图方案:
.logo { background: url("logo.svg"); }若存在"仅图标"按钮且 SVG 加载失败,可以补一条降级规则,借助attr()把aria-label属性渲染为文字,保持可访问性:
.no-svg .icon-only::after { content: attr(aria-label); }20. 为表单元素设置可见的:focus样式
依赖键盘操作的视障用户需要清晰的焦点指示来判断键盘事件落点。与其依赖浏览器默认的焦点样式,不如统一声明:
a:focus, button:focus, input:focus, select:focus, textarea:focus { box-shadow: none; outline: #000 dotted 2px; outline-offset: 0.05em; }outline: #000 dotted 2px提供高对比度的虚线焦点环,outline-offset: 0.05em让焦点环与元素保持少量间距、视觉上更醒目;同时移除box-shadow,避免与其他样式(如输入框阴影)混淆。
21. 表单font-size: 16px,杜绝移动端自动缩放
iOS Safari 等移动浏览器在聚焦表单输入框时,若字号小于 16px 会自动放大页面,造成糟糕的交互体验。解决办法是在表单元素上显式设置不小于 16px 的字号:
input[type="text"], input[type="number"], select, textarea { font-size: 16px; }命中文本、数字输入框、下拉框与多行文本框,让移动端不再"莫名缩放"。
22. 美化破损图片
图片加载失败时浏览器会显示默认的"破图"图标,用一点 CSS 即可让错误状态变得体面:
img { display: block; font-family: sans-serif; font-weight: 300; height: auto; line-height: 2; position: relative; text-align: center; width: 100%; }再配合伪元素,展示提示信息与图片地址:
img::before { content: "Desculpe, a imagem abaixo não pode ser carregada :("; display: block; margin-bottom: 10px; } img::after { content: "(url: " attr(src) ")"; display: block; font-size: 12px; }::before渲染友好提示文案,::after通过attr(src)输出原图的 URL 引用,帮助定位问题来源。图片本身则用display: block、width: 100%、height: auto保证正常加载时也具有良好的流体表现。
23. 隐藏"未静音"的自播放视频
写自定义用户样式表(User Stylesheet)时,可以用这条规则避免自动播放视频的声音打扰用户:
video[autoplay]:not([muted]) { display: none; }video[autoplay]命中声明了autoplay属性的视频,:not([muted])排除已静音者——即"凡自动播放且未静音的视频一律隐藏"。这再次体现了:not()伪类的实用价值。
24. 用pointer-events控制鼠标交互
pointer-events属性控制元素如何响应指针(鼠标/触控)事件。禁用按钮的默认指针交互可以这样写:
button:disabled { opacity: 0.5; pointer-events: none; }pointer-events: none使元素不接收任何指针事件,配合opacity: 0.5的视觉弱化,让禁用状态既"看着不可点"也"实际不可点",无需额外 JavaScript 拦截。
25. 隐藏被当作间距使用的换行标签
有些 CMS 使用者会用多余的<br>制造段落间距。可以"收编"这类行为,让连续换行不产生视觉空隙:
br + br { display: none; }br + br匹配"紧跟在另一个<br>之后的<br>",即连续换行中的第二个及其后的所有换行——它们会被隐藏,从而阻止通过堆叠换行伪造间距的做法。
七、主 README 中的扩展技巧(尚未同步至 pt-PT 翻译)
由于翻译维护成本,translations/pt-PT/README.md 未包含主 README.md 中较新的 4 条技巧,这里一并列出供参考。
aspect-ratio替代固定宽高
现代浏览器可用原生aspect-ratio属性保持宽高比,配合object-fit防止图片尺寸变化引起布局抖动:
img { aspect-ratio: 16 / 9; /* 宽 / 高 */ object-fit: cover; }这是第 17 节"padding 比例盒子"的现代替代方案。
:is()精简选择器并管理优先级
:is()可一次匹配多个选择器,大幅减少冗余(详见 README.md):
:is(section, article, aside, nav) :is(h1, h2, h3, h4, h5, h6) { color: green; }等价于写全 24 条组合规则;注意:is()的优先级取其参数列表中的最高者。
:empty隐藏空元素
CMS 或脚本动态注入的空元素(如<p class="error-message"></p>)会占用版面空间,可用:empty隐藏(详见 README.md):
:empty { display: none; }注意:包含空白字符的元素不算空(如<p> </p>),不会命中该选择器。
margin-inline/margin-block逻辑属性
用逻辑属性替代物理方向的 margin(详见 README.md):
.div { margin-inline: auto; /* 替代 margin-left/right */ } .div { margin-block: auto; /* 替代 margin-top/bottom */ }八、参与贡献与代码风格约定
本仓库欢迎新增技巧,具体流程见 贡献指南(pt-PT 版 README 中的../../CONTRIBUTING.md相对链接即指向仓库根目录的该文件)。贡献指南值得注意的约定包括:
- 新增技巧须添加在主 README.md 末尾,并在目录底部补充锚点链接;
- 代码格式遵循 CSSLint 默认规范:两个空格缩进、使用简写属性(如
margin: 10px 10px 0.5rem;)、字符串用双引号、数值保留前导零(如padding: 0.75rem;)、属性按字母序排列等(见 CONTRIBUTING.md)。
这也意味着本文所有代码片段均与项目约定的风格一致,可直接粘贴使用。
九、兼容性与总结
pt-PT 版 README 的"Suporte"声明与主 README 一致:本集合面向Chrome、Firefox、Safari、Edge 的当前版本。文中多数技巧(:not()、nth-child、Flexbox、Grid、@font-face的local()等)在现代浏览器中均稳定可用;个别技巧如aspect-ratio、:is()属较新特性,使用时请结合实际项目的浏览器支持范围判断。
25 条技巧贯穿了 CSS 的几大核心议题:重置与盒模型(第 1–3 条)、选择器表达力(第 4–8 条)、字体与度量单位(第 9–12 条)、布局方案(第 13–17 条)以及组件与可访问性细节(第 18–25 条)。每条都是可直接复制的最小代码单元,理解了它们背后的原理,就能把这些模式迁移到自己的项目中——这正是 css-protips 集合"让你的 CSS 技能更专业"的初衷。想继续深入,可对照阅读仓库中的 主 README 及各语言 translations 目录下的翻译版本。
- 教程
- 前端
【免费下载链接】css-protips
A collection of tips to help take your CSS skills pro. 🕹
相关推荐
CAI 安全评估报告 Agent:基于 system_reporting_agent 提示词构建专业 HTML 安全报告
CAI 安全评估报告 Agent:基于 system_reporting_agent 提示词构建专业 HTML 安全报告 安全评估的最后一公里是"报告"——将渗
教程前端探索CSS高级技巧:CSS Protips库的全面解析
探索CSS高级技巧:CSS Protips库的全面解析 <div align="center" <img src="./assets/img/bulb.svg"
教程前端Refine 项目中的 CSS Box Shadow 全面指南:属性解析与 25 个可直接复用的实战示例
Refine 项目中的 CSS Box Shadow 全面指南:属性解析与 25 个可直接复用的实战示例 CSS box shadow 属性是前端开发中为元素添
前端企业应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考