是否有“以前的兄弟”CSS选择器?

时间:2009-11-30 04:06:37

标签: css css-selectors

加号(+)适用于下一个兄弟。是否有以前兄弟姐妹的等价物?

15 个答案:

答案 0 :(得分:742)

不,没有“上一个兄弟”选择器。

在相关的注释中,~用于一般继承兄弟(意思是元素在此之后,但不一定紧接在之后)并且是CSS3选择器。 +用于下一个兄弟,是CSS2.1。

请参阅Adjacent sibling combinator中的Selectors Level 35.7 Adjacent sibling selectors中的Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification

答案 1 :(得分:201)

我找到了一种方法来塑造所有以前的兄弟姐妹(~的对面),这可能会根据你的需要而有效。

我们假设您有一个链接列表,当悬停在一个链接上时,所有以前的链接都应该变为红色。你可以这样做:



/* default link color is blue */
.parent a {
  color: blue;
}

/* prev siblings should be red */
.parent:hover a {
  color: red;
}
.parent a:hover,
.parent a:hover ~ a {
  color: blue;
}

<div class="parent">
  <a href="#">link</a>
  <a href="#">link</a>
  <a href="#">link</a>
  <a href="#">link</a>
  <a href="#">link</a>
</div>
&#13;
&#13;
&#13;

答案 2 :(得分:141)

Selectors level 4 introduces :has()(以前是主题指标!),可让您选择以前的兄弟姐妹:

previous:has(+ next) {}

...但在撰写本文时,浏览器支持已超出前沿的距离。

答案 3 :(得分:126)

考虑flex和网格布局的order属性。

我将在下面的示例中关注flexbox,但相同的概念适用于Grid。

使用flexbox,可以模拟以前的兄弟选择器。

特别是,flex order属性可以在屏幕上移动元素。

以下是一个例子:

  

当元素B悬停时,您希望元素A变为红色。

<ul>
    <li>A</li>
    <li>B</li>
</ul>

STEPS

  1. ul设为弹性容器。

    ul { display: flex; }
    
    1. 反转标记中兄弟姐妹的顺序。

      <ul>
         <li>B</li>
         <li>A</li>
      </ul>
      
      1. 使用兄弟选择器定位元素A(~+将会这样做)。

        li:hover + li { background-color: red; }
        
        1. 使用flex order属性恢复可视显示中兄弟姐妹的顺序。

          li:last-child { order: -1; }
          
        2. ...瞧!之前的兄弟选择器诞生(或至少是模拟)。

          这是完整的代码:

          ul {
              display: flex;
          }
          
          li:hover + li {
              background-color: red;
          }
          
          li:last-child {
              order: -1;
          }
          
          /* non-essential decorative styles */
          li {
              height: 200px;
              width: 200px;
              background-color: aqua;
              margin: 5px;
              list-style-type: none;
              cursor: pointer;
          }
          <ul>
              <li>B</li>
              <li>A</li>
          </ul>

          来自flexbox规范:

            

          5.4. Display Order: the order property

               

          默认情况下,Flex项目的显示和排列顺序与它们在源文档中显示的顺序相同。该   order属性可用于更改此顺序。

               

          order属性通过将弹性项目分配给序列组来控制弹性项目在弹性容器中的显示顺序。它需要一个<integer>值,它指定flex项的哪个序数组   属于。

          所有弹性项目的初始order值为0.

          另见order in the CSS Grid Layout spec

          使用flex order属性创建的“以前的兄弟选择器”示例。

          .container { display: flex; }
          
          .box5 { order: 1; }    
          .box5:hover + .box4 { background-color: orangered; font-size: 1.5em; }
          
          .box6 { order: -4; }
          .box7 { order: -3; }
          .box8 { order: -2; }
          .box9 { order: -1; }
          .box9:hover ~ :not(.box12):nth-child(-1n+5) { background-color: orangered;
                                                        font-size: 1.5em; }
          .box12 { order: 2; }
          .box12:hover ~ :nth-last-child(-1n+2) { background-color: orangered;
                                                  font-size: 1.5em; }
          .box21 { order: 1; }
          .box21:hover ~ .box { background-color: orangered; font-size: 1.5em; }
          
          /* non-essential decorative styles */
          .container {
              padding: 5px;
              background-color: #888;
          }
          .box {
              height: 50px;
              width: 75px;
              margin: 5px;
              background-color: lightgreen;
              display: flex;
              justify-content: center;
              align-items: center;
              text-align: center;
              cursor: pointer;
          }
          <p>
          Using the flex <code>order</code> property to construct a previous sibling selector
          </p>
          
          <div class="container">
              <div class="box box1"><span>1</span></div>
              <div class="box box2"><span>2</span></div>
              <div class="box box3"><span>3</span></div>
              <div class="box box5"><span>HOVER ME</span></div>
              <div class="box box4"><span>4</span></div>
          </div>
          
          <br>
          
          <div class="container">
              <div class="box box9"><span>HOVER ME</span></div>
              <div class="box box12"><span>HOVER ME</span></div>
              <div class="box box6"><span>6</span></div>
              <div class="box box7"><span>7</span></div>
              <div class="box box8"><span>8</span></div>
              <div class="box box10"><span>10</span></div>
              <div class="box box11"><span>11</span></div>
          </div>
          
          <br>
          
          <div class="container">
              <div class="box box21"><span>HOVER ME</span></div>
              <div class="box box13"><span>13</span></div>
              <div class="box box14"><span>14</span></div>
              <div class="box box15"><span>15</span></div>
              <div class="box box16"><span>16</span></div>
              <div class="box box17"><span>17</span></div>
              <div class="box box18"><span>18</span></div>
              <div class="box box19"><span>19</span></div>
              <div class="box box20"><span>20</span></div>
          </div>

          jsFiddle

          附注 - 关于CSS的两个过时信念

          Flexbox打破了人们对CSS的长期信念。

          一个这样的信念是a previous sibling selector is not possible in CSS

          说这种观点是普遍的,这是轻描淡写的。以下是Stack Overflow的相关问题示例:

          如上所述,这种看法并不完全正确。可以使用flex order属性在CSS中模拟先前的兄弟选择器。

          z-index神话

          另一个长期存在的信念是z-index仅适用于定位元素。

          事实上,该规范的最新版本 - W3C Editor's Draft - 仍然断言这是真的:

            

          9.9.1 Specifying the stack level: the z-index property

               

          <强> z-index

               
              
          • 价值:自动| |继承
          •   
          • 初始:自动
          •   
          • 适用于:定位元素
          •   
          • 继承:否
          •   
          • 百分比:N / A
          •   
          • 媒体:视觉
          •   
          • 计算值:指定
          •   
               

          (强调添加)

          但实际上,这些信息已经过时且不准确。

          即使positionstaticflex itemsgrid items元素也可以创建堆叠上下文。

            

          4.3. Flex Item Z-Ordering

               

          Flex项目绘制与内联块完全相同,除了使用订单修改的文档顺序代替raw   文档顺序以及z-index以外的auto值即使positionstatic也会创建堆叠上下文。

               

          5.4. Z-axis Ordering: the z-index property

               

          网格项的绘制顺序与内联块完全相同,但订单修改的文档顺序除外   用于代替原始文档订单,z-index以外的auto值创建堆叠上下文,即使   positionstatic

          以下是z-index处理非定位弹性项目的演示:https://jsfiddle.net/m0wddwxs/

答案 4 :(得分:24)

两个技巧。基本上反转HTML中所需元素的HTML顺序并使用
~ 下一个兄弟运营商:

float-right + 与HTML元素的顺序相反

div{ /* Do with the parent whatever you know just to make the
  inner float-right elements appear where desired */
  display:inline-block;
}
span{
  float:right;  /* float-right the elements! */
}
span:hover ~ span{ /* On hover target it's "previous";) elements */
  background:red;
} 
<div>
  <!-- Reverse the order of inner elements -->
  <span>5</span>
  <span>4</span>
  <span>3</span>
  <span>2</span>
  <span>1</span>
</div>

direction: rtl; +与内元素的顺序相反

.inverse{
  direction: rtl;
  display: inline-block; /* inline-block to keep parent at the left of window */
}
span:hover ~ span{ /* On hover target it's "previous";) elements */
  background:gold;
}
Hover one span and see the previous elements being targeted!<br>

<div class="inverse">
  <!-- Reverse the order of inner elements -->
  <span>5</span>
  <span>4</span>
  <span>3</span>
  <span>2</span>
  <span>1</span>
</div>

答案 5 :(得分:17)

  

+适用于下一个兄弟姐妹。有没有与前一个相同的   同级?

您可以使用两个 ax 选择器:!?

传统CSS中有 2 后续兄弟选择器

  • +直接后续兄弟选择器
  • ~任何后续兄弟选择器

在传统的CSS中,没有先前的兄弟选择器

但是,在 ax CSS后处理器库中,有 2 以前的兄弟选择器:< / p>

  • ?直接上一个兄弟选择器(与+相对)
  • !任何上一个兄弟选择器(与~相对)

工作示例:

在下面的例子中:

  • .any-subsequent:hover ~ div选择后续div
  • .immediate-subsequent:hover + div选择后续的div
  • .any-previous:hover ! div选择之前的任何div
  • .immediate-previous:hover ? div选择之前的div

div {
  display: inline-block;
  width: 60px;
  height: 100px;
  color: rgb(255, 255, 255);
  background-color: rgb(255, 0, 0);
  text-align: center;
  vertical-align: top;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.6s ease-out;
}

code {
  display: block;
  margin: 4px;
  font-size: 24px;
  line-height: 24px;
  background-color: rgba(0, 0, 0, 0.5);
}

div:nth-of-type(-n+4) {
  background-color: rgb(0, 0, 255);
}

div:nth-of-type(n+3):nth-of-type(-n+6) {
  opacity: 1;
}

.any-subsequent:hover ~ div,
.immediate-subsequent:hover + div,
.any-previous:hover ! div,
.immediate-previous:hover ? div {
  opacity: 1;
}
<h2>Hover over any of the blocks below</h2>

<div></div>
<div></div>

<div class="immediate-previous">Hover for <code>?</code> selector</div>
<div class="any-previous">Hover for <code>!</code> selector</div>
<div class="any-subsequent">Hover for <code>~</code> selector</div>
<div class="immediate-subsequent">Hover for <code>+</code> selector</div>

<div></div>
<div></div>

<script src="https://rouninmedia.github.io/axe/axe.js"></script>

答案 6 :(得分:15)

另一个flexbox解决方案

您可以使用HTML中的元素顺序。然后,除了在Michael_B's answer中使用order之外,您还可以使用flex-direction: row-reverse;flex-direction: column-reverse;,具体取决于您的布局。

工作样本:

&#13;
&#13;
.flex {
  display: flex;
  flex-direction: row-reverse;
   /* Align content at the "reversed" end i.e. beginning */
  justify-content: flex-end;
}

/* On hover target its "previous" elements */
.flex-item:hover ~ .flex-item {
  background-color: lime;
}

/* styles just for demo */
.flex-item {
  background-color: orange;
  color: white;
  padding: 20px;
  font-size: 3rem;
  border-radius: 50%;
}
&#13;
<div class="flex">
  <div class="flex-item">5</div>
  <div class="flex-item">4</div>
  <div class="flex-item">3</div>
  <div class="flex-item">2</div>
  <div class="flex-item">1</div>
</div>
&#13;
&#13;
&#13;

答案 7 :(得分:14)

目前没有正式的方法可以做到这一点,但你可以用一个小技巧来实现这一目标!请记住它是实验性的,它有一些限制...... (如果您担心导航器兼容性,请查看this link

你可以做的是使用CSS3选择器:名为nth-child()

的伪classe

&#13;
&#13;
#list>* {
  display: inline-block;
  padding: 20px 28px;
  margin-right: 5px;
  border: 1px solid #bbb;
  background: #ddd;
  color: #444;
  margin: 0.4em 0;
}

#list :nth-child(-n+4) {
  color: #600b90;
  border: 1px dashed red;
  background: orange;
}
&#13;
<p>The oranges elements are the previous sibling li selected using li:nth-child(-n+4)</p>

<div id="list">
  <span>1</span><!-- this will be selected -->
  <p>2</p><!-- this will be selected -->
  <p>3</p><!-- this will be selected -->
  <div>4</div><!-- this will be selected -->
  <div>5</div>
  <p>6</p>
  <p>7</p>
  <p>8</p>
  <p>9</p>
</div>
&#13;
&#13;
&#13;

限制

  • 您无法根据下一个元素的类
  • 选择以前的元素
  • 伪类
  • 也是如此

答案 8 :(得分:4)

如果你知道确切的位置,那么基于:nth-child()的所有兄弟姐妹的排除都会有效。

ul li:not(:nth-child(n+3))

哪个会在第3个之前选择所有li(例如第1个和第2个)。但是,在我看来,这看起来很丑陋并且使用非常紧张。

你也可以从右到左选择第n个孩子:

ul li:nth-child(-n+2)

其中也是如此。

答案 9 :(得分:2)

遗憾的是,没有“上一个”同级选择器,但是可能仍然可以通过使用定位(例如,向右浮动)获得相同的效果。这取决于你想要做什么。

在我的情况下,我想要一个主要的CSS 5星评级系统。我需要为之前的星星着色(或交换图标)。通过将每个元素向右浮动,我基本上可以获得相同的效果(星星的html因此必须写成'向后')。

我在这个例子中使用FontAwesome并在fa-star-o和fa-star的unicodes之间交换 http://fortawesome.github.io/Font-Awesome/

CSS:

.fa {
    display: inline-block;
    font-family: FontAwesome;
    font-style: normal;
    font-weight: normal;
    line-height: 1;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* set all stars to 'empty star' */
.stars-container {
    display: inline-block;      
}   

/* set all stars to 'empty star' */
.stars-container .star {
    float: right;
    display: inline-block;
    padding: 2px;
    color: orange;
    cursor: pointer;

}

.stars-container .star:before {
    content: "\f006"; /* fontAwesome empty star code */
}

/* set hovered star to 'filled star' */
.star:hover:before{
    content: "\f005"; /* fontAwesome filled star code */
}

/* set all stars after hovered to'filled star' 
** it will appear that it selects all after due to positioning */
.star:hover ~ .star:before {
    content: "\f005"; /* fontAwesome filled star code */
}

HTML:                                                                                                      (40)     

JSFiddle:http://jsfiddle.net/andrewleyva/88j0105g/

答案 10 :(得分:1)

根据您的确切目标,有一种方法可以在不使用父选择器的情况下实现父选择器的有用性(即使存在一个)...

说我们有:

<div>
  <ul>
    <li><a>Pants</a></li>
    <li><a>Socks</a></li>
    <ul>
      <li><a>White socks</a></li>
      <li><a>Blue socks</a></li>
    </ul>
  </ul>
</div>

我们可以做些什么来使Socks块(包括袜子颜色)在视觉上使用间距突出?

什么会好但不存在:

ul li ul:parent {
  margin-top: 15px;
  margin-bottom: 15px;
}

存在什么:

li > a {
  margin-top: 15px;
  display: block;
}
li > a:only-child {
  margin-top: 0px;
}

这将设置所有锚链接在顶部具有15px的边距,并将其重置为0,以用于LI内没有UL元素(或其他标记)的那些。

答案 11 :(得分:1)

我遇到了类似的问题,发现所有这种性质的问题都可以解决如下:

  1. 为您的所有物品添加风格。
  2. 为您选择的项目添加样式。
  3. 使用+或〜。
  4. 为下一个项目添加样式

    通过这种方式,您可以设置当前,之前的项目(所有被当前和下一项覆盖的项目)和下一项目的样式。

    示例:

    /* all items (will be styled as previous) */
    li {
      color: blue;
    }
    
    /* the item i want to distinguish */
    li.milk {
      color: red;
    }
    
    /* next items */
    li ~ li  {
      color: green;
    }
    
    
    <ul>
      <li>Tea</li>
      <li class="milk">Milk</li>
      <li>Juice</li>
      <li>others</li>
    </ul>
    

    希望它有所帮助。

答案 12 :(得分:0)

不。无法通过CSS。它深深地吸引了“级联”;-)。


但是,如果您能够在页面中添加 JavaScript ,那么一些 jQuery 可以使您达到最终目标。
您可以使用jQuery的find对目标元素/类/ id执行“前瞻”,然后回溯以选择目标。
然后,您使用jQuery重新编写元素的DOM(CSS)。

基于this answer by Mike Brant, 以下jQuery代码段可能会有所帮助。

$('p + ul').prev('p')

此操作首先选择紧随<ul>之后的所有<p>
然后,它“回溯”以从该组<p>中选择所有先前的<ul>

实际上,已通过jQuery选择了“上一个兄弟”。
现在,使用.css函数为该元素传递CSS新值。


在我的情况下,我正在寻找一种选择ID为#full-width的DIV的方法,但是仅当它具有一个.companies类的(间接)后代DIV时。

我可以控制.companies下的所有HTML,但是无法更改其上方的任何HTML。
而且级联仅向1个方向:向下。

因此,我可以选择所有#full-width个。
或者,我可以选择仅跟随.companies的{​​{1}}。
但是我不能不能只选择进行 #full-width的{​​{1}}。

同样,我无法在HTML的更高处添加#full-width。 HTML的那部分是外部编写的,并包装了我们的代码。

但是使用jQuery,我可以选择所需的.companies,然后分配适当的样式:

.companies

这将找到所有#full-width,并仅选择$("#full-width").find(".companies").parents("#full-width").css( "width", "300px" ); ,这与使用选择器定位CSS标准中的特定元素的方式类似。
然后,它使用#full-width .companies进行“回溯”并选择.companies的所有父级,
但过滤这些结果以仅保留.parents个元素,以便最后,
只有具有.companies类后代的元素,它才会选择#fill-width元素。
最后,它将为结果元素分配一个新的CSS(#full-width)值。

.companies
width
$(".parent").find(".change-parent").parents(".parent").css( "background-color", "darkred");

jQuery参考文档:
$() or jQuery():DOM元素。
.find:获取当前匹配元素集中每个元素的后代,并通过选择器,jQuery对象或元素进行过滤。
.parents:获取匹配元素集中每个元素的前一个同级。如果提供了选择器,则仅当与该选择器匹配时才检索前一个同级(将结果筛选为仅包括列出的元素/选择器)。
.css:为匹配的元素集设置一个或多个CSS属性。

答案 13 :(得分:0)

我需要一个解决方案来选择之前的同级tr。我使用React和Styled-components提出了这个解决方案。这不是我的确切解决方案(这是几个小时后从内存中获取的)。我知道setHighlighterRow函数存在缺陷。

OnMouseOver行将把行索引设置为state,并用新的背景色重新呈现上一行

  props: {
    propsTitle: String, 
    propsLevel: Number,
    propsProgress: Number,
  },

  data() {
    console.log(this)
    return { 
      title: this.propsTitle,
      progress: this.propsProgress,
      level: this.propsLevel,
      activeBtnTxt: "Start",
      isStarted: false
    }
  },

答案 14 :(得分:0)

这是我使用jQuery所使用的

    $('.child-selector').hover( function() {
        $(this).prev().addClass('hovered');
        $(this).addClass('hovered');
        $(this).next().removeClass('hovered');
    });

这是如何获得工作代码的方法:

enter image description here

豫ICP备18024241号-1