0

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

我的情况如下:

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

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

.imagesContainer div.imageContainer  .imagedata

然后这个元素意味着当用户没有js时隐藏。所以我做了类似的事情:

.nojs{
    display:none;
}

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

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

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

4

4 回答 4

2

好吧,如果您display已经设置了一个属性,.imagesContainer div.imageContainer .imagedata那么由于特定性,简单地添加nojs到元素不会被覆盖。你必须:

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

或者nojs添加任何元素。

如果我是你,我会完全扭转这一点。对于没有启用 js 时不显示的元素,我会将它们设置为display: none默认值。然后,对于头部中的任何样式/链接或其他脚本,我将使用一些 js 来js分配给bodyorhtml元素。然后在 css 中,我将更改显示属性以显示.js <the rest of the selector>要显示的元素。

于 2012-10-25T22:03:21.190 回答
2

正如@prodigitalson 正确指出的那样,您的nojs课程总是没有您详细的课程定义那么具体。

据我所知,!important这确实是实现您想要做的事情的唯一方法,而无需创建大量更具体的类定义。

可以说,这样的案例!important是最初设计的,并且完全可以使用它。!important当它被滥用来覆盖特异性时会变得有问题,因为您无法弄清楚如何以“正确”的方式达到所需的特异性。

于 2012-10-26T07:12:09.957 回答
1

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

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

然后将 .nojs 类放置到您希望仅在用户不使用 js 时出现的所有 (x)HTML 元素,而 .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。

于 2012-10-27T19:20:24.117 回答
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 .imagedata0031 的特殊性(0 没有内联,0 没有 id,3 个类,1 个元素)。您必须超过此数字才能覆盖显示。

假设您的body标签看起来像这样,<body id="foobar">这应该会覆盖示例元素上的显示设置:

#foobar .nojs { display: none; }

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

(并不是说我必须提倡 id'ing 你的 body 标签,这只是选择器嵌套的一个例子,它会覆盖你给的 css 选择器)

编辑:查看这个小提琴以获得更具体的解决方案:http: //jsfiddle.net/KAuAx/

于 2012-10-26T07:30:34.083 回答