使用 CSS :not() 定位元素中的选定内容

Use CSS :not() to target selected content in an element

我有一个 .header div,其中有一个跨度 maindomain 和一个 div otherdomains

<div class="header"><span class="maindomain">LatestFooty.co.uk</span> is currently available for sale, along with:
<div class="otherdomains">    
LatestFootie.com<br>
LatestFootie.co.uk
</div>
</div>

我正在尝试定位 目前有售,连同:,但不涉及 .maindomain.otherdomains 的内容。我知道最好的方法可能是将它包装在一个 span 中并以此为目标,但此时我想弄清楚为什么我无法获得 :not 伪 class 在职的。

这是我的:

@media (min-width:300px) and (max-width:450px) {
  .header:not(.maindomain):not(.otherdomains) {
  font-style: italic;  
  }
}

据我所知,语法是正确的,我不认为这是一个特异性问题,因为 !important 没有什么区别。我做错了什么?

I'm trying to target the "is currently available for sale, along with:", without touching the contents of .maindomain or .otherdomains.

您不能定位 CSS 中的匿名元素。

CSS 规则需要 HTML 中的 "hook" 附加到。该钩子是一个 HTML 标签。没有标签,CSS 就没有目标。此概念适用于各种盒子模型。

来自MDN

An anonymous box is created when there is not an HTML element to use for the box. This situation happens when, for example, you declare display: flex on a parent element, and directly inside there is a run of text not contained in another element. In order to fix the box tree, an anonymous box is created around that run of text. It will then behave as a flex item, however, it cannot be targeted and styled like a regular box because there is no element to target.

(强调我的)

.header:not(.maindomain):not(.otherdomains) 仅针对具有 .header class 而没有 .maindomain and/or .otherdomain [= 的元素40=] 他们自己。

您的规则目前是这样的:

<div class="header"> 被定位

<div class="header maindomain"> 未被定位

<div class="header otherdomains"> 未被定位

<div class="header maindomain otherdomains"> 未被定位

但这显然不是您想在这里做的。

您不能将规则应用到 .header class,具体取决于单独具有 CSS 的 class 个子项。

您的问题 here 有一个经过批准的答案,它可能会引导您朝着正确的方向前进(在这种情况下使用 JavaScript 或 jQuery)。

您将需要两个选择器:

.header {
  font-style:italic;
}
.header .otherdomains,
.header .maindomain {
  font-style:initial;
}

/* OR
.header * {
  font-style:initial;
}

*/
<div class="header"><span class="maindomain">LatestFooty.co.uk</span> is currently available for sale, along with:
<div class="otherdomains">    
LatestFootie.com<br>
LatestFootie.co.uk
</div>
</div>

一切都在演示本身中,JavaScript 用于演示目的。

演示

const lnx = [...document.links];
lnx.forEach(lnk => lnk.addEventListener('click', viewHTML));
function viewHTML(e) {
  const link = e.target;
  const headers = document.querySelectorAll('.'+this.dataset.tag);
  headers.forEach(hdr => {
    if (!hdr.matches('.hide')) {
      link.className = 'off';
      let str = hdr.outerHTML;
      let txt = document.createElement('div');
      txt.className = 'txt';
      hdr.insertAdjacentElement('afterend', txt);
      hdr.nextElementSibling.insertAdjacentText('beforeend', str);
      hdr.classList.add('hide'); 
    } else {
      link.className = '';
      hdr.classList.remove('hide');
      hdr.nextElementSibling.remove();
    }
  });
}
body {
  font: 400 2.5vw/1.5 Consolas
}

[class^=header] {
  font-family: Arial;
}

/* Header (OP)
Selector fails -- :not() is prefixed incorrectly
.header:...  means .header is targeted
.header :... means the descendants of .header is targeted
There is no .header.A, .header.B, nor .header.A.B 
so .header without .A and/or .B will have everything in italics
*/
.header:not(.A):not(.B) {
  font-style: italic;  
}

/* Header 1
Best solution with no extra HTML tags:
Assign font-style: normal...
directly (.C1, .D1)
or by class (.N)
*/
.header1 {
  font-style: italic;
}

.C1,
.D1,
.N {
  font-style: normal;
}

/* Header 2
Using :not() needs extra HTML tag:
Wrap second textnode in an inline or inline-block tag
As content of a descendant tag, the text can be targeted
*/
.header2 *:not(.E):not(.F) {
  font-style: italic;
}

/* Header 3
Smart solution with extra HTML tag:
Wrap second textnode in <i> or <em>
*/
.header3 {
  /* no styles needed */
}

/* Header 4
Slickest solution with least HTML:
Wrap text that needs italics in <i> and then style lines with CSS
*/
.header4 {
  white-space: pre-line;
}

/* For Demo Purposes */
.dash {
  border-style: dashed;
}

.edge {
  border-style: ridge;
  border-width: 3px;
}

summary:hover {
  color: lime;
  background: #000;
  cursor: pointer;
}

summary + u {
  display: inline-block;
  text-decoration: none;
  white-space: pre-line;
}

code {
  color: green;
  background: rgba(0, 0, 0, 0.2);
  white-space: pre;
}

summary + code {
  display: block;
}

a {
  display: block;
  text-decoration: none;
  text-align: center;
}

a:link, 
a:visited {
  color: cyan;
  background: #000;
}

a:hover,
a:active {
  color: blue;
  background: none;
}  

a::before {
  content: 'View .'attr(data-tag);
}

a.off::before {
  content: 'Hide .'attr(data-tag);
} 

a::after {
  content: ' HTML';
}

.hide {
  display: none;
}

.txt {
  color: blue;
  background: rgba(0, 0, 0, 0.2);
  white-space: pre;
}
<main>
<hr class='edge'>
<details><summary>Header (OP)</summary>
<u>Selector fails -- :not() is prefixed incorrectly
.header:...  means .header is targeted &#128078;
.header<code>&blank;</code>:... means the descendants of .header is targeted &#128077;
There is no .header.A, .header.B, nor .header.A.B so
.header <em>without</em> .A and/or .B will have everything in italics</u></details>
<details><summary>CSS</summary>
<code>.header:not(.A):not(.B) {
  font-style: italic;  
}</code>
<a href='#/' data-tag='header'></a>
</details>
<hr>

<div class='header'>
  <span class="A">LatestFooty.co.uk</span> is currently available for sale, along with:
  <div class="B">
    LatestFootie.com<br> LatestFootie.co.uk
  </div>
</div>

<hr class='edge'>
<details><summary>Header 1</summary>
<u>Best solution with no extra HTML tags:
Assign <code>font-style: normal</code>...
directly (.C1, .D1)
or by class (.N)</u></details>
<details><summary>CSS</summary>
<code>.header1 {
  font-style: italic;
}

.C1,
.D1,
.N {
  font-style: normal;
}</code>
<a href='#/' data-tag='header1'></a>
</details>
<hr>

<div class="header1">
  <span class="C1">LatestFooty.co.uk</span> is currently available for sale, along with:
  <div class="D1">
    LatestFootie.com<br> LatestFootie.co.uk
  </div>
</div>

<hr class='dash'>

<div class="header1">
  <span class="C2 N">LatestFooty.co.uk</span> is currently available for sale, along with:
  <div class="D2 N">
    LatestFootie.com<br> LatestFootie.co.uk
  </div>
</div>

<hr class='edge'>
<details><summary>Header 2</summary>
<u>Using :not() needs extra HTML tag:
Wrap second textnode in an inline or inline-block tag
As content of a descendant tag, the text can be targeted</u></details>
<details><summary>CSS</summary>
<code>.header2 *:not(.E):not(.F) {
  font-style: italic;
}</code>
<a href='#/' data-tag='header2'></a>
</details>
<hr>

<div class='header2'>
  <span class="E">LatestFooty.co.uk</span> <span>is currently available for sale, along with:</span>
  <div class="F">
    LatestFootie.com<br> LatestFootie.co.uk
  </div>
</div>

<hr class='edge'>
<details><summary>Header 3</summary>
<u>Smart solution with extra HTML tag:
Wrap second textnode in <code>&lt;i&gt;</code> or <code>&lt;em&gt;</code></u></details>
<details><summary>CSS</summary>
<code>.header3 {
  /* no styles needed */
}</code>
<a href='#/' data-tag='header3'></a>
</details>
<hr>

<div class='header3'>
  <span class="G">LatestFooty.co.uk</span> <i>is currently available for sale, along with:</i>
  <div class="H">
    LatestFootie.com<br> LatestFootie.co.uk
  </div>
</div>

<hr class='edge'>
<details><summary>Header 4</summary>
<u>Slickest solution with least HTML:
Wrap text that needs italics in <code>&lt;i&gt;</code> and then style lines with CSS</u></details>
<details><summary>CSS</summary>
<code>.header4 {
  white-space: pre-line;
}</code>
<a href='#/' data-tag='header4'></a>
</details>
<hr>

<header class='header4'>LatestFooty.co.uk <i>is currently available for sale, along with:</i>
  LatestFootie.com
  LatestFootie.co.uk
</header>
</main>