(给前端大全加星标,提升前端技能)
英文:rachel-andrew 译文:廖泽恩
https://zhuanlan.zhihu.com/p/57994014
很多人想让我给他们推荐有关CSS部分的教程,或者问我如何学习CSS。 我也看到很多人对CSS的部分内容感到困惑,一部分原因是由于对语言的过时认识。 鉴于CSS在过去几年中发生了相当大的变化,这是一个更新知识的好时机。 即使CSS只是你所做工作的一小部分(因为你使用其他技术栈),CSS是你最终希望在屏幕上显示的结果,所以值得合理去学习。
因此,本文旨在概述CSS的关键基础和资源,以便进一步阅读现代CSS开发的关键领域。 其中许多资源在Smashing杂志上已经有了,但我也选择了其他一些资源,也有人关注CSS的关键领域。 这不是一本完整的初学者指南或旨在涵盖所有知识点。 我的目标是覆盖现代CSS的广度,同时重点关注几个关键领域,将帮助你理解CSS的其他部分。
对于CSS的大部分内容,你不需要特意去学习属性和值,你可以在需要时查找它们。 然而,CSS中一些基础知识没有掌握好,你将很难去理解它。 这些基础知识值得你花时间去理解,从长远看,它会帮你节省很多时间和少走弯路。
选择器的表现如标题所说的,它选择文档的某些部分,以便你可以将CSS规则应用于它。 大多数人都熟悉使用 class,或在 直接使用HTML元素设置样式,比如 body,但是还有很多更高级的选择器可以根据文档中的位置选择元素,直接选择位于元素之后的元素,或选择表格中的奇数行。
这些选择器是CSS3规范的一部分(你可能听说过它们被称为第3级选择器)具有出色的浏览器支持。 有关可以使用的各种选择器的详细信息,请参阅 MDN 参考。
有些选择器的行为就好像你已经将类应用于文档中的某些内容。 例如p:first-child就像你在第一个p元素中添加了一个类一样,这些被称为 伪类选择器。 伪元素选择器就像动态插入一个元素一样,例如::first-line的表现与用span 包裹第一行文本类似。 但是,如果该行的长度发生变化,它将重新应用,如果插入该元素则不会出现这种情况。 这些选择器可能会相当复杂。 在下面的CodePen中是一个用伪类链接的伪元素的例子。 我们使用:first-child伪类定位第一个p元素,然后::first-line选择器选择该元素的第一行,就好像在第一行周围添加了一个以使其变为粗体和改变颜色。
class="container">
Veggies es bonus vobis, proinde vos postulo essum magis kohlrabi welsh onion daikon amaranth tatsoi tomatillo melon azuki bean garlic.Gumbo beet greens corn soko endive gumbo gourd. Parsley shallot courgette tatsoi pea sprouts fava bean collard greens dandelion okra wakame tomato. Dandelion cucumber earthnut pea peanut soko zucchini.Turnip greens yarrow ricebean rutabaga endive cauliflower sea lettuce kohlrabi amaranth water spinach avocado daikon napa cabbage asparagus winter purslane kale. Celery potato scallion desert raisin horseradish spinach carrot soko. Lotus root water spinach fennel kombu maize bamboo shoot green bean swiss chard seakale pumpkin onion chickpea gram corn pea. Brussels sprout coriander water chestnut gourd swiss chard wakame kohlrabi beetroot carrot watercress. Corn amaranth salsify bunya nuts nori azuki bean chickweed potato bell pepper artichoke.Nori grape silver beet broccoli kombu beet greens fava bean potato quandong celery. Bunya nuts black-eyed pea prairie turnip leek lentil turnip greens parsnip. Sea lettuce lettuce water chestnut eggplant winter purslane fennel azuki bean earthnut pea sierra leone bologi leek soko chicory celtuce parsley jícama salsify.
body {
padding: 20px;
font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;}* {box-sizing: border-box;}
p {
margin: 0 0 1em 0;}.container {
border: 5px solid rgb(111,41,97);
border-radius: .5em;
padding: 10px;
column-count: 2;}.container p:first-child::first-line {
font-weight: bold;
color: rgb(111,41,97);}
层叠是指当元素应用了多个样式规则,哪个规则优先应用。 如果你曾经遇到过无法理解为什么某些CSS似乎没有应用的情况,那可能是层叠没有运用好。 层叠与继承紧密相关,继承定义了子元素可以继承父元素的样式属性。 它还与特异性有关,不同的选择器具有不同的特异性,当有几个选择器可以应用于一个元素时,继承可以决定应用哪个规则。
注意:为了理解所有这些内容,我建议阅读MDN CSS简介中的 层叠和继承。
如果你正在尝试将一些CSS应用于一个元素,那么你的浏览器开发者工具是开始最好的地方。看看下面的例子,我用元素选择器 h1 将 h1 标题设置为橙色。同时,我也使用类选择器设置h1 设置为紫色。 由于类更具体,因此h1是紫色的。 在开发者工具中,您可以看到元素选择器被划掉,因为它没有被应用。 一旦你看到浏览器正在获取你的CSS(但其他东西已经推翻了它),那么你可以开始找出原因。
class="container">
class="veggies">I like veggies
Veggies es bonus vobis, proinde vos postulo essum magis kohlrabi welsh onion daikon amaranth tatsoi tomatillo melon azuki bean garlic.Gumbo beet greens corn soko endive gumbo gourd. Parsley shallot courgette tatsoi pea sprouts fava bean collard greens dandelion okra wakame tomato. Dandelion cucumber earthnut pea peanut soko zucchini.Turnip greens yarrow ricebean rutabaga endive cauliflower sea lettuce kohlrabi amaranth water spinach avocado daikon napa cabbage asparagus winter purslane kale. Celery potato scallion desert raisin horseradish spinach carrot soko. Lotus root water spinach fennel kombu maize bamboo shoot green bean swiss chard seakale pumpkin onion chickpea gram corn pea. Brussels sprout coriander water chestnut gourd swiss chard wakame kohlrabi beetroot carrot watercress. Corn amaranth salsify bunya nuts nori azuki bean chickweed potato bell pepper artichoke.Nori grape silver beet broccoli kombu beet greens fava bean potato quandong celery. Bunya nuts black-eyed pea prairie turnip leek lentil turnip greens parsnip. Sea lettuce lettuce water chestnut eggplant winter purslane fennel azuki bean earthnut pea sierra leone bologi leek soko chicory celtuce parsley jícama salsify.
body {
padding: 20px;
font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;}* {box-sizing: border-box;}
p {
margin: 0 0 1em 0;}.container {
border: 5px solid rgb(111,41,97);
border-radius: .5em;
padding: 10px;}.veggies {
color: rebeccapurple;}
h1 {
color: orange;}
CSS里一切都是盒子。 屏幕上显示的所有内容都有一个框,盒模型描述了如何计算该框的大小 - 将外边距,内边距和边框考虑进去。 标准的CSS框模型接受给定元素的宽度,然后将内边框和边框添加到该宽度上——这意味着元素占用的空间大于给定的宽度。
最近,我们已经能够选择使用IE盒模型,使得元素上的给定宽度作为屏幕上可见元素的宽度。 任何内边距或边框都会从边缘插入框的内容。 这对许多布局更有意义。
在下面的演示中,我有两个盒子。 两者的宽度均为200像素,边框为5像素,内边距为20像素。 第一个框使用标准框模型,因此占用总宽度为250像素,第二个框使用IE盒模型,因此实际上是200像素宽。
class="box">
I use the standard box model.
class="box box2">
I use the alternate box model.
body {
padding: 20px;
font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;}
p {
margin: 0 0 1em 0;}.box {
border: 5px solid rgb(111,41,97);
border-radius: .5em;
padding: 20px;
width: 200px;
margin-bottom: 2em;}.box2 {
box-sizing: border-box;}
浏览器开发者工具可以再次帮助你了解正在使用的盒子模型。 在下图中,我使用火狐浏览器的开发者工具使用默认的内容框框模型检查框。 工具告诉我这是正在使用的盒模型,我可以看到大小以及如何将边框和内边框添加到指定的宽度。
注意:在IE6之前,Internet Explorer使用IE盒模型,内边框和边框插入给定宽度的内容里。 所以有一段时间浏览器使用不同的盒模型! 如果今天的互操作性问题感到沮丧,现在已经有所改善,那么我们就不会处理浏览器以不同的方式计算元素的宽度。
在 CSS Tricks 里,有关于盒模型和盒子尺寸的很好的解释,并解释了在你的网站中全局使用IE盒模型的最佳方法。
如果你的文档内容用一些HTML标记,你的文档将具有可读性。标题和段落会另起新的一行,单词组成句子时,它们之间有一个空格。标记是用来格式化的,像 em 不会破坏句子的流。 句子会表现标准流,或块流布局。句子的每个部分都被描述为“在流中”,它知道句子其余内容,所以不会重叠。
如果你去了解,而不是去反对这种行为,你会变得更加轻松。这是为什么从正确标记的HTML文档开始很有意义的原因之一,由于浏览器遵守正常流和内置样式表,你的内容从可读的地方开始。
一旦文档的内容处于正常流程中,您可能希望更改其中一些内容的外观。 你可以通过更改元素的格式上下文来完成此操作。 举个一个非常简单的示例,如果你希望所有段落连在一起而不是从新行开始,你可以设置 p 元素的样式属性display:inline ,将 p 元素由块级元素变成内联元素。
本质上,格式化上下文定义了外部和内部类型。外部控制元素与页面上其他元素的行为,内部控制子元素的外观。例如,当你设置 display:flex ,你在设置外部为块格式化上下文,设置子元素为 flex 格式化上下文。
注意:最新版本的Display规范改变了 display 的值,显式声明外部和内部的类型。因此,将你可能会声明 display:block flex; (外部为 block,内部为 flex)
在 MDN 上阅读更多关于 display的信息
CSS中的元素被描述为“在流中”或“脱离流”。流中的元素被赋予空间,并且空间被流中的其他元素所影响。 如果通过浮动或定位元素使元素脱离流,则该元素的空间将不再受到其他流元素的影响。
对于绝对定位的元素,是最明显的。 如果你设置一个元素 position: absolute ,该元素会从流中脱离,你需要确保这个元素不会与流中的元素重叠,且不影响你布局的其他部分的可读性。
class="container">
Veggies es bonus vobis, proinde vos postulo essum magis kohlrabi welsh onion daikon amaranth tatsoi tomatillo melon azuki bean garlic.Gumbo beet greens corn soko endive gumbo gourd. Parsley shallot courgette tatsoi pea sprouts fava bean collard greens dandelion okra wakame tomato. Dandelion cucumber earthnut pea peanut soko zucchini.Turnip greens yarrow ricebean rutabaga endive cauliflower sea lettuce kohlrabi amaranth water spinach avocado daikon napa cabbage asparagus winter purslane kale. Celery potato scallion desert raisin horseradish spinach carrot soko. Lotus root water spinach fennel kombu maize bamboo shoot green bean swiss chard seakale pumpkin onion chickpea gram corn pea. Brussels sprout coriander water chestnut gourd swiss chard wakame kohlrabi beetroot carrot watercress. Corn amaranth salsify bunya nuts nori azuki bean chickweed potato bell pepper artichoke.Nori grape silver beet broccoli kombu beet greens fava bean potato quandong celery. Bunya nuts black-eyed pea prairie turnip leek lentil turnip greens parsnip. Sea lettuce lettuce water chestnut eggplant winter purslane fennel azuki bean earthnut pea sierra leone bologi leek soko chicory celtuce parsley jícama salsify.
class="item">
I am absolutely positioned and out of flow.
body {
padding: 20px;
font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;}* {box-sizing: border-box;}
p {
margin: 0 0 1em 0;}.container {
border: 5px solid rgb(111,41,97);
border-radius: .5em;
padding: 10px;
column-count: 2;
max-width: 400px;
position: relative;}.item {
border-radius:.5em;
position: absolute;
top: 10px;
left: 20px;
background-color: rgba(111,41,97,.9);
color: #fff;
padding: 20px;
width: 200px;}
然而,浮动元素也会从流中脱离,但后面的元素的文本将环绕该浮动元素。你可以设置后面元素的背景颜色,你会看到他们会上升并占用了原来浮动元素原来的空间。
class="container">
class="item">
I am floated and out of flow.
Veggies es bonus vobis, proinde vos postulo essum magis kohlrabi welsh onion daikon amaranth tatsoi tomatillo melon azuki bean garlic.Gumbo beet greens corn soko endive gumbo gourd. Parsley shallot courgette tatsoi pea sprouts fava bean collard greens dandelion okra wakame tomato. Dandelion cucumber earthnut pea peanut soko zucchini.Turnip greens yarrow ricebean rutabaga endive cauliflower sea lettuce kohlrabi amaranth water spinach avocado daikon napa cabbage asparagus winter purslane kale. Celery potato scallion desert raisin horseradish spinach carrot soko. Lotus root water spinach fennel kombu maize bamboo shoot green bean swiss chard seakale pumpkin onion chickpea gram corn pea. Brussels sprout coriander water chestnut gourd swiss chard wakame kohlrabi beetroot carrot watercress. Corn amaranth salsify bunya nuts nori azuki bean chickweed potato bell pepper artichoke.Nori grape silver beet broccoli kombu beet greens fava bean potato quandong celery. Bunya nuts black-eyed pea prairie turnip leek lentil turnip greens parsnip. Sea lettuce lettuce water chestnut eggplant winter purslane fennel azuki bean earthnut pea sierra leone bologi leek soko chicory celtuce parsley jícama salsify.
body {
padding: 20px;
font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;}* {box-sizing: border-box;}
p {
margin: 0 0 1em 0;}.container {
border: 5px solid rgb(111,41,97);
border-radius: .5em;
padding: 10px;
max-width: 500px;}.item {
border-radius:.5em;
float: left;
background-color: rgba(111,41,97,.9);
color: #fff;
padding: 20px;
width: 100px;
margin: 10px;}.container p:nth-of-type(1) {
background-color: yellow;}
你可以在MDN上阅读更多有关 流中和脱离流 的信息。 需要记住的重要一点是,如果从流中取出一个元素,则需要自己管理重叠,因为块流布局的常规规则不再适用。
十五年来,我们一直使用CSS布局,但没有设计一套布局系统。这已经改变了。 我们现在拥有功能完备的布局系统,其中包括 Grid 和 Flexbox ,还有多列布局和旧布局方法也应用于实际目的。如果你想对CSS布局还不熟悉,你可以阅读 MDN 上的布局教程,或阅读我发表在Smashing杂志上的文章 《开始学习CSS布局》。
不要认为grid和flexbox等方法在某种程度上是竞争的。为了更好地使用布局,你有时会发现组件最好作为 flex ,有时作为 Grid。有时,你想要多列流动布局。所有这些都是不错的选择。如果你觉得自己在与某些事物的行为方式作斗争,这通常是一个非常好的迹象,表明它可能值得退一步,尝试一种不同的方法。我们已经习惯了在CSS上做一些我们想做的事情,以至于我们可能会忘记我们还有很多其他的选择可以尝试。
布局是我的主要专业领域,我在Smashing Magazine和其他地方写了很多文章,试图开拓新的布局美化。 除了上面提到的布局文章,我在Flexbox上有一整套系列 - 《从创建Flex 容器时,发生了什么》。 在 Grid示例 上,我列出很多CSS Grid 的例子 — 以及一个视频教程。
此外 - 特别是对于设计师 - 查看 Jen Simmons 和她的《Layout Land》视频系列。
通常,我会将对齐和布局分开,虽然大多数人把对齐当作 Flexbox的一部分。对齐这些属性适用于所有布局方法上,应该在上下文去理解对齐,而不是考虑 “Flexbox对齐”或“CSSGrid 对齐”。对齐属性在大体上表现一样,但不同布局方式里会有一些差异。
在MDN上,您可以深入了解 盒对齐 及其在Grid,Flexbox,多列和块布局中的实现方式。 在Smashing Magazine上,我有一篇文章专门介绍Flexbox中的对齐方式:你需要知道的有关Flexbox中对齐的所有内容。
我在2018年花了很多时间讨论了内部和外部尺寸规范,特别是它与Grid和Flexbox的关系。在web上,我们习惯于设置尺寸为长度或百分比,这就是我们如何使用浮动来制作网格类型布局的方法。然而,现代的布局方法可以为我们做很多空间分配——如果我们允许的话。值得花时间去了解Flexbox如何分配空间(或Grid fr 单元如何工作)。
在Smashing Magazine上,我写了一些关于 布局中的尺寸 的文章,也写了一些关于Flexbox的文章,比如 Flex 盒子有多大?
通常,新的Grid和Flexbox布局方法意味着我们可以使用比旧方法更少的媒体查询,因为它们非常灵活,可以响应视口或组件大小的变化,而无需我们更改元素的宽度。 但是,有些地方需要添加一些断点来进一步增强设计。
以下是响应式设计的一些简单指南,一般情况下,对于媒体查询,请查看我的文章《在2018年使用媒体查询进行响应式设计》。我将查看媒体查询的用途,并介绍规范4的媒体查询的新功能。
与布局一样,网络上的字体使用在去年发生了巨大的变化。现在,可变字体,使单个字体文件具有无限的变化。 要了解它们是什么以及它们如何工作,请观看Mandy Michael的精彩简短演讲:可变字体和网页设计的未来。 另外,我会推荐Jason Pamental的动态排版与现代CSS和可变字体。
为了探索可变字体和它们的功能,微软提供了一个有趣的演示,以及一些尝试可变字体的游乐场 - Axis Praxis是最知名的(我也喜欢字体游乐场)。
MDN上的指南将证明一开始使用可变字体是非常有用的。要了解如何为不支持可变字体的浏览器实现回退解决方案,请阅读Oliver Schondorfer的《使用回退Web字体实现可变字体》Firefox DevTools字体编辑器还支持使用可变字体。
CSS转换和动画绝对是我需要知道的基础。 我不经常需要使用它们,在使用时会忘记语法。 值得庆幸的是,MDN上的参考资料帮助了我,我建议从使用CSS变换和使用CSS动画的指南开始。 Zell Liew也有一篇很好的文章,为CSS过渡提供了很好的解释。
要发现一些可能的事情,请查看Animista网站。
关于动画可能令人困惑的事情之一是采取哪种方法。 除了CSS支持的内容之外,你可能还需要涉及JavaScript,SVG或Web Animation API,而这些事情往往都会被混为一谈。 在她的演讲中,选择你的动画冒险记录在事件中,Val Head解释了这些选项。
当我提到Grid或Flexbox资源时,我经常看到回复说,如果没有特定的速查表,他们就不能使用Flexbox。我觉得把速查表作为记忆助手查找语法没有问题,我自己也出版过一些速查表。完全依赖速查表的问题是当你复制语法时,你可能会忽略为什么要这样写。然后,当你遇到属性的行为似乎不同的情况时,这种明显的不一致性似乎令人困惑,或者是语言的错误 。
如果你发现CSS在做一些非常奇怪的事情的情况下,问问为什么。创建一个简单的测试用例来强调这个问题,问问对规范更熟悉的人。我被问到的许多CSS问题都是因为人们认为属性的表现与它在现实中的表现不同。这就是为什么我经常讨论关于对齐和尺寸,因为这些地方经常会混淆。
是的,CSS中有一些奇怪的东西。它是一门经过多年进化的语言,有些东西我们无法改变,除非我们发明了时间机器。然而,一旦你掌握了一些基础知识,并且理解了为什么会这样,你就可以更轻松地处理棘手的问题。
推荐阅读
(点击标题可跳转阅读)
老生常谈之 CSS 的垂直居中
探究 CSS 混合模式\滤镜导致 CSS 3D 失效问题
纯 CSS 实现多行文字截断
觉得本文对你有帮助?请分享给更多人
关注「前端大全」加星标,提升前端技能
好文章,我在看❤️