Maison > interface Web > tutoriel CSS > Analyse approfondie des styles de réinitialisation CSS personnalisés

Analyse approfondie des styles de réinitialisation CSS personnalisés

青灯夜游
Libérer: 2022-01-26 11:04:20
avant
3200 Les gens l'ont consulté

Cet article vous donnera une analyse approfondie du style de réinitialisation CSS personnalisé, étudiera chacune des règles et analysera les raisons d'utiliser cette règle. J'espère qu'il sera utile à tout le monde !

Analyse approfondie des styles de réinitialisation CSS personnalisés

Chaque fois que je démarre un nouveau projet, ma première priorité est de m'occuper des coins et recoins du langage CSS. Pour résoudre ces problèmes, un ensemble personnalisé de styles de base est souvent utilisé.

J'utilisais depuis longtemps le fameux style CSS Reset (CSS Reset) d'Eric Meyer. En tant que code CSS ancien et pratique, il n’a jamais été mis à jour au cours des dix dernières années, et beaucoup de choses ont radicalement changé au cours de cette période !

Récemment, j'ai commencé à utiliser mes propres styles de réinitialisation CSS personnalisés. Il contient de nombreux conseils que j'ai résumés pour améliorer à la fois l'expérience utilisateur et l'expérience de développement CSS. Dans cet article, nous présenterons ce style de réinitialisation CSS personnalisé. Et étudiez chacune de ces règles en profondeur. En plus de discuter de la fonction de chaque règle, nous analyserons également les raisons d'utiliser cette règle d'une manière simple et facile à comprendre !

<strong>Introduction au contexte

Historiquement, la fonction principale du style de réinitialisation CSS est d'effacer le style par défaut du navigateur pour assurer la cohérence du style entre les navigateurs. Et mon style de réinitialisation CSS ne vise pas à résoudre ce problème.

De nos jours, il existe des différences minimes de mise en page ou d'espacement entre les navigateurs. En général, les navigateurs modernes ont implémenté la spécification CSS aussi fidèlement que prévu. Par conséquent, traiter les problèmes de cohérence du style n’est plus aussi important.

De plus, je ne pense jamais qu'il soit nécessaire de supprimer tous les styles par défaut du navigateur. Par exemple, j'utiliserais la balise <em> pour définir le style de police en italique ! Bien qu'il puisse y avoir différentes spécifications de conception à respecter dans différents projets, je ne vois aucun intérêt à supprimer les valeurs par défaut de bon sens.

Mon style de réinitialisation CSS ne répond peut-être pas à la définition classique du "style de réinitialisation CSS", mais d'un autre point de vue, ce style de réinitialisation CSS a également plus de créativité.

<strong>My CSS Reset

Ne parlons plus, passons directement au code :

/*
  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;
}
Copier après la connexion

Bien que le code soit court, cette petite feuille de style contient beaucoup d'informations utiles. Commençons !

<strong>1. Modèle de boîte de taille de boîte

Avant de commencer, répondez d'abord à une question ! Sans style CSS supplémentaire, quelle est la largeur de l'élément .box (la zone rectangulaire avec une bordure rose) dans le code ci-dessous ? Est-ce 200px, 240px, 244px ou 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>
Copier après la connexion

.box 元素的样式中设置了 width: 100%,由于它的父元素 .parent 的宽度是 200px,所以 这里的 100% 会被解析为 200px。

那么这 200px 的宽度会作用在哪里呢?默认情况下,浏览器会将这个宽度应用在内容框上 (content box)。正如我们所熟知的那样,这里所说的 “内容框” 是盒模型里的盒子实际包含的内容,它在 border 和 padding 内部:

Analyse approfondie des styles de réinitialisation CSS personnalisés

width: 100%.box 盒模型的 content 部分设置为 200px;内边距 padding 会额外增加 40px 宽度(每边各 20px);边框 border 会增加 4px(每边各 2px)。通过加法计算不难得出粉色边框矩形的宽度为 244px。因此,上面提到的问题的答案是 244px。

当我们试图将一个 244px 的盒子塞进一个 200px 宽的父容器时,它会发生溢出:

Analyse approfondie des styles de réinitialisation CSS personnalisés

这种行为看起来很奇怪,我们可以通过以下设置来更改它:

*, *::before, *::after {
  box-sizing: border-box;
}
Copier après la connexion

应用此规则后,宽度的百分比将基于 border-box 进行解析。在上面的例子中,我们的粉色框是 200px,而内部的 content-box 将缩小到 156px (200px - 40px - 4px)。

在我看来,这是一条必不可少的样式的规则,因为它会使 CSS 更易于使用。我们用通配符选择器(*

html {
  box-sizing: border-box;
}
*, *:before, *:after {
  box-sizing: inherit;
}
Copier après la connexion
Copier après la connexion
Définissez width : 100% dans le style de l'élément .box Puisque la largeur de son élément parent .parent est de 200px, Donc 100 % ici sera analysé comme 200 px.

Alors, où s'applique cette largeur de 200 px ? Par défaut, les navigateurs appliquent cette largeur à la zone de contenu. Comme nous le savons tous, la « boîte de contenu » mentionnée ici est le contenu réellement contenu dans la boîte dans le modèle de boîte, qui se trouve à l'intérieur de la bordure et du remplissage :

<strong>Analyse approfondie des styles de réinitialisation CSS personnalisés

largeur : 100% Changer .box< /code> La partie contenu du modèle de boîte est définie sur 200 px ; le remplissage augmentera la largeur de 40 px supplémentaires (20 px de chaque côté) ; Il n'est pas difficile de calculer par addition que la largeur du rectangle de bordure rose est de 244 pixels. Par conséquent, la réponse à la question mentionnée ci-dessus est 244 pixels. <p></p>Lorsque nous essayons de placer une boîte de 244 px dans un conteneur parent de 200 px de large, elle déborde : 🎜🎜<img src="https://img.php.cn/upload/image/680/530/ 658/164316568896511Analyse approfondie des styles de réinitialisation CSS personnalisés " title="164316568896511Analyse approfondie des styles de réinitialisation CSS personnalisés" alt="Analyse approfondie des styles de réinitialisation CSS personnalisés"/>🎜🎜Ce comportement semble bizarre, nous pouvons le modifier avec les paramètres suivants : 🎜<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:css;toolbar:false;">.legacy { box-sizing: content-box; }</pre><div class="contentsignin">Copier après la connexion</div></div><div class="contentsignin">Copier après la connexion</div></div>🎜Après avoir appliqué cette règle, la largeur Le pourcentage sera analysé en fonction de la bordure-boîte. Dans l'exemple ci-dessus, notre boîte rose mesure 200 px et la zone de contenu interne sera réduite à 156 px (200 px – 40 px – 4 px). 🎜🎜À mon avis, c'est une règle de style essentielle car elle rend le CSS plus facile à utiliser. Nous utilisons des sélecteurs génériques (<code>*) pour l'appliquer à tous les éléments et pseudo-éléments. Complètement contrairement à la croyance populaire, ce paramètre de style n'entraînera pas de détérioration des performances. Pour plus de détails, veuillez vous référer à l'article 🎜* { Box-sizing : Border-box } FTW🎜. 🎜🎜🎜Héritage du dimensionnement de la boîte🎜🎜🎜J'ai vu un autre paramètre de style en ligne : 🎜
html {
  box-sizing: border-box;
}
*, *:before, *:after {
  box-sizing: inherit;
}
Copier après la connexion
Copier après la connexion

如果您想在一个已存在的大型项目中迁移使用 border-box,那么这将是一个有用的策略。如果你从零开始一个全新的项目,这是没有必要的。为了简单起见,我在 CSS 重置样式中省略了它。

首先,我们可以创建一个 “legacy” 选择器,将 box-sizing 的值继续保留为 content-box,这也是 box-sizing 属性的默认值:

.legacy {
  box-sizing: content-box;
}
Copier après la connexion
Copier après la connexion

然后,当应用程序中存在尚未迁移使用 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>
Copier après la connexion

为什么要这样做呢?现在,让我们思考一下这个代码段中的元素是如何计算的。

  • <header> 被赋予了 legacy,因此它使用了 box-sizing: content-box

  • 其子元素 <nav> 的样式为 box-sizing: inherit。由于其父元素设置为 content-boxnav 也将设置为 content-box

  • <main> 标签没有 legacy,因此它从其父级 <body> 继承;而 <body> 继承自 <html><html> 已经被设置为 border-box

从本质上讲,每个元素都可以从其父元素获得 box-sizing 属性。如果它有一个设置了 legacy 的祖先,那么它的属性值是 content-box。否则,它将最终从 <html> 标签中继承,其属性值为 border-box

<strong>2. 移除 margin 的默认值

* {
  margin: 0;
}
Copier après la connexion

浏览器会对外边距 (margin) 做出很多常识性假设。例如,h1 在默认情况下要比段落的边距更大。这些假设在那些做文字处理的文档中是合理的,但对于现代 web 应用程序来说可能并不准确。

另外,外边距会在你稍不留神的时候遭遇外边距塌陷的问题,它可真是一个令人讨厌的小机灵鬼呢。而且,我发现自己经常希望元素在默认情况下没有任何外边距。所以我决定把它全部去掉。

当我确实希望向特定的标签添加外边距时,我可以在项目中用自定义样式中来实现。通配符选择器(*)的优先级极低,这条规则很容易被覆盖。

<strong>3. 基于百分比的 height

html, body {  height: 100%;
}复制代码
Copier après la connexion

我们在 CSS 中经常会使用百分比来设置高度,很多时候却发现它似乎并没有效果。请看下面的示例:

Analyse approfondie des styles de réinitialisation CSS personnalisés

虽然将 main 元素设置为 height: 100%,但元素的高度根本没有变化!

这里不起作用的原因是,在 CSS 流式布局(CSS 中的主要布局模式)中,heightwidth 的工作原理完全不同。元素的宽度是基于父元素计算的,元素的高度是根据其子元素计算的。这个话题说起来比较复杂,远远超出了本文的范围,本文中不再展开讨论。

在下面的代码示例中,我们将上面的规则应用到代码中,会发现 main 元素的高度变为了 100%:

Analyse approfondie des styles de réinitialisation CSS personnalisés

如果您使用的是像 React 这样的 JavaScript 框架,那么您可能还需要在此规则中添加第三个选择器:框架使用的根元素。

例如,在我的 Next.js 项目中,会将规则做如下更新:

html, body, #__next {
  height: 100%;
}
Copier après la connexion

<strong>为什么不使用 vh?

你可能会想:为什么非得使用百分比来设置高度呢?为什么不用 vh 替代呢?

问题是 vh 不能在移动设备上正常工作;在移动设备上浏览器 UI 在上下滑动的时候,视口的可见部分会进行调整,这就导致 100vh 在浏览器中是不固定的,可能会超过屏幕实际的使用面积。

在未来,新的 CSS 单位将解决这个问题。在此之前,我继续使用基于百分比的高度。

<strong>4. 更改 line-height

body {
  line-height: 1.5;
}
Copier après la connexion

行高 line-height 控制段落中每行文本之间的垂直间距。它的默认值因浏览器而异,但通常在 1.2 左右。这个没有单位的数字是基于字体大小的比值。它的功能就像 em 一样。line-height 为 1.2 时,每行的行高将比元素的字体大 20%。

这里带来一个问题,对于那些有阅读障碍的人来说,这些句子排得太近,使阅读变得更困难。WCAG 标准规定,行高应至少为 1.5

现在,1.5 这个数字会影响标题 (如 h1、h2 等标签) 和其他大字体元素,使它们产生了相当大的行间距:

Analyse approfondie des styles de réinitialisation CSS personnalisés

您可能直观的想到,在标题上重新设置行高。我的理解是,WCAG 标准是针对 “body” 文本,这里只对 body 设置了 1.5 倍行高。

<strong>使用 “calc” 灵活的设置 line-heights

我一直在尝试着另一种设置行高的方法,如下所示:

* {
  line-height: calc(1em + 0.5rem);
}
Copier après la connexion

这是一个相当高级的代码片段,虽然它又超出了本文的范围,这里还是会简单做一下介绍。

这个方法并没有用字体的大小值乘以 1.5 这样的数字来计算行高,而是以字体大小作为基数,并为每行添加固定的空间。对于 body 里面的文字段落((paragraphs),每行都将解析为 24px(假设使用的是浏览器的默认字体大小)。

不过,在较大的文本上,此声明会产生更紧的行。下面的示例可以做出验证:

Analyse approfondie des styles de réinitialisation CSS personnalisés

这个在使用时需谨慎,目前我还在试验中。

其中的一个缺点是,我们必须用 * 将其设置在所有元素上,而不是将其应用于 body。这是因为 em 单位不能被子元素很好地继承;它不能使每个元素重新计>算 1em 所对应的值。例如,在这个博客上,因为第三方代码假设行高是可继承的,导致我的代码被它破坏了。

有关这项技术的更多信息,请查看 Kitty Giraudel 的这篇很棒的博文:使用 calc 计算最佳行高

<strong>5. 设置 font-smoothing

body {
  -webkit-font-smoothing: antialiased;
}
Copier après la connexion

这个 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 来显式关闭亚像素抗锯齿。

这两者的区别在于:

Analyse approfondie des styles de réinitialisation CSS personnalisés

MacOS 是唯一使用亚像素抗锯齿的操作系统,因此这个 CSS 规则对 Windows、Linux 或移动设备没有影响。如果您使用的是 MacOS 计算机,则可以尝试运行一下下面的代码示例:

Analyse approfondie des styles de réinitialisation CSS personnalisés

<strong>6. 更改媒体元素的默认值

img, picture, video, canvas, svg {
  display: block;
  max-width: 100%;
}
Copier après la connexion

在 CSS 中图像被认为是 “inline” 内联元素,也就意味着它们应该像<em><strong>那样在段落中间使用。这与我们经常使用图像的方式是不符的。通常,我们使用图片的方式与对待段落、标题或边栏的方式相同,这些都是布局元素。

但是,如果我们布局中试图使用内联元素,就会碰到奇奇怪怪的事情。比如内联元素的 4px 空白间距问题,这个神奇的空白与 line-height 有关系。通过在所有图像上设置 display:block,我们避开了这一类问题。

我还设置了 max-width: 100%,这样做是为了防止大型图像溢出,特别是它们被放在一个不够宽的容器中。

大多数块级元素将自动伸长/收缩以适应其父元素,但像 <img alt="Analyse approfondie des styles de réinitialisation CSS personnalisés" > 这样的媒体元素是特殊的:它们被称为替换元素,并且它们也不遵循相同的规则。

如果图像的 “自身的” 大小为 800 × 600,那么 <img alt="Analyse approfondie des styles de réinitialisation CSS personnalisés" > 元素的宽度也将为 800px,即使我们将其放入一个 500px 宽的父元素中。

这个规则将防止图像超出其容器,我认为这是一个比较明智的做法。

<strong>7. 表单控件的字体继承

input, button, textarea, select {
  font: inherit;
}
Copier après la connexion
Copier après la connexion

在默认情况下,按钮和输入框不会从它们的父项继承排版样式。相反,他们有自己怪异的风格。例如,<textarea> 将使用系统默认的 Monospace 字体。文本输入框将使用系统默认的 sans-serif 字体。两者都会选择 microscopically-small 字体大小(Chrome 为 13.333px)。

正如您所想象的,在移动设备上阅读 13px 的文本非常困难。当我们聚焦设置了较小字体的输入框时,浏览器会自动放大,这样文本更容易阅读。

不幸的是,这样的用户体验并不好:

Analyse approfondie des styles de réinitialisation CSS personnalisés

如果要避免这种自动缩放行为,输入的字体大小必须至少为 1rem/16px。有一种方法可以解决这个问题:

input, button, textarea, select {
  font-size: 1rem;
}
Copier après la connexion

这修正了自动缩放问题,但这只是一个权宜之计。让我们从根本上来解决这个问题:表单输入不应该有自己的排版样式!

input, button, textarea, select {
  font: inherit;
}
Copier après la connexion
Copier après la connexion

font 是一种 CSS 设置字体的简略写法,它设置了一系列与字体相关的属性,如 font-sizefont-weightfont-family 等。通过把它的值设置为 inherit,可将这些元素与其周围环境中的排版一致。

只要我们没有在 body 中使用令人讨厌的较小的字体,这就一次解决了我们所有的问题。

<strong>8. 设置文字换行

p, h1, h2, h3, h4, h5, h6 {
  overflow-wrap: break-word;
}
Copier après la connexion

在 CSS 中,如果没有足够的空间容纳一行中的所有字符,文本将自动换行。

默认情况下,算法将寻找 “软换行” 机会;这些是算法可以对字符进行拆分。在英语中,唯一软换行的机会是空格和连字符,但这因语言而异。

如果一行没有任何软换行机会,并且不适合,则会导致文本溢出:

Analyse approfondie des styles de réinitialisation CSS personnalisés

这可能会导致一些恼人的布局问题。在这里,它添加了一个水平滚动条。在其他情况下,它可能会导致文本与其他元素重叠,或滑到图像/视频后面。

overflow-wrap 属性允许我们调整换行算法,并允许它在找不到软换行机会时使用硬换行:

1Analyse approfondie des styles de réinitialisation CSS personnalisés

虽热,这两种解决方案都不是完美的,但至少硬换行不会破坏布局!

感谢 Sophie Alpert 提出了类似的规则!她建议将其应用于所有元素,这可能是一个好主意,但不是我个人测试过的东西。

您还可以尝试添加 hyphens 属性:

p {
  overflow-wrap: break-word;
  hyphens: auto;
}
Copier après la connexion

hyphens: aut:自动使用连字符(在支持它们的语言中)表示硬换行。这也使得硬换行更为常见。如果你有非常窄的文本栏,可以使用一下它。在我个人的 CSS 重置样式中并为包含它,但它值得尝试!

<strong>9. Root 堆栈上下文

#root, #__next {
  isolation: isolate;
}
Copier après la connexion

最后一个是可选的。通常只有在使用 React 之类的 JavaScript 框架时才需要它。

正如我们在 滚蛋吧,z-index 中看到的那样,isolation 属性允许我们创建新的堆栈上下文,而无需设置 z-index

这是有益的,因为它允许我们保证某些高优先级元素(模态、下拉列表、工具提示)在应用程序中始终显示在其他元素之上。没有奇怪的堆叠背景错误,没有 层出不穷的 z-index。

为了匹配您使用的框架,您需要根据您的需要来调整选择器。我们希望选择在应用程序中呈现的顶级元素。例如,在 create-react-app 使用的是<div id="root">,因此正确的选择器是 #root

最终的可用代码

以下是我的 CSS 重置样式,采用了精简的、可复制的、优美的格式:

/*
  Josh&#39;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;
}
Copier après la connexion

请随意复制/粘贴到您自己的项目中!它的发布没有任何限制(不过如果你想保留这篇博文的链接,我将不胜感激!)。

我没有将这个 CSS 重置样式作为 NPM 包发布,因为我觉得你应该拥有自己的重置样式。把它带到你的项目中,随着时间的推移,当你学习新事物或发现新技巧时,可以对它进行调整。如果需要,您可以随时制作自己的 NPM 包,以便于在项目中重用。请记住:代码恒久远,一段永流传;您拥的有这段代码,它应该与您一起成长。

感谢 Andy Bell 分享他的现代 CSS 样式重置。它激发了我的一些灵感,并启发了这篇博文!

深入学习 CSS

我的 CSS 重置样式很短(只有 11 次声明!),但我还是花了整整一篇博文来谈论它们。老实说,我还有很多话要说!我们对一些知识点只简单的提及,并未深入展开。

CSS 看似复杂,其实不然。只有你打破砂锅问到底,才能了解里面到底发生了什么,否则语言总是会感到有点不可预测和不一致。当你的心智模型不完整时,你肯定会遇到一些问题。

不过,如果你花一点时间来学习该语言的实际工作原理,一切都会变得更加直观和可预测。在那些阳光灿烂的日子里,我喜欢自由自在的写 CSS!

(学习视频分享:css视频教程

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
css
source:juejin.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal