W3C selector
Related html new tags
figure、figcaption、pre、blockquote
<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.
/* 卡片不带标题的样式规则 */
.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
section:not(:has(h1, h2, h3, h4, h5, h6))
section:has(:not(h1, h2, h3, h4, h5, h6))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>).
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
<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:
section:not(:has(h1, h2, h3, h4, h5, h6)): It selects section elements that do not contain any heading elements.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 examplea > b, called a direct child element combination selector, only matches top-level unnested child elements;+characters, such asa + b, are called adjacent sibling combination selectors, and only match the next sibling element immediately following;~characters, for examplea ~ 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,:targetand:focus, etc.; - Focus pseudo-class selectors, such as
:focus-withinand: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-typeand: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,:requiredand:optionaletc; - 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.
/* 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
<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
<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>/**选中 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
<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>/* 选择范围组中开始和结束元素 */
[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);
}