CSS重要概念层叠,你搞清楚了吗

CSS简介

CSS在1994年被提出,1996年由Internet Explorer 3首次(部分地)实现。每个经验丰富的Web开发者在见识到CSS的神奇效果后,大部分会问:“我该如何学习CSS? ”

在软件开发中,CSS是很特别的存在。严格来讲,它不是编程语言,却要求抽象思维。它不是纯粹的设计工具,却要求创造力。它提供了看似简单的声明式语法,但是在大型项目中写过CSS的人都知道它可能会变得极其复杂。在学习传统编程中遇到问题时,你通常知道该搜索什么(比如,“如何找到一个数组里类型为x的元素”)。在CSS中,却很难将问题提炼成一句话。即使可以,答案一般也是“这得看情况”。最好的解决办法通常取决于具体场景,以及你希望以多大粒度处理各种边缘情况。

CSS层叠

在讲解层叠之前,先让我们先一段代码,在html中创建一个div,代码如下:

<div id="menus" class="layui-menus"></div>

接下来,我们对这个div声明规则,代码如下:

/** 标签选择器 */
div {
    font-size: 12px;
    color: #fff;
}

/** ID选择器 */
#menus {
    font-size: 14px;
    color:#000; 
}

/** 类选择器 */
.layui-menus{
    font-size: 16px;
    color:#fff;
}

三个规则集尝试给菜单设置不同的字体和颜色,哪一个会生效呢?浏览器为了解决这个问题会遵循一系列规则,因此最终的效果可以预测。在上面的代码里,规则决定了第二个声明(即 ID选择器)生效。

层叠指的就是这一系列规则。它决定了如何解决冲突,是CSS语言的基础。虽然有经验的开发人员对层叠有大体的了解,但是层叠里有些规则还是容易让人误解。
下面来分析层叠的规则。当声明冲突时,层叠会依据三种条件解决冲突。
(1) 样式表的来源:
样式是从哪里来的,包括你的样式和浏览器默认样式等。
(2) 选择器优先级:
哪些选择器比另一些选择器更重要。
(3) 源码顺序:
样式在样式表里的声明顺序。

这些规则让浏览器以可预测的方式解决CSS样式规则的冲突。我们来一个一个地分析。

样式表的来源

你添加到网页里的样式表并不是浏览器唯一使用的样式表,还有其他类型或来源的样式表。你的样式表属于作者样式表,除此之外还有用户代理样式表,即浏览器默认样式。用户代理样式表优先级低,你的样式会覆盖它们。用户代理样式表因为设置了用户普遍需要的样式,所以不会做一些完全超出预期的事情。当你不喜欢默认样式时,可以在自己的样式表里设置别的值。例如:ul li 标签前面的小黑点,链接为蓝色且有下划线等。

  • important声明

样式来源规则有一个例外:标记为重要(important)的声明。如下所示,在声明的后面、分号的前面加上!important,该声明就会被标记为重要的声明。

#menus {
    font-size: 14px;
    color:#000 !important; 
}

标记了!important的声明会被当作更高优先级的来源,因此总体的优先级按照由高到低排列如下所示:
(1) 作者的!important
(2) 作者
(3) 用户代理
层叠独立地解决了网页中每个元素的样式属性的冲突。例如,如果给段落设置加粗的字体,用户代理的上下外边距样式仍然会生效(除非被明确覆盖)。处理过渡和动画时,还会再提到样式来源的概念,因为它们会引入更多的来源。! important 注释是 CSS的一个有趣而怪异的特性,稍后会再解释。

样式表优先级

如果无法用来源解决冲突声明,浏览器会尝试检查它们的优先级。理解优先级很重要。不理解样式的来源照样可以写CSS,因为99%的网站样式是来自同样的源。但是如果不理解优先级,就会被坑得很惨。浏览器将优先级分为两部分:HTML的行内样式和选择器的样式。

  • 行内样式

如果用HTML的style属性写样式,这个声明只会作用于当前元素。实际上行内元素属于“带作用域的”声明,它会覆盖任何来自样式表或者

为了在样式表里覆盖行内声明,需要为声明添加!important,这样能将它提升到一个更高优先级的来源。但如果行内样式也被标记为

!important,就无法覆盖它了。最好是只在样式表内用!important。将以上修改撤销,我们来看看更好的方式。

  • 选择器优优先

优先级的第二部分由选择器决定。比如,有两个类名的选择器比只有一个类名的选择器优先级更高。如果一个声明将字体颜色设置为白色,但另一个更高优先级的声明将其设置为黑色,浏览器就会将黑色应用到元素上。

/** 更高优先级的选择器 */
#menus div{
	color:#000; 
}

.layui-menus{
    color: #fff;
}

不同类型的选择器有不同的优先级。比如,ID 选择器比类选择器优先级更高。实际上,ID选择器的优先级比拥有任意多个类的选择器都高。同理,类选择器的优先级比标签选择器(也称类型选择器)更高。
优先级的准确规则如下。
❑ 如果选择器的ID数量更多,则它会胜出(即它更明确)。
❑ 如果ID数量一致,那么拥有最多类的选择器胜出。
❑ 如果以上两次比较都一致,那么拥有最多标签名的选择器胜出。

说明:伪类选择器(如:hover)和属性选择器(如[type=“input”])与一个类选择器的优先级相同。通用选择器(*)和组合器(>、+、~)对优先级没有影响。

如果你在 CSS 里写了一个声明,但是没有生效,一般是因为被更高优先级的规则覆盖了。很多时候开发人员使用 ID选择器,却不知道它会创建更高的优先级,之后就很难覆盖它。如果要覆盖一个ID选择器的样式,就必须要用另一个ID选择器。这个概念很简单,但是如果你不理解优先级,就无法弄清楚为什么一个规则能生效,另一个却不能。

源码顺序

如果两个声明的来源和优先级相同,其中一个声明在样式表中出现较晚,或者位于页面较晚引入的样式表中,则该声明胜出。也就是说,可以通过控制源码顺序,来给特殊链接添加样式。如果两个冲突选择器的优先级相同,则出现得较晚的那个胜出。

div .layui-menus {
    color: #fff;
}

.layui-menus div {
    color: #000;
}

在这个方法里,选择器优先级相同。源码顺序决定了哪个声明作用于特殊链接,最终的字体颜色为黑色。

总结

浏览器遵循三个步骤,即来源、优先级、源码顺序,来解析网页上每个元素的每个属性。如果一个声明在层叠中“胜出”,它就被称作一个层叠值。元素的每个属性最多只有一个层叠值。网页上一个特定的段落(

)可以有一个上外边距和一个下外边距,但是不能有两个不同的上外边距或两个不同的下外边距。如果 CSS 为同一个属性指定了不同的值,层叠最终会选择一个值来渲染元素,这就是层叠值。

正如之前所说,在CSS中最好的答案通常是“这得看情况”。实现相同的效果有很多途径。多想些实现方法,并思考每一种方法的利弊,这是很有价值的。面对一个样式问题时,我经常分两个步骤来解决它。首先确定哪些声明可以实现效果。其次,思考可以用哪些选择器结构,然后选择最符合需求的那个。

最后的最后

为初学者提供学习指南,为从业者提供参考价值。我坚信码农也具有产生洞见的能力。扫描下图二维码关注,学习和交流!
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/pangpengshuai/article/details/119377800