【问题标题】:Use CSS :not() to target selected content in an element使用 CSS :not() 定位元素中的选定内容
【发布时间】:2020-08-16 03:06:42
【问题描述】:

我有一个 .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 的内容。我知道解决这个问题的最佳方法可能是将它包装在一个跨度中并以它为目标,但在这一点上,我想弄清楚为什么我不能让 :not 伪类工作。

这是我所拥有的:

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

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

【问题讨论】:

标签: html css css-selectors pseudo-class


【解决方案1】:

一切都在演示本身中,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>

【讨论】:

    【解决方案2】:

    你需要两个选择器:

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

    【讨论】:

    • 我选择了另一个答案,因为它是对这个问题的更直接的答案,但我赞成解释如何在没有:not() 的情况下在 CSS 中实现这一点。
    【解决方案3】:

    .header:not(.maindomain):not(.otherdomains) 仅针对具有 .header 类且本身不具有 .maindomain 和/或 .otherdomain 类的元素。

    您目前的规则是:

    &lt;div class="header"&gt; 被定位

    &lt;div class="header maindomain"&gt; 不是目标

    &lt;div class="header otherdomains"&gt; 不是目标

    &lt;div class="header maindomain otherdomains"&gt; 不是目标

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

    您不能将规则应用到 .header 类,这取决于它的子类仅使用 CSS。

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

    【讨论】:

    • 所以我误解了:not() 的工作原理,这很公平。 JavaScript 或 jQuery 将是矫枉过正,所以我认为此时最好只在有问题的文本周围环绕一个跨度。谢谢。
    • @Hashim 这将是最好的方法,是的。
    【解决方案4】:

    我正在尝试定位“目前有售,以及:”,而不触及 .maindomain.otherdomains 的内容。

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

    CSS 规则需要附加到 HTML 中的“钩子”。该钩子是一个 HTML 标记。没有标签,CSS 就没有目标。这个概念适用于所有盒子模型。

    来自MDN

    当没有用于该框的 HTML 元素时,将创建一个匿名框。例如,当您在父元素上声明 display: flex 时,就会发生这种情况,并且直接在其中有一段文本不包含在另一个元素中。为了修复框树,围绕该文本运行创建了一个匿名框。然后它将表现为一个弹性项目,但是,它不能像常规框一样被定位和设置样式,因为没有可定位的元素

    (强调我的)

    【讨论】:

      猜你喜欢
      • 2011-12-22
      • 2013-01-27
      • 1970-01-01
      • 1970-01-01
      • 2011-06-25
      • 1970-01-01
      • 2011-11-04
      • 2010-09-15
      • 2011-01-12
      相关资源
      最近更新 更多