提问



+是为了下一个兄弟姐妹。以前的兄弟姐妹是否有同等效力?

最佳参考


不,没有以前的兄弟选择器。


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


请参阅选择器级别3和5.7中的相邻同级组合子级联样式表级别2修订版1(CSS 2.1)规范。[68] [69] [70] [71]

其它参考1


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


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




/* 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>



选择器级别4引入:has()(以前是主题指示符!),这将允许您选择以前的兄弟:[72]


previous:has(+ next) {}


...但在撰写本文时,对于浏览器支持而言,这是一个超越前沿的距离。

其它参考2


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



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





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


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


这是一个例子:



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


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



脚步



  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; }
    






...瞧!之前的兄弟选择器诞生(或至少是模拟)。


这是完整的代码:




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>



我有同样的问题,但后来我有一个呃的时刻。而不是写作


x ~ y





y ~ x


显然这匹配x而不是y,但它回答有匹配吗?问题,简单的DOM遍历可以比在javascript中循环更有效地使你到达正确的元素。


我意识到最初的问题是一个CSS问题所以这个答案可能完全无关紧要,但其他Javascript用户可能会像我一样通过搜索偶然发现问题。

其它参考3


两个技巧。基本上反转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>



另一个flexbox解决方案



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


工作样本:




.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%;
}

<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>



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


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




#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;
}

<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>




  +是为了下一个兄弟姐妹。有没有与以前相同的
  兄弟?



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



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



  • +是立即后续兄弟选择器

  • ~是任何后续兄弟选择器



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


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



  • ?是立即上一个兄弟选择器(+的对面)

  • !是任何以前的兄弟选择器(~的对面)



工作示例:


在下面的示例中:



  • .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>



如果您知道确切的位置,:nth-child() - 基于所有后续兄弟姐妹的排除将起作用。


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


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


您还可以选择从右到左的第n个子:


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


哪个也一样。

其它参考4


遗憾的是,没有之前的兄弟选择器,但是你可以通过使用定位(例如,向右浮动)可能获得相同的效果。这取决于你想要做什么。


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


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


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/[76]

其它参考5


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


说我们有:


<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>


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


什么会好,但不存在:


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元素(或其他标记)的那些。

其它参考6


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



  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>


希望它可以帮到某人。

其它参考7


因为已经多次说过 - div ~ p选择了以<div>元素开头的所有<p>元素。


查看所有CSS选择器的列表。[77]