Answers:
不,没有“上一个兄弟”选择器。
与此相关的是,~
它用于一般后继兄弟(这意味着该元素在此之后,但不一定紧随其后)并且是CSS3选择器。+
是下一个兄弟姐妹,是CSS2.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>
float:right
)中对元素进行重新排序。它确实需要在单位/单词和填充之间(而不是空白处)之间留白空格,但是在其他方面,它可以完美地工作!
order
flex和grid布局的属性。在下面的示例中,我将重点介绍flexbox,但是相同的概念也适用于Grid。
使用flexbox,可以模拟先前的同级选择器。
特别是,flex order
属性可以使元素在屏幕上移动。
这是一个例子:
您希望元素A悬停时元素A变为红色。
<ul> <li>A</li> <li>B</li> </ul>
脚步
做ul
一个弹性容器。
ul { display: flex; }
反转标记中兄弟姐妹的顺序。
<ul>
<li>B</li>
<li>A</li>
</ul>
使用同级选择器将元素A作为目标(~
或+
将这样做)。
li:hover + li { background-color: red; }
使用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规范:
默认情况下,弹性项目的显示和布局方式与它们在源文档中显示的顺序相同。的
order
属性可用于更改此顺序。该
order
属性通过将弹性项目分配给顺序组来控制其在弹性容器中的显示顺序。它采用一个<integer>
值,该值指定弹性项目所属的顺序组。
order
所有弹性项目的初始值为0。
使用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>
Flexbox打破了人们长期以来对CSS的信念。
一个这样的信念是,在CSS中不可能有以前的兄弟选择器。
要说这种信念很普遍,那就轻描淡写了。这是仅有关堆栈溢出的相关问题的样本:
如上所述,这种信念并不完全正确。可以使用flex order
属性在CSS中模拟先前的同级选择器。
在z-index
神话
另一个长期存在的信念是z-index
仅对定位的元素起作用。
实际上,该规范的最新版本– W3C编辑器的草案 –仍然认为这是正确的:
z-index
- 值:自动| | 继承
- 初始:自动
- 适用于:定位元素
- 继承:否
- 百分比:不适用
- 媒体:视觉
- 计算值:指定
(添加了重点)
但是,实际上,此信息已过时且不准确。
弹性项目或网格项目的元素即使在position
is 时也可以创建堆叠上下文static
。
Flex项的绘制与内联块完全相同,不同之处在于,使用经顺序修改的文档顺序代替原始文档顺序,并且
z-index
除了auto
创建堆叠上下文外,其他值position
也是如此static
。网格项目的绘制顺序与内联块完全相同,不同之处在于,使用顺序修改后的文档顺序代替原始文档顺序,并且
z-index
除了auto
创建堆叠上下文外 ,其他值position
也是如此static
。
这是z-index
处理未定位的弹性项目的演示:https : //jsfiddle.net/m0wddwxs/
order
属性不是一个解决方案,因为它仅意在改变视觉秩序,所以它并没有恢复原来的语义顺序,你不得不改变在HTML这种解决方法的工作。
float: right
(或任何其他颠倒顺序的方式,其flex/order
副作用很小(最少?))。鞭打了两个小提琴:演示float: right
方法,以及演示direction: rtl
我有同样的问题,但后来我有一个“ duh”时刻。而不是写作
x ~ y
写
y ~ x
显然,它匹配“ x”而不是“ y”,但是它回答了“是否存在匹配?”。问题,简单的DOM遍历可能比循环javascript更有效地将您带到正确的元素。
我意识到原来的问题是CSS问题,因此该答案可能完全不相关,但是其他Javascript用户可能会像我一样通过搜索偶然发现该问题。
y ~ x
解决我的问题
y ~ x
不回答“有匹配吗?” 问题,因为此处给出的两个选择器的含义完全不同。有没有办法y ~ x
所能产生给出的子树匹配<root><x/><y/></root>
的例子。如果问题是“您存在吗?” 那么选择器就是y
。如果问题是“给定兄弟姐妹x在任意位置,y是否存在?” 那么您将需要两个选择器。(尽管此时我可能只是在挑剔...)
两个招。基本上反转所需元素在HTML中的HTML顺序,并使用
~
Next兄弟姐妹运算符:
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>
+
是给下一个兄弟姐妹的。以前的兄弟姐妹有同等学历吗?
!
和?
常规CSS中有2个后续的同级选择器:
+
是紧随其后的同级选择器~
是任何后续的同级选择器在常规CSS中,没有先前的兄弟选择器。
但是,在ax CSS后处理器库中,有两个以前的兄弟选择器:
?
是立即前一个兄弟选择器(的相对+
)!
是任何先前的同级选择器(与相对~
)工作示例:
在下面的示例中:
.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>
您可以使用相反的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>
目前尚无官方方法可以执行此操作,但是您可以使用一些技巧来实现此目的!请记住,这是实验性的,并且有一定的局限性...(请检查此链接)如果您担心导航器的兼容性,)
您可以使用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>
:nth-child(-n+4)
是伪类,需要将其应用于选择器才能正常工作。如果您不确定,请尝试用我的小提琴的叉子对其进行试验,您会发现它没有
*
选择器来独立于节点类型,但这是令人讨厌的坏习惯。
li#someListItem
我想在它之前添加一个节点(这就是我解释“上一个”的方式)-我看不到您提供的信息如何通过CSS来表达这一点。您只是选择前n个兄弟姐妹,并假设我知道n。基于此逻辑,任何选择器都可以解决问题,并选择我需要的元素(例如:not())。
不可以。无法通过CSS。它把“级联”深深地放在心上;-)。
但是,如果您能够将JavaScript添加到页面中,则使用jQuery可以使您达到最终目标。
您可以使用jQuery find
在目标元素/类/ id上执行“前瞻”,然后回溯以选择目标。
然后,您使用jQuery重新编写元素的DOM(CSS)。
根据Mike Brant的回答,以下jQuery代码段可能会有所帮助。
$('p + ul').prev('p')
这首先选择<ul>
紧接在之后的所有<p>
。
然后,它“回溯”以<p>
从该组<ul>
s中选择所有先前的。
实际上,已通过jQuery选择了“以前的兄弟姐妹”。
现在,使用.css
函数为该元素传入CSS新值。
就我而言,我正在寻找一种方法来选择ID为ID的DIV #full-width
,但仅当它具有类为的(间接)后代DIV时才可以.companies
。
我可以控制下方的所有HTML .companies
,但无法更改其上方的任何HTML。
级联仅向1个方向移动:向下。
因此,我可以选择ALL #full-width
。
或者我可以选择.companies
仅在后面跟随#full-width
。
但我不能只选择#full-width
s表示进行 .companies
。
再说一次,我无法添加 .companies
在HTML中任何更高的内容。HTML的那部分是外部编写的,并包装了我们的代码。
但是使用jQuery,我可以选择所需#full-width
的,然后分配适当的样式:
$("#full-width").find(".companies").parents("#full-width").css( "width", "300px" );
这将查找all #full-width .companies
,并仅选择那些.companies
,类似于使用选择器定位CSS标准中的特定元素的方式。
然后,它用于.parents
“回溯”并选择的所有父项.companies
,
但过滤这些结果以仅保留#fill-width
元素,因此最后,
仅#full-width
当它具有.companies
类后代时才选择一个元素。
最后,它将新的CSS(width
)值分配给结果元素。
$(".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对象或元素进行过滤。
。parent:获取匹配元素集中每个元素的前一个同级。如果提供了选择器,则仅当它与选择器匹配时才检索先前的同级(将结果筛选为仅包括列出的元素/选择器)。
。css:为匹配的元素集设置一个或多个CSS属性。
previousElementSibling
)。
previousElementSibling()
对于那些更熟悉本机JS DOM函数的人,可以提供另一个非CSS路径。
+
OP专门要求的(不存在)选择器。将此答案视为JS“ hack”。在这里节省了我花时间寻找解决方案的其他人。
没有“以前的”兄弟选择很不幸,但你能可能仍然获得通过使用定位(如浮动右)相同的效果。这取决于您要执行的操作。
就我而言,我想要一个主要是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/
+
或者~
选择器让我感到最干净。
根据您的确切目标,有一种无需使用父选择器(即使存在一个父选择器)就可以实现其有用性的方法...
说我们有:
<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的边距,并且对于LI内部没有UL元素(或其他标签)的那些链接,将其重置为0。
我需要一个解决方案来选择以前的兄弟tr。我使用React和Styled-components提出了这个解决方案。这不是我的确切解决方案(这是几个小时后从内存中获取的)。我知道setHighlighterRow函数存在缺陷。
OnMouseOver一行将把行索引设置为state,并用新的背景色重新渲染上一行
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;
}
`;
我遇到了类似的问题,发现所有这种性质的问题都可以通过以下方式解决:
这样,您就可以为当前,上一个项目(所有项目替换为当前和下一个项目)和下一个项目设置样式。
例:
/* 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>
希望它可以帮助某人。