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

Tre*_*ner 5 html javascript css css-selectors

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

使用类似的东西:not(style) + item是我的第一个想法,但是如果<style>页面中间的某个地方有任何标签,那么其中一个之后的任何元素也会被错误地设置样式。

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

编辑:奖金的问题,我该如何选择是页面中的第一个元素不是一个<style>标签?即,我现在如何body > *:first-child不选择<style>标签?

例如,我的 CSS 文件和目标 HTML:

div {
  background-color: yellow;
}

*+div {
  background-color: lime;
  margin-top: 1em;
}
Run Code Online (Sandbox Code Playgroud)
<style>
  div {
    font-weight: bold;
  }
</style>

<div>Yellow</div>
<div>Green</div>
<div>Green</div>
<div>Green</div>
<div>Green</div>
Run Code Online (Sandbox Code Playgroud)

Bol*_*ock 3

随着文档布局变得更加复杂,边距可能会变得复杂,但为了简单起见,这个答案将假设您只需要担心脑白质切除的猫头鹰,以及具有相对简单的块布局的文档,其中父级和子级之间的边距折叠,因此我们可以专注于选择器在手。

以下选择器对于任意数量的元素类型和任意嵌套深度(即不仅仅是 的子元素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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

额外问题,如何选择页面中第一个不是标签的元素<style>body > *:first-child即,如果不选择标签,我现在该怎么办<style>

style假设第一个非子元素之前永远不会有多个元素style

body > :not(style):first-child, body > style:first-child + *
Run Code Online (Sandbox Code Playgroud)

如果您认为可能存在多个连续的文档作为style的第一个子级body,则需要使用此技术

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 */
}
Run Code Online (Sandbox Code Playgroud)

在浏览器开始实现 level 4 之前,没有一种基于选择器的可靠替代方案: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))
Run Code Online (Sandbox Code Playgroud)