3

深入解析 CSS 选择器

 3 years ago
source link: https://www.zoo.team/article/about-css-selector
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

文章目录

  • 深入解析 CSS 选择器

    • 二、CSS 选择器的分类

    • 三、不同种类选择器的用法

      • 属性选择器

      • 伪类选择器

      • 伪元素选择器

      • 组合选择器

    • 四、CSS 选择器优先级

      • 基本选择器

      • 其他选择器

深入解析 CSS 选择器

2021-04-19 发布于 方案沉淀 · 阅读量:12

责任小编:北渊

深入解析 CSS 选择器

​ CSS 选择器对 HTML 页面中的元素实现一对一,一对多或者多对一的控制,从而给指定元素添加样式。同时还要考虑一个元素被赋予多个样式时如何生效的问题,这个就和选择器优先级相关了。

优先级是基于不同种类选择器组成的匹配规则。浏览器通过优先级来判断哪些样式与一个元素最为相关,从而在该元素上应用这些样式。

二、CSS 选择器的分类

三、不同种类选择器的用法

​ 接下来我们看一看基本选择器之外的其他选择器。

属性选择器

(通过已经存在的属性名或属性值匹配元素)

<style> div { margin-top: 20px;} /* 带有属性 title 的元素 */ [title]{ background: #faf3e0; } /* 带有属性 class 且值为 div1 的元素 */ [class=div1]{ background: #eabf9f; } /* 带有属性 attr 并且该属性是一个以空格作为分隔的值列表,其中至少有一个值为 attr-test2 的元素 */ [attr~=attr-test2]{ background: #b68973; } /* 带有属性 attr 且值以 te 为开头的元素 */ [attr^=te]{ background: #f39189; } /* 带有属性 attr 且值以 Test 为结尾的元素 */ [attr$=Test]{ background: #bb8082; } /* 带有属性 attr 且值包含 test3 的元素 */ [attr*=test3]{ background: #6e7582; } /* 带有属性 attr 且值为 attr1 或以 attr1- 开头 */ [attr|=attr1]{ background: #046582; } /* 属性选择器默认区分大小写,在属性选择器的右方括号前添加一个用空格隔开的字母 i(或 I),可忽略大小写 */ [attr*=test5 i]{ background: #865858; } </style> <body> <div title='helloWorld'>[title]</div> <div class="div1">[class=div1]</div> <div attr='attr-test1 attr-test2'>[attr~=attr-test2]</div> <div attr='test'>[attr^=te]</div> <div attr='attrTest'>[attr$=Test]</div> <div attr='attr-test3'>[attr*=test3]</div> <div attr='attr1-test4'>[attr|=attr1]</div> <div attr='attr-Test5'>attr*=test5 i</div> </body>

伪类选择器

  • 动态伪类(多用于超链接的样式)
<style> /* 未访问的链接 */ a:link { color: #11698e; } /* 已访问过的链接 注:只要是当前浏览器有访问记录的都算作已访问的状态 */ a:visited {color: #9fb8ad; } /* 当鼠标悬浮在元素上方时 */ /* 注: 为了使点击过后的链接仍然受设置的伪类样式影响,在CSS 定义时 :hover 需设置在 :link 和 :visited 之后 */ a:hover{ color: #383e56; } /* 被激活的元素 (鼠标点下且为松开时) */ /* 注: 为了使点击过后的链接仍然受设置的伪类样式影响,在CSS 定义时 :active 需设置在 :hover 之后 */ a:active{ color: #fb743e; } </style> <body> <a target="_blank" href='https://juejin.cn/user/3456520257288974'>超链接</a> </body>

注:伪类 active 在 IOS 系统下存在兼容问题,具体解决办法可参考 IOS 伪类active兼容问题

  • 目标伪类、否定伪类、语言伪类
<style> html { font-size: 14px; } /* 目标伪类 :target: 代表一个唯一的页面元素(目标元素),其 id 与当前URL片段匹配 */ div:target { color: #f05454; } /* 否定伪类 :not 注: 仅 Chrome、Firefox 和 Safari 高版本浏览器适用*/ p:not(#p1){ color: #e27802; } /* 语言伪类 :lang */ div:lang(zh) { color: #ffc1b6; } </style> <body> <h3>目标伪类 :target</h3> <div id="div1">目标伪类: 这是 div1</div> <div id="div2">目标伪类: 这是 div2</div> <h3>否定伪类 :not</h3> <p id="p1">否定伪类: 这是 p1</p> <p id="p2">否定伪类: 这是 p2</p> <h3>语言伪类 :lang</h3> <div lang="en">语言伪类: 这是 en</div> <div lang="zh">语言伪类: 这是 zh</div> </body> <style> /* 父元素的第一个子元素且该子元素为 p 的元素 */ p:first-child { background: #046582; } /* 父元素中第一个 span 元素 */ span:first-of-type { background: #6e7582; } /* 父元素中第 2n 个子元素且为 p 的元素 */ p:nth-child(2n) { background: #bb8082; } /* 父元素中第 2n 个 span 元素 */ span:nth-of-type(2n) { background: #f39189; } /* 父元素有且仅有一个为 i 的元素 */ i:only-child { background: #865858; } /* 父元素有且仅有一个为 i 的元素 */ strong:only-of-type { background: #8e7f7f; } /* 没有子元素的元素 */ p:empty { height: 16px; background: #bbb; } /* 根元素 HTML 中相当于 <html> */ :root { background: #e2d5d5; color: #fff; } </style> <body> <div> <p class="p1">这是 p1</p> <p class="p2">这是 p2</p> <p class="p3"><i>这是 p3</i></p> <p class="p4">这是 p4</p> <span class="span1">这是 span1</span> <span class="span2">这是 span2</span> <p class="empty-p p5">这是 p5</p> <strong>这是 strong</strong> </div> </body>
  • UI 元素伪类
<style> /* :enabled 可用状态 */ input[type="radio"]:enabled { box-shadow: 0 0 0 3px #7c9473; } /* :disabled 禁用状态 */ input[type="radio"]:disabled { box-shadow: 0 0 0 3px #cfdac8; cursor: not-allowed; } /* :checked radio 或 checkbox 表单被勾选状态 */ /* 注意书写顺序,选择元素相同时 :checked 应写在 :enabled/:disabled 后面 */ input[type="radio"]:checked { box-shadow: 0 0 0 3px #c0e218 ; } /* :default 表示一组相关元素中的默认(选中)表单元素 此处 :default 应用于默认设置了 checked 的 radio 表单上 */ /* 该选择器可以在 <button>, <input type="checkbox">, <input type="radio">, 以及 <option> 上使用 */ input[type="radio"]:default { box-shadow: 0 0 0 3px #86aba1;} /* :read-only 只读状态 */ input:read-write { background: #7c9473; } /* :read-only 只读状态 */ input:read-only { background: #cfdac8; } </style> <body> <div> <input type="radio" name="my-radio" id="radio1" checked> <label for="radio1">默认选中</label> <input type="radio" name="my-radio" id="radio2"> <label for="radio2">未选中-可用</label> <input type="radio" name="my-radio" id="radio1" disabled> <label for="radio1">未选中-禁用</label> </div> <div> <input type="input" name="my-input" id="input1" value="input1"> <input type="input" name="my-input" id="input2" value="input2" readonly> </div> </body>

伪元素选择器

<style> div { margin-left: 50px;} /* ::after 在选中元素的最后添加一个子元素,默认为行内元素 (替换元素上不生效) */ .div1::after { content: 'div1 的 after'; margin-left: 10px; color: #ef4f4f } /* ::before 在选中元素的第一个位置添加一个子元素 (其他用法同 ::after) */ .div2::before { content: 'div2 的 before'; margin-right: 10px; color: #ee9595 } /* ::first-letter 匹配选中块级元素的第一行的第一个字符 */ .div3::first-letter { color: #ff4646 } /* ::first-line 匹配选中块级元素的第一行 */ .div4::first-line { color: #9dab86 } /* ::marker 匹配选中有序或无序列表的序号或符号 */ .div5 ul li::marker { color: #fdb827 } /* ::selection 匹配元素中被选中高亮的部分 */ .div6::selection { background: #9dab86; color: white } </style> <body> <div class="div1">div1</div> <div class="div2">div2</div> <div class="div3">div3</div> <div class="div4">div4第一行<br>div4第二行</div> <div class="div5">div5 <ul> <li>item1</li> <li>item2</li> <li>item3</li> </ul> </div> <div class="div6">div6</div> </body>
  • 一个选择器中只能使用一个伪元素
  • CSS3 中伪元素应该用双冒号,以便区分伪元素和伪类。但是旧版的规范未做明确区分,所以大多数浏览器中支持部分伪元素使用单双冒号两种写法

组合选择器

<style> /* 后代选择器 空格隔开 匹配所有符合的后代元素*/ div span { margin-left: 10px; background: #ff8585 } /* 直接子后代选择器 > 连接; 匹配符合的直接子元素; 不包括子元素的子元素 */ .div1>span { color: #6155a6 } /* 群组选择器 逗号隔开 */ .div1, .div2 { color: #a7c5eb } /* 相邻兄弟元素选择器 + 连接; 匹配某元素后紧邻的兄弟元素 */ .div3 + div { color: #fd3a69 } /* 兄弟选择器 ~ 连接; 匹配某元素后所有同级的指定元素,强调的是所有的 */ .div5 ~ div { color: #008891 ; } </style> <body> <div class="div1">div1 <span class="span1">span1 <span class="span1-1">span1-1</span> </span> </div> <div class="div2">div2<span class="span2">span2</span></div> <div class="div3">div3<span class="span3">span3</span></div> <div class="div4">div4<span class="span4">span4</span></div> <div class="div5">div5<span class="span5">span5</span></div> <div class="div6">div6<span class="span6">span6</span></div> <div class="div7">div7<span class="span7">span7</span></div> <div class="div8">div8<span class="span8">span8</span></div> </body>

四、CSS 选择器优先级

​ 基本选择器的优先级是:!important > 内联 > ID选择器 > 类选择器 > 标签选择器 > 通用选择器。那么它如何计算的呢?有这样一个计算表格

选择器 示例 权重值 !impotant color: #fff !important; 正无穷 内联选择器
样式作用元素
1 0 0 0 ID 选择器 #id 1 0 0 类选择器、属性选择器、伪类选择器 .class 1 0 标签选择器、伪元素选择器 div 1 通用选择器 * 0 继承属性
样式作用元素
-1

假设在一个拍卖会上,有以下几种筹码:

* 一个`内联样式`相当于一千元 * 一个`ID 选择器`相当于一百元 * 一个`类选择器`相当于十元; * 一个`标签选择器`相当于一元 * 通用选择器为零元

​ 每出现一个上述选择器,就增加对应筹码的钱数,最终采用出钱最多的样式。但是,这里的钱数计算方法和生活中的计算方法不一样,这里的"单位"不会因为值的累加而进行换算。 例如十个一百只能是‘十百’,仍然小于一千。

基本选择器

<style> * { color: #31326f } /* 通用 */ div { background: #9ddfd3 } /* 标签 */ .div-class { background: #dbf6e9 } /* 类 */ .p1, .p2, .p3 { background: #ffdada; color: #060930 } /* 类 */ #p1-1 { background: #595b83 } /* id */ .p3 { color: #595b83 !important } /* !important */ </style> <body> <div class="div-class"> <h1>Hello word!</h1> <p class="p1" id="p1-1">Hello word!</p> <p class="p2" style="color: white">Hello word!</p> <!-- 内联样式 --> <p class="p3" style="color: white">Hello word!</p> <!-- 内联样式 --> </div> </body>

其他选择器

<style> div { color: #a20a0a } div .p1 ~ p { background: #fceef5; color: #ffa36c } /* 总权重值: 12 */ div p ~ p { background: pink; } /* 总权重值: 3 */ .div-class .p1 ~ p { color: #799351 } /* 总权重值: 21 */ /* 以下两行样式若互换位置,则 .p1 的 ::after 文本颜色为 #333456 */ .div-class p::after { content:'p-after'; margin-left: 10px; color: #333456 } /* 总权重值: 0 0 1 2 */ div .p1::after { color: #42bfd8 } /* 总权重值: 12 */ /* 以下两行样式若互换位置,则 .p1 的文本颜色为 #92817a */ .p1 { color: #92817a } [name="p1"] { color: #bedbbb } /* 同一元素样式存在冲突且同时存在 !important */ div .span1 { color: #0e918c !important; } .span1 { color: #6a097d !important; } </style> <body> <div class="div-class"> <h1>Hello word!</h1> <p class="p1" name="p1">p1</p> <p class="p2">p2</p> <p class="p3">p3</p> <span class="span1">span1</span> </div> </body>
  • 权重值相同时,写在后面的样式生效
  • !important 是 CSS 选择器中的一个"流氓"属性,不论选择器的权重或者优先级的高低,只要加上 !important,那么这个样式的优先级就是最高的
  • 如果针对同一元素样式存在冲突且同时存在 !important ,那么选择器总权重值高者生效

选择器的权重值最高就一定会生效吗?不一定哦~

<style> div { max-width: 100px; } div, p { background: #bedbbb } .div1 { width: 200px !important; } .p1 { width: 200px; } </style> <body> <div class="div1"> 这是 div1</div> <p class="p1"> 这是 p1</p> </body>

注:对于一些互斥的样式,例如 max-width 与 width,选择器的权重值再高也是无能为力的。

​ 如你所见,CSS 选择器也是暗藏玄机的哦。不过到目前为止,暂时没有能够通过元素选择其父元素或其父元素相关元素的选择器,这就让人很是头疼。

​ 如有问题,欢迎沟通与指正~

❉ 作者介绍 ❉
%E4%BA%9A%E6%A0%BC.png
快来做第一个评论的人吧~

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK