如果要掌握 css,一定要理解基础知识,并且深入的理解。css 的意思是层叠样式表。我们先讲层叠。我们需要理解浏览器如何解析样式规则。每条规则单独看很简单,但是当两条规则提供了冲突的样式会发生什么呢。如果你发现一条规则没有按照预期生效,可能是因为另一条规则跟它冲突了。要想预测规则最终的效果,就需要理解 CSS 里的层叠。我们写一个网页头部来展示下。
<header class="page-header">
<h1 id="page-title" class="title">coffee roasters</h1>
<nav>
<ul id="main-nav" class="nav">
<li><a href="/">Home</a></li>
<li><a href="/coffee">coffee</a></li>
<li><a href="/specials" class="featured">specials</a></li>
</ul>
</nav>
</header>
<style>
h1 {
color: red;
}
#page-title {
color: green;
}
.title {
color: blue;
}
</style>
三个规则尝试给标题设置不同的字体。浏览器为了解决这个问题会遵循一些列规则,因此最终的效果可以预测。上面例子,id 选择器生效。层叠指的就是这一系列规则。它决定了如何解决冲突,是 CSS 语言的基础。虽然有经验的开发人员对层叠有大体的了解,但是层叠里有些规则还是容易让人误解。
当生命冲突时,层叠会依据三种条件解决冲突。1 样式表的来源:样式是从哪里来的,包括你的样式盒浏览器的默认样式等。2 选择器优先级:哪些选择器比另一些选择器更重要。3 源码顺序:样式在样式表里的声明顺序。大致的比较逻辑可以这样说。发生冲突时,首先判断来源或重要性。假如是使用更高优先级的来源里的声明,假如不是。判断是否内连样式。假如内连样式使用内连声明。假如不是判断选择器是否有不同的优先级。假如是的话,使用更高优先级的声明。假如不是,使用源码顺序里较晚出现的声明。
这些规则让浏览器以可预测的方式解决 CSS 样式规则的冲突。我们一个个来讲:样式表的来源。你添加到网页里的样式表并不是浏览器惟一的样式表,还有其他类型或来源的恶样式表。你的样式属于作者样式表,除此之外还有用户代理样式表,即浏览器默认样式。用户代理样式表优先级低,你的样式会覆盖它们。
用户代理样式,默认颜色是黑色。列表有左侧内边距,list-style-type 为 disc,因此有项目符号小黑点。链接为蓝色且有下划线。标题盒列表有上下外边距。浏览器应用来用户代理样式之后才会应用你的样式表。你指定的声明会覆盖用户代理样式表里的样式。如果你在 html 里链接里多个样式表,那么它们的来源都相同。都是作者样式表。
<style>
h1 {
color: #2f4f4f;
margin-bottom: 10px;
}
#main-nav {
margin-top: 10px;
list-style: none;
padding-left: 0;
}
#main-nav li {
display: inline-block;
}
#main-nav a {
color: #fff;
background-color: #13a4a4;
padding: 5px;
border-radius: 2px;
text-decoration: none;
}
</style>
长期使用 CSS,大概习惯了覆盖用户代理的样式。这种做法实际上就是利用了层叠的样式来源规则。你写的样式会覆盖用户代理样式,因为来源不同。
样式来源规则有一个例外:标记为重要的声明。在声明的后面,分号的前面加上!important,该声明就会被标记为重要的声明。会被当作更高优先级的来源。
如果无法用来源解决冲突声明,浏览器会尝试检查它们的优先级。理解优先级很重要。不理解样式的来源照样可以写 CSS,因为 99%的网站样式来自同样的源,但是如果不理解优先级,就会被坑的很惨。浏览器把优先级分为两部分:HTML 的行内样式盒选择器的样式。
行内样式:如果用 HTML 的 styls 属性写样式,这个声明只用作用域当前元素。实际上行内元素属于带作用域的声明,它会覆盖任何来自样式表活着 style 标签的样式。行内样式没有选择器,因为它们直接作用于所在的元素。如果我们想要按钮其中一个变为橘黄色。有几种方式能够实现效果。为了样式表里覆盖行内声明,需要为声明添加!important,这样将它升到一个更高优先级的来源。但是行内样式也被标记为!important,就无法覆盖它了。但这种不是更好的写法。
<style>
#main-nav a {
color: #fff;
background-color: #13a4a4;
padding: 5px;
border-radius: 2px;
text-decoration: none;
}
.featured {
color: orange;
}
</style>
优先级的第二部分由选择器决定。(bb 时刻)比如,有两个类名的选择器比只有一个类名的选择器优先级更高。如果一个声明将背景色设置为橘黄色,但另一个更高优先级的声明将其设置为蓝绿色,浏览器会应用蓝绿色。这是因为第一个选择器优先级高于第二个选择器。第一个由一个 ID 盒一个标签名组成,第二个由一个类名组成。但选择器的长度并不是决定优先级的唯一因素。
不同类型的选择器有不同的优先级。比如 ID 选择器比类选择器优先级高。ID 选择器的优先级比拥有任意多个类的选择器都高。同理,类选择器的优先级比标签选择器更高。比较规则如下如果选择器的 ID 数量更多。它会生出。如果 ID 数量一致,拥有最多类选择器的胜出。如果以上两次比较一致,拥有最多标签名的选择器胜出。
这个比较看起来脑子很累,有一种常用的表示优先级的方式是用数值形式来标记,通常用逗号隔开每个数。比如 1,2,2 代表 1 个 id,2 个类,2 个标签组成。优先级最高的 id 列卫第一位,紧接着是类,最后是标签。选择器 #page-header #page-title 有两个 id 没有类,也没有标签,它的优先级可以用 2,0,0 来表示。选择 ul li 有两个标签,没有类也没有 id,她的优先级可以用 0,0,2 来表示。然后通过数值比较久能决定哪个选择器优先级更高。1,0,0 的优先级高于,0,2,2 甚至 0,10,0(一个长达 10 个类名的选择器很奇怪)。因为第一个数有最高优先级。有时候会使用 4 个数的标记,其中最重要的位置用 0,1 来表示,代表一个声明是否用行内样式添加的。
之前 feature 选择器添加橘黄色没有成功,有几种方式让她成功,一个是添加!important 到元素的声明上。但是会在以后带来更多问题。一旦给很多声明加上!important,要覆盖已设置为 important 的声明时,只能再加上 important,然后再使用常规的优先级规则规则。最终会让一切回到起点。那更好的办法就是提升选择器的优先级。
<style>
#main-nav a {
color: #fff;
background-color: #13a4a4;
padding: 5px;
border-radius: 2px;
text-decoration: none;
}
#main-nav .featured {
color: orange;
}
</style>
他们的优先级变成,1,0,1和1,1,0.但这个方法还能改进。不提升第二个选择器的优先级,而是降低第一个选择器的优先级。将ID选择器改为公共的class。通过这些例子可以发现,优先级容易变成一种军备竞赛。在大型项目中这种尤其突出。通过最好让优先级尽可能低,这样当需要覆盖一些样式时,才有选择空间。
层叠的第三步是源码顺序。如果两个声明的来源和优先级相同,其中一个声明在样式表中出现较晚,或者位于页面较晚引入的样式表中。则该声明胜出。书写顺序之所以很重要,是因为层叠。优先级相同时,后出现的样式会覆盖先出现的样式。如果用户将鼠标悬停在一个访问过的连接上,悬停效果会生效。如果用户在悬停时激活了链接,即点击了它,激活的样式会生效。这个顺序的记忆口诀是love.hate,line,visited,hover,active.
浏览器遵循三个步骤,即来源,优先级,源码顺序,来解析网页上每个元素的每个属性。如果一个声明在层叠中胜出,它就被称作一个层叠值。层叠值作为层叠结果,应用到一个元素上的特定属性的值。
接下来分享两条通用的经验法则。1,在选择器中不要使用iD,就算只用一个iD,也会大幅提升优先级。当需要覆盖这个选择器时,通常找不到另一个有意义的iD,于是就会复制原来的选择器,然后加上另一个类,让它区别于想要覆盖的选择器。2,不要使用!important。它比id更难覆盖。这两条建议都不错,但不必固守他们,因为也有例外。只是不要为了赢得优先级竞赛而习惯性的使用这两个方法。
行内元素也要少用,因为当别人引用你的组件时,想修改只能通过important来覆盖。正确的做法还是class。
标签:优先级,样式,笔记,深入,样式表,层叠,声明,选择器,css From: https://www.cnblogs.com/wlxll/p/16759516.html