如何正确覆盖外部文件中的CSS

时间:2012-10-25 21:53:39

标签: css xhtml

有很多问题看起来像这个,但没有一个真正回答我的问题。

我的情况如下:

我需要更改许多元素的显示,以便它们在页面中正确显示并且语义正确。
我有点有js版本和nojs版本。有些元素只有在用户使用js时才能看到,而其他元素仅在js关闭时才会被看到。

我有一些具有良好特异性的选择(不要争论,它们确实在上下文中有意义,我只是在这里更改了类,以便不放弃原始代码所在的位置)

.imagesContainer div.imageContainer  .imagedata

然后当用户没有js时,此元素将被隐藏。所以我做了类似的事情:

.nojs{
    display:none;
}

我在同一个文件中尝试了它,因为HTML期望优先级是外部文件<相同的文件<排队。但似乎现在的外部文件=同一文件<内联(外部文件和内联之间没有优先级)。

处理这个问题的最佳方法是什么?

改变我所显示的第一个选择器的特异性是没有办法解决的 我也不想把CSS放在内联中。这是一种痛苦,在标记中占用太多空间并使其更难阅读 我也不愿意使用!important。它被认为不是解决这类问题的正确方法,我同意 我正在使用XHTML,因此在DTD中没有定义noscript标签(我需要根据我所遵守的规则使用XHTML),

4 个答案:

答案 0 :(得分:2)

如果您已经为display设置了.imagesContainer div.imageContainer .imagedata属性,那么只是将nojs添加到该元素不会因为具体情况而被覆盖。你必须:

.imagesContainer div.imageContainer .imagedata.nojs { display: none; }

或者添加任何元素nojs

如果我是你,我会彻底改变这一点。对于没有启用js时不显示的元素,我默认将它们设置为display: none。然后,对于头部中的任何样式/链接或其他脚本,我将使用一些j来向jsbody元素提供html。然后在css中,我将使用.js <the rest of the selector>更改显示属性,以显示要素。

答案 1 :(得分:2)

正如@prodigitalson正确指出的那样,你的nojs类总是不如你详细的类定义那么具体。

据我所知,!important确实是实现你想要做的事情的唯一方法,而没有创建更多特异性的大量类定义。

可以说,像这样的案例是!important最初的设计目标,以及完全可以使用它的地方。 !important在被滥用以超越特异性时会出现问题,因为你无法弄清楚如何以“正确”的方式达到所需的特异性。

答案 2 :(得分:1)

所以...如何解决这个问题......这并不容易,但在w3c和你的答案的帮助下,我能够得到正确的结果。

在尝试了多个可能解决此问题的路径后(包括以编程方式添加样式或链接标记),我得到了我需要的答案。
为了以最简单的方式执行此操作,您需要至少拥有2个样式表。一个用于此系统,另一个用作“常规”样式表(具有页面所有CSS的样式表)。

然后将.nojs类放置到所有(x)HTML元素,只有当用户没有使用js时才会出现,并且只有当用户使用js时才会出现.js。

将以下内容放在此系统的样式表中:

.js{
    display:none !important;
}

然后使用此js代码在完成后执行。最好在调度DOMContentLoaded事件时使用。

var jsNojsStyleSheet = document.styleSheets[1]; // change this index depending on your needs
if(jsNojsStyleSheet.deleteRule){
    jsNojsStyleSheet.deleteRule(0);
    jsNojsStyleSheet.insertRule('.nojs{ display:none !important; }', 0);
}else{
    // IE8 has his own way of dealing with this situation
    jsNojsStyleSheet.removeRule(0);
    jsNojsStyleSheet.addRule('.nojs', 'display:none !important', 0);
}

不要忘记根据需要更改列表中的索引。

现在你可以去测试一下。
这应该删除.js规则并插入.nojs规则,替换之前的规则。

对我来说,这是最干净的工作方式。欢迎批评或改进这项技术。

注意:IE要求您做一些事情来刷新页面的解析。我使用了一个代码,用于切换复选框的选中两次,具有创造性并找到自己的解决方案。

编辑: 我还发现,与其他使用jQuery的技术相比,这要快得多,而且没有其他技术可以解决这个问题。所有更改都是使用浏览器自己适应CSS更改时的更改而不是逐个更改每个HTML节点。

此系统适用于IE8,但不确定IE7。

答案 3 :(得分:0)

有关计算特定性的确切方法,请参阅http://www.w3.org/TR/CSS2/cascade.html#specificity

根据本节:

count 1 if the declaration is from is a 'style' attribute rather than a rule with a selector, 0 otherwise (= a) (In HTML, values of an element's "style" attribute are style sheet rules. These rules have no selectors, so a=1, b=0, c=0, and d=0.)
count the number of ID attributes in the selector (= b)
count the number of other attributes and pseudo-classes in the selector (= c)
count the number of element names and pseudo-elements in the selector (= d) 

您对.imagesContainer div.imageContainer .imagedata的指定是0031(0没有内联,0没有id,3个类,1个元素)。您必须超过此数字才能覆盖显示。

我们假设您的body标记看起来像<body id="foobar">这应该覆盖示例元素的显示设置:

#foobar .nojs { display: none; }

因为它的特殊性是0110而110大于31.(0没有内联,1个id,1个类,0个元素)

(并不是说我主张id'ing你的身体标签,这只是一个选择器嵌套的例子,会覆盖你给你的css选择器)

编辑: 请参阅此小提琴,了解更具体的解决方案:http://jsfiddle.net/KAuAx/