如何防止CSS继承?


94

我的侧边栏中有一个使用嵌套列表(<ul>和<li>标记)的分层导航菜单。我正在使用一个已经具有列表项样式的预制主题,但是我想更改顶级项的样式,但不能将其应用于子项。是否有一种简单的方法可以将样式应用于顶级列表项标签,​​而无需将样式层叠到其子级列表项?我知道我可以在子项目中显式添加重写样式,但是如果有一种简单的方法可以说“将这些样式应用于此类并且不要级联”,我真的希望避免重复所有样式代码。他们将其归结为任何子元素”。这是我正在使用的html:

<ul id="sidebar">
  <li class="top-level-nav">
    <span>HEADING 1</span>
    <ul>
      <li>sub-heading A</li>
      <li>sub-heading B</li>
    </ul>
  </li>
  <li class="top-level-nav">
    <span>HEADING 2</span>
    <ul>
      <li>sub-heading A</li>
      <li>sub-heading B</li>
    </ul>
  </li>
</ul>

所以CSS有样式#sidebar ul#sidebar ul li了,但我想增加额外的样式到#sidebar .top-level-nav那些不会向下继承到其子儿。有什么方法可以简单地做到这一点,还是我需要重新排列所有样式,以便#sidebar ul现在使用的样式特定于某些类?


2
我确实在网站上搜索了类似的问题,但没有发现任何问题(不是说没有,但我确实找到了)。如果您知道它是什么,请直接告诉我吗?谢谢!


1
所以我认为答案是“不,没有办法简单地做到这一点-您必须手动覆盖子项目上的每个样式设置”-我是否正确解释了这一点?再次感谢。

Answers:


37

到目前为止,还没有父选择器(或者Shaun Inman称它们为合格选择器),因此您将必须将样式应用于子列表项,以覆盖父列表项上的样式。

级联是级联样式表的全部要点,因此得名。


13
自IE8以来,此信息已过时。参见Silviu Postavaru的答案。请考虑将支票更改为更合适的答案。
tmuecksch

大声笑,我同意级联有点本质。但是,应该有一种方法可以阻止从特定父对象传播出去,而该目的是不同的。
Obay Abd-Algader

72

您可以使用子选择器

所以使用

#parent > child

将仅使第一级子级应用样式。不幸的是IE6不支持子选择器。

否则你可以使用

#parent child child

为以下一级以上的子级设置另一种特定样式。


1
您能否在JSFiddle中向我展示此操作?我试图将内联块显示的div居中,但仍使div内的文本居中。
Calmarius 2014年

41

有一个名为属性allCSS3继承模块。它是这样的:

#sidebar ul li {
  all: initial;
}

自2016年12月起,除IE / Edge和Opera Mini以外的所有浏览器均支持此属性。


4
@AndriusDobrotinas最终会得到支持吗?我似乎并不完全了解您的评论。如果您使用PostCSS,则有一个提供此功能的PostCSS插件:github.com/maximkoretskiy/postcss-initial
Boldewyn

1
@AndriusDobrotinas,您的评论非常无建设性。答案是为社区着想而发布的;尽力看到它的好处。
科迪

2
到目前为止,只有IE和Opera Mini不支持它,所有其他主流浏览器都支持
传奇

@Boldewyn没有“默认”值,据链接的w3文档可以得知...
benomatis

@webeno有,当我写了答案:w3.org/TR/2013/WD-css3-cascade-20130103/#all-shorthand似乎有老有一些细微的差别default和新的unset,但现在我”没有时间进一步调查。随时编辑答案以使其更新。
Boldewyn

26

您可以使用*选择器将子样式更改回默认样式

#parent {
    white-space: pre-wrap;
}

#parent * {
    white-space: initial;
}

1
这是一个非常英俊的解决方案-特别是如果您不知道父母的班级。
BurninLeo

我想我知道答案,但是仍然可以设置此内联吗?<div id="parent" style="white-space:pre-wrap;*white-space:initial;"/>
1.21吉瓦,2015年

11

使用iframe进行包装会使父CSS变得过时。


2
有趣的是,这是最糟糕的答案,因为从技术上讲,这是阻止CSS继承的唯一物理方法。我并不是说您应该以这种方式使用它。
davidelrizzo

2
我建议不要对CSS有所了解,将其留在它所属的虚拟世界中!
michaelward82 '16

实际上添加iframe使我的子组件不可见。有什么想法吗?
Kevin Ghaboosi

5

简短的答案是:不,不可能防止CSS继承。您只能覆盖在父级上设置的样式。参见规格:

HTML文档中的每个元素都将从其父元素继承所有可继承的属性,但根元素(html)没有父元素。- W3C

除了覆盖每个继承的属性。您也可以使用initial关键字,例如color: initial;。它也可以与一起使用all,例如all: initial;,它将立即重置所有属性。例:

.container {
  color: blue;
  font-style: italic;
}
.initial {
  all: initial;
}
<div class="container">
  The quick brown <span class="initial">fox</span> jumps over the lazy dog
</div>

根据我可以使用的浏览器支持表...

  • all (目前,IE和Edge均不支持,其他都不错)
  • initial (目前在IE中不提供支持,其他都不错)

在某些情况下,使用直接子选择器>可能会发现它很有用。例:

.list > li {
  border: 1px solid red;
  color: blue;
}
<ul class="list">
  <li>
    <span>HEADING 1</span>
    <ul>
      <li>sub-heading A</li>
      <li>sub-heading B</li>
    </ul>
  </li>
  <li>
    <span>HEADING 2</span>
    <ul>
      <li>sub-heading A</li>
      <li>sub-heading B</li>
    </ul>
  </li>
</ul>

边框样式仅适用于直接子级<li>border非继承属性也是如此。但是,文本颜色color和继承的属性一样,已应用于所有子级。

因此,>在防止继承方面,选择器仅对非继承属性有用。


2

您可以使用jQuery之类的功能来“禁用”此行为,尽管我几乎认为这不是一个很好的解决方案,因为您可以在CSS和javascript中获得显示逻辑。不过,根据您的要求,您可能会发现jQuery的css utils使您的生活比尝试变黑的css更容易,尤其是在您尝试使其适用于IE6的情况下。


2

例如,如果您在XHTML文档中有两个div。

<div id='div1'>
    <p>hello, how are you?</p>
    <div id='div2'>
        <p>I am fine, thank you.</p>
    </div>
</div>

然后在CSS中尝试。

#div1 > #div2 > p{
    color: red;
}

仅影响“ div2”段落。

#div1 > p {
    color: red;
} 

仅影响“ div1”段落。


2

您不需要的类引用li。而不是像CSS

li.top-level-nav { color:black; }

你可以写

ul#sidebar > li { color:black; }

这将仅将样式应用于li从边栏立即下降的ul


0

只需在“ #sidebar ul li”选择器中将它们恢复为默认值


谢谢你的回答。是的,我知道我可以将其重新设置为子项目的样式,但是我试图避免这种情况,因为我使用的主题不是我创建的,我想知道是否可以节省大量时间通过仅使用一些“请勿层叠:真实”规则或类似的规则,而不是查找遍布各处的ul和li的所有不同样式,然后担心该站点其他区域的意外后果。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.