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

Is there a "previous sibling" selector?

提问人:Jourkey 提问时间:11/30/2009 最后编辑:TylerHJourkey 更新时间:5/30/2023 访问量:1088076

问:

加号选择器 () 用于选择下一个相邻的同级。+

前一个兄弟姐妹有等价物吗?

css css-selectors 同级

评论

0赞 Gabriel Linassi 1/15/2021
您不需要它,因为您可以使用常规选择器和下一个同级选择器的组合来执行所有操作。
7赞 Ben Taliadoros 5/13/2021
我不确定您是否在所有情况下都可以,即使如此 - 它很难阅读和推理,因此应该添加为方便的 imo
0赞 vishal 2/23/2022
哪个 combinator 可以用作父选择器 ?,@GabrielLinassi
0赞 Scott 3/12/2022
这可以通过以下方法实现:display: flex;flex-direction:行反转;
2赞 Indra 9/9/2022
这绝对是设计CSS选择器的人的疏忽。当你有一个下一个选择器时,有一个前一个选择器也是有意义的,即使可以通过其他方式实现同样的选择器。我希望将来能添加它。我曾多次被这个问题所困扰,不得不使用其他一些选择器组合来实现我的目标,这并不优雅。

答:

1022赞 cletus 11/30/2009 #1

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

与此相关的是,is 用于一般的后继同级(意味着元素在此之后,但不一定紧随其后),并且是 CSS3 选择器。 是下一个兄弟姐妹,是 CSS2.1。~+

请参阅选择器级别 3 中的相邻同级组合器和级联样式表级别 2 修订版 1 (CSS 2.1) 规范中的相邻同级组合器

评论

20赞 Lie Ryan 2/27/2011
来自 CSS3 标准:两个序列表示的元素在文档树中共享相同的父元素,并且第一个序列表示的元素位于(不一定立即)第二个序列表示的元素之前
33赞 BoltClock 3/30/2011
@Lie Ryan:是的,但 Cletus 在他的回答中指出,你没有选择前面的元素。
57赞 Abacus 7/18/2013
这是我举的一个例子,看看它能做什么,不能做什么。 jsfiddle.net/NuuHy/1
11赞 Satbir Kira 5/19/2015
对此有用的jquery函数是prev()。例如:$(“#the_element”).prev().css(“background-color”, “red”)
0赞 The Myth 10/28/2022
有不同的方法可以选择前一个,通过简单的 vanilla js
79赞 Bryan Larsen 12/1/2011 #2

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

x ~ y

y ~ x

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

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

评论

22赞 David 2/13/2013
我相信当 y 很容易找到时,它会起作用。问题是,如果 y 只能相对于 x 找到,并且在反转它时,你找不到 y,因为你必须先找到 x。这当然是指 y 是前一个兄弟姐妹而不是下一个兄弟姐妹的问题,但也可能适用于 y 是下一个兄弟姐妹的问题。
19赞 Bryan Larsen 3/13/2013
你有点苛刻,苛刻。(对不起,无法抗拒。关键是,有时你只需要知道“y存在吗?其他时候,您可以使用“:before”在两个元素之间放置一些东西。最后,如果您必须进入 jQuery,使用 find(“y ~ x”).prev() 比许多替代方案更容易。
185赞 Zenexer 7/31/2013
前一个同级选择器的想法是它将选择前一个元素。遗憾的是,如此处所述,反转它并不提供此功能。
17赞 Jaime Hablutzel 4/24/2014
感谢@Zenexer澄清这个答案并没有为原始问题提供实际的解决方案,我开始觉得自己愚蠢地思考如何解决我的问题y ~ x
6赞 BoltClock 10/27/2015
我理解这个答案背后的想法,但是答案中给出的推理不太有意义。选择器没有回答“有匹配吗?”的问题,因为这里给出的两个选择器的含义完全不同。例如,在给定子树的情况下,没有办法产生匹配。如果问题是“y 存在吗?”,那么选择器就是 。如果问题是“给定任何任意位置的同级 x ,y 是否存在?”那么您将需要两个选择器。(虽然也许我现在只是在吹毛求疵......y ~ xy ~ x<root><x/><y/></root>y
367赞 Quentin 3/19/2013 #3

选择器级别 4 提出了 :has(),它允许您选择具有以下功能的上一个同级:

previous:has(+ next) {}

或(对于一般的先前兄弟姐妹而不是相邻的兄弟姐妹):

previous:has(~ next) {}

它具有出色的浏览器支持

评论

9赞 Waruyama 12/16/2022
要跟踪 FIrefox 的状态,请在 Bugzilla 上关注此问题: bugzilla.mozilla.org/show_bug.cgi?id=418039has()
3赞 DynamicDan 2/8/2014 #4

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

假设我们有:

<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 元素(或其他标签)的链接。

评论

0赞 Benjamin Carlsson 10/26/2023
这并不能回答这个问题。
3赞 Andrew Leyva 8/13/2014 #5

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

就我而言,我想要一个主要的 CSS 5 星评级系统。我需要给以前的星星着色(或交换图标)。通过向右浮动每个元素,我基本上得到了相同的效果(因此星星的 html 必须“向后”编写)。

我在此示例中使用 FontAwesome 并在 fa-star-o 和 fa-star 的 unicode 之间切换 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/

评论

1赞 Wylliam Judd 11/2/2017
向右浮动和/或选择器让我印象深刻,这是最干净的解决方法。+~
6赞 kernel 8/29/2014 #6

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

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

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

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

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

这做同样的事情。

19赞 0x1gene 9/4/2014 #7

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

你可以做的是使用一个CSS3选择器:伪类称为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>

局限性

  • 不能根据下一个元素的类选择上一个元素
  • 这对于伪类也是一样的

评论

0赞 Ian 10/28/2014
为什么它们必须是同一个节点?为什么不直接使用?:nth-child(-n+4)
1赞 0x1gene 10/28/2014
@Ian因为 是一个伪类,需要应用于选择器才能正常工作。如果你不相信,试着用我的小提琴叉子来试验它,你会发现它没有炒锅:nth-child(-n+4)
1赞 Josh Burgess 1/14/2015
实际上,您可以使用选择器独立于节点类型,但这是令人讨厌的糟糕做法。*
1赞 Jamie Barker 6/1/2015
实际上,它确实适用于不同的节点:jsfiddle.net/aLhv9r1w/316。请更新您的答案:)
2赞 bitoolean 7/11/2019
我有一个复杂的选择器,但假设它是,我希望节点就在它之前(这就是我解释“以前”的方式)——我不明白你提供的信息如何帮助我通过 CSS 表达它。你只是选择了前 n 个兄弟姐妹,并假设我知道 n。基于这个逻辑,任何选择器都可以解决问题并选择我需要的元素(例如:not() )。li#someListItem
350赞 mantish 1/17/2015 #8

我找到了一种方法来设计所有以前的兄弟姐妹(与 相反),这可能适用于您的需要。~

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

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

评论

25赞 A.L 4/25/2015
您可以添加其工作原理的说明。(似乎您将样式应用于所有项目和以下项目,但它可以明确描述)
17赞 azerafati 5/1/2016
是的,但大多数时候需要一个前一个,而不是所有以前的!
73赞 Lynn 8/1/2016
对我来说,如果将鼠标悬停在它们之间的空间上,链接都会变成红色。
0赞 Joe Van Leeuwen 11/11/2021
由于样式的原因,将鼠标悬停在父标签上时,所有标签都会变为红色,但同时不会将鼠标悬停在任何子标签上。.parent:hover a
0赞 mantish 11/12/2021
@Lynn @JoeVanLeeuwen,此示例仅包含针对以前同级的最小规则量。要删除间距,您需要添加更多规则,可能会更改竞争者的规则display
35赞 Roko C. Buljan 8/19/2015 #9

三个技巧
基本上,在 HTML 中颠倒元素的 HTML 顺序
并使用 Next siblings 运算符:
~

1.使用 CSS Flex 和行反转

.reverse {
  display: inline-flex;
  flex-direction: row-reverse;
}
.reverse span:hover ~ span { /* On SPAN hover target its "previous" elements */
  background:gold;
}
Hover a SPAN and see the previous elements being styled!<br>

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

2. 使用带有方向的 Flex:RTL

.reverse {
  display: inline-flex;
  direction: rtl;
}
.reverse span:hover ~ span { /* On SPAN hover target its "previous" elements */
  background: red;
}
Hover a SPAN and see the previous elements being styled!<br>

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

3.使用浮点权

.reverse { 
  display: inline-block;
}
.reverse span{
  float: right; 
}
.reverse span:hover ~ span { /* On SPAN hover target its "previous" elements */
  background: red;
}
Hover a SPAN and see the previous elements being styled!<br>

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

212赞 Michael Benjamin 3/21/2016 #10

考虑 flex 和 grid 布局的属性。order

在下面的示例中,我将重点介绍 flexbox,但相同的概念也适用于 Grid。


使用 flexbox,可以模拟以前的同级选择器。

具体而言,flex 属性可以在屏幕上移动元素。order

下面是一个示例:

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

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

步骤

  1. 制作 flex 容器。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>

从 flexbox 规范:

5.4. Display Order:order 属性

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

该属性通过将 flex 项分配给序号组来控制它们在 flex 容器中的显示顺序。它采用单个值,该值指定 flex 项的序号组 属于。order<integer>

所有 flex 项的初始值均为 0。order

另请参阅 CSS 网格布局规范中的顺序


使用 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 的信念。

其中一种观点是,在CSS中不可能有以前的同级选择器

如果说这种信念很普遍,那就太轻描淡写了。以下是仅针对 Stack Overflow 的相关问题的示例:

如上所述,这种信念并不完全正确。可以在 CSS 中使用 flex 属性模拟以前的同级选择器。order

z-index 神话

另一个由来已久的信念是,它只适用于定位元素。z-index

事实上,该规范的最新版本——W3C 编辑草案——仍然断言这是真的:

9.9.1 指定堆栈级别:z-index 属性

z-index

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

(着重号后加)

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

作为 flex 项或网格项的元素可以创建堆叠上下文,即使 是 .positionstatic

4.3. Flex 项目 Z 排序

Flex 项的绘制方式与内联块完全相同,只是使用修改顺序的文档顺序代替原始文档 文档顺序和值,而不是创建堆叠上下文,即使 是 。z-indexautopositionstatic

5.4. Z轴排序:z-index属性

网格项的绘制顺序与内联块完全相同,只是顺序修改后的文档顺序是 用于代替原始文档顺序,以及创建堆叠上下文以外的值,即使 是 .z-indexautopositionstatic

下面是处理未定位的 flex 项目的演示: https://jsfiddle.net/m0wddwxs/z-index

评论

33赞 Marat Tanalin 3/21/2016
该属性不是解决方案,因为它仅用于更改视觉顺序,因此它不会还原您在 HTML 中强制更改的原始语义顺序,以便此解决方法起作用。order
5赞 BoltClock 3/21/2016
请记住,您引用的 CSS2.2 ED 本质上仍然是 CSS2。而 CSS2 中并不存在 flexbox 和网格布局,所以就 CSS2 而言,这些信息当然是正确的。至少,文本可以更新,以提及 z-index 可能适用于未来 CSS 级别中的其他类型的元素,就像它说其他属性可以建立堆叠上下文一样,例如不透明度。
3赞 Marat Tanalin 3/21/2016
@BoltClock 我的评论与浏览器支持无关。该技术打破了语义,有利于呈现。我相信在服务器端将普通的常规类添加到前一个兄弟姐妹元素中要合理得多。
3赞 Rogier Spieker 4/29/2016
如果有人难以理解何时会起作用,即使“天哪,没有指定!”,规范中提到了堆叠上下文的概念,这篇关于 MDN 的文章很好地解释了这一点z-indexposition
3赞 Rogier Spieker 4/29/2016
@Michael_B不客气!我和很多前端打过交道,却没有意识到这一点。我想提的另一件事是,以前的仿同级选择器也可以很好地配合(或任何其他反转排序的方法,其副作用很小(最少?))。鞭打两把小提琴:演示浮动:正确的方法以及演示方向:RTLfloat: rightflex/order
21赞 Vadim Ovchinnikov 1/15/2017 #11

另一个 flexbox 解决方案

您可以在 HTML 中使用相反的元素顺序。然后,除了使用 as in Michael_B 的答案之外,您还可以使用或取决于您的布局。orderflex-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>

34赞 Rounin 4/25/2017 #12

+是给下一个兄弟姐妹的。是否有前一个的等价物 兄弟?

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

在传统的 CSS 中,有 2后续的同级选择器

  • +紧随其后的同级选择器
  • ~任何后续的同级选择器

在传统的 CSS 中,没有以前的同级选择器

但是,在 axe 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>

评论

5赞 alex 9/6/2017
当我尝试在 rails 项目中的 sass 上实现它时,这给了我一个语法错误。
36赞 Rounin 9/6/2017
axe 是一个 CSS 后处理器。它不使用与 CSS 预处理器(如 Sass、Less 或 Stylus)相同的语法。
2赞 Dionys 5/27/2020
@Rounin介意添加一些文档链接吗?我找不到斧头后处理器。
1赞 Rounin 5/27/2020
@Dionys - 感谢您的关注。axe 是我在 2016 年底开始的一个项目,当时我还不知道 ES2015,甚至 JS 中的对象对我来说都是非常新的。GitHub 存储库位于此处:github.com/RouninMedia/axe 。我非常想在某个时候回到这个(我还开发了一种叫做 axe-blades 的东西,它相当于 javascript 事件的 CSS),但我需要先完成我在另一个项目(代号为 ashiva)上的工作。
1赞 Hejar 2/24/2018 #13

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

  1. 为您的所有物品赋予风格。
  2. 为所选项目指定样式。
  3. 使用 + 或 ~ 为下一个项目指定样式。

这样,您将能够设置当前、上一个项目(所有项目被当前和下一个项目覆盖)和下一个项目的样式。

例:

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

希望它对某人有所帮助。

评论

2赞 quetzalcoatl 9/16/2019
这与来自同一线程的旧答案中的技巧基本相同:stackoverflow.com/a/27993987/717732
1赞 Teepeemm 10/2/2020
但是这个费心解释它在做什么,不像另一个。
0赞 Bobort 6/4/2022
@Teepeemm,我同意。我看到了那个答案,我跳过了它,因为没有很好的解释。只是“看看我做了什么,然后复制我!
6赞 SherylHohman 5/9/2019 #14

不。这是不可能的,通过CSS。它把“级联”放在心上;-)。


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

根据迈克·布兰特(Mike Brant)的回答, 以下jQuery代码片段可能会有所帮助。

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

这首先选择紧跟在 .
然后它“回溯”从该组 s 中选择所有先前的 s。
<ul><p><p><ul>

实际上,“以前的兄弟姐妹”是通过jQuery选择的。
现在,使用该函数传入该元素的 CSS 新值。
.css


就我而言,我正在寻找一种方法来选择具有 id 的 DIV,但前提是它有一个类为 的(间接)后代 DIV。#full-width.companies

我可以控制下面的所有 HTML,但无法更改它上面的任何 HTML。
级联只有一个方向:向下。
.companies

因此,我可以选择 ALL s,
或者我可以选择只跟在 .
但是我不能只选择继续进行的 s .
#full-width.companies#full-width#full-width.companies

而且,再一次,我无法在 HTML 中添加任何更高的内容。HTML的那部分是外部编写的,并包装了我们的代码。.companies

但是使用 jQuery,我可以选择所需的 s,然后分配适当的样式:#full-width

$("#full-width").find(".companies").parents("#full-width").css( "width", "300px" );

这将找到所有 ,并只选择那些 ,类似于在 CSS 中使用选择器来定位标准中的特定元素的方式。
然后,它使用“回溯”并选择 的所有父元素,但过滤这些结果以仅保留元素,
因此最终,
它只选择具有类后代的元素。
最后,它将一个新的 CSS() 值分配给生成的元素。
#full-width .companies.companies.parents.companies#fill-width#full-width.companieswidth

$(".parent").find(".change-parent").parents(".parent").css( "background-color", "darkred");
div {
  background-color: lightblue;
  width: 120px;
  height: 40px;
  border: 1px solid gray;
  padding: 5px;
}
.wrapper {
  background-color: blue;
  width: 250px;
  height: 165px;
}
.parent {
  background-color: green;
  width: 200px;
  height: 70px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<div class="wrapper">

  <div class="parent">
    "parent" turns red
    <div class="change-parent">
    descendant: "change-parent"
    </div>
  </div>
  
  <div class="parent">
    "parent" stays green
    <div class="nope">
    descendant: "nope"
    </div>
  </div>
  
</div>
Target <b>"<span style="color:darkgreen">parent</span>"</b> to turn <span style="color:red">red</span>.<br>
<b>Only</b> if it <b>has</b> a descendant of "change-parent".<br>
<br>
(reverse cascade, look ahead, parent un-descendant)
</html>

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

评论

0赞 Fabian von Ellerts 7/11/2019
这与问题无关。当然,可以使用JS,你甚至不需要jQuery()。previousElementSibling
1赞 SherylHohman 7/11/2019
@FabianvonEllerts 我直接在回复的第一行回答了 OP 的问题。正如我的回答所说,通过CSS实际上是不可能的。然后,我提供了 1可能的前进路径来实现目标,使用一种技术 (JS |JQuery),CSS 用户可能熟悉并有权访问。例如,许多 WordPress 网站也有 JQuery,因此它是一个简单的切入点:易于使用、记忆和扩展。简单地回答“否”,而不提供实现目标的替代方法是不负责任的。当我遇到同样的问题时,我分享了我学到和使用的东西。
0赞 SherylHohman 7/11/2019
previousElementSibling() 对于那些更熟悉原生 JS DOM 函数的人来说,可以提供另一条非 CSS 前进的路径。
0赞 SherylHohman 7/11/2019
我发现其他 CSS HACKS 非常有趣,但对于我的特定用例,它们要么不起作用(属于警告类别),要么太复杂了。对于陷入相同情况的其他人,在上述解决方案失败或难以实施/维护的情况下,分享这种易于使用的方法是公平的。许多 CSS HACKS 被共享。未涵盖此解决方法。没有一个答案使用 OP 特别要求的(不存在的)选择器。将这个答案视为 JS 的“黑客”。这是为了节省我花在寻找解决方案上的其他人的时间。+
1赞 ruffin 6/19/2020
"它把“Cascade”放在心上;-)”。说得好。你可能已经停在那里了。;^D
2赞 kyle 6/10/2019 #15

我需要一个解决方案来选择以前的兄弟姐妹 tr。我使用 React 和 Styled 组件提出了这个解决方案。这不是我的确切解决方案(这是几个小时后的记忆)。我知道setHighlighterRow函数存在缺陷。

OnMouseOver 一行会将行索引设置为状态,并使用新的背景颜色重新呈现上一行

class ReactClass extends Component {
  constructor() {
    this.state = {
       highlightRowIndex: null
    }
  }

  setHighlightedRow = (index) => {
    const highlightRowIndex = index === null ? null : index - 1;
    this.setState({highlightRowIndex});
  }

  render() {
    return (
       <Table>
        <Tbody>
           {arr.map((row, index) => {
                const isHighlighted = index === this.state.highlightRowIndex
                return {
                    <Trow 
                        isHighlighted={isHighlighted}
                        onMouseOver={() => this.setHighlightedRow(index)}
                        onMouseOut={() => this.setHighlightedRow(null)}
                        >
                        ...
                    </Trow>
                }
           })}  
        </Tbody>   
       </Table>
    )
  }
}

const Trow = styled.tr`
    & td {
        background-color: ${p => p.isHighlighted ? 'red' : 'white'};
    }

    &:hover {
        background-color: red;
    }
`;
3赞 Ron16 6/6/2020 #16

没有,而且

如果必须将标签放在输入之前,只需将标签放在输入之后,并将标签 输入都保留在 div 中,并按如下方式设置 div 的样式:

.input-box {
  display: flex;
  flex-direction: column-reverse;
}
<div class="input-box">
  <input
   id="email"
   class="form-item"           
   />

   <label for="email" class="form-item-header">                  
   E-Mail*                  
   </label>
</div>

现在,您可以应用 css 中可用的标准下一个同级样式选项,它看起来就像您正在使用以前的同级样式一样。

1赞 Jackal 9/18/2020 #17

这是类似问题的链接

CSS 选择所有以前的兄弟姐妹进行星级评定

因此,我使用每个人的回复来发布我的解决方案,任何人都可以将其用作参考,并可能提出改进建议。

// Just to check input value
// Consts
const starRadios = document.querySelectorAll('input[name="rating"]');

// EventListeners
starRadios.forEach((radio) => radio.addEventListener('change', getStarRadioValue));

// Get star radio value
function getStarRadioValue(event) { 
    alert(event.target.value) 
    // Do something with it
};
.star-rating {
  font-size: 1.5rem;
  unicode-bidi: bidi-override;
  direction: rtl;
  text-align: left;
}
.star-rating.editable label:hover {
  cursor: pointer;
}
.star-rating.editable .icon-star:hover,
.star-rating.editable .icon-star:hover ~ .icon-star {
  background-color: #fb2727 !important;
}

.icon-star {
  position: relative;
  background-color: #72747d;
  width: 32px;
  height: 32px;
  display: inline-block;
  transition: background-color 0.3s ease;
}
.icon-star.filled {
  background-color: #fb2727;
}

.icon-star > label {
  display: inline-block;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  position: absolute;
}

.icon-star > label > input[type="radio"] {
  position: absolute;
  top: 0;
  left: 0;
  transform: translateY(50%) translateX(50%);
  display: none;
}
<div class="star-rating editable">
  <span class="icon-star">
    <label>
      <input type="radio" name="rating"  value="5" />
    </label>
  </span>
  <span class="icon-star">
    <label>
      <input type="radio" name="rating" value="4" />
    </label>
  </span>
  <span class="icon-star">
    <label>
      <input type="radio" name="rating" value="3" />
    </label>
  </span>
  <span class="icon-star">
    <label>
      <input type="radio" name="rating" value="2" />
    </label>
  </span>
  <span class="icon-star">
    <label>
      <input type="radio" name="rating"  value="1" />
    </label>
  </span>
</div>

7赞 meghahere 10/12/2020 #18

在悬停时覆盖下一个同级的样式,这样看起来只有前一个同级在悬停时添加了样式。

ul li {
  color: red;
}

ul:hover li {
  color: blue;
}

ul:hover li:hover ~ li{
  color: red;
}
<ul>
    <li>item 1</li>
    <li>item 2</li>
    <li>item 3</li>
</ul>

4赞 R-D 12/3/2020 #19

/* Add a style to all the children, then undo the style to the target 
and sibling children of your target. */

ul>li {
  color: red;
}

ul>li.target,
ul>li.target~li {
  color: inherit;
}
<ul>
  <li>before</li>
  <li class="target">target</li>
  <li>after</li>
  <li>after</li>
</ul>

评论

0赞 Jasmine Hegman 12/11/2020
我认为 stackoverflow.com/a/48952456/1347604 方法在某种程度上是相同的,但是这种方法将继承用于其他元素,这可能有助于将重点放在问题的字面上,即对前一个兄弟姐妹的等价性要求
-1赞 user7153178 1/14/2021 #20

我遇到了同样的问题,当我尝试更改输入焦点上的前置图标填充颜色时,我的代码看起来像这样:

<template #append>
    <b-input-group-text><strong class="text-danger">!</strong></b-input-group-text>
</template>
<b-form-input id="password_confirmation" v-model="form.password_confirmation" type="password" placeholder="Repeat password" autocomplete="new-password" />

问题是我使用 vue-bootstrap 插槽来注入前置,所以即使我更改了位置,仍然会在输入后呈现

好吧,我的解决方案是滑动它们的位置,并添加自定义前缀和使用的~符号,因为css不支持以前的兄弟姐妹。

<div class="form-input-prepend">
    <svg-vue icon="common.lock" />
</div>
<b-form-input id="password_confirmation" v-model="form.password_confirmation" type="password" placeholder="Repeat password" autocomplete="new-password" />

Scss 风格

.form-control:focus ~ .form-input-prepend {
    svg path {
        fill: $accent;
    }
}

因此,只需尝试更改其位置,并在必要时使用css orderposition: absolute;来实现您想要的,并避免使用javascript来满足这种需求。

12赞 Carel 2/3/2021 #21

您可以使用双重否定

SELECTOR:not([SELECTOR]FILTER):not([SELECTOR]FILTER + SELECTOR) { ... }

替换为 or ( 使用可能太具体了 )。 替换为其他一些(我只尝试过)或(更多用于切换 Javascript)。SELECTORTAG.CLASS#IDFILTER:PSUEDO-SELECTOR:hover.CLASS

由于典型的用法可能依赖于悬停(请参阅以下示例)

/* Effect only limited when hovering */
TAG.CLASS:not(TAG.CLASS:hover):not(TAG.CLASS:hover + TAG.CLASS) {}
/* Effect only applied when hovering */
PARENT.CLASS:hover > CHILD.CLASS:not(CHILD.CLASS:hover):not(CHILD.CLASS:hover + CHILD.CLASS) {}

/* Solution */
div.parent:hover > div.child:not(:hover):not(:hover ~ .child)  {
    background-color:red;
    border-radius:1.5em;
}
div.parent:hover > div.child:not(:hover):not(:hover ~ .child) > div {
    background-color:yellow;
}

/* Make pretty (kinda) */
div.parent {
  width:9em;
  height:9em;
  /* Layout */
  display:grid;
  grid-template-columns : auto auto auto;
  grid-template-rows : auto auto auto;
}
div.child {
  /* Dimensions */
  height:3em;
  width:3em;
  /* Layout */
  position:relative;
  /* Cursor */
  cursor: pointer;
  /* Presentation */
  border: 1px black solid;
  border-radius:1.5em;
}
.star {
  /* Dimensions */
  width: 2.5em;
  height: 2.5em;
  /* Placement */
  position:absolute;
  top: 50%;
  left: 50%;
  transform:translate(-50%,-50%);
  /* Geometry */
  -webkit-clip-path: polygon(
    50% 0%,
    63% 38%,
    100% 38%,
    69% 59%,
    82% 100%,
    50% 75%,
    18% 100%,
    31% 59%,
    0% 38%,
    37% 38%
  );
  clip-path: polygon(
    50% 0%,
    63% 38%,
    100% 38%,
    69% 59%,
    82% 100%,
    50% 75%,
    18% 100%,
    31% 59%,
    0% 38%,
    37% 38%
  );
  /* Presentation */
  background-color: lightgrey;
}
div.child:hover {
    /* Presentation */
    background-color:yellow;
    border-radius:1.5em;
}
div.child:hover > div.star {
    /* Presentation */
    background-color:red;
}
<div class="parent">
  <div class="child" href="#"><div class="star"></div></div>
  <div class="child" href="#"><div class="star"></div></div>
  <div class="child" href="#"><div class="star"></div></div>
  <div class="child" href="#"><div class="star"></div></div>
  <div class="child" href="#"><div class="star"></div></div>
  <div class="child" href="#"><div class="star"></div></div>
  <div class="child" href="#"><div class="star"></div></div>
  <div class="child" href="#"><div class="star"></div></div>
  <div class="child" href="#"><div class="star"></div></div>
 </div>

2赞 Dandgerson 3/26/2021 #22

没有这样的选择器,但在 DOM API 中有一个漂亮的只读属性

Node.previousSibling

47赞 Victor Gorban 5/12/2021 #23

没有“上一个选择器”,但你可以使用和(“后选择器”)的组合。没有相反的顺序,没有javascript。:not~

.parent a{
  color: blue
}

.parent a.active{
  color: red
}

.parent a:not(.parent a.active ~ a){
  color: red
}
<div class="parent">
  <a href="">link</a>
  <a href="">link</a>
  <a href="" class="active">link</a>
  <a href="">link</a>
  <a href="">link</a>
</div>

我认为我的方法比“设置所有 div 的样式,而不是删除 div 之后的样式”、使用 javascript 或使用相反的顺序更直接。

评论

7赞 Oleg Valter is with Ukraine 8/6/2021
读者须注意:请注意,这不是以前的同级选择器,而是“一般的上一个同级”选择器,因为它将匹配任何匹配的元素,而不仅仅是前一个(不过,它不会从解决方案中抽离出来,这是非常有创意的)。
1赞 CubicInfinity 8/27/2021
我以前只给第二个孩子上色。.parent a:not(.parent a.active ~ a, a.active, .parent :first-child) { color: red }
0赞 Huangism 8/19/2022
这个答案就像是 mantish 在 2015 年回答的一种复杂方式
0赞 centurian 4/8/2023
适用于要显示的 div 位于选中的输入之前的 css 选项卡!!我不相信有人能为标签的相反顺序找到如此创造性的解决方案:div-input 作为正常顺序,input-div 很容易编码!!但是,关于以前的兄弟姐妹选择器的答案仍然是否定的。
4赞 Roma Kim 9/7/2021 #24

我找到了最简单的解决方案。它可能只适用于您正在执行的操作。

假设您要将鼠标悬停在“sibling_2”上以更改以下示例中的“sibling_1”:

<div class='parent'>
  <div class='sibling_1'></div>
  <div class='sibling_2'></div>
</div>

由于之前没有元素选择器,因此您可以简单地切换“sibling_1”和“sibling_2”并应用,使它们看起来相同。

.parent {
  display: flex;
  flex-direction: row-reverse;
}

现在你可以像这样选择它们。

.sibling_1:hover ~ .sibling_2 {
  #your CSS
}

2赞 tolypash 9/23/2021 #25

我通过将我的元素放在 flexbox 中然后使用 .flex-direction: column-reverse

然后我不得不手动反转 HTML 中的元素(将它们按相反的顺序放置),它看起来很正常并且有效!

<div style="display: flex; flex-direction: column-reverse">
  <a class="element2">Element 2</a>
  <a class="element1">Element 1</a>
</div>
...
<style>
  .element2:hover + element1 {
    ...
  }
</style>
0赞 Nerius Jok 10/22/2021 #26

对于我的用例,需要更改以前的元素样式,并将鼠标悬停在父元素中只有 2 个项目。为此,使用了伪类和伪类。:focus-within:hover

因此,每当焦点/悬停事件发生时进行选择

.root-element:hover .element-to-style { background-color: red;} 
.root-element:focus-within .element-to-style { background-color: green;} 
<div class="root-element">
<span class="element-to-style"> TextFocused</span>
<input type="text" placeholder="type To Style"/>

</div>

评论

0赞 mehmet 2/7/2022
这个答案对我来说是行不通的!
0赞 TylerH 3/28/2023
这并不是以前的兄弟姐妹选择情况。
7赞 Harshil Modi 9/8/2022 #27

我的要求是在@Quentin的答案的帮助下选择当前悬停项目的上一个和下一个两个兄弟姐妹,我选择了以前的兄弟姐妹。

.child{
  width: 25px;
  height: 25px;
}

.child:hover {
    background:blue;
}

 .child:has( + .child:hover) {
  background: yellow;
}

.child:has(+ .child + .child:hover){
  background:green;
}

.child:hover + .child {
  background: red;
}

.child:hover + .child + .child {
  background: magenta;
}
<ul class="parent">
  <li class="child"></li>
  <li class="child"></li>
  <li class="child"></li>
  <li class="child"></li>
  <li class="child"></li>
  <li class="child"></li>
</ul>

选择所有以前的同级

.child {
    width: 25px;
    height: 25px;
}

.child:hover {
    background: blue;
}

.child:has(~ .child:hover) {
    background: red;
}
<ul class="parent">
  <li class="child"></li>
  <li class="child"></li>
  <li class="child"></li>
  <li class="child"></li>
  <li class="child"></li>
  <li class="child"></li>
</ul>

评论

0赞 David 10/3/2022
这实际上只选择下一个上一个兄弟姐妹,而不是所有兄弟姐妹。
4赞 Bahtiyar Özdere 10/12/2022 #28

您可以按如下方式使用。:has()

.thePrevious:has(+ .theNextSibling)

我用它来修复重叠的引导模式,如下所示。如果有多个模态,则任何先前的模态都将被隐藏。

.modal.show.modal--open:has(~ .modal.show.modal--open){
   opacity: 0;
 }
-4赞 The Myth 10/28/2022 #29

虽然以前没有CSS选择器。我找到了一种快速简便的方法来自己选择一个。 下面是 HTML 标记:

<div class="parent">
    <div class="child-1"></div>
    <div class="child-2"></div>
</div>

在你的 JavaScript 中,只需执行以下操作:

document.querySelector(".child-2").parentElement.querySelector(".child-1")

这将首先选择 ,然后从 .parent divchild-1 divchild-2 div

如果您正在使用,您可以简单地执行以下操作:jQuery

$(".child-2").prev()
3赞 Hasan Ismayilov 2/20/2023 #30

实际上没有选择器可以在 css 中选择上一个同级。但是可以使用某些技巧。 例如,如果要将鼠标悬停在任何元素上时更改上一个元素的样式,可以使用以下命令:

<!DOCTYPE html>
<html lang="en">
<head>
  <style>
    .element:has(+ .next-element:hover){
      /* here your style for .element */
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="element"></div>
    <div class="next-element"></div>
  </div>
</body>
</html>

在这种情况下,如果将鼠标悬停在 .next-element 上,则 .element 的样式将按照上面的定义进行更改

0赞 ab_Dominoble_dev 4/14/2023 #31

这是我的工作解决方案,仅使用CSS作为金星(特别是在这种情况下是SCSS)

  • 我在一个容器 div 中有 5 颗最初灰色的星星
  • 在容器 div 的悬停上,我把所有的星星都变成金色
  • 将鼠标悬停在特定恒星上时,我将所有继任的兄弟姐妹 div 设置为灰色

下面是精简的代码(但可以很容易地转换为 HTML)

<button id="review">
        <div id="star-container">
          <div><Fa icon="{faStar}" /></div>
          <div><Fa icon="{faStar}" /></div>
          <div><Fa icon="{faStar}" /></div>
          <div><Fa icon="{faStar}" /></div>
          <div><Fa icon="{faStar}" /></div>
        </div>
</button>

<style lang="scss">
  #review {
    color: $cool-gray;
    #star-container {
      display: flex;
      &:hover {
        color: $custom-gold;
      }
      div {
        &:hover ~ div {
          color: $cool-gray;
        }
      }
    }
  }
</style>
-1赞 Yasin Rahnaward 4/23/2023 #32

有一个名为 has() 的新 PSUDOclass,当您想要选择已发生事件的项的第一个上一个同级时,它很有用。 吉姆·尼尔森(Jim Nielsen)的博客文章可能对您有所帮助。

在此处输入链接描述

14赞 Roman Pushkin 5/30/2023 #33

2023 年情况发生了变化。现在有这样的选择器:

    // 1 item before
    :has(+ .item:hover) {
        ...
    }

如果要之前选择 3 个项目,请执行以下操作:

    // 3 items before
    :has(+ .item:hover),
    :has(+ .item + .item:hover),
    :has(+ .item + .item + .item:hover) {
        ...
    }

请在此处查看我的演示 https://codepen.io/ro31337/pen/YzJbEZv

评论

2赞 lsblsb 8/21/2023
您还可以使用 item:has(~ item:hover) 来更改当前悬停元素之前的所有先前的同级元素。
0赞 VirtualWolf 12/20/2023
这应该是新接受的答案,是一种享受!
0赞 Thiago Telles 12/14/2023 #34

我找到了一种方法,试试这个:

.prev_item:has(+ .next_item) {
  color: red;
}

如果是兄弟姐妹,它会改变.prev_item的颜色.next_item;