Skip to content
Created: March 10, 2024

W3C selector ​

Related html new tags ​

figure、figcaption、pre、blockquote

html
<figure>
  <img src="image.png" alt="">
  <figcaption>caption and descriptions</figcaption>
</figure>

<figure>
  <figcaption>code</figcaption>
  <pre>
    function log(val) {
      console.log(val)
    }
    
    log('hello world')      
  </pre>
</figure>

<figure>
  <figcaption>Shakespeare: </figcaption>
  <blockquote>Nutrition books in the world. There is no book in life, there is no sunlight; wisdom without
    books, as if the birds do not have wings.</blockquote>
</figure>

Use of :has ​

Describe it in one sentence: The :has() selector is a relational pseudo-class selector, also known as a functional pseudo-class selector. It and :is(), :not() and :where() functional selectors are called CSS logical combination selectors.

css
/* 卡片不带标题的样式规则 */
.card {
    display: flex;
    border-radius: 10px;
    max-width: 40vw;
    background-color: #F5F5F5;
}

.card img {
    display: block;
    max-width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    object-position: center;
}

/* 卡片带标题的样式规则 */
.card:has(figcaption) {
    flex-direction: column;
    gap: 1rem;
    padding: 20px;
}

Interesting Facts: Compare the Differences

css
section:not(:has(h1, h2, h3, h4, h5, h6))
section:has(:not(h1, h2, h3, h4, h5, h6))
  1. section:not(:has(h1, h2, h3, h4, h5, h6))

Syntax analysis:

  • section: Select all section elements.
  • :not(): is an exclusion pseudo-class, which will exclude elements that meet the conditions.
  • :has(h1, h2, h3, h4, h5, h6): Indicates that section elements containing <h1> to <h6> are selected.

So this selector means:

  • Selects section elements that do not contain any <h1> to <h6> elements.

Key points:

  • It selects section elements without heading tags (i.e. <h1> to <h6>).
  1. section:has(:not(h1, h2, h3, h4, h5, h6))

Syntax analysis:

  • section: Select all section elements.

  • :has(): This pseudo-class is used to select parent elements that contain child elements that meet specific conditions.

  • :not(h1, h2, h3, h4, h5, h6): Indicates to select those child elements that do not contain <h1> to <h6> elements.
    So this selector means:

  • Selects section elements that contain at least one child element that is not a child of <h1> through <h6>.

Key points:

  • It selects those Contains other elements (non-title elements) sections, it does not require that these sections have no internal <h1> Arrive <h6> , but requires other non-title elements.

Give a clearer example

html
<section>
  <p>This section has no headings, just a paragraph.</p>
</section>

<section>
  <h2>Title</h2>
  <p>This section has a heading.</p>
</section>

<section>
  <h1>Title</h1>
  <div>Some other content</div>
</section>

<section>
  <h1>Title</h1>
  <h3>Another Title</h3>
</section>

First selector: section:not(:has(h1, h2, h3, h4, h5, h6))

  • The first section is selected because it does not have any heading tags (no <h1> to <h6>).
  • The second section is excluded because it contains <h2>, which qualifies for :has().
  • The third section is excluded because it contains <h1>, qualifying for :has().
  • The fourth section is excluded because it contains <h1> and <h3>, qualifying for :has().

Second selector: section:has(:not(h1, h2, h3, h4, h5, h6))

  • The first section is selected because it contains <p>, which is an element that is not a title.
  • The second section is selected because it has <p>, and <p> is not a heading element.
  • The third section is selected because it contains <div> , while <div> Not a title element.
  • The fourth section will not be selected because it only has heading elements (<h1> and <h3>) and no other non-heading elements.

Main differences:

  1. section:not(:has(h1, h2, h3, h4, h5, h6)): It selects section elements that do not contain any heading elements.
  2. section:has(:not(h1, h2, h3, h4, h5, h6)): It selects section elements that contain other types of elements (non-titles).

Summary:

  • The first selector is more restrictive and excludes all section elements that contain titles.
  • The second selector is a bit looser. It only requires that there must be other types of elements in the section, but does not require that the title must not exist.

Combination selector ​

A "combination selector" is a special character that indicates the type of relationship between selectors.Common combination selectors mainly include:

  • Space characters, such as a b , are called descendant combination selectors, matching direct or nested child elements;
  • > characters, for example a > b , called a direct child element combination selector, only matches top-level unnested child elements;
  • + characters, such as a + b, are called adjacent sibling combination selectors, and only match the next sibling element immediately following;
  • ~ characters, for example a ~ b , called a universal sibling combination selector, matching the basic selector (a) one or more sibling elements after (b) 。

Pseudo class selector ​

Pseudo-class elements use two colons (::) instead of one colon (:). This is part of the requirement in the CSS3 specification. The purpose is to distinguish pseudo-classes and pseudo-elements. Most browsers support the following two expressions.

  • Status pseudo-class selectors, such as :hover, :active, :visited, :target and :focus, etc.;
  • Focus pseudo-class selectors, such as :focus-within and :focus-visible, etc.;
  • Structural pseudo-class selectors, such as :nth-child, :nth-last-child, :first-child, :last-child, :only-child, :nth-of-type, :nth-last-of-type, :first-of-type, :last-of-type and :only-of-type, etc.;
  • Form pseudo-class selectors, such as :autofill, :enabled, :disabled, :read-only, :read-write, :placeholder-shown, :default, :checked, :indeterminate, :valid, :invalid, :in-range, :out-of-range, :required and:optional etc;
  • Target pseudo-class selector, such as :target;
  • Language pseudo-class selectors, such as :dir() and :lang(), etc.;
  • Function pseudo-class selectors, such as :not(), :is() and :where(), etc.

The use of has, in addition, it should be noted that the CSS working group decided to prohibit the use of all existing pseudo-elements inside :has(), such as ::before, ::after, ::marker and ::first-line, etc.

css
/* ul 包含最多 3 个( 3 个或更少,不包括 0 ) li 项 */
ul:has(> :nth-child(-n+3):last-child) {
    border: 3px solid palegreen;
}

/* ul 包含最多 3 个( 3 个或更少,包括 0 个) li 项 */
ul:not(:has(> :nth-child(3))) {
    border: 3px solid limegreen;
}

/* ul 正好包含 5 个 li 项 */
ul:has(> :nth-child(5):last-child) {
    border: 3px solid plum;
}

/* ul 至少包含 10 个 (10 个或更多)li 项 */
ul:has(> :nth-child(10)) {
    border: 3px solid pink;
}

/* ul 包含 7 ~ 9 个 li 项*/
ul:has(> :nth-child(7)):has(> :nth-child(-n+9):last-child) {
    border: 3px solid tomato;
}
/** 不支持:has时的备选方案 */
@supports not selector(:has(works)) { 
    .card { 
        flex-direction: column; 
        align-items: flex-start; 
    } 
}

:target implements modal box ​

html
<a href="#target-content" id="button">Open CSS Modal via <code>:target</code></a>
<div id="target-content">
    <a href="#" class="close"></a>
    <div id="target-inner">
        <h2>CSS Modal</h2>
    </div>
</div>
<style>
    target-content {
    pointer-events: none;
    opacity: 0;
    transition: opacity 200ms;
}
target-content:target {
    pointer-events: all;
    opacity: 1;
}
</style>

Select multiple ranges of groups ​

html
<ul>
    <li class="rect"></li>
    <li class="rect"></li>
    <li data-range></li>
    <li class="circle"></li>
    <li class="circle"></li>
    <li class="circle"></li>
    <li class="circle"></li>
    <li data-range></li>
    <li class="star"></li>
    <li class="star"></li>
    <li class="star"></li>
    <li class="rect"></li>
</ul>
css
/**选中 data-range 开始和结束之间所有 li (即所有 .circle 元素) */
[data-range] ~ :has(~ [data-range])  {
    width: 100px;
    border: 2px solid #09f;
    outline: 4px solid rgb(0 0 0 / .5);
}

/**
* [data-range]:has(~ [data-range]) 给范围起始元素(第一个设置 data-range 的 li 元素)设置样式*/
[data-range]:has(~ [data-range]) {
    background-color: #987;
    outline: 2px solid red;
}
/* [data-range] ~ [data-range] 给范围结束元素(第二个设置 data-range 的 li 元素)设置样式*/
[data-range] ~ [data-range] {
    background-color: #90f;
    outline: 2px solid orange;
}

Multiple range selection ​

html
<ul>
    <li data-range="start"></li>
    <li class="rect"></li>
    <li class="rect"></li>
    <li data-range="end"></li>
    <li data-range="start"></li>
    <li class="circle"></li>
    <li class="circle"></li>
    <li class="circle"></li>
    <li class="circle"></li>
    <li data-range="end"></li>
    <li data-range="start"></li>
    <li class="star"></li>
    <li class="star"></li>
    <li class="star"></li>
    <li data-range="end"></li>
    <li class="rect"></li>
</ul>
css
/* 选择范围组中开始和结束元素 */
[data-range] {
    box-shadow: 0 0 0 6px red;
    border-radius: 2px;
}

/* 选择范围组中起始元素 */
[data-range="start"] {
    outline:3px solid yellow;
}

/* 选择范围组中结束元素 */
[data-range="end"] {
    outline: 3px solid #e90;
}

/* 选择范围组内的第一个元素 */
[data-range="start"] + :has(~ [data-range="end"]):not([data-range]) {
    width: 80px;
    border: 4px solid #09f;
}

/* 选择范围组内的最后一个元素 */
[data-range="start"] ~ :has(+ [data-range="end"]):not([data-range]) {
     width: 80px;
     border: 4px solid;
}

/* 选择范围组内的所有元素 */
[data-range="start"] ~ :has(~ [data-range="end"]):not([data-range]) {
    width: 80px;
    border: 4px solid;
    box-shadow: 0 0 0 4px rgb(0 0 0 / .125);
}