Css last / deeppest匹配元素或属性,用于应用覆盖先前所有内容的规则

时间:2015-05-04 13:20:36

标签: html css css-selectors

例如,

给出

<html dir=rtl>    
<body>
    <div>I am right to left</div>
    <div>I am right to left
       <div dir=ltr>I should be left to right
           <div dir=rtl>I should be right to left</div>
       </div>
    </div>    
</body>
</html>

我问这个问题是因为生成了嵌套内容,而且无法知道这有多深。

理想情况下,CSS规则应该能够根据最深的匹配应用某个规则。

规则:

[dir=rtl] {
    text-align:right;
}

只会匹配第一个。理想情况下,你需要像

这样的东西
[dir=rtl]:deepest {
    text-align:right;
}

更新

我意识到问题的框架可能仍然有点令人困惑,对此感到抱歉!

以下是解释问题的代码:

.container {
  padding:20px;
}

[dir=ltr] .container {
  border:5px solid blue;
}

[dir=rtl] .container {
  border:5px solid red;
}
<div id="searchHere">
  <div dir=ltr>
    <div class="container">
      l t r
    </div>
    <div dir=rtl>
      <div class="container">
        r t l
      </div>
      <div>
        <div class="container">
          r t l
        </div>
        <div dir=ltr>
          <div class="container">
            l t r ( should be but is r t l colors instead )
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

为了澄清目标是什么,可以说任何在更深层次上找到的匹配都应该应用于所有子匹配。

这可以使用唯一标识符来实现,因为这将覆盖先前的规则,或者使用更好定义的css选择器。更明确的选择器可以是div > div > div > div ...但是,给定动态生成的内容,要知道要定义的规则将非常困难。

3 个答案:

答案 0 :(得分:1)

<强> 更新

使所需元素可直接定位

在您的初始示例中,所需元素可直接定位,因此我的原始答案如下。

但是在你的评论中,你提到了一些你用the Code Pen you shared澄清的更复杂的东西。

您实际要完成的目标是定位某些元素的后代,这些元素也不是竞争元素的后代,在本例中为[dir=rtl] .container[dir=ltr] .container

没有当前的CSS选择器可以在没有干扰的情况下执行此操作(正如您在笔中演示的那样),因此设置这些元素的最佳方式是通过应用标识符类来确保它们可直接定位每个都基于它与最近父亲的关系,并设置了dir属性。

如果您可以控制生成的标记,则应在生成模板之前处理逻辑,以便标记就绪。

但是如果您无法控制生成的标记,则可以使用带有传入函数的.filter将jQuery应用于类。

无论哪种方式,您希望您的标记最终如下:

<div id="searchHere">
  <div dir=ltr>
    <div class="container ltr">
      l t r
    </div>
    <div dir=rtl>
      <div class="container rtl">
        r t l
      </div>
      <div>
        <div class="container rtl">
          r t l
        </div>
        <div dir=ltr>
          <div class="container ltr">
            l t r
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

jQuery方法

$(function () {
  
  $('.container')
    .filter(function () {
      // Return elements whose closest parent w/ attribute 'dir' is 'rtl'
      return $(this).closest('[dir]').attr('dir') === 'rtl';
    })
    .addClass('rtl')  // Apply identifier class
    .end()
    .filter(function () {
      // Return elements whose closest parent w/ attribute 'dir' is 'ltr'
      return $(this).closest('[dir]').attr('dir') === 'ltr';
    })
    .addClass('ltr'); // Apply identifier class
  
});
.container {
  padding: 20px;
}
.container.ltr {
  border: 5px solid blue;
}
.container.rtl {
  border: 5px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="searchHere">
  <div dir=ltr>
    <div class="container">
      l t r
    </div>
    <div dir=rtl>
      <div class="container">
        r t l
      </div>
      <div>
        <div class="container">
          r t l
        </div>
        <div dir=ltr>
          <div class="container">
            l t r
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

原始答案:

CSS默认提供此功能

CSS原生行为是将样式应用于与给定选择器匹配的每个元素。

在您的示例中,规则[dir=rtl] { text-align:right; }将应用于与选择器[dir=rtl]匹配的每个元素,而不仅仅是第一个。

此外,您的示例甚至不需要使用CSS,因为您正在使用HTML dir属性,因此浏览器会自动对这些元素中的文本应用右对齐。

<body dir="rtl">
    <div>I am right to left</div>
    <div>I am right to left
       <div dir="ltr">I should be left to right
           <div dir="rtl">I should be right to left</div>
       </div>
    </div>    
</body>

但即使在纯CSS示例中,您也只需要使用标准选择器来定位嵌套元素:

.rtl {
    direction: rtl;
}

.ltr {
    direction: ltr;
}
<body class="rtl">
    <div>I am right to left</div>
    <div>I am right to left
       <div class="ltr">I should be left to right
           <div dir="rtl">I should be right to left</div>
       </div>
    </div>    
</body>

答案 1 :(得分:0)

看来这是可能的,使用:dir或:lang属性。

在2015年使用:lang是首选,因为大多数浏览器都支持它。

示例:

&#13;
&#13;
.container {
  padding:20px;
}

:lang(ar) {
  direction:rtl;
}

:lang(en) {
  direction:ltr;
}

.container:lang(en) {
  background-color:blue;
}

.container:lang(ar)  {
  background-color:red;
}

.container .a:lang(en)   {
  background-color:orange;
}

.container .a:lang(ar) {
  background-color:yellow;
}
&#13;
<div id="searchHere">
  
    <div lang=en>      
      <div class="container">
          l t r
        <div class=a>
              a
         </div>
      </div>
      
      <div lang=ar>
          <div class="container">
             r t l
            <div class=a>
              a
              </div>
          </div>        
        
          <div>
            <div class="container">
                r t l 
              <div class=a>
              a
              </div>
            </div>  
            
            <div lang=ar>
                <div class="container">
                   r t l
                  <div class=a>
                    a
                    </div>
                </div>  
            </div>
            
            <div lang=en>      
              <div class="container">
                  l t r
                <div class=a>
              a                  
              </div>
                
                <div lang=ar>
                  <div class="container">
                     r t l
                    <div class=a>
                      a                      
                      <div lang=en>      
                        <div class="container">
                          l t r
                          <div class=a>
                            a                  
                          </div>
                          <div>
                            <div>
                            
                              <div lang=en>      
                                <div class="container">
                                  l t r
                                  <div class=a>
                                    a                  
                                  </div>
                                </div>                      
                              </div>
                              
                              <div lang=ar>      
                                <div class="container">
                                  r t l
                                  <div class=a>
                                    a                  
                                  </div>
                                </div>                      
                              </div>
                              
                            </div>
                            
                          </div>
                        </div>                      
                      </div>
                  </div> 
                </div>
              </div>            
            </div>
            
          </div>
        
      </div>
      
    </div>
  
</div>
&#13;
&#13;
&#13;

虽然这个例子用ltr和rtl证明了这一点,但是理论上:lang可以表现为最深的匹配,例如:lang(deepest-overrides-all)虽然可能不是lang = deepest-覆盖 - 所有都应该在元素上定义。

答案 2 :(得分:-1)

不。

如果您可以将HTML生成为未指定的深度,那么您可以为CSS执行此操作,但是我们没有&#34;最里面的匹配&#34;选择器。

您可以做的最好的事情就是使用一个脚本生成CSS,该脚本了解级别越深,oiot级别越不重要。这与HTML和CSS的假设相反。