CSS 是否有“前一个兄弟”选择器?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1817792/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 21:19:58  来源:igfitidea点击:

Is there a "previous sibling" selector?

csscss-selectors

提问by Jourkey

The plus sign (+) is for the next sibling.

加号 ( +) 表示下一个兄弟。

Is there an equivalent for the previous sibling?

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

采纳答案by cletus

No, there is no "previous sibling" selector.

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

On a related note, ~is for general successor sibling (meaning the element comes after this one, but not necessarily immediately after) and is a CSS3 selector. +is for next sibling and is CSS2.1.

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

See Adjacent sibling combinatorfrom Selectors Level 3and 5.7 Adjacent sibling selectorsfrom Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification.

请参阅来自Selectors Level 3 的相邻同级组合和来自Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification 的相邻同级选择器

回答by mantish

I found a way to style all previous siblings (opposite of ~) that may work depending on what you need.

我找到了一种方法来为所有以前的兄弟姐妹(与 的相反~)设置样式,这可能取决于您的需要。

Let's say you have a list of links and when hovering on one, all the previous ones should turn red. You can do it like this:

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

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

回答by Quentin

Selectors level 4 introduces :has()(previously the subject indicator !) which will allow you to select a previous sibling with:

选择器级别 4 引入了:has()(以前的主题指示符!),它允许您选择以前的兄弟姐妹:

previous:has(+ next) {}

… but at the time of writing, it is some distance beyond the bleeding edge for browser support.

……但在撰写本文时,它距离浏览器支持的前沿还有一段距离。

回答by Michael Benjamin

Consider the orderproperty of flex and grid layouts.

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

I'll focus on flexbox in the examples below, but the same concepts apply to Grid.

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



With flexbox, a previous sibling selector can be simulated.

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

In particular, the flex orderproperty can move elements around the screen.

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

Here's an example:

下面是一个例子:

You want element A to turn red when element B is hovered.

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

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

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

STEPS

脚步

  1. Make the ula flex container.

    ul { display: flex; }
    
  1. 制作ul一个弹性容器。

    ul { display: flex; }
    


  1. Reverse the order of siblings in the mark-up.

    <ul>
       <li>B</li>
       <li>A</li>
    </ul>
    
  1. 颠倒标记中兄弟姐妹的顺序。

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


  1. Use a sibling selector to target Element A (~or +will do) .

    li:hover + li { background-color: red; }
    
  1. 使用同级选择器来定位元素 A(~+将要做)。

    li:hover + li { background-color: red; }
    


  1. Use the flex orderproperty to restore the order of siblings on the visual display.

    li:last-child { order: -1; }
    
  1. 使用 flexorder属性恢复视觉显示上兄弟姐妹的顺序。

    li:last-child { order: -1; }
    


...and voilà! A previous sibling selector is born (or at least simulated).

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

Here's the full code:

这是完整的代码:

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>

From the flexbox spec:

来自 flexbox 规范:

5.4. Display Order: the orderproperty

Flex items are, by default, displayed and laid out in the same order as they appear in the source document. The orderproperty can be used to change this ordering.

The orderproperty controls the order in which flex items appear within the flex container, by assigning them to ordinal groups. It takes a single <integer>value, which specifies which ordinal group the flex item belongs to.

5.4. 显示顺序:order属性

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

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

The initial ordervalue for all flex items is 0.

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

Also see orderin the CSS Grid Layout spec.

另请参阅orderCSS 网格布局规范



Examples of "previous sibling selectors" created with the flex orderproperty.

使用 flexorder属性创建的“以前的同级选择器”示例。

.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

js小提琴



A Side Note – Two Outdated Beliefs about CSS

旁注——关于 CSS 的两个过时的信念

Flexbox is shattering long-held beliefs about CSS.

Flexbox 正在打破人们长期以来对 CSS 的看法。

One such belief is that a previous sibling selector is not possible in CSS.

一个这样的信念是在 CSS 中不可能有以前的同级选择器

To say this belief is widespread would be an understatement. Here's a sampling of related questions on Stack Overflow alone:

说这种信念很普遍是轻描淡写的。以下是仅与 Stack Overflow 相关的问题示例:

As described above, this belief is not entirely true. A previous sibling selector can be simulated in CSS using the flex orderproperty.

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

The z-indexMyth

z-index神话

Another long-standing belief has been that z-indexworks only on positioned elements.

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

In fact, the most current version of the spec – the W3C Editor's Draft– still asserts this to be true:

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

9.9.1 Specifying the stack level: the z-indexproperty

z-index

  • Value: auto | | inherit
  • Initial: auto
  • Applies to: positioned elements
  • Inherited: no
  • Percentages: N/A
  • Media: visual
  • Computed value: as specified

(emphasis added)

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

z-index

  • 值:自动 | | 继承
  • 初始:自动
  • 适用于:定位元素
  • 继承:无
  • 百分比:不适用
  • 媒体:视觉
  • 计算值:如指定

(强调)

In reality, however, this information is obsolete and inaccurate.

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

Elements that are flex itemsor grid itemscan create stacking contexts even when positionis static.

元素是弯曲的物品网格项目可以创建时甚至堆叠内容positionstatic

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, and z-indexvalues other than autocreate a stacking context even if positionis static.

5.4. Z-axis Ordering: the z-indexproperty

The 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, and z-indexvalues other than autocreate a stacking context even if positionis static.

4.3. Flex 项目 Z 排序

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

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

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

Here's a demonstration of z-indexworking on non-positioned flex items: https://jsfiddle.net/m0wddwxs/

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

回答by Bryan Larsen

I had the same question, but then I had a "duh" moment. Instead of writing

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

x ~ y

write

y ~ x

Obviously this matches "x" instead of "y", but it answers the "is there a match?" question, and simple DOM traversal may get you to the right element more efficiently than looping in javascript.

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

I realize that the original question was a CSS question so this answer is probably completely irrelevant, but other Javascript users may stumble on the question via search like I did.

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

回答by Roko C. Buljan

Two tricks. Basically inverting the HTML order of your desired elements in HTML and using
~Next siblingsoperator:

。基本上反转 HTML 中所需元素的 HTML 顺序并使用
~Nextsiblings运算符:

float-right+inverse the order of HTML elements

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>



Parent with direction: rtl;+ inverse the order of inner elements

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

回答by Rounin

+is for the next sibling. Is there an equivalent for the previous sibling?

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

You can use the two axeselectors: !and ?

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

There are 2subsequent sibling selectorsin conventional CSS:

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

  • +is the immediatesubsequent sibling selector
  • ~is the anysubsequent sibling selector
  • +紧随其后的兄弟选择器
  • ~任何后续的兄弟选择器

In conventional CSS, there is no previous sibling selector.

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

However, in the axeCSS post-processor library, there are 2previous sibling selectors:

但是,在axCSS 后处理器库中,有2 个以前的同级选择器

  • ?is the immediateprevious sibling selector (opposite of +)
  • !is the anyprevious sibling selector (opposite of ~)
  • ?立即前一个兄弟选择器(相对的+
  • !任何以前的同级选择器(与 相反~

Working Example:

工作示例:

In the example below:

在下面的例子中:

  • .any-subsequent:hover ~ divselects any subsequent div
  • .immediate-subsequent:hover + divselects the immediate subsequent div
  • .any-previous:hover ! divselects any previous div
  • .immediate-previous:hover ? divselects the immediate previous div
  • .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>

回答by Vadim Ovchinnikov

Another flexbox solution

另一个弹性盒解决方案

You can use inverse the order of elements in HTML. Then besides using orderas in Michael_B's answeryou can use flex-direction: row-reverse;or flex-direction: column-reverse;depending on your layout.

您可以使用反转 HTML 中元素的顺序。然后除了orderMichael_B 的答案中使用之外,您还可以使用flex-direction: row-reverse;flex-direction: column-reverse;取决于您的布局。

Working sample:

工作样本:

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

回答by 0x1gene

There is no official way to do that at the moment but you can use a little trick to achieve this ! Remember that it is experimental and it has some limitation ... (check this linkif you worries about navigator compatibility )

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

What you can do is use a CSS3 selector : the pseudo classe called nth-child()

您可以做的是使用 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>

Limitations

限制

  • You can't select previous elements based on the classes of the next elements
  • This is the same for pseudo classes
  • 您不能根据下一个元素的类选择前一个元素
  • 这对于伪类也是一样的

回答by kernel

If you know the exact position an :nth-child()-based exclusion of all following siblings would work.

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

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

Which would select all lis before the 3rd (e.g. 1st and 2nd). But, in my opinion this looks ugly and has a very tight usecase.

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

You also could select the nth-child right-to-left:

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

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

Which does the same.

哪个也一样。