可以合成“:next-of-type”吗?

时间:2019-02-26 09:38:30

标签: css css-selectors

在使用混合元素类型的大型网格的情况下,使用:next-of-type作为伪类会很好。我的定义是下一个与添加了:next-of-type的选择器选择的元素具有相同类型的同级。 (我想拥有:next-child:next-of-class等也很好。还有prev-child,prev-of-type,prev-of-class等。)

在CSS文档中找不到这样的东西,所以我想它不存在。我花了一些时间尝试将其合成出来,但失败了。

不确定这是否可以解决,也许只能由W3 CSS工作组来解决...

作为示例,假设您有一个大的元素网格。为了简单起见,我在示例中仅使用两个,但是我的实际案例中有十几个或更多不同类型的元素。我将按照元素在HTML中存在的顺序对元素内容进行编号,但是由于网格放置算法(此处未演示),这些元素实际上可能不会以与HTML中出现的顺序不同的顺序出现。尽管如此,HTML中的项目顺序还是选择计划所需要的。我将<a-><b->用作(自定义)元素。

<div style="display: grid;">
     <a->1</a->
     <a->2</a->
     <b- class="special">3</b->
     <a->4</a->
     <a- class="ordinary">5</a->
     <a- class="surprise">6</a->
     <b->7</b->
     <b->8</b->
     <a->9</a->
</div>

因此,最好有一种方法来指定.special:next-of-type并选择项目7,.ordinary:next-of-type将选择项目6,而.surprise:next-of-type将选择项目9。

2 个答案:

答案 0 :(得分:0)

展开我的评论:

从根本上讲,与“下一个”和“上一个”元素匹配的伪类将与您将其“附加”到的任何复合选择器所代表的元素匹配的元素不同,因此与CSS的“伪”定义不兼容-class”或实际上是“简单选择器” /“复合选择器”。

Selectors L4将简单选择器和复合选择器描述为与单个元素同时匹配的条件。根据此定义,只有当该类型的下一个元素也匹配.special:next-of-type时,像.special这样的选择器才起作用。然后,它将进行递归匹配,从而得到每个父元素中每个元素类型的第一个之外的所有.special ~ .special。至关重要的是,由于第7项与.special不匹配,因此在您的情况下根本无法使用。

人为地理解选择器可能会直观地理解它的作用,但仍然不能与选择器语法混为一谈,因为要使其发挥作用,您需要将:next-of-type定义为一个特殊的伪类,与规范中的定义相反,它忽略或与其他复合选择器分开进行匹配。这意味着选择器匹配算法会增加复杂性。在jQuery's :eq() family of selectors中可以看到类似的复杂性-可能有很好的理由说明这些选择器尚未标准化。

此外,类似:next-of-type的元素不是元素的条件,而是在该元素和其他元素之间建立关系。在选择器中,两个或多个不同元素之间的关系用组合器表示。 “下一个同级兄弟”组合器可以轻松完成此任务,而无需从根本上改变选择器匹配的工作方式(例如.special ~~ *),但是在任何Selectors规范中都不存在,我看不到这样的用例因为CSSWG足以证明其设计,测试和实施的合理性。而且,如果没有这样的组合器,则需要预先知道元素类型才能确定该类型的下一个同级对象,而这不能使用当今可用的选择器来实现,甚至不包括L4 :nth-child(An+B of S)

答案

  

可以合成“:next-of-type”吗?

否,今天不提供选择器,并且可以使用现有选择器语法的解决方案是引入具有此确切功能的组合器。

答案 1 :(得分:0)

所以有可能,但是除了知道网格中元素类型的完整列表以及相同类型元素之间的最大元素跨度之外,拥有一个宏处理器来确实很方便生成合成的溶液。

下面的代码段仅处理两种类型的元素,同一类型的元素之间最多包含5个元素,但是显然可以在任何一个维度上进行繁琐的扩展。

      .container {
        display: grid;
        font-size: 30px;
        grid-template-areas:
          ". . ."
          ". . ."
          ". . .";
      }
      .special ~next-of-type { color: red; }
      a-.special + a- { color: red; }
      a-.special + :not( a- ) + a- { color: red; }
      a-.special + :not( a- ) + :not( a- ) + a- { color: red; }
      a-.special + :not( a- ) + :not( a- ) + :not( a- ) + a- { color: red; }
      a-.special + :not( a- ) + :not( a- ) + :not( a- ) + :not( a- ) + a- { color: red; }
      a-.special + :not( a- ) + :not( a- ) + :not( a- ) + :not( a- ) + :not( a- ) + a- { color: red; }
      b-.special + b- { color: red; }
      b-.special + :not( b- ) + b- { color: red; }
      b-.special + :not( b- ) + :not( b- ) + b- { color: red; }
      b-.special + :not( b- ) + :not( b- ) + :not( b- ) + b- { color: red; }
      b-.special + :not( b- ) + :not( b- ) + :not( b- ) + :not( b- ) + b- { color: red; }
      b-.special + :not( b- ) + :not( b- ) + :not( b- ) + :not( b- ) + :not( b- ) + b- { color: red; }

      .ordinary ~next-of-type { color: blue; }
      a-.ordinary + a- { color: blue; }
      a-.ordinary + :not( a- ) + a- { color: blue; }
      a-.ordinary + :not( a- ) + :not( a- ) + a- { color: blue; }
      a-.ordinary + :not( a- ) + :not( a- ) + :not( a- ) + a- { color: blue; }
      a-.ordinary + :not( a- ) + :not( a- ) + :not( a- ) + :not( a- ) + a- { color: blue; }
      a-.ordinary + :not( a- ) + :not( a- ) + :not( a- ) + :not( a- ) + :not( a- ) + a- { color: blue; }
      b-.ordinary + b- { color: blue; }
      b-.ordinary + :not( b- ) + b- { color: blue; }
      b-.ordinary + :not( b- ) + :not( b- ) + b- { color: blue; }
      b-.ordinary + :not( b- ) + :not( b- ) + :not( b- ) + b- { color: blue; }
      b-.ordinary + :not( b- ) + :not( b- ) + :not( b- ) + :not( b- ) + b- { color: blue; }
      b-.ordinary + :not( b- ) + :not( b- ) + :not( b- ) + :not( b- ) + :not( b- ) + b- { color: blue; }

      .surprise ~next-of-type { color: orange; }
      a-.surprise + a- { color: orange; }
      a-.surprise + :not( a- ) + a- { color: orange; }
      a-.surprise + :not( a- ) + :not( a- ) + a- { color: orange; }
      a-.surprise + :not( a- ) + :not( a- ) + :not( a- ) + a- { color: orange; }
      a-.surprise + :not( a- ) + :not( a- ) + :not( a- ) + :not( a- ) + a- { color: orange; }
      a-.surprise + :not( a- ) + :not( a- ) + :not( a- ) + :not( a- ) + :not( a- ) + a- { color: orange; }
      b-.surprise + b- { color: orange; }
      b-.surprise + :not( b- ) + b- { color: orange; }
      b-.surprise + :not( b- ) + :not( b- ) + b- { color: orange; }
      b-.surprise + :not( b- ) + :not( b- ) + :not( b- ) + b- { color: orange; }
      b-.surprise + :not( b- ) + :not( b- ) + :not( b- ) + :not( b- ) + b- { color: orange; }
      b-.surprise + :not( b- ) + :not( b- ) + :not( b- ) + :not( b- ) + :not( b- ) + b- { color: orange; }
    <h1>next-of-type synthesized</h1>
    <div class=container>
     <a->1</a->
     <a->2</a->
     <b- class="special">3</b->
     <a->4</a->
     <a- class="ordinary">5</a->
     <a- class="surprise">6</a->
     <b->7</b->
     <b->8</b->
     <a->9</a->
    </div>

感谢BoltClock表示这是不可能的,还有其他有用的评论使我想到了这个解决方案。