大家好,我是 CUGGZ。
当开始一个新的前端项目时,首要任务就是重置 CSS 中的一些默认样式。下面就来看看现代 CSS 重置的最佳实践。我们将深入研究每条规则,以了解它的作用和使用它的原因!
下面是自定义的 CSS 重置代码:
/* 1. 使用更直观的 box-sizing 模型 */ *, *::before, *::after { box-sizing: border-box; } /* 2. 移除默认 margin */ * { margin: 0; } /* 3. 在应用中允许基于百分比的高度 */ html, body { height: 100%; } /* 排版调整 4. 添加无障碍行高 5. 改进文本渲染 */ body { line-height: 1.5; -webkit-font-smoothing: antialiased; } /* 6. 改进媒体默认设置 */ img, picture, video, canvas, svg { display: block; max-width: 100%; } /* 7. 删除内置表单排版样式 */ input, button, textarea, select { font: inherit; } /* 8. 避免文字溢出 */ p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; } /* 9. 创建根层叠上下文 */ #root, #__next { isolation: isolate; }
这里的代码较短,但是这个小样式表中包含了很多内容。 下面来逐条介绍!
从历史上看,CSS 重置的主要目标是确保浏览器之间的一致性,并撤消所有默认样式。 这段 CSS 重置代码并没有真正做这些事情。
如今,浏览器在布局或间距方面没有太大的差异。 总的来说,浏览器准确的实现了 CSS 规范,并且一切都如你期望的那样,所以它不再是必要的了。
这里的 CSS 重置可能不符合“CSS重置”的经典定义,但这会发挥其创造性!
1. box-sizing 模型
先来看一段代码,假设没有应用其他 CSS,以下场景中的 .box
元素有多宽?
<style> .parent { width: 200px; } .box { width: 100%; border: 2px solid hotpink; padding: 20px; } </style> <div class="parent"> <div class="box"></div> </div>
这里的 .box
元素的宽度为:100%。 因为它的父级宽度为 200px ,所以 100% 将解析为 200px。但是它在哪里应用了 200px 的宽度呢? 默认情况下,它将该大小应用于内容区域,即下图中白色的区域:
width: 100%
声明会将 .box
的内容框设置为 200px。 而 padding
将增加额外的 40 px(每边 20 px)。 border 将增加额外的 4px(每边 2px)。 当进行计算时,粉红色矩形的宽度将是 244 px。
当尝试将 244px 的框放入宽度为 200px 的父级时,就会发生溢出:
我们可以通过设置以下规则来更改这种奇怪的行为:
*, *::before, *::after { box-sizing: border-box;}
应用此规则后,百分比将根据 border-box 进行解析。 在上面的例子中,粉色框宽度为 200 px,内部内容框的宽度将缩小到 156 px(200 px - 40 px - 4 px)。
这是一条必须具备的规则,它使 CSS 更好用。这里使用通配符选择器 (*) 将它应用于所有元素和伪元素。与人们普遍的看法相反,这对性能来说并不坏。
网络上有一些人建议改为执行以下操作:
html { box-sizing: border-box; } *, *:before, *:after { box-sizing: inherit; }
如果i正在尝试迁移一个大型的已经存在的项目以使用 border-box,这可能是一个有用的策略。 如果要从头开始一个全新的项目,这就是没有必要的。 为了简单起见,上面的 CSS 重置中省略了它。
那在什么时候,这是有用的呢?下面来看一个可能有用的示例。 如果您正在尝试迁移一个大型的预先存在的项目以使用 border-box,这可能是一个有用的策略。 如果您要从头开始一个全新的项目,则没有必要。 为了简单起见,我在 CSS 重置中省略了它。
展开以查看何时可能有用的示例。首先,将 legacy
的 box-sizing
属性设置为 content-box
,即 box-sizing
属性的默认值:
.legacy { box-sizing: content-box; }
然后,当应用有一部分尚未迁移到使用 border-box 时,可以将类这样放:
<body> <header class="legacy"> <nav> <!-- 遗留的内容在这里 --> </nav> </header> <main> <section> <!-- 现代的内容在这里 --> </section> <aside class="legacy"> <!-- 遗留的内容在这里 --> </aside> </main> </body>
这里, 被赋予了 legacy
类,因此它使用 box-sizing: content-box
。它的子元素 具有 box-sizing: inherit
。 因为它的父级设置为 content-box
,所以 nav 也将设置为 content-box
。
标签没有 legacy
类,因此它继承自其父类 。 继承自 。 被设置为了 border-box
。
本质上,每个元素现在都会从其父元素中找出其 box-sizing 的行为。 如果它有一个设置 legacy
类的祖先,它将是 content-box
。 否则,最终会继承 html 标签,即使用 border-box
。
2. 移除默认 margin
* { margin: 0; }
通常,浏览器会围绕 margin 做出常识性假设。 例如,默认情况下,h1 将包含比 p 更多的边距。这些假设在处理文档文字的上下文中是合理的,但对于现代 Web 应用而言可能并不准确。
我们可能通常希望元素默认是没有任何边距的,所以就把默认的边距全部删除了。当确实想为特定标签添加一些边距时,可以在自定义样式中来添加。 通配符选择器 (*) 的特异性极低,因此很容易覆盖此规则。
3. 基于百分比的高度
html, body { height: 100%; }
你有没有试过在 CSS 中使用基于百分比的高度,却发现它似乎没有效果?下面来看一个例子:
这里 main 元素具有 100% 的高度,但是元素根本没有变长。这是行不通的,因为在流式布局(CSS 中的主要布局模式)中,高度和宽度的操作原理完全不同。元素的宽度是根据其父元素计算的,而元素的高度是根据其子元素计算的。
当应用这条规则时,main
元素就可以增长:
如果使用的是像 React 这样的 JavaScript 框架,可能还希望在此规则中添加第三个选择器:框架使用的根级的元素。
例如,在 Next.js 项目中,将规则更新如下:
html, body, #__next {
height: 100%;}
那为什么要设置基于百分比的 height,而不改用 vh 单位呢?问题就在于 vh 单元在移动设备上无法正常工作; 100vh 将占据超过 100% 的屏幕空间,因为移动浏览器会在浏览器 UI 出现和消失的地方做这件事。未来,新的 CSS 单位将解决这个问题。在那之前,可以使用基于百分比的高度。
4. 调整行高
body { line-height: 1.5; }
line-height 控制段落中每行文本之间的垂直间距。 默认值因浏览器而异,通常在 1.2 左右。这个没有单位的数字是基于字体大小的,就像 em 单位。行高为 1.2 时,每行高度将比元素的字体大小大 20%。
这就是问题所在:对于有阅读障碍的人来说,这些行挤得太紧了,很难阅读。 WCAG 标准规定行高应至少为 1.5。这个数字确实倾向于在标题和其他大字体元素上产生相当大的行:
你可能希望在标题上覆盖此值。我的理解是 WCAG 标准适用于“正文”文本,而不是标题。
现代CSS样式重置最佳实践!(下)https://developer.aliyun.com/article/1411403