Có một bộ chọn anh chị em trước đây của người Viking không?


1355

Dấu cộng ( +) dành cho anh chị em tiếp theo.

Có tương đương với anh chị em trước không?


18
OMG, tất cả các câu trả lời ở đây đề nghị bạn đảo ngược thứ tự của các phần tử html và sau đó sử dụng CSS để làm cho chúng xuất hiện lạc hậu là một sự kéo dài thực sự. Chắc chắn rằng nó không chỉ định trong câu hỏi, nhưng hầu hết các câu hỏi "bạn có thể làm X bằng CSS" không nên cho rằng bạn không thể thay đổi cấu trúc HTML.
squarecandy

3
@squarecandy, tôi hầu hết đồng ý với nhận xét của bạn. Nhưng các giải pháp bạn tham khảo là không đầy đủ dù sao cũng hữu ích trong một số trường hợp (chú ý các upvote). Vì vậy, họ có giá trị đăng. Những gì bạn thấy là một "giải pháp thực sự" có thể là một "giải pháp sáng tạo" cho người khác.
Michael Benjamin

Câu trả lời:


839

Không, không có bộ chọn "anh chị em trước".

Trên một lưu ý liên quan, ~dành cho anh chị em kế vị chung (có nghĩa là phần tử xuất hiện sau phần này, nhưng không nhất thiết phải ngay sau đó) và là một bộ chọn CSS3. +dành cho anh chị em tiếp theo và là CSS2.1.

Xem Trình kết hợp anh chị em liền kề từ Bộ chọn Cấp 35.7 Bộ chọn anh chị em liền kề từ Đặc tả Cascading Style Sheets Cấp 2 Bản sửa đổi 1 (CSS 2.1) .


14
Từ tiêu chuẩn CSS3: Các phần tử được biểu thị bằng hai chuỗi có cùng cha mẹ trong cây tài liệu và phần tử được biểu thị bằng chuỗi thứ nhất có trước (không nhất thiết phải ngay lập tức) phần tử được biểu thị bằng phần thứ hai.
Lie Ryan

26
@Lie Ryan: Vâng, nhưng cletus đang đưa ra câu trả lời của anh ấy là bạn không chọn yếu tố trước.
BoltClock

42
Đây là một ví dụ tôi đã thực hiện để xem những gì nó có thể, và không thể, làm được. jsfiddle.net/NuuHy/1
Bàn tính

7
Hàm jquery hữu ích cho việc này là trước (). Ví dụ: $ ("# the_element"). Trước (). Css ("màu nền", "đỏ")
Satbir Kira

1
Tùy thuộc vào đánh dấu của bạn, điều này có thể giúp: stackoverflow.com/questions/42680881/
samnau

235

Tôi tìm thấy một cách để tạo kiểu cho tất cả anh chị em trước đây (đối diện ~) có thể hoạt động tùy thuộc vào những gì bạn cần.

Giả sử bạn có một danh sách các liên kết và khi di chuột vào một liên kết, tất cả các liên kết trước đó sẽ chuyển sang màu đỏ. Bạn có thể làm như thế này:

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


17
Bạn có thể thêm một lời giải thích về cách nó hoạt động. (có vẻ như bạn áp dụng một kiểu cho tất cả các mục và cho các mục sau nhưng nó có thể được mô tả rõ ràng)
AL

1
Giải pháp tuyệt vời. Không cần phải sắp xếp lại các thành phần trong đánh dấu cũng như trong kết xuất (thông qua float:right). Nó đã yêu cầu thu gọn khoảng trắng giữa các đơn vị / từ và phần đệm thay vì lề, nhưng nó hoạt động hoàn toàn khác!
Steven Vachon

7
vâng, nhưng một lần trước là cần thiết hầu hết thời gian KHÔNG TẤT CẢ những người trước đó!
azerafati

42
Các liên kết đều chuyển sang màu đỏ nếu tôi di chuột qua khoảng trống giữa chúng, đối với tôi.
Lynn

3
@Lynn câu trả lời chỉ bao gồm mã để làm cho các liên kết trước đó màu đỏ khi di chuột. Phong cách bổ sung phụ thuộc vào trường hợp sử dụng của bạn. Đối với thành phần xếp hạng sao (mà tôi đoán là trường hợp phổ biến), bạn sẽ cần phải thoát khỏi không gian đó và cũng tạo màu đỏ cho liên kết được di chuột.
mantish

164

Bộ chọn cấp 4 giới thiệu:has() (trước đây là chỉ báo chủ đề !) sẽ cho phép bạn chọn anh chị em trước đó với:

previous:has(+ next) {}

Tuy nhiên, tại thời điểm viết bài, đó là một khoảng cách vượt quá giới hạn để hỗ trợ trình duyệt.


51
"Chảy máu cạnh để hỗ trợ trình duyệt" có thể là một lời nói quá. Khi viết bài này, ngay cả phiên bản Chrome mới nhất cũng không thể sử dụng lớp :has()giả.
Reed Martin

33
@ReedMartin - Đó là lý do tại sao tôi nói một số khoảng cách vượt ra ngoài giới hạn
Quentin

12
": đã không được đánh dấu là một phần của cấu hình bộ chọn động, điều đó có nghĩa là nó không thể được sử dụng trong các bảng định kiểu; chỉ với các hàm như document.querySelector ()." - developer.mozilla.org/en-US/docs/Web/CSS/:has
Arch Linux Tux

1
@ArchLinuxTux: "Giới hạn này hiện đã được xóa", vì vậy, trước đây chúng ta có thể sử dụng tính năng này: D.
Jacob van Lingen

@JacobvanLingen - caniuse.com/#feat=css-has - Hiện tại không có trình duyệt nào hỗ trợ nó.
Quentin

153

Xem xét các thuộc ordertính của bố trí flex và lưới.

Tôi sẽ tập trung vào flexbox trong các ví dụ bên dưới, nhưng các khái niệm tương tự áp dụng cho Grid.


Với flexbox, một bộ chọn anh chị em trước đó có thể được mô phỏng.

Đặc biệt, thuộc tính flex ordercó thể di chuyển các yếu tố xung quanh màn hình.

Đây là một ví dụ:

Bạn muốn phần tử A chuyển sang màu đỏ khi phần tử B được di chuột.

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

BƯỚC

  1. Làm cho ulmột container flex.

    ul { display: flex; }

  1. Đảo ngược thứ tự của anh chị em trong đánh dấu.

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

  1. Sử dụng bộ chọn anh chị em để nhắm mục tiêu Phần tử A ( ~hoặc +sẽ làm).

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

  1. Sử dụng thuộc tính flex orderđể khôi phục thứ tự của anh chị em trên màn hình trực quan.

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

...và Voila! Một bộ chọn anh chị em trước đó được sinh ra (hoặc ít nhất là mô phỏng).

Đây là mã đầy đủ:

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>

Từ thông số kỹ thuật flexbox:

5.4. Lệnh hiển thị: ordertài sản

Theo mặc định, các mục Flex được hiển thị và sắp xếp theo thứ tự như chúng xuất hiện trong tài liệu nguồn. Các ordertài sản có thể được sử dụng để thay đổi thứ tự này.

Các orderkiểm soát bất động sản thứ tự mà mục flex xuất hiện trong container flex, bằng cách gán chúng cho các nhóm thứ. Nó nhận một <integer>giá trị duy nhất , xác định nhóm thứ tự mà mục flex thuộc về.

orderGiá trị ban đầu cho tất cả các mục flex là 0.

Cũng xem ordertrong thông số Bố cục Lưới CSS .


Ví dụ về "bộ chọn anh chị em trước" được tạo bằng thuộc tính 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


Lưu ý bên lề - Hai niềm tin lỗi thời về CSS

Flexbox đang phá vỡ niềm tin từ lâu về CSS.

Một niềm tin như vậy là một bộ chọn anh chị em trước đó là không thể trong CSS .

Nếu nói niềm tin này là phổ biến sẽ là một cách đánh giá thấp. Dưới đây là một mẫu các câu hỏi liên quan trên Stack Overflow một mình:

Như đã mô tả ở trên, niềm tin này không hoàn toàn đúng. Một bộ chọn anh chị em trước có thể được mô phỏng trong CSS bằng cách sử dụng thuộc tính flex order.

các z-indexMyth

Một niềm tin lâu dài khác là z-indexchỉ hoạt động trên các yếu tố định vị.

Trên thực tế, phiên bản mới nhất của thông số kỹ thuật - Dự thảo của W3C Editor - vẫn khẳng định điều này là đúng:

9.9.1 Chỉ định cấp độ ngăn xếp: thuộc z-index tính

z-index

  • Giá trị: tự động | | thừa kế
  • Ban đầu: tự động
  • Áp dụng cho: các yếu tố định vị
  • Kế thừa: không
  • Tỷ lệ: Không áp dụng
  • Phương tiện: trực quan
  • Giá trị tính toán: theo quy định

(nhấn mạnh thêm)

Tuy nhiên, trên thực tế, thông tin này đã lỗi thời và không chính xác.

Các yếu tố là vật phẩm flex hoặc vật phẩm lưới có thể tạo ra bối cảnh xếp chồng ngay cả khi positionstatic.

4.3. Đặt hàng linh hoạt Z

Các mục Flex vẽ chính xác giống như các khối nội tuyến, ngoại trừ thứ tự tài liệu được sửa đổi theo thứ tự được sử dụng thay cho thứ tự tài liệu thô và z-indexcác giá trị khác ngoài việc autotạo bối cảnh xếp chồng ngay cả khi positionstatic.

5.4. Đặt hàng trục Z: thuộc z-indextính

Thứ tự vẽ của các mục lưới hoàn toàn giống với các khối nội tuyến, ngoại trừ thứ tự tài liệu được sửa đổi thứ tự được sử dụng thay cho thứ tự tài liệu thô và z-indexcác giá trị khác ngoài việc autotạo bối cảnh xếp chồng ngay cả khi positionstatic.

Dưới đây là một minh chứng về cách z-indexlàm việc trên các mục flex không định vị: https://jsfiddle.net/m0wddwxs/


15
Các orderbất động sản không phải là một giải pháp vì nó chỉ được thiết kế để thay đổi hình ảnh theo thứ tự, vì vậy nó không phục hồi bản gốc ngữ nghĩa thứ tự mà bạn buộc phải thay đổi trong HTML cho workaround này để làm việc.
Marat Tanalin

2
@Marat Tanalin: Đối với 90% trường hợp sử dụng, giả sử hỗ trợ trình duyệt không phải là vấn đề, điều này sẽ hoạt động tốt. 10% trường hợp sử dụng còn lại là 1) trường hợp thay đổi thứ tự trực quan không phải là giải pháp hoặc 2) trường hợp không liên quan đến CSS. Rất may, đối với # 2, bộ chọn-4 cung cấp: has () và đơn giản là tùy thuộc vào các nhà phát triển thư viện bộ chọn để triển khai nó.
BoltClock

5
Hãy nhớ rằng CSS2.2 ED bạn đang trích dẫn, về bản chất, vẫn là CSS2. Và bố cục flexbox và lưới không tồn tại trong CSS2, theo như CSS2 có liên quan, thông tin đó chắc chắn là đúng. Ít nhất, văn bản có thể được cập nhật để đề cập rằng chỉ số z có thể áp dụng cho các loại yếu tố khác trong các cấp độ CSS trong tương lai, giống như cách nó nói rằng các thuộc tính khác có thể thiết lập bối cảnh xếp chồng, chẳng hạn như độ mờ.
BoltClock

3
Trong trường hợp bất cứ ai gặp khó khăn khi hiểu khi nào z-indexsẽ hoạt động, ngay cả khi "omg, không có positionchỉ định!", Thông số kỹ thuật đề cập đến khái niệm sắp xếp bối cảnh , được giải thích độc đáo bởi bài viết này trên MDN
Rogier Spieker

3
@Michael_B bạn được chào đón! Tôi đã đối phó với rất nhiều người đi trước không biết về điều này. Một điều khác tôi muốn đề cập, bộ chọn anh chị em trước đây cũng hoạt động độc đáo với float: right(hoặc bất kỳ phương tiện nào khác để đảo ngược thứ tự, trong đó flex/ordercó ít (ít nhất?) Tác dụng phụ). Đánh đòn hai câu đố: thể hiện float: rightcách tiếp cậntrình diễndirection: rtl
Rogier Spieker

69

Tôi đã có cùng một câu hỏi, nhưng sau đó tôi đã có một khoảnh khắc "duh". Thay vì viết

x ~ y

viết

y ~ x

Rõ ràng điều này khớp với "x" thay vì "y", nhưng nó trả lời "có khớp không?" câu hỏi và truy cập DOM đơn giản có thể đưa bạn đến đúng yếu tố hiệu quả hơn là lặp trong javascript.

Tôi nhận ra rằng câu hỏi ban đầu là một câu hỏi CSS nên câu trả lời này có lẽ hoàn toàn không liên quan, nhưng những người dùng Javascript khác có thể vấp phải câu hỏi thông qua tìm kiếm như tôi đã làm.


18
Tôi tin rằng nó hoạt động khi y có thể được tìm thấy dễ dàng. Vấn đề là nếu y chỉ có thể được tìm thấy liên quan đến x và khi đảo ngược nó, bạn không thể tìm thấy y vì bạn phải tìm x trước. Điều này tất nhiên liên quan đến câu hỏi y là anh chị em đi trước hơn là tiếp theo, nhưng cũng có thể áp dụng cho y là anh chị em sau.
David

19
Bạn là loại người khắc nghiệt, khắc nghiệt. (xin lỗi, không thể cưỡng lại.) Vấn đề là đôi khi bạn chỉ cần biết "bạn có tồn tại không?". Những lần khác, bạn có thể sử dụng ": trước" để đặt một cái gì đó giữa hai yếu tố. Cuối cùng, nếu bạn phải thả vào jQuery, sử dụng find ("y ~ x"). Trước () dễ dàng hơn nhiều lựa chọn thay thế.
Bryan Larsen

156
Ý tưởng của bộ chọn anh chị trước là nó sẽ chọn phần tử trước. Thật không may, đảo ngược nó, như được mô tả ở đây, không cung cấp chức năng này.
Zenexer

14
Cảm ơn @Zenexer đã làm rõ rằng câu trả lời này không cung cấp giải pháp thực sự cho câu hỏi ban đầu, tôi bắt đầu cảm thấy ngu ngốc khi nghĩ về cách y ~ xgiải quyết vấn đề của mình
Jaime Hablutzel

4
Tôi hiểu ý tưởng đằng sau câu trả lời này, tuy nhiên lý do đưa ra trong câu trả lời không hoàn toàn có ý nghĩa. Công cụ chọn y ~ xkhông trả lời "có khớp không?" câu hỏi, bởi vì hai bộ chọn được đưa ra ở đây có nghĩa là những thứ hoàn toàn khác nhau. Chẳng có cách nào y ~ xcó thể tạo ra một trận đấu được đưa ra cho cây con <root><x/><y/></root>chẳng hạn. Nếu câu hỏi là "y có tồn tại không?" sau đó bộ chọn chỉ đơn giản là y. Nếu câu hỏi là "y có tồn tại với anh chị em x ở vị trí tùy ý không?" sau đó bạn cần cả hai bộ chọn. (Mặc dù có lẽ tôi chỉ đang
say sưa

25

Hai thủ đoạn . Về cơ bản đảo ngược thứ tự HTML của các yếu tố bạn muốn trong HTML và sử dụng toán tử
~ anh chị em tiếp theo :

float-right + đảo ngược thứ tự các phần tử 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>


Cha mẹ có direction: rtl;+ nghịch đảo thứ tự các yếu tố bên trong

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


25

+dành cho anh chị em tiếp theo. Có tương đương với anh chị em trước không?

Bạn có thể sử dụng hai bộ chọn rìu : !?

2 bộ chọn anh chị em tiếp theo trong CSS thông thường:

  • +là công cụ chọn anh chị em ngay sau đó
  • ~bất kỳ bộ chọn anh chị em tiếp theo

Trong CSS thông thường, không có bộ chọn anh chị em trước đó .

Tuy nhiên, trong thư viện bộ xử lý hậu rìu CSS, có 2 bộ chọn anh chị em trước đó :

  • ?ngay lập tức chọn anh chị em trước đó (đối diện +)
  • !bất kỳ bộ chọn anh chị em nào trước đó (ngược lại ~)

Ví dụ làm việc:

Trong ví dụ dưới đây:

  • .any-subsequent:hover ~ div chọn bất kỳ tiếp theo div
  • .immediate-subsequent:hover + div chọn ngay sau đó div
  • .any-previous:hover ! div chọn bất kỳ trước div
  • .immediate-previous:hover ? div chọn trước 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>


3
Điều này cho tôi một lỗi cú pháp khi tôi cố gắng thực hiện nó trên sass bên trong một dự án rails.
alex

25
ax là một bộ xử lý hậu kỳ CSS. Nó không sử dụng cú pháp giống như các bộ xử lý trước CSS như Sass, Less hoặc Stylus.
Rounin

1
@Rounin bạn có phiền khi thêm một số liên kết tài liệu không? Tôi không thể tìm thấy rìu hậu xử lý.
Dionys

@Dionys - Cảm ơn bạn đã quan tâm. ax là một dự án tôi đã bắt đầu vào cuối năm 2016, khi tôi không biết ES2015 và thậm chí các đối tượng trong JS còn rất mới đối với tôi. Kho lưu trữ GitHub ở đây: github.com/RouninMedia/axe . Tôi rất muốn quay trở lại vấn đề này vào một lúc nào đó (trước đây tôi cũng đã phát triển một thứ gọi là ax-blade tương đương với CSS của các sự kiện javascript), nhưng trước tiên tôi cần hoàn thành công việc của mình trên một dự án khác (tên mã là ashiva ).
Rounin

17

Một giải pháp flexbox khác

Bạn có thể sử dụng nghịch đảo thứ tự các phần tử trong HTML. Sau đó, ngoài việc sử dụng ordernhư trong câu trả lời của Michael_B, bạn có thể sử dụng flex-direction: row-reverse;hoặc flex-direction: column-reverse;tùy thuộc vào bố cục của bạn.

Mẫu làm việc:

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


16

Không có cách chính thức để làm điều đó vào lúc này nhưng bạn có thể sử dụng một mẹo nhỏ để đạt được điều này! Hãy nhớ rằng đó là thử nghiệm và nó có một số hạn chế ... (kiểm tra liên kết này nếu bạn lo lắng về khả năng tương thích của hoa tiêu)

Những gì bạn có thể làm là sử dụng bộ chọn CSS3: classe giả được gọi là 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>

Hạn chế

  • Bạn không thể chọn các yếu tố trước dựa trên các lớp của các yếu tố tiếp theo
  • Điều này cũng tương tự đối với các lớp giả

1
@Ian vì đây :nth-child(-n+4)là lớp giả cần được áp dụng cho bộ chọn để hoạt động đúng. Nếu bạn không thuyết phục, hãy thử trải nghiệm nó bằng một cái nĩa của tôi và bạn sẽ thấy rằng nó không bị
rung

1
Trên thực tế, bạn có thể sử dụng loại nút độc lập bằng cách sử dụng *bộ chọn, nhưng thực tế nó rất tệ.
Josh Burgess

1
Đây là câu trả lời phù hợp với tôi, không biết tại sao nó không được bình chọn cao hơn hoặc được chấp nhận.
Jake Cattrall

1
Trên thực tế, nó hoạt động cho các nút khác nhau: jsfiddle.net/aLhv9r1w/316 . Vui lòng cập nhật câu trả lời của bạn :)
Jamie Barker

1
Tôi đã có một bộ chọn phức tạp, nhưng hãy nói rằng nó li#someListItemvà tôi muốn (các) nút ngay trước nó (đó là cách tôi diễn giải "trước đó") - Tôi không thấy cách thông tin bạn cung cấp có thể giúp tôi thể hiện điều đó thông qua CSS. Bạn chỉ đang chọn n anh chị em đầu tiên, và giả sử tôi biết n. Dựa trên logic này, bất kỳ bộ chọn nào cũng có thể thực hiện thủ thuật và chọn (các) phần tử tôi cần (chẳng hạn như: không ()).
bitoolean

4

Nếu bạn biết chính xác vị trí :nth-child()loại trừ dựa trên tất cả các anh chị em sau đây sẽ hoạt động.

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

Mà sẽ chọn tất cả li s trước thứ 3 (ví dụ 1 và 2). Nhưng, theo tôi điều này có vẻ xấu và có một usecase rất chặt chẽ.

Bạn cũng có thể chọn con thứ n từ phải sang trái:

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

Mà làm như vậy.


3

Không. Không thể thông qua CSS. Nó đưa "Cascade" vào trái tim ;-).


Tuy nhiên, nếu bạn có thể thêm JavaScript vào trang của mình, một chút jQuery có thể đưa bạn đến mục tiêu cuối cùng.
Bạn có thể sử dụng jQuery findđể thực hiện "nhìn về phía trước" trên phần tử / lớp / id mục tiêu của bạn, sau đó quay lại để chọn mục tiêu của bạn.
Sau đó, bạn sử dụng jQuery để viết lại DOM (CSS) cho phần tử của bạn.

Dựa trên câu trả lời này của Mike Brant , đoạn mã jQuery sau đây có thể giúp ích.

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

Điều này đầu tiên chọn tất cả <ul>s ngay lập tức theo a <p>.
Sau đó, nó "quay lại" để chọn tất cả các <p>s trước đó từ tập <ul>s đó.

Thực tế, "anh chị em trước" đã được chọn thông qua jQuery.
Bây giờ, sử dụng .csshàm để truyền vào các giá trị mới CSS của bạn cho phần tử đó.


Trong trường hợp của tôi, tôi đang tìm cách chọn một DIV với id #full-width, nhưng CHỈ nếu nó có một DIV hậu duệ (gián tiếp) với lớp .companies.

Tôi đã kiểm soát tất cả các HTML bên dưới .companies, nhưng không thể thay đổi bất kỳ HTML nào ở trên nó.
Và dòng thác chỉ đi 1 hướng: xuống.

Do đó tôi có thể chọn TẤT CẢ #full-width.
Hoặc tôi có thể chọn .companieschỉ theo a #full-width.
Nhưng tôi không thể chỉ chọn #full-widths mà tiến hành .companies .

Và, một lần nữa, tôi không thể thêm .companiesbất kỳ thứ gì cao hơn trong HTML. Đó là một phần của HTML được viết ra bên ngoài và bao bọc mã của chúng tôi.

Nhưng với jQuery, tôi có thể chọn #full-widths yêu cầu , sau đó gán kiểu thích hợp:

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

Điều này tìm thấy tất cả #full-width .companiesvà chỉ chọn những thứ đó .companies, tương tự như cách các bộ chọn được sử dụng để nhắm mục tiêu các yếu tố cụ thể trong tiêu chuẩn trong CSS.
Sau đó, nó sử dụng .parentsđể "quay lại" và chọn TẤT CẢ cha mẹ .companies,
nhưng lọc các kết quả đó để chỉ giữ lại #fill-widthcác phần tử, do đó, cuối cùng,
nó chỉ chọn một #full-widthphần tử nếu có .companieshậu duệ lớp.
Cuối cùng, nó gán một widthgiá trị CSS ( ) mới cho phần tử kết quả.

$(".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>

Tài liệu tham khảo jQuery:
$ () hoặc jQuery () : Phần tử DOM.
. find : Lấy hậu duệ của từng phần tử trong tập hợp các phần tử phù hợp hiện tại, được lọc bởi bộ chọn, đối tượng jQuery hoặc phần tử.
. cha mẹ : Nhận anh chị em ngay trước mỗi phần tử trong tập hợp các phần tử phù hợp. Nếu một bộ chọn được cung cấp, nó chỉ truy xuất anh chị em trước đó nếu nó phù hợp với bộ chọn đó (lọc kết quả để chỉ bao gồm các thành phần / bộ chọn được liệt kê).
. css : Đặt một hoặc nhiều thuộc tính CSS cho tập hợp các phần tử phù hợp.


Điều này không có gì để làm với câu hỏi. Tất nhiên là có thể sử dụng JS và bạn thậm chí không cần jQuery cho việc này ( previousElementSibling).
Fabian von Ellerts

1
@FabianvonEllerts Tôi đã trả lời câu hỏi của OP trực tiếp trong dòng đầu tiên của câu trả lời của tôi. Như câu trả lời của tôi, nó thực sự không thể thông qua CSS . Sau đó, tôi đã cung cấp 1 đường dẫn khả dĩ để đạt được mục tiêu, sử dụng công nghệ (JS | JQuery) mà người dùng CSS có thể quen thuộc và có quyền truy cập. Ví dụ: nhiều trang web WordPress cũng có JQuery, vì vậy đây là một điểm vào dễ dàng: dễ sử dụng, ghi nhớ và mở rộng theo. Thật vô trách nhiệm khi chỉ trả lời KHÔNG , mà không cung cấp một cách khác để hoàn thành mục tiêu. Tôi đã chia sẻ những gì tôi đã học và sử dụng khi tôi có cùng một câu hỏi.
SherylHohman

previousElementSibling()đối với những người quen thuộc hơn với các hàm DOM DOM gốc có thể cung cấp một đường dẫn không phải CSS khác về phía trước.
SherylHohman

Tôi thấy các CSS HACKS khác rất thú vị, nhưng trong trường hợp sử dụng cụ thể của tôi, chúng không hoạt động (rơi vào danh mục cảnh báo) hoặc quá phức tạp. Đối với những người khác rơi vào hoàn cảnh tương tự, thật công bằng khi chia sẻ phương pháp dễ sử dụng này có thể hoạt động, khi các giải pháp trên không thành công hoặc quá khó để thực hiện / duy trì. Nhiều CSS HACKS đã được chia sẻ. Công việc này không được bảo hiểm. Không có câu trả lời nào sử dụng bộ chọn +(không tồn tại) mà OP yêu cầu cụ thể. Hãy xem câu trả lời này là một bản "hack". Nó ở đây để tiết kiệm thời gian của người khác mà tôi đã dành để tìm giải pháp.
SherylHohman

2

Không có bộ chọn anh chị em "trước" không may, nhưng bạn có thể vẫn được hiệu ứng tương tự bằng cách sử dụng định vị (ví dụ: float phải). Nó phụ thuộc vào những gì bạn đang cố gắng làm.

Trong trường hợp của tôi, tôi muốn có một hệ thống xếp hạng 5 sao chủ yếu là CSS. Tôi sẽ cần tô màu (hoặc hoán đổi biểu tượng của) các ngôi sao trước đó. Bằng cách thả nổi từng phần tử đúng, về cơ bản, tôi nhận được cùng một hiệu ứng (do đó, html cho các ngôi sao phải được viết 'ngược').

Tôi đang sử dụng FontAwgie trong ví dụ này và hoán đổi giữa các unicodes của fa-star-o và fa-star http://fortawclaw.github.io/Font-Awemme/

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
nổi bên phải và +hoặc ~bộ chọn tấn công tôi là công việc sạch nhất xung quanh.
Wylliam Judd

2

Tùy thuộc vào mục tiêu chính xác của bạn, có một cách để đạt được sự hữu ích của bộ chọn cha mà không cần sử dụng một (ngay cả khi chúng tồn tại) ...

Nói rằng chúng tôi có:

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

Chúng ta có thể làm gì để làm cho khối Vớ (bao gồm cả màu sock) nổi bật bằng cách sử dụng khoảng cách?

Điều gì sẽ tốt đẹp nhưng không tồn tại:

ul li ul:parent {
  margin-top: 15px;
  margin-bottom: 15px;
}

Cái gì tồn tại:

li > a {
  margin-top: 15px;
  display: block;
}
li > a:only-child {
  margin-top: 0px;
}

Điều này đặt tất cả các liên kết neo có lề 15px ở trên cùng và đặt lại về 0 cho những liên kết không có phần tử UL (hoặc các thẻ khác) bên trong LIs.


2

Tôi cần một giải pháp để chọn anh chị tr trước. Tôi đã đưa ra giải pháp này bằng cách sử dụng các thành phần React và Styled. Đây không phải là giải pháp chính xác của tôi (Đây là từ bộ nhớ, vài giờ sau). Tôi biết có một lỗ hổng trong hàm setHighlighterRow.

OnMouseOver một hàng sẽ đặt chỉ mục hàng thành trạng thái và đăng ký lại hàng trước đó bằng màu nền mới

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

0

Không có, và .

Nếu bạn phải đặt nhãn trước đầu vào, thay vì đặt nhãn sau đầu vào, hãy giữ cả nhãn & đầu vào bên trong div và tạo kiểu cho div như sau:

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

Bây giờ bạn có thể áp dụng các tùy chọn kiểu dáng anh chị em tiêu chuẩn tiếp theo có sẵn trong css và nó sẽ xuất hiện giống như bạn sử dụng kiểu dáng anh chị em trước đó.


-1

Tôi đã có một vấn đề tương tự và phát hiện ra rằng tất cả các vấn đề thuộc về bản chất này có thể được giải quyết như sau:

  1. cung cấp cho tất cả các mục của bạn một phong cách.
  2. cung cấp cho mục đã chọn của bạn một phong cách.
  3. cung cấp cho các mục tiếp theo một phong cách bằng cách sử dụng + hoặc ~.

và bằng cách này, bạn sẽ có thể tạo kiểu cho các mục hiện tại, trước đây của bạn (tất cả các mục được ghi đè bằng các mục hiện tại và tiếp theo) và các mục tiếp theo của bạn.

thí dụ:

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

Hy vọng nó sẽ giúp được ai đó.


1
về cơ bản, đây là một mẹo tương tự như trong câu trả lời cũ hơn từ cùng một chủ đề: stackoverflow.com/a/27993987/717732
quetzalcoatl
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.