如何避免 `<style>` 标签被我的 CSS 选择器捕获?

How do I avoid `<style>` tags getting caught in my CSS selectors?

我正在使用 CSS 来设置一些现有文档的样式,并使用大量相邻的同级 select 或(例如 item1 + item2)在元素之间应用间距等。但是,许多文档还在页面顶部包含 <style> 标记,或者散布在已应用自定义样式的各处。自定义样式本身很好,但不幸的是 <style> 标签本身干扰了我的 CSS select 或。例如,如果我想将 margin-top 应用于除第一个元素之外的每个元素,我通常会使用 * + * (又名 "lobotomized owl" 方法),并且这种方法非常有效,直到有人将样式标签在顶部。现在 样式标签 被读取为第一个元素,因此页面上的每个元素都被 select 编辑。事先不知道元素类型;它们可以是有效 HTML 代码(div、span、p、table 等)的任意组合,并且还需要考虑嵌套元素 t。关键 select 或者我试图修复的是相邻的兄弟 select 或者以通配符 ( * + item) 开头。

我的第一个想法是使用 :not(style) + item 之类的东西,但是如果页面中间某处有任何 <style> 标记,其中一个之后的任何元素的样式也会不正确.

有没有绝对可靠的方法可以完全使用 CSS 来做到这一点?我无法自己编辑 HTML 文件,但如果必须的话,可以在渲染它们之前使用 Javascript 对其进行预处理。

编辑: 奖金问题,我如何 select 页面中的第一个元素 而不是 a <style> 标签?即,我现在如何在没有 selecting <style> 标签的情况下 body > *:first-child

比如我的CSS文件然后是一个目标HTML:

div {
  background-color: yellow;
}

*+div {
  background-color: lime;
  margin-top: 1em;
}
<style>
  div {
    font-weight: bold;
  }
</style>

<div>Yellow</div>
<div>Green</div>
<div>Green</div>
<div>Green</div>
<div>Green</div>

页边距会随着文档布局变得更复杂而变得复杂,但为了简单起见,这个答案假设您只需要担心被切除的猫头鹰,以及具有相对简单的块布局的文档,其中页边距在 parents 之间折叠和 children,所以我们可以专注于手头的选择器。

以下选择器对任意数量的元素类型和任意嵌套深度(即不只是 children of body)具有鲁棒性。不幸的是,它确实涉及重复相同的复合选择器:

div, p {
  background-color: yellow;
  margin: 0; /* Remove default p margins for the sake of illustration */
}

:not(style):nth-of-type(n+2),
:not(style):nth-of-type(n+2) ~ * {
  background-color: lime;
  margin-top: 1em;
}

/* Ignore .nest elements for the sake of illustration */
.nest {
  background-color: transparent !important;
}
<style>
  div {
    font-weight: bold;
  }
</style>

<div>Yellow</div>
<div>Green</div>
<p>Green</p>

<style>
  p {
    font-style: italic;
  }
</style>

<div>Green</div>
<p>Green</p>

<section class="nest">
  <div>Yellow</div>
  <div>Green</div>
  <p>Green</p>
</section>

Bonus question, how do I select the first element in the page that is not a <style> tag? I.e, how do I now do body > *:first-child without selecting a <style> tag?

假设在第一个非 style child:

之前永远不会有超过一个 style 元素
body > :not(style):first-child, body > style:first-child + *

如果您认为可能有超过一个连续的 style 作为 body 的第一个 children 的文件,您需要使用 this technique 来代替:

body > :not(style) {
  /* Apply styles to the first non-style child */
}

body > :not(style) ~ :not(style) {
  /* Undo the above styles for following non-style children */
}

在浏览器开始实施级别 4 之前,没有 selector-based 可靠的替代方案 :nth-child(An+B of S):

/* Replaces the main answer's entire selector-list */
:nth-child(n+2 of :not(body, style))

/* Replaces the bonus question's answer */
body > :nth-child(1 of :not(style))