如何防止 CSS 继承?

我的侧边栏中有一个分层导航菜单,它使用嵌套列表(< 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上的样式现在特定于某些类?

157322 次浏览

just set them back to their defaults in the "#sidebar ul li" selector

You either use the child selector

So using

#parent > child

Will make only the first level children to have the styles applied. Unfortunately IE6 doesn't support the child selector.

Otherwise you can use

#parent child child

To set another specific styles to children that are more than one level below.

As of yet there are no parent selectors (or as Shaun Inman calls them, qualified selectors), so you will have to apply styles to the child list items to override the styles on the parent list items.

Cascading is sort of the whole point of Cascading Style Sheets, hence the name.

You could use something like jQuery to "disable" this behaviour, though I hardly think it's a good solution as you get display logic in css & javascript. Still, depending upon your requirements you might find jQuery's css utils make life easier for you than trying hacky css, especially if you're trying to make it work for IE6

There is a property called all in the CSS3 inheritance module. It works like this:

#sidebar ul li {
all: initial;
}

As of 2016-12, all browsers but IE/Edge and Opera Mini support this property.

For example if you have two div in XHTML document.

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

Then try this in CSS.

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

affect only 'div2' paragraph.

#div1 > p {
color: red;
}

affect only 'div1' paragraph.

You can use the * selector to change the child styles back to the default

example

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


#parent * {
white-space: initial;
}

Wrapping with iframe makes parent css obsolete.

You don't need the class reference for the lis. Instead of having CSS like

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

you can write

ul#sidebar > li { color:black; }

This will apply the styling only to lis that immediately descend from the sidebar ul.

Short answer is: No, it's not possible to prevent CSS inheritance. You can only override the styles that are set on the parents. See the spec:

Every element in an HTML document will inherit all inheritable properties from its parent except the root element (html), which doesn’t have a parent. -W3C

Apart from overriding every single inherited property. You can also use initial keyword, e.g. color: initial;. It also can be used together with all, e.g. all: initial;, that will reset all properties at once. Example:

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

Browser support tables according to Can I use...

  • all (Currently no support in both IE and Edge, others are good)
  • initial (Currently no support in IE, others are good)

You may find it useful by using direct children selector > in some cases. Example:

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

The border style has been applied only to the direct children <li>s, as border is an non-inherited property. But text color has been applied to all the children, as color is an inherited property.

Therefore, > selector would be only useful with non-inherited properties, when it comes to preventing inheritance.

You may use Shadow Dom which is a new feature provided by browsers. Browser support is also pretty decent for the date.

Documentation: https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM

You can wrap the element that you don't want to inherit any styles in a div with no style.

Something like this:

<div style='all: revert !important;'>
Your content here
</div>

here's an live example using cascade, initial and all property:

div {
border: 1px solid red;
margin: 10px;
}


div p {
color: red;
}


.initial {
border-color: initial;
}


.initial p {
color: initial;
}


.asterisk,
.asterisk * {
border-color: initial;
color: initial;
}


.all,
.all * {
all: initial
}

https://jsbin.com/cosabusiwi/1/edit?html,css,output