이 글에서는 사용자 정의 CSS 재설정 스타일에 대한 심층 분석을 제공하고 각 규칙을 연구하며 이 규칙을 사용하는 이유를 분석합니다. 모든 사람에게 도움이 되기를 바랍니다.
저는 새로운 프로젝트를 시작할 때마다 CSS 언어의 구석구석을 다루는 것을 최우선으로 생각합니다. 이러한 문제를 해결하기 위해 사용자 정의 기본 스타일 세트가 사용되는 경우가 많습니다.
예전부터 Eric Meyer의 유명한 CSS Reset 스타일(CSS Reset)을 사용했습니다. 오래되고 실용적인 CSS 코드로서 지난 10년 동안 업데이트된 적이 없으며 이 기간 동안 많은 것들이 극적으로 변했습니다!
최근에 저는 나만의 맞춤 CSS 재설정 스타일을 사용하기 시작했습니다. 여기에는 사용자 경험과 CSS 개발 경험을 모두 향상시킬 수 있는 많은 팁이 요약되어 있습니다. 이 기사에서는 이 사용자 정의 CSS 재설정 스타일을 소개합니다. 그리고 각 규칙을 심도 깊게 연구하고, 각 규칙의 기능을 논의하는 것 외에도 이 규칙을 사용하는 이유도 간단하고 이해하기 쉽게 분석해 보겠습니다.
역사적으로 CSS 재설정 스타일의 주요 기능은 브라우저의 기본 스타일을 지워 브라우저 간의 스타일 일관성을 보장하는 것입니다. 그리고 내 CSS 재설정 스타일은 이 문제를 해결하는 것이 아닙니다.
요즘에는 브라우저 간 레이아웃이나 간격의 차이가 거의 없습니다. 일반적으로 최신 브라우저는 우리가 기대하는 만큼 충실하게 CSS 사양을 구현했습니다. 따라서 스타일 일관성 문제를 다루는 것은 더 이상 중요하지 않습니다.
또한 브라우저에서 모든 기본 스타일을 제거할 필요는 없다고 생각합니다. 예를 들어 태그를 사용하여 글꼴 스타일을 기울임꼴로 설정합니다. 프로젝트마다 준수해야 할 디자인 사양이 다를 수 있지만 상식적인 기본값을 제거하는 것은 의미가 없습니다.
내 CSS 재설정 스타일은 "CSS 재설정 스타일"의 고전적인 정의를 충족하지 못할 수도 있지만, 다른 관점에서 보면 이 CSS 재설정 스타일도 더 창의성이 있습니다.
더 이상 이야기하지 말고 바로 코드로 들어가겠습니다.
/* 1. Use a more-intuitive box-sizing model. */ *, *::before, *::after { box-sizing: border-box; } /* 2. Remove default margin */ * { margin: 0; } /* 3. Allow percentage-based heights in the application */ html, body { height: 100%; } /* Typographic tweaks! 4. Add accessible line-height 5. Improve text rendering */ body { line-height: 1.5; -webkit-font-smoothing: antialiased; } /* 6. Improve media defaults */ img, picture, video, canvas, svg { display: block; max-width: 100%; } /* 7. Remove built-in form typography styles */ input, button, textarea, select { font: inherit; } /* 8. Avoid text overflows */ p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; } /* 9. Create a root stacking context */ #root, #__next { isolation: isolate; }
코드는 짧지만 이 작은 스타일 시트에는 유용한 정보가 많이 포함되어 있습니다. 시작해 봅시다!
시작하기 전에 질문에 답하세요! 추가 CSS 스타일을 적용하지 않은 경우 아래 코드에서 .box
요소(분홍색 테두리가 있는 직사각형 영역)의 너비는 얼마입니까? 200px, 240px, 244px 또는 0px입니까? .box
元素(粉红色边框的矩形区域)的宽度是多少?是 200px、240px、244px 还是 0px 呢?
<style> .parent { width: 200px; } .box { width: 100%; border: 2px solid hotpink; padding: 20px; } </style> <div class="parent"> <div class="box"></div> </div>
在 .box
元素的样式中设置了 width: 100%
,由于它的父元素 .parent
的宽度是 200px,所以 这里的 100% 会被解析为 200px。
那么这 200px 的宽度会作用在哪里呢?默认情况下,浏览器会将这个宽度应用在内容框上 (content box)。正如我们所熟知的那样,这里所说的 “内容框” 是盒模型里的盒子实际包含的内容,它在 border 和 padding 内部:
width: 100%
将 .box
盒模型的 content 部分设置为 200px;内边距 padding 会额外增加 40px 宽度(每边各 20px);边框 border 会增加 4px(每边各 2px)。通过加法计算不难得出粉色边框矩形的宽度为 244px。因此,上面提到的问题的答案是 244px。
当我们试图将一个 244px 的盒子塞进一个 200px 宽的父容器时,它会发生溢出:
这种行为看起来很奇怪,我们可以通过以下设置来更改它:
*, *::before, *::after { box-sizing: border-box; }
应用此规则后,宽度的百分比将基于 border-box 进行解析。在上面的例子中,我们的粉色框是 200px,而内部的 content-box 将缩小到 156px (200px - 40px - 4px)。
在我看来,这是一条必不可少的样式的规则,因为它会使 CSS 更易于使用。我们用通配符选择器(*
html { box-sizing: border-box; } *, *:before, *:after { box-sizing: inherit; }
.box
요소의 스타일에 width: 100%
를 설정하세요. 상위 요소 .parent
의 너비가 200px이므로, 따라서 여기서 100%는 200px로 구문 분석됩니다. 그럼 이 200px 너비는 어디에 적용되나요? 기본적으로 브라우저는 이 너비를 콘텐츠 상자에 적용합니다. 우리 모두 알고 있듯이, 여기에 언급된 "콘텐츠 상자"는 테두리와 패딩 내부에 있는 상자 모델의 상자에 실제로 포함된 콘텐츠입니다.
너비: 100%
.box 상자 모델의 콘텐츠 부분은 200px로 설정됩니다. 패딩은 너비를 추가로 40px(각 측면에서 20px) 증가시킵니다. 테두리는 4px(각 측면에서 2px)만큼 증가합니다. 분홍색 테두리 직사각형의 너비가 244px임을 더해 계산하는 것은 어렵지 않습니다. 따라서 위에서 언급한 질문에 대한 답은 244px 입니다. <p></p>244px 상자를 200px 너비의 상위 컨테이너에 채우려고 하면 오버플로가 발생합니다. 🎜🎜<img src="https://img.php.cn/upload/image/680/530/658/1643165688965117.%20png" title="164316568896511사용자 정의 CSS 재설정 스타일에 대한 심층 분석" alt="사용자 정의 CSS 재설정 스타일에 대한 심층 분석">🎜🎜이 동작은 이상해 보입니다. 다음 설정으로 변경할 수 있습니다. 🎜<pre class="brush:css;toolbar:false;">.legacy {
box-sizing: content-box;
}</pre>🎜이 규칙을 적용한 후 너비 백분율은 기반으로 구문 분석됩니다. 테두리 상자에. 위의 예에서 분홍색 상자는 200px이고 내부 콘텐츠 상자는 156px(200px - 40px - 4px)로 축소됩니다. 🎜🎜제 생각에는 이것이 CSS를 더 쉽게 사용할 수 있게 해주기 때문에 필수적인 스타일 규칙입니다. 와일드카드 선택기(<code>*
)를 사용하여 모든 요소와 의사 요소에 적용합니다. 대중의 인식과는 완전히 반대로, 이 스타일 설정은 성능 저하를 일으키지 않습니다. 자세한 내용은 🎜* { Box-sizing: Border-box } FTW🎜 문서를 참조하세요. 🎜🎜🎜상자 크기 상속🎜🎜🎜온라인에서 다른 스타일 설정을 봤습니다. 🎜html { box-sizing: border-box; } *, *:before, *:after { box-sizing: inherit; }
如果您想在一个已存在的大型项目中迁移使用 border-box,那么这将是一个有用的策略。如果你从零开始一个全新的项目,这是没有必要的。为了简单起见,我在 CSS 重置样式中省略了它。
首先,我们可以创建一个 “legacy” 选择器,将 box-sizing 的值继续保留为 content-box
,这也是 box-sizing 属性的默认值:
.legacy { box-sizing: content-box; }
然后,当应用程序中存在尚未迁移使用 border-box 时,我们就可以将该类添加到对应的位置,以保持原有样式不被影响:
<body> <header class="legacy"> <nav> <!-- Legacy stuff here --> </nav> </header> <main> <section> <!-- Modern stuff here --> </section> <aside class="legacy"> <!-- Legacy stuff here --> </aside> </main> </body>
为什么要这样做呢?现在,让我们思考一下这个代码段中的元素是如何计算的。
<header></header>
被赋予了 legacy
,因此它使用了 box-sizing: content-box
。
其子元素 <nav></nav>
的样式为 box-sizing: inherit
。由于其父元素设置为 content-box
,nav
也将设置为 content-box
。
<main></main>
标签没有 legacy
,因此它从其父级 继承;而
继承自
;
已经被设置为
border-box
。
从本质上讲,每个元素都可以从其父元素获得 box-sizing 属性。如果它有一个设置了 legacy
的祖先,那么它的属性值是 content-box
。否则,它将最终从 标签中继承,其属性值为
border-box
。
* { margin: 0; }
浏览器会对外边距 (margin) 做出很多常识性假设。例如,h1
在默认情况下要比段落的边距更大。这些假设在那些做文字处理的文档中是合理的,但对于现代 web 应用程序来说可能并不准确。
另外,外边距会在你稍不留神的时候遭遇外边距塌陷的问题,它可真是一个令人讨厌的小机灵鬼呢。而且,我发现自己经常希望元素在默认情况下没有任何外边距。所以我决定把它全部去掉。
当我确实希望向特定的标签添加外边距时,我可以在项目中用自定义样式中来实现。通配符选择器(*
)的优先级极低,这条规则很容易被覆盖。
html, body { height: 100%; }复制代码
我们在 CSS 中经常会使用百分比来设置高度,很多时候却发现它似乎并没有效果。请看下面的示例:
虽然将 main
元素设置为 height: 100%
,但元素的高度根本没有变化!
这里不起作用的原因是,在 CSS 流式布局(CSS 中的主要布局模式)中,height
和 width
的工作原理完全不同。元素的宽度是基于父元素计算的,元素的高度是根据其子元素计算的。这个话题说起来比较复杂,远远超出了本文的范围,本文中不再展开讨论。
在下面的代码示例中,我们将上面的规则应用到代码中,会发现 main
元素的高度变为了 100%:
如果您使用的是像 React 这样的 JavaScript 框架,那么您可能还需要在此规则中添加第三个选择器:框架使用的根元素。
例如,在我的 Next.js 项目中,会将规则做如下更新:
html, body, #__next { height: 100%; }
为什么不使用 vh?
你可能会想:为什么非得使用百分比来设置高度呢?为什么不用 vh
替代呢?
问题是 vh
不能在移动设备上正常工作;在移动设备上浏览器 UI 在上下滑动的时候,视口的可见部分会进行调整,这就导致 100vh
在浏览器中是不固定的,可能会超过屏幕实际的使用面积。
在未来,新的 CSS 单位将解决这个问题。在此之前,我继续使用基于百分比的高度。
body { line-height: 1.5; }
行高 line-height
控制段落中每行文本之间的垂直间距。它的默认值因浏览器而异,但通常在 1.2 左右。这个没有单位的数字是基于字体大小的比值。它的功能就像 em
一样。line-height
为 1.2 时,每行的行高将比元素的字体大 20%。
这里带来一个问题,对于那些有阅读障碍的人来说,这些句子排得太近,使阅读变得更困难。WCAG 标准规定,行高应至少为 1.5。
现在,1.5 这个数字会影响标题 (如 h1、h2 等标签) 和其他大字体元素,使它们产生了相当大的行间距:
您可能直观的想到,在标题上重新设置行高。我的理解是,WCAG 标准是针对 “body” 文本,这里只对 body 设置了 1.5 倍行高。
使用 “calc” 灵活的设置 line-heights
我一直在尝试着另一种设置行高的方法,如下所示:
* { line-height: calc(1em + 0.5rem); }
这是一个相当高级的代码片段,虽然它又超出了本文的范围,这里还是会简单做一下介绍。
这个方法并没有用字体的大小值乘以 1.5 这样的数字来计算行高,而是以字体大小作为基数,并为每行添加固定的空间。对于 body 里面的文字段落((paragraphs),每行都将解析为 24px(假设使用的是浏览器的默认字体大小)。
不过,在较大的文本上,此声明会产生更紧的行。下面的示例可以做出验证:
这个在使用时需谨慎,目前我还在试验中。
其中的一个缺点是,我们必须用 *
将其设置在所有元素上,而不是将其应用于 body
。这是因为 em
单位不能被子元素很好地继承;它不能使每个元素重新计>算 1em
所对应的值。例如,在这个博客上,因为第三方代码假设行高是可继承的,导致我的代码被它破坏了。
有关这项技术的更多信息,请查看 Kitty Giraudel 的这篇很棒的博文:使用 calc 计算最佳行高。
body { -webkit-font-smoothing: antialiased; }
这个 CSS 设置存在一点争议。
在 MacOS 计算机上,默认情况下浏览器会使用 “亚像素抗锯齿(subpixel antialiasing)”。这种技术可以利用每个像素内的 R/G/B 灯光使文本更易于阅读。
在过去,这个技术被认为提高了可访问性,因为它改善了文本对比度。你可能读过一篇流行的博文,停止 “修复” 字体平滑,这篇文章并不提倡切换到 “抗锯齿(antialiased)”。
问题是,这篇文章写于 2012 年,那时高 DPI “视网膜(retina)” 显示时代还未来临。今天的像素更小,肉眼根本看不见。LED 像素的物理布局也发生了变化。如果你在显微镜下观察现代显示器,你已经不会看到有序的 R/G/B 线网格了。
在 2018 年发布的 MacOS Mojave 中,苹果公司在操作系统中禁用了亚像素抗锯齿。我猜他们意识到,对现代硬件来说,这个技术的弊大于利。
令人困惑的是,像 Chrome 和 Safari 这样的 MacOS 浏览器,在默认情况下仍然使用亚像素抗锯齿。因此,我们需要将 -webkit-font-smoothing
设置为 antialiased
来显式关闭亚像素抗锯齿。
这两者的区别在于:
MacOS 是唯一使用亚像素抗锯齿的操作系统,因此这个 CSS 规则对 Windows、Linux 或移动设备没有影响。如果您使用的是 MacOS 计算机,则可以尝试运行一下下面的代码示例:
img, picture, video, canvas, svg { display: block; max-width: 100%; }
在 CSS 中图像被认为是 “inline” 内联元素,也就意味着它们应该像<em></em>
或 <strong></strong>
那样在段落中间使用。这与我们经常使用图像的方式是不符的。通常,我们使用图片的方式与对待段落、标题或边栏的方式相同,这些都是布局元素。
但是,如果我们布局中试图使用内联元素,就会碰到奇奇怪怪的事情。比如内联元素的 4px 空白间距问题,这个神奇的空白与 line-height
有关系。通过在所有图像上设置 display:block
,我们避开了这一类问题。
我还设置了 max-width: 100%
,这样做是为了防止大型图像溢出,特别是它们被放在一个不够宽的容器中。
大多数块级元素将自动伸长/收缩以适应其父元素,但像 <img alt="사용자 정의 CSS 재설정 스타일에 대한 심층 분석" >
这样的媒体元素是特殊的:它们被称为替换元素,并且它们也不遵循相同的规则。
如果图像的 “自身的” 大小为 800 × 600,那么 <img alt="사용자 정의 CSS 재설정 스타일에 대한 심층 분석" >
元素的宽度也将为 800px,即使我们将其放入一个 500px 宽的父元素中。
这个规则将防止图像超出其容器,我认为这是一个比较明智的做法。
input, button, textarea, select { font: inherit; }
在默认情况下,按钮和输入框不会从它们的父项继承排版样式。相反,他们有自己怪异的风格。例如,<textarea></textarea>
将使用系统默认的 Monospace 字体。文本输入框将使用系统默认的 sans-serif 字体。两者都会选择 microscopically-small 字体大小(Chrome 为 13.333px)。
正如您所想象的,在移动设备上阅读 13px 的文本非常困难。当我们聚焦设置了较小字体的输入框时,浏览器会自动放大,这样文本更容易阅读。
不幸的是,这样的用户体验并不好:
如果要避免这种自动缩放行为,输入的字体大小必须至少为 1rem/16px。有一种方法可以解决这个问题:
input, button, textarea, select { font-size: 1rem; }
这修正了自动缩放问题,但这只是一个权宜之计。让我们从根本上来解决这个问题:表单输入不应该有自己的排版样式!
input, button, textarea, select { font: inherit; }
font
是一种 CSS 设置字体的简略写法,它设置了一系列与字体相关的属性,如 font-size
、font-weight
和 font-family
等。通过把它的值设置为 inherit
,可将这些元素与其周围环境中的排版一致。
只要我们没有在 body 中使用令人讨厌的较小的字体,这就一次解决了我们所有的问题。
p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; }
在 CSS 中,如果没有足够的空间容纳一行中的所有字符,文本将自动换行。
默认情况下,算法将寻找 “软换行” 机会;这些是算法可以对字符进行拆分。在英语中,唯一软换行的机会是空格和连字符,但这因语言而异。
如果一行没有任何软换行机会,并且不适合,则会导致文本溢出:
这可能会导致一些恼人的布局问题。在这里,它添加了一个水平滚动条。在其他情况下,它可能会导致文本与其他元素重叠,或滑到图像/视频后面。
overflow-wrap
属性允许我们调整换行算法,并允许它在找不到软换行机会时使用硬换行:
虽热,这两种解决方案都不是完美的,但至少硬换行不会破坏布局!
感谢 Sophie Alpert 提出了类似的规则!她建议将其应用于所有元素,这可能是一个好主意,但不是我个人测试过的东西。
您还可以尝试添加 hyphens
属性:
p { overflow-wrap: break-word; hyphens: auto; }
hyphens: aut
:自动使用连字符(在支持它们的语言中)表示硬换行。这也使得硬换行更为常见。如果你有非常窄的文本栏,可以使用一下它。在我个人的 CSS 重置样式中并为包含它,但它值得尝试!
#root, #__next { isolation: isolate; }
最后一个是可选的。通常只有在使用 React 之类的 JavaScript 框架时才需要它。
正如我们在 滚蛋吧,z-index 中看到的那样,isolation
属性允许我们创建新的堆栈上下文,而无需设置 z-index
。
这是有益的,因为它允许我们保证某些高优先级元素(模态、下拉列表、工具提示)在应用程序中始终显示在其他元素之上。没有奇怪的堆叠背景错误,没有 层出不穷的 z-index。
为了匹配您使用的框架,您需要根据您的需要来调整选择器。我们希望选择在应用程序中呈现的顶级元素。例如,在 create-react-app 使用的是<div id="root">,因此正确的选择器是 <code>#root
。
以下是我的 CSS 重置样式,采用了精简的、可复制的、优美的格式:
/* Josh's Custom CSS Reset https://www.joshwcomeau.com/css/custom-css-reset/ */ *, *::before, *::after { box-sizing: border-box; } * { margin: 0; } html, body { height: 100%; } body { line-height: 1.5; -webkit-font-smoothing: antialiased; } img, picture, video, canvas, svg { display: block; max-width: 100%; } input, button, textarea, select { font: inherit; } p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; } #root, #__next { isolation: isolate; }
请随意复制/粘贴到您自己的项目中!它的发布没有任何限制(不过如果你想保留这篇博文的链接,我将不胜感激!)。
我没有将这个 CSS 重置样式作为 NPM 包发布,因为我觉得你应该拥有自己的重置样式。把它带到你的项目中,随着时间的推移,当你学习新事物或发现新技巧时,可以对它进行调整。如果需要,您可以随时制作自己的 NPM 包,以便于在项目中重用。请记住:代码恒久远,一段永流传;您拥的有这段代码,它应该与您一起成长。
感谢 Andy Bell 分享他的现代 CSS 样式重置。它激发了我的一些灵感,并启发了这篇博文!
我的 CSS 重置样式很短(只有 11 次声明!),但我还是花了整整一篇博文来谈论它们。老实说,我还有很多话要说!我们对一些知识点只简单的提及,并未深入展开。
CSS 看似复杂,其实不然。只有你打破砂锅问到底,才能了解里面到底发生了什么,否则语言总是会感到有点不可预测和不一致。当你的心智模型不完整时,你肯定会遇到一些问题。
不过,如果你花一点时间来学习该语言的实际工作原理,一切都会变得更加直观和可预测。在那些阳光灿烂的日子里,我喜欢自由自在的写 CSS!
(学习视频分享:css视频教程)
위 내용은 사용자 정의 CSS 재설정 스타일에 대한 심층 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!