【问题标题】:CSS specificity problemCSS 特异性问题
【发布时间】:2011-09-13 03:04:07
【问题描述】:

我正在为我自己的教育创建一个 javascript 游戏。游戏需要几个页面,我通过隐藏的divs 实现这些页面,当你想查看它们时会隐藏/取消隐藏(题外话:欢迎任何关于这是否是个好主意的建议)。

我有一个 CSS 规则,它用 display: none; 隐藏我的所有 div,然后是一个用 display:block; 取消隐藏特定 div 的类。但是,似乎我的用于选择所有 div 的 css 选择器不是隐藏类,而是覆盖了类,导致规则不适用。我知道我可以使用 !important 属性来解决这个问题,但我想了解为什么我所写的内容不起作用。我认为一个类将是一个足够具体的选择器,并且规则甚至出现在隐藏规则之后。

这是我的来源:

<!DOCTYPE HTML>
<html>
<head>
    <link rel="stylesheet" href="style.css" type="text/css" media="screen" charset="utf-8">
</head>
<body>
    <div id="game">
        <div id="content">
            <div id="viewport">
                <div id="home_page" class="current_page">Home</div>
                <div  id="work_page">Work</div>
            </div>
        </div>
    </div>
</body>
</html>

和css:

#content
{
    background: #eef;
    padding: 5px;
}

#viewport div
{
    display:none;
}

.current_page
{
    display:block;
    //display:block !important; //One solution, but not preferred
}

【问题讨论】:

    标签: html css css-selectors


    【解决方案1】:

    #viewport div 是一个 ID 选择器和一个类型选择器。这比 .current_page 更具体,因为它本身就是一个类选择器,因为只有 ID。

    您可以并且应该修改最后一个选择器,而不是应用display: block !important;,给它一个ID,使它变成#viewport .current_page。这使得 ID 具有同样的特定性,类选择器比类型选择器更具体。

    【讨论】:

    • 像魅力一样工作! #viewport div > .current_page 因为 id,所以 #viewport div #viewport .current_page 拥有更多权重,然后我可以使用 jquery.removeClass()/jquery.addClass() 来操纵我的菜单页面的可见性。跨度>
    【解决方案2】:

    这行得通吗?

    #viewport div.current_page
    {
       display:block;
       /* display:block !important; //One solution, but not preferred */
    }
    

    【讨论】:

    • 这确实有效!谢谢!事实证明,就像 #viewport .current_page 一样简洁也能完成工作。
    【解决方案3】:

    试试

    #viewport #home_page {
      display:block;
    }
    

    您需要增加特异性,因为在 CSS 规则选择器中使用类、ID 或嵌套元素会增加不同程度的特异性。

    这是一篇关于CSS Specificity 的好文章,易于阅读。

    作为一般规则,我会说如果您需要使用!important 语句,可能您没有使用正确的CSS 选择器。有时我发现自己使用!important 语句只是为了后来意识到我可以使用更好的选择器获得相同的结果。

    【讨论】:

    • 同意。 !important 感觉像是在作弊,我阻止自己这样做,因为如果项目变得足够大,很快我可能会有两个不同的 !important 规则相互冲突。
    【解决方案4】:

    ID 比类更重要,所以使用

    #viewport div.current_page
    

    【讨论】:

      【解决方案5】:

      除了其他答案中提供的方法外,您还可以将display:none 样式内联。大多数 javascript 库都有 show()/hide() 方法 - 这些方法通常将 display CSS 属性分别更改为 blocknone。这似乎是最易于维护的方法,然后您甚至根本不必考虑 CSS 级联或特殊性 - 内联样式胜过其他一切。

              <div id="viewport">
                  <div id="home_page" class="viewportPage">Home</div>
                  <div  id="work_page" class="viewportPage" style="display:none;">Work</div>
              </div>
      

      Javascript:

      function handlePageShow (page_element_to_show) {
        // hide all pages
        var pages = document.getElementsByClassName('viewportPage');
        var page_count = pages.length;
        for (var i = 0; x < page_count; i++) {
          pages[i].style.display = 'none';
        }
        // now show the target page
        page_element_to_show.styles.display = '';
      }
      

      使用mootoolsjQuery 等javascript 库可以更轻松地完成此操作。我不会去添加框架只是来实现这一点,但如果你正在制作一个游戏,你会遇到更多的例子,一个库会让你的生活更轻松。在这种情况下...getElementsByClassName 在 IE 中不可用,因此您必须为 IE 用户提供它的实现。这是编写适用于所有浏览器的复杂 javascript 所涉及的头痛的一个简单示例。

      【讨论】:

      • 感谢您提供有关跨浏览器问题的说明。仅此一项就会促使我使用一个可以为我解决这些问题的库。没错,就 CSS 的特殊性而言,页面上的内联样式胜过一切。
      猜你喜欢
      • 2019-07-26
      • 2013-09-01
      • 1970-01-01
      • 2010-10-06
      • 2017-11-11
      • 2012-01-10
      • 1970-01-01
      • 2013-05-19
      • 2014-02-04
      相关资源
      最近更新 更多