Is there a “previous sibling” selector?
加号(
以前的兄弟姐妹是否有同等效力?
不,没有"以前的兄弟"选择器。
在相关的说明中,
请参阅级联样式表级别2修订版1(CSS 2.1)规范中的选择器级别3和5.7相邻同级选择器的相邻同级组合器。
我找到了一种方法来设置所有以前的兄弟姐妹(与
假设您有一个链接列表,当悬停在一个链接上时,所有以前的链接都应该变为红色。你可以这样做:
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* 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; } |
1 2 3 4 5 | link link link link link |
选择器级别4引入
1 | previous:has(+ next) {} |
...但在撰写本文时,浏览器支持已超出前沿。
考虑flex和网格布局的
我将在下面的示例中关注flexbox,但相同的概念适用于Grid。
使用flexbox,可以模拟先前的兄弟选择器。
特别是,flex
这是一个例子:
You want element A to turn red when element B is hovered.
1
2
3
4
5
6
7
8
9
10
11
12
13
14 <ul>
<li>
A
</li>
<li>
B
</li>
</ul>
脚步
使
1 | ul { display: flex; } |
在标记中反转兄弟姐妹的顺序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <ul> <li> B </li> <li> A </li> </ul> |
使用同级选择器来定位元素A(
1 | li:hover + li { background-color: red; } |
使用flex
1 | li:last-child { order: -1; } |
......瞧!先前的兄弟选择器诞生(或至少模拟)。
这是完整的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <ul> <li> B </li> <li> A </li> </ul> |
来自flexbox规范:
5.4. Display Order: the
order propertyFlex items are, by default, displayed and laid out in the same order as they appear in the source document. The
order property can be used to change this ordering.The
order property controls the order in which flex items appear within the flex container, by assigning them to ordinal groups. It takes a singlevalue, which specifies which ordinal group the flex item
belongs to.
所有弹性项的初始
另请参阅CSS网格布局规范中的
使用flex
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | .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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <p> Using the flex <wyn>order</wyn> property to construct a previous sibling selector </p> <span>1</span> <span>2</span> <span>3</span> <span>HOVER ME</span> <span>4</span> <span>HOVER ME</span> <span>HOVER ME</span> <span>6</span> <span>7</span> <span>8</span> <span>10</span> <span>11</span> <span>HOVER ME</span> <span>13</span> <span>14</span> <span>15</span> <span>16</span> <span>17</span> <span>18</span> <span>19</span> <span>20</span> |
的jsfiddle
一个侧面注意关于CSS的两个过时的信念
Flexbox打破了人们对CSS的长期信念。
一个这样的信念是CSS中不可能使用先前的兄弟选择器。
说这种信念是普遍的,这是轻描淡写的。以下是Stack Overflow相关问题的示例:
- 使用选择器在CSS中选择元素的前一个兄弟
- CSS:选择以前的兄弟姐妹
- CSS选择以前的兄弟姐妹
- CSS中的上一个相邻选择器
- 在悬停时选择以前的兄弟姐妹
- 获得前面兄弟的CSS选择器
- 使用CSS更改悬停时兄弟元素的颜色
- 如何使用selenium css语法选择以前的兄弟
- CSS Selector用于选择另一个元素之前的元素?
- 如何仅使用CSS将样式添加到活动输入上一个兄弟
- 下一个和前一个元素的CSS选择器
- 当div悬停时如何影响其他元素
如上所述,这种看法并不完全正确。可以使用flex
另一个长期存在的信念是
实际上,W3C编辑器草案的最新版规范仍然断言这是真的:
9.9.1 Specifying the stack level: the
z-index
property
z-index
- Value: auto | | inherit
- Initial: auto
- Applies to: positioned elements
- Inherited: no
- Percentages: N/A
- Media: visual
- Computed value: as specified
(emphasis added)
但实际上,这些信息已经过时且不准确。
即使
4.3. Flex Item Z-Ordering
Flex items paint exactly the same as inline blocks, except that order-modified document order is used in place of raw
document order, andz-index values other thanauto create a stacking context even ifposition isstatic .5.4. Z-axis Ordering: the
z-index propertyThe painting order of grid items is exactly the same as inline blocks, except that order-modified document order is
used in place of raw document order, andz-index values other thanauto create a stacking context even if
position isstatic .
以下是
我有同样的问题,但后来我有一个"呃"的时刻。而不是写作
1 | x ~ y |
写
1 | y ~ x |
显然这匹配"x"而不是"y",但它回答"有匹配吗?"问题,简单的DOM遍历可能比在javascript中循环更有效地使您获得正确的元素。
我意识到最初的问题是一个CSS问题所以这个答案可能完全无关紧要,但其他Javascript用户可能会像我一样通过搜索偶然发现问题。
两招。基本上反转HTML中所需元素的HTML顺序并使用
1 2 3 4 5 6 7 8 9 10 | 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; } |
1 2 3 4 5 6 | <!-- Reverse the order of inner elements --> <span>5</span> <span>4</span> <span>3</span> <span>2</span> <span>1</span> |
父
1 2 3 4 5 6 7 | .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; } |
1 2 3 4 5 6 7 8 9 | Hover one span and see the previous elements being targeted! <!-- Reverse the order of inner elements --> <span>5</span> <span>4</span> <span>3</span> <span>2</span> <span>1</span> |
+ is for the next sibling. Is there an equivalent for the previous
sibling?
您可以使用两个轴选择器:
常规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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Hover over any of the blocks below Hover for <wyn>?</wyn> selector Hover for <wyn>!</wyn> selector Hover for <wyn>~</wyn> selector Hover for <wyn>+</wyn> selector <script src="https://rouninmedia.github.io/axe/axe.js"> |
另一个flexbox解决方案
您可以使用HTML中的元素顺序。然后除了在Michael_B的答案中使用
工作样本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | .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%; } |
1 2 3 4 5 | 5 4 3 2 1 |
目前没有正式的方法可以做到这一点,但你可以使用一个小技巧来实现这一目标!请记住它是实验性的,它有一些限制......
(如果您担心导航器兼容性,请查看此链接)
你可以做的是使用CSS3选择器:名为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <p> The oranges elements are the previous sibling li selected using li:nth-child(-n+4) </p> <span>1</span><!-- this will be selected --> <p> 2 </p><!-- this will be selected --> <p> 3 </p><!-- this will be selected --> 4<!-- this will be selected --> 5 <p> 6 </p> <p> 7 </p> <p> 8 </p> <p> 9 </p> |
限制
- 您无法根据下一个元素的类选择以前的元素
- 伪类也是如此
如果你知道确切的位置,那么基于
1 | ul li:not(:nth-child(n+3)) |
哪个会在第3个之前选择所有
您还可以从右到左选择第n个孩子:
1 | ul li:nth-child(-n+2) |
哪个也一样。
遗憾的是,没有"前一个"兄弟选择器,但你可能仍然可以通过使用定位(例如,向右浮动)获得相同的效果。这取决于你想要做什么。
在我的情况下,我想要一个主要的CSS 5星评级系统。我需要为之前的星星着色(或交换图标)。通过向右浮动每个元素,我基本上得到了相同的效果(因此必须将'html代表星''向后'写入。
我在这个例子中使用FontAwesome并在fa-star-o和fa-star的unicodes之间交换
http://fortawesome.github.io/Font-Awesome/
CSS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | .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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <ul> <li> Pants </li> <li> Socks </li> <ul> <li> White socks </li> <li> Blue socks </li> </ul> </ul> |
我们可以做些什么来使袜子块(包括袜子颜色)在视觉上使用间距突出?
什么会好但不存在:
1 2 3 4 | ul li ul:parent { margin-top: 15px; margin-bottom: 15px; } |
存在什么:
1 2 3 4 5 6 7 | li > a { margin-top: 15px; display: block; } li > a:only-child { margin-top: 0px; } |
这将所有锚链接设置为在顶部具有15px边距,并且对于在LI内没有UL元素(或其他标记)的那些将其重置为0。
我需要一个解决方案来选择以前的兄弟tr。我使用React和Styled-components提出了这个解决方案。这不是我的确切解决方案(这是内存,几小时后)。我知道setHighlighterRow函数有一个缺陷。
OnMouseOver一行将行索引设置为state,并使用新的背景颜色重新渲染上一行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | 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; } `; |
我遇到了类似的问题,发现所有这种性质的问题都可以解决如下:
这样你就可以设置当前的前一个项目(所有被当前和下一个项目覆盖的项目)和下一个项目的样式。
例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | /* 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> |
希望它可以帮助某人。
不可以。通过CSS无法实现。它需要"级联";-)。
但是,如果您能够在页面中添加JavaScript,那么一些jQuery可以帮助您实现最终目标。
您可以使用jQuery的
然后使用jQuery重新编写元素的DOM(CSS)。
根据Mike Brant的回答,
以下jQuery代码段可以提供帮助。
1 | $('p + ul').prev('p') |
这首先选择紧跟
的所有
-
。
然后它"回溯"以从该组
实际上,已经通过jQuery选择了"以前的兄弟姐妹"。
现在,使用
在我的情况下,我希望找到一种方法来选择ID为
我控制了
级联仅向一个方向发展:向下。
因此我可以选择ALL
或者我可以选择只跟随
但我不能只选择继续
而且,再次,我无法在HTML中添加
但是使用jQuery,我可以选择所需的
1 | $("#full-width").find(".companies").parents("#full-width").css("width","300px" ); |
这将找到所有
然后它使用
但过滤那些结果只保留
它只选择一个
最后,它为结果元素分配一个新的CSS(
1 | $(".parent").find(".change-parent").parents(".parent").css("background-color","darkred"); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"> <html> "parent" turns red descendant:"change-parent" "parent" stays green descendant:"nope" Target"<span style="color:darkgreen">parent</span>" to turn <span style="color:red">red</span>. Only if it has a descendant of"change-parent". (reverse cascade, look ahead, parent un-descendant) </html> |
jQuery参考文档:
$()或jQuery():DOM元素。
.find:获取当前匹配元素集中每个元素的后代,由选择器,jQuery对象或元素过滤。
.parents:获取匹配元素集中每个元素的前一个兄弟。如果提供了选择器,则仅当它与该选择器匹配时才会检索先前的兄弟(将结果过滤为仅包括列出的元素/选择器)。
.css:为匹配元素集设置一个或多个CSS属性。