目前 Css 关于逻辑选择器::not:is:where:has,除了 :has 比较新以外,其他选择器在一些 UI 库中都有广泛的使用,浏览器基本都已经支持了,一起卷起来,使用更先进的选择器~

:not

MDN: :not() CSS 伪类用来匹配不符合一组选择器的元素。由于它的作用是防止特定的元素被选中,它也被称为反选伪类(negation pseudo-class)。

<ul class="css-selectors selector-not">
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ul>
.selector-not {
  li:not(:first-child) {
    border: 1px solid red;
  }
}
  • 1
  • 2
  • 3

li:not(:first-child) 选择除 :first-child 第一个 li 以外的其他 li 元素。

:not 优先级

:not 不会提升优先级,它的优先级由将由其逗号分割的参数中优先级最高的选择器指定

:not 兼容性

can i use,还是可以放心使用滴~

:is

:is 选择器并没有什么新功能,它像一个语法糖,可以让我们更方便的书写选择器,它的作用是将一组选择器包裹起来,然后作为一个整体使用,这样就可以减少选择器的书写量,提高代码的可读性。如下示例

之前对有相同属性的子元素父元素不同时:

header p:hover,
main p:hover,
footer p:hover {
  color: red;
  cursor: pointer;
}

使用 :is 之后:

:is(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}

:is demo

<ul class="css-selectors css-selectors-is">
  <li>
    <div>div</div>
    <p>p</p>
  </li>

  <li>
    <div>div</div>
    <span>span</span>
  </li>

  <li>
    <div>div</div>
    <i> tag i </i>
  </li>

  <li>
    <section>
      <i>deep level i</i>
    </section>
  </li>
</ul>

若将 li 内的 div,span,p,i 元素的颜色设置颜色时,之前写法

.css-selectors-is > li > div,
.css-selectors-is > li > span,
.css-selectors-is > li > p,
.css-selectors-is > li > i {
  background-color: #0a9caf;
}

使用 :is 之后:

.css-selectors-is > li > :is(div, span, p, i) {
  background-color: #0a9caf;
}

支持层叠嵌套使用

.css-selectors-is :is(li) > :is(div, span, p, :is(i, section)) {
  background-color: #0a9caf;
}
  • div

    p

  • div
    span
  • div
    tag i
  • deep level i

来看 MDN 提供的复杂场景:

ol ol ul,     ol ul ul,     ol menu ul,     ol dir ul,
ol ol menu,   ol ul menu,   ol menu menu,   ol dir menu,
ol ol dir,    ol ul dir,    ol menu dir,    ol dir dir,
ul ol ul,     ul ul ul,     ul menu ul,     ul dir ul,
ul ol menu,   ul ul menu,   ul menu menu,   ul dir menu,
ul ol dir,    ul ul dir,    ul menu dir,    ul dir dir,
menu ol ul,   menu ul ul,   menu menu ul,   menu dir ul,
menu ol menu, menu ul menu, menu menu menu, menu dir menu,
menu ol dir,  menu ul dir,  menu menu dir,  menu dir dir,
dir ol ul,    dir ul ul,    dir menu ul,    dir dir ul,
dir ol menu,  dir ul menu,  dir menu menu,  dir dir menu,
dir ol dir,   dir ul dir,   dir menu dir,   dir dir dir {
  list-style-type: square;
}

使用 :is 之后:

:is(ol, ul, menu, dir) :is(ol, ul, menu, dir) :is(ul, menu, dir) {
  list-style-type: square;
}

:is() 不能选择伪元素

:is() 伪类不匹配伪元素(伪类是可以的,例如::visible:focus)。所以这样不行:

some-element:is(::before, ::after) {
  display: block;
}

:is 的优先级

先看示例

<ul class="css-selectors css-selectors-is-priority">
  <li>
    <div id="is-priority-id" class="is-priority-class">id div</div>
  </li>

  <li>
    <div class="is-priority-class">class div</div>
  </li>
</ul>
.css-selectors-is-priority {
  > li {
    & > :is(div, #is-priority-id) {
      background-color: #0a9caf;
    }

    & > .is-priority-class {
      background-color: red;
    }
  }
}
  • id div
  • class div

上述 css 按照正常理解的话,应该对应下述代码,理论 div 的背景颜色应该是 红色蓝色,分别是由 li > #is-priority-idli > .is-priority-class 两个选择器作用的,但是实际上 div 的背景颜色是 蓝色,这是为什么呢?

li > div {
    background-color: #0a9caf;
}
li > #is-priority-id {
    background-color: #0a9caf;
}
li > .is-priority-class {
    background-color: red;
}

:not 一样,:is 的优先级由 选择器 列表内最高的选择器决定的,需要把他们当做整体来看。
由于 is 选择器内的优先级由列表内优先级最高的决定。所以 标签选择器 div 拥有和 id 选择器相同的优先级,即也会覆盖下方的 class 选择器

:is 兼容性

can i use

:where

:where 选择器其实和 :is 几乎一样,除了优先级外。

<ul class="css-selectors css-selectors-where">
  <li>
    <div id="css-selectors-where-id">where</div>
  </li>
</ul>
// where 的优先级总为 0,其他与 is 一致
.css-selectors-where {
  li :is(div) {
    color: red;
  }

  li :where(#css-selectors-where-id) {
    color: green;
  }
}

正常理解下 :is(div):where(id div) 都可以转化为 li div,后面的甚至是 id,但 li 的颜色却是红色

  • where

由此可看出 :where 的优先级总为 0,其他与 :is 一致

:has

重量级选手 :has,css 里可以往上选择的选择器。

<ul class="css-selectors css-selectors-has">
  <li>
    <div>
      <p>has - p</p>
    </div>
  </li>

  <li>
    <div>
      <a>
        <span>has - span</span>
      </a>
    </div>
  </li>

  <li>
    <div>
      <span>
        <i>has - i</i>
      </span>
    </div>
  </li>
</ul>
/*找自己*/
.css-selectors-has li:has(>div >p) {
    border: 1px solid red;
}

/*找前面的兄弟*/
.css-selectors-has li:has(+ li >div >span >i) {
    border: 1px solid green;
}

li:has(>div >p) { border: 1px solid red; } 选择器,选择的是 li 里面有 div 里面有 pli,所以第一个 li 会有红色边框
li:has(+ li >div >span >i) { border: 1px solid green; } 通过兄弟选择器 + 选择的是相邻兄弟 li 里面有 div 里面有 span 里面有 ili,所以有 span 的符合规则。

:has 选择的是参数匹配的宿主元素而不是参数本身

:has 兼容性

can i use,早用早享受~