有很多问题看起来像这个,但没有一个真正回答我的问题。
我的情况如下:
我需要更改许多元素的显示,以便它们在页面中正确显示并且语义正确。
我有点有js版本和nojs版本。有些元素只有在用户使用js时才能看到,而其他元素仅在js关闭时才会被看到。
我有一些具有良好特异性的选择(不要争论,它们确实在上下文中有意义,我只是在这里更改了类,以便不放弃原始代码所在的位置)
.imagesContainer div.imageContainer .imagedata
然后当用户没有js时,此元素将被隐藏。所以我做了类似的事情:
.nojs{
display:none;
}
我在同一个文件中尝试了它,因为HTML期望优先级是外部文件<相同的文件<排队。但似乎现在的外部文件=同一文件<内联(外部文件和内联之间没有优先级)。
处理这个问题的最佳方法是什么?
改变我所显示的第一个选择器的特异性是没有办法解决的 我也不想把CSS放在内联中。这是一种痛苦,在标记中占用太多空间并使其更难阅读 我也不愿意使用!important。它被认为不是解决这类问题的正确方法,我同意 我正在使用XHTML,因此在DTD中没有定义noscript标签(我需要根据我所遵守的规则使用XHTML),
答案 0 :(得分:2)
如果您已经为display
设置了.imagesContainer div.imageContainer .imagedata
属性,那么只是将nojs
添加到该元素不会因为具体情况而被覆盖。你必须:
.imagesContainer div.imageContainer .imagedata.nojs { display: none; }
或者添加任何元素nojs
。
如果我是你,我会彻底改变这一点。对于没有启用js时不显示的元素,我默认将它们设置为display: none
。然后,对于头部中的任何样式/链接或其他脚本,我将使用一些j来向js
或body
元素提供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/