这是我参与更文挑战的第五天,活动详情查看:更文挑战
层叠样式表 (Cascading
Style Sheets,缩写为
CSS),是一种 样式表 语言,用来描述
HTML或
XML(包括如
SVG、
MathML、
XHTML之类的
XML 分支语言)文档的呈现。
CSS` 描述了在屏幕、纸质、音频等其它媒体上的元素应该如何被渲染的问题。
而CSS
选择器规定了 CSS
规则会被应用到哪些元素上。
1.1 简单/基本选择器
标签/元素选择器:
-
按照给定的节点名称,选择所有匹配的元素。
-
语法:
elementname
-
例子:
input
匹配任何<input>
元素。div
(标签选择器)svg
|a
(命名空间选择器-html 部分的知识)
类选择器:
-
按照给定的
class
属性的值,选择所有匹配的元素。 -
语法:
.classname
,.class
(支持用空格分隔多个) -
例子:
.index
匹配任何class
属性中含有 “index” 类的元素。
ID 选择器:
-
按照
id
属性选择一个与之匹配的元素。需要注意的是,一个文档中,每个ID
属性都应当是唯一的。 -
语法:
#idname
,#id
(必须完全匹配) -
例子:
#toc
匹配 ID 为 “toc” 的元素。
属性选择器:
-
按照给定的属性,选择所有匹配的元素。
-
语法:
[attr]
[attr=value]
[attr~=value]
[attr|=value]``[attr^=value]
[attr$=value]
[attr*=value]
。 -
例子:
[autoplay]
选择所有具有autoplay 属性
的元素(不论这个属性的值是什么)。
/* 匹配存在title属性的a标签*/
a[title] {
color: purple;
}
/* 匹配href="https://example.org"的a标签 */
a[href="https://example.org"]
{
color: green;
}
/* 匹配href的内容包含"example"的 a 标签 */
a[href*="example"] {
font-size: 2em;
}
/* 匹配href的内容以 ".org" 结尾的a标签 */
a[href$=".org"] {
font-style: italic;
}
/* 匹配class属性的内容包含"logo"的 a标签 */
a[class~="logo"] {
padding: 2px;
}
复制代码
伪类选择器:
-
:
伪选择器支持按照未被包含在文档树中的状态信息来选择元素。 -
例子:
a:visited
匹配所有曾被访问过的<a>
元素。:hover
(伪类)
伪元素选择器:
-
::
伪选择器用于表示无法用HTML
语义表达的实体。 -
例子:
p::first-line
匹配所有<p>
元素的第一行。::before
(伪元素)
1.2 选择器语法
1.2.1 复合选择器
复合选择器即多个简单选择器的组合,此情况下必须匹配每一个选择器
- <简单选择器><简单选择器><简单选择器>
*
或者div
必须写在最前面,伪类
,伪元素
写在最后面
1.2.2 选择器列表
-
,
是将不同的选择器组合在一起的方法,它选择所有能被列表中的任意一个选择器选中的节点。 -
语法:
A, B
-
示例:
div , span
会同时匹配<span>
元素和<div>
元素。
/*
*/
div,
#id,
.class {
}
复制代码
1.2.3 复杂选择器
复杂选择器也叫组合器, 是把复合选择器用一定的操作符链接
- <复合选择器>
<sp>
<复合选择器> - <复合选择器>
>
<复合选择器> - <复合选择器>
~
<复合选择器> - <复合选择器>
+
<复合选择器> - <复合选择器>
||
<复合选择器>
1.2.3.1 子孙选择器
子孙选择器也叫后代组合器(Descendant combinator)
-
-
语法:
A B
-
例子:
div span
匹配所有位于任意<div>
元素之内的<span>
元素。
/*
选中 div 下面 含有 .class 的所有子元素
*/
div .class {
}
复制代码
1.2.3.2 子选择器
子选择器也叫直接子代组合器(Child combinator)
-
>
组合器选择前一个元素的直接子代的节点。 -
语法:
A > B
-
例子:
ul > li
匹配直接嵌套在<ul>
元素内的所有<li>
元素。 -
特点: 只能选择子一级,是一个严格的父子关系
/*
选中 div 下面 含有 .class 的一个子元素
*/
div > .class {
}
复制代码
1.2.3.3 兄弟选择器
兄弟选择器也叫一般兄弟组合器(General sibling combinator)
-
~
组合器选择兄弟元素,也就是说,后一个节点在前一个节点后面的任意位置,并且共享同一个父节点。 -
语法:
A ~ B
-
例子:
p ~ span
匹配同一父元素下,<p>
元素后的所有<span>
元素。
/*
*/
div ~ .class {
}
复制代码
1.2.3.4 邻居选择器
邻居选择器也叫紧邻兄弟组合器(Adjacent sibling combinator)
-
+
组合器选择相邻元素,即后一个元素紧跟在前一个之后,并且共享同一个父节点。 -
语法:
A + B
-
例子:
h2 + p
会匹配所有紧邻在<h2>
(en-US) 元素后的<p>
元素。
/*
*/
div + .class {
}
复制代码
1.2.3.5 双竖线(level4 标准)
-
||
组合器选择属于某个表格行的节点。 -
语法:
A || B
-
例子:
col || td
会匹配所有<col>
作用域内的<td>
元素。
table 里面去选中一列
/*
*/
div||.class {
}
复制代码
2. 选择器优先级
从高到低排列有
- 行内样式
给元素添加的内联样式 (例如,style="font-weight:bold"
) 总会覆盖外部样式表的任何样式 ,因此可看作是具有最高的优先级。
-
关系选择符(combinators)
-
ID 选择器(例如,
#example
)。 -
类选择器 (例如,
.example
),属性选择器(例如,[type="radio"]
)和伪类(例如,:hover
) -
类型选择器(例如,
h1
)和伪元素(例如,::before
)
可以访问以下来了解更多关于优先级的详细信息。
2.1 简单选择器优先级的如何计算
当我们用一个非常复杂的规则去选择元素时,最终优先级可以用一个”四元组”来表示:
[inline(最高),id 个数,class 个数,tag 个数]
结果从后往前数(因为最后一位是 inline,优先级最高)
在 CSS 标准
中我们需要使用一个足够大的 N 进制 来进行计算出优先级
在简单选择器中, 除了 #id
, .class
, 其他简单选择器的优先级是一样的
/*1 2*/
#id div.a#id {
/**/
}
/* [0,2,1,1] */
复制代码
S = 0 _ N+ 2 _ N + 1 N+1
取 N = 1000000
S = 2000001000001
请使用[inline(最高),id 个数,class 个数,tag 个数]
的范式写出下面选择器的优先级:
div#a.b .c[id=x]
#a:not(#b)
.a
div.a
正确答案
- [0,1,3,1]
- [0,2,0,0]
- [0,0,1,0]
- [0,0,1,1]
解析 div#a.b .c[id=x]的优先级
相同的规则的优先级–二者相等()
优先级相同,后面的规则会覆盖前面的规则
<style>
div#a.b .c[id="x"] {
color: red;
}
/*
优先级相同,后面的规则会覆盖前面的规则
*/
div#a.b .c[id="x"] {
color: blue;
}
</style>
<div id="a" class="b">
<div class="c" id="x">666</div>
</div>
复制代码
id 选择器优先级 > 属性选择器优先级
<style>
/*
#x 与 [id=x] 相比, #x优先级跟高
*/
div#a.b .c#x {
color: red;
}
div#a.b .c[id="x"] {
color: blue;
}
</style>
<div id="a" class="b">
<div class="c" id="x">666</div>
</div>
复制代码
class 选择器优先级 === 属性选择器优先级
<style>
/*
.d 与 [id=x] 相比, 二者优先级是一致的
*/
div#a.b .c.d {
color: red;
}
div#a.b .c[id="x"] {
color: blue;
}
</style>
<div id="a" class="b">
<div class="c d" id="x">666</div>
</div>
复制代码
<style>
/*
.d 与 [id=x] 相比, 二者优先级是一致的
*/
div#a.b .c.d {
color: blue;
}
div#a.b .c[id="x"] {
color: red;
}
</style>
<div id="a" class="b">
<div class="c d" id="x">666</div>
</div>
复制代码
解析 #a:not(#b)的优先级
伪类是不参与优先级计算的
<style>
/*
伪类是不参与优先级计算的
但是,在 :not() 内部声明的选择器会影响优先级
MDN中说到(https://developer.mozilla.org/zh-CN/docs/Web/CSS/:not)
可以利用这个伪类提高规则的优先级。例如, #foo:not(#bar) 和 #foo 会匹配相同的元素,
但是前者的优先级更高。
*/
#a:not(#b) {
color: green;
}
#a {
color: black;
}
</style>
<div id="x" class="b">
<div class="c d" id="a">666</div>
</div>
复制代码
<style>
/*
伪类是不参与优先级计算的
*/
#a:not(#b) {
color: green;
}
#x #a {
color: black;
}
</style>
<div id="x" class="b">
<div class="c d" id="a">666</div>
</div>
复制代码
解析 .a 与 div.a 的优先级
*
号不会影响优先级
<style>
/*
* 号不会影响优先级
*/
div.a {
color: brown;
}
*.a {
color: green;
}
</style>
<div id="x" class="b">
<div class="a" id="a">666</div>
</div>
复制代码
- 复杂选择器的优先级就是把每个简单选择器的优先级加起来吗? 是的!
- transform 不会改变别的元素, 只会改变自身元素位置,会改变重绘,
- css 有继承吗? 是指子元素属性与父元素属性的继承, 不是 面向对象说到的继承
3 . 伪类
表示链接/行为的伪类
CSS
伪类 选择器代表一个有链接锚点的元素,而不管它是否被访问过,也就是说,它会匹配每一个有 href
属性的 <a>
、<area>
或 <link>
元素。因此,它会匹配到所有的 :link
或 :visited
。
active
表示当所指元素处于激活状态(鼠标在元素上按下还没有松开)时所显示的颜色。
focus
表示元素获得光标焦点时使用的颜色,主要用于文本框输入文字时使用(鼠标松开时显示的颜色)。
伪类的顺序应为:
:link
:visited
:hover
:focus
:active
a:link {
color: blue;
} /* 未访问链接 */
a:visited {
color: purple;
} /* 已访问链接 */
a:hover {
background: yellow;
} /* 用户鼠标悬停 */
a:active {
color: red;
} /* 激活链接 */
p:active {
background: #eee;
} /* 激活段落 */
复制代码
表示树形结构的伪类
代表没有子元素的元素。子元素只可以是元素节点或文本(包括空格)。注释或处理指令都不会产生影响。
在玩具浏览器中,在 startTag 的时候去做 computeCSS,
至少要到 endtag 之后的下一个 token 是什么
至少要到标签结束的时候,再往后扫一个 token,才能知道是不是 此伪类对应的元素
是无法实现的,在真实代码场景中不建议使用,
CSS 回溯问题
逻辑型
not 中加复杂选择器, 可以这样使用
4.伪元素
<div>
<::before/> content content content content content content content content
content content content content content content content content <::after/>
</div>
复制代码
<div >
<::first-letter/>c</::first-letter> ontent content content content
content content content content
content content content content
content content content content
</div>
复制代码
<div>
<::first-line/>content content content content </::first-line>
content content content content
content content content content
content content content content
</div>
复制代码
思考
- 编写一个 match 函数
function match(selector, element) {
return true;
}
// 第一个参数:任意选择器
// 第二个参数,定位html中一个已存在的元素
// 结果: 返回第一个参数与第二个参数是否相等
match("div #id.class", document.getElementById("id"));
复制代码
<body>
<div>
<div id="id" class="class">1</div>
<div class="class">2</div>
</div>
</body>
<script>
function match(selector, element) {
// 返回与指定的选择器组匹配的文档中的元素列表 (使用深度优先的先序遍历文档的节点)。返回的对象是 NodeList 。
const nodeList = document.querySelectorAll(selector);
for (let e in nodeList) {
// 给定的元素与 NodeList的某一项是否匹配
return nodeList[e] === element;
}
return false;
}
const mydiv = document.getElementById("id");
const res = matchesSelector("div #id.class", mydiv);
console.log(res);
</script>
复制代码
最后
文章浅陋,欢迎各位看官评论区留下的你的见解!
觉得有收获的同学欢迎点赞,关注一波!