CSS - 仅选择第一个后代

时间:2017-08-24 02:27:19

标签: html css

我正在尝试根据某个主题设置所有主要标签的样式。

如果某个部分的类是红色的,那么它的所有内部标记都应该使用红色样式,而不管该部分是否在另一个使用黄色样式的部分中。

所以我的问题是如何限制section / div / nav等的内部标记,只使用它遇到的第一个后代的样式。

注意:我不想依赖我声明我的标签的顺序。

.red input {
  background-color: red;
}

.red article {
  background-color: red;
}

.red p {
  background-color: red;
}


/*.. other tags.. */

.yellow input {
  background-color: yellow;
}

.yellow article {
  background-color: yellow;
}

.yellow p {
  background-color: yellow;
}


/*.. other tags.. */

.blue input {
  background-color: blue;
}

.blue article {
  background-color: blue;
}

.blue p {
  background-color: blue;
}


/*.. other tags.. */
<section class="yellow">

  <section class="blue">
    <form>
      <input type="button" value="This should use the blue theme" />
    </form>
  </section>

  <section class="red">
    <article>
      <p>This should use the red theme</p>
      <!-- This is instead yellow, how do I fix that? -->
    </article>
  </section>

  <section class="yellow">
    <nav>
      <p>This should use the yellow theme</p>
    </nav>
  </section>

  <p>This should be yellow.</p>

</section>

更新

好的,所以我尝试了给定的解决方案,他们使用给定的示例,但是一旦我将html代码扩展为更复杂的东西,它就不再起作用了。

问题是,由于我必须构建一个通用主题,我不能使用依赖于构建html的顺序的css规则。用户应该能够构建其网站,无论如何构建html,都应该应用正确的样式。

因此,如果用户给出了容器标签(nav,section,div,aside等),类暗主题,黄色主题或其他任何主题,它的所有孩子都应该使用该样式,除非子容器具有还指定了自己的主题。

这是不可能的吗? :(

例如:

section class=yellow-theme

    p: use yellow-theme

    aside: use yellow-theme

    div class=red-theme

        ul: use red-theme *not yellow

        p: use red-theme *not yellow

        footer class=blue-theme

            a: use blue-theme *not red not yellow

            h3: use blue-theme *not red not yellow

            div class=yellow-theme

                header: use yellow-theme *not blue * not red

                form: user yellow-theme *not blue *not red

                <!--This could go on forever and in any order with any tags-->

的CSS:

.yellow-theme anytag{
    /* Style any attributes needed: borders, colors, fonts, margins, paddings, etc. */
}
/* Do this for all the tags that needs to be styled */

.red-theme anytag{
    /* Style any attributes needed: borders, colors, fonts, margins, paddings, etc. */
}
/* Do this for all the tags that needs to be styled */

.blue-theme anytag{
    /* Style any attributes needed: borders, colors, fonts, margins, paddings, etc. */
}
/* Do this for all the tags that needs to be styled */

6 个答案:

答案 0 :(得分:2)

任何仅限选择器的解决方案都要求您对您的标记进行假设,这些假设可能在您的控制之内,也可能不在您的控制之内,因为无论祖先与每个匹配的后代有多接近,两个上下文选择器的特异性始终相同,并且任何使用继承实际属性的解决方案都要求您将它们应用于.red.yellow.blue部分,这可能是不可取的。例如,您必须将background-color应用于这些部分,以便background-color: inherit能够处理后代,但您可能不希望这些部分本身具有任何背景颜色,以便赢得& #39;是你的选择。

自定义属性允许后代继承其最近祖先的值,而不会以这种方式污染其他属性,并且不会妨碍其他级联规则(具有同等特定上下文选择器的竞争规则等)。由于这个原因,您只能使用自定义属性可靠地执行此操作。

&#13;
&#13;
.red {
  --color: red;
}

.yellow {
  --color: yellow;
}

.blue {
  --color: blue;
}

input, article, p {
  background-color: var(--color);
}
&#13;
<section class="yellow">

  <section class="blue">
    <form>
      <input type="button" value="This should use the blue theme" />
    </form>
  </section>

  <section class="red">
    <article>
      <p>This should use the red theme</p>
    </article>
  </section>

  <section class="yellow">
    <nav>
      <p>This should use the yellow theme</p>
    </nav>
  </section>

  <p>This should be yellow.</p>

</section>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

如果你想用所有元素解决它,这个问题有点困难。

你必须考虑另一种方式:不是“规则有效,直到有另一条规则”但“最接近的规则有效”。

如何实现这一目标?

首先为所有孙子元素设置一个规则,除了表格标签(也许还有ol,ul,nav,...标签),背景颜色外壳继承。现在所有这些元素都从父元素继承了背景颜色。

为每个主题设置第二个规则,定义所有直接子项的背景颜色。在这里,您必须查看表单标记的问题。表单标签没有继承(见上文),因此表单的子节点不会从最近的主题父节点获取规则。所以你必须为这种情况设置一个额外的规则。

总而言之:

*.color * > *:not(form):not(html):not(body) {
    background-color:inherit!important;
}
.red > *:not(form):not(.color), .red > form > *:not(.color) {background-color: red!important}
.yellow > *:not(form):not(.color), .yellow > form > *:not(.color) {background-color: yellow!important}
.blue > *:not(form):not(.color), .blue > form > *:not(.color) {background-color: blue!important}

(。color是所有部分都有的css类,也有css类.red或.yellow或.blue)

&gt; - 迹象很重要

你可以混淆所有规则。

<小时/> 编辑现在我看到!important不是必需的:)

你也可以写

*.color * > *:not(form):not(html):not(body) {
    background-color:inherit;
}
.blue > *:not(form):not(.color), .blue > form > *:not(.color) {background-color: blue}
.red > *:not(form):not(.color), .red > form > *:not(.color) {background-color: red}
.yellow > *:not(form):not(.color), .yellow > form > *:not(.color) {background-color: yellow}

EDIT2 如果要在主题中设置特定标记的样式,则必须按以下方式添加规则。

1)将要设置样式的所有css属性添加到集合的第一个规则:

*.color * > *:not(form):not(html):not(body) {
    background-color:inherit;
    color:inherit;
}

2)用标签名称

替换星号
.blue > *:not(form):not(.color), .blue > form *:not(.color) {background-color: blue}
.red > *:not(form):not(.color), .red > form *:not(.color) {background-color: red}
.yellow > *:not(form):not(.color), .yellow > form *:not(.color) {background-color: yellow}
.blue > input:not(form):not(.color), .blue > form input:not(.color) { color:white; }
.red > input:not(form):not(.color), .red > form input:not(.color) { color: green; }
.yellow > input:not(form):not(.color), .yellow > form input:not(.color) { color: purple; }

3)看看&gt; - 标志!我在一个位置删除它以使其适用于所有标签。

答案 2 :(得分:0)

不确定我是否理解您的问题,所以如果我错了,请发表评论。

增加样式的特异性,以免轻易覆盖。

.red > article > p {
  background-color: red;
}

&#13;
&#13;
.red input {
  background-color: red;
}

.red article {
  background-color: red;
}

.red > article > p {
  background-color: red;
}


/*.. other tags.. */

.yellow input {
  background-color: yellow;
}

.yellow article {
  background-color: yellow;
}

.yellow p {
  background-color: yellow;
}


/*.. other tags.. */

.blue input {
  background-color: blue;
}

.blue article {
  background-color: blue;
}

.blue p {
  background-color: blue;
}


/*.. other tags.. */
&#13;
<section class="yellow">

  <section class="blue">
    <form>
      <input type="button" value="This should use the blue theme" />
    </form>
  </section>

  <section class="red">
    <article>
      <p>This should use the red theme</p>
      <!-- This is instead yellow, how do I fix that? -->
    </article>
  </section>

  <section class="yellow">
    <nav>
      <p>This should use the yellow theme</p>
    </nav>
  </section>

  <p>This should be yellow.</p>

</section>
&#13;
&#13;
&#13;

答案 3 :(得分:0)

要仅定位元素的直接后代,可以使用直接后代运算符:>

.red > input {
    background-color: red;
}

为了更好一步,您可以替换所有重复,而不必手动声明每个元素:

.red > * {
    background-color: red;
}

.yellow > * {
    background-color: yellow;
}

.blue > * {
    background-color: blue;
}

答案 4 :(得分:0)

试试这个:

.yellow > *:not(form):not(section), .yellow form * {background-color: yellow !important}
.blue > *:not(form):not(section), .blue form * {background-color: blue !important}
.red > *:not(form):not(section), .red form * {background-color: red !important}

.yellow > *:not(form):not(section), .yellow form * {background-color: yellow !important}
.blue > *:not(form):not(section), .blue form * {background-color: blue !important}
.red > *:not(form):not(section), .red form * {background-color: red !important}
<section class="yellow">

  <section class="blue">
    <form>
      <input type="button" value="This should use the blue theme" />
    </form>
  </section>

  <section class="red">
    <article>
      <p>This should use the red theme</p>
      <!-- This is instead yellow, how do I fix that? -->
    </article>
  </section>

  <section class="yellow">
    <nav>
      <p>This should use the yellow theme</p>
    </nav>
  </section>

  <p>This should be yellow.</p>

</section> 

答案 5 :(得分:-2)

我试过这个并且它有效,无论你定义父元素是什么元素,希望这有帮助

body > :first-child 
{
     background-color: #ff0000;
}