6
头图

This is the 97th original without water. If you want to get more original good articles, please search the public depth analysis of CSS selector

I. Introduction

​ The CSS selector implements one-to-one, one-to-many or many-to-one control of elements in the HTML page, so as to add styles to the specified elements. At the same time, we must also consider how to take effect when an element is given multiple styles. This is related to the priority of the selector.

priority is matching rules based on the composition of different types of selectors. The browser uses priority to determine which styles are most relevant to an element, and apply these styles to the element.

Second, the classification of CSS selectors

Three, the usage of different types of selectors

​ Next, let's take a look at other selectors besides the basic selector.

Attribute selector

(Match the element by the existing attribute name or attribute value)

<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>

Pseudo-class selector

  • Dynamic pseudo-class (mostly used for hyperlink style)
<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>

Note: The pseudo-class active in the IOS system compatibility issues, specific solutions refer IOS pseudo-class active compatibility

  • Target pseudo-category, negative pseudo-category, language pseudo-category
<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>

  • Structural pseudo-classes
<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 element pseudo-classes
<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>

Pseudo element selector

<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>

  • Only one pseudo element can be used in a selector
  • In CSS3, pseudo-elements should use double colons to distinguish pseudo-elements and pseudo-classes. However, the old version of the specification did not make a clear distinction, so most browsers support the use of single and double colons for some pseudo-elements.

Combination selector

<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>

Fourth, CSS selector priority

​ The priority of the basic selector is:!important> inline> ID selector> class selector> tag selector> general selector. So how is it calculated? There is such a calculation table

SelectorExampleWeights
!impotantcolor: #fff !important;Positive infinity
Inline selector<div style='color: #fff'>Style effect element</div>1 0 0 0
ID selector#id1 0 0
Class selector, attribute selector, pseudo-class selector.class1 0
Tag selector, pseudo element selectordiv1
Universal selector*0
Inherited properties<div style='color: #fff'><span>Style effect element</span></div>-1

Suppose that in an auction, there are the following types of chips:

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

​ Whenever one of the above selectors appears, the amount of money corresponding to the chip is increased, and the style that pays the most is finally adopted. However, the calculation method of the amount of money here is different from the calculation method in life, and the "unit" here will not be converted because of the accumulation of values. For example, ten hundred can only be'ten hundred', which is still less than one thousand.

Basic selector

<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>

Other selector

<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>

Note:

  • When the weight value is the same, the style written in the back takes effect
  • !important is a "rogue" attribute in CSS selectors. Regardless of the weight or priority of the selector, as long as !important is added, the priority of this style is the highest
  • If there is a conflict for the same element style and !important exists at the same time, the one with the highest total weight of the selector takes effect

Will the selector with the highest weight value always take effect? Not necessarily~

<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>

Note: For some mutually exclusive styles, such as max-width and width, no matter how high the weight value of the selector is, it is powerless.

Five, summary

​ As you can see, CSS selectors are also hidden. But so far, there is no selector that can select its parent element or its parent element related elements through the element, which is very troublesome.

​ If you have any questions, please communicate and correct me~

Reference article

Recommended reading

Realize the front-end exposure buried point through custom Vue instructions

H5 page list caching scheme

Recruitment

ZooTeam, a young, passionate and creative front-end team, is affiliated to the product development department of Zheng Caiyun. The Base is located in picturesque Hangzhou. The team now has more than 40 front-end partners with an average age of 27 years old. Nearly 30% are full-stack engineers, a proper youth storm troupe. The membership consists of not only “veteran” soldiers from Ali and Netease, as well as newcomers from Zhejiang University, University of Science and Technology of China, Hangzhou Electric Power and other schools. In addition to the daily business docking, the team also conducts technical exploration and actual combat in the material system, engineering platform, building platform, performance experience, cloud application, data analysis and visualization, and promotes and implements a series of internal technical products. Explore the new boundaries of the front-end technology system.

If you want to change that you have been tossed by things, hope to start to toss things; if you want to change and have been warned, you need more ideas, but you can’t break the game; if you want to change you have the ability to make that result, but you don’t need you; If you want to change what you want to accomplish, you need a team to support it, but there is no position for you to lead people; if you want to change the established rhythm, it will be "5 years of work time and 3 years of work experience"; if you want to change the original The comprehension is good, but there is always the ambiguity of the window paper... If you believe in the power of belief, believe that ordinary people can achieve extraordinary things, believe that you can meet a better self. If you want to participate in the process of business take-off, and personally promote the growth of a front-end team with in-depth business understanding, complete technical system, technology to create value, and influence spillover, I think we should talk. Anytime, waiting for you to write something, send it to ZooTeam@cai-inc.com


政采云前端团队
3.8k 声望4k 粉丝

Z 是政采云拼音首字母,oo 是无穷的符号,结合 Zoo 有生物圈的含义。寄望我们的前端 ZooTeam 团队,不论是人才梯队,还是技术体系,都能各面兼备,成长为一个生态,卓越且持续卓越。