มีตัวเลือก“ พี่น้องก่อนหน้า” หรือไม่?


1355

เครื่องหมายบวก ( +) สำหรับพี่น้องคนต่อไป

มีเทียบเท่าสำหรับพี่น้องก่อนหน้า?


18
OMG คำตอบทั้งหมดที่นี่แนะนำให้คุณย้อนกลับลำดับขององค์ประกอบ html จากนั้นใช้ CSS เพื่อทำให้พวกเขาดูย้อนหลังเป็นการยืดตัวที่แท้จริง แน่นอนว่ามันไม่ได้ระบุไว้ในคำถาม แต่คำถาม "คุณสามารถทำ X กับ CSS" ได้ส่วนใหญ่ควรถือว่าคุณไม่สามารถเปลี่ยนโครงสร้าง HTML ได้
squarecandy

3
@squarecandy ฉันเห็นด้วยกับความคิดเห็นของคุณเป็นส่วนใหญ่ แต่วิธีแก้ปัญหาที่คุณอ้างอิงว่าไม่เพียงพอนั้นมีประโยชน์ในบางกรณี (สังเกตเห็น upvotes) ดังนั้นพวกเขาจึงควรโพสต์ สิ่งที่คุณเห็นว่าเป็น "การยืดตัวที่แท้จริง" อาจเป็น "โซลูชั่นสร้างสรรค์" สำหรับผู้อื่น
Michael Benjamin

คำตอบ:


839

ไม่ไม่มีตัวเลือก "พี่น้องก่อนหน้า"

ในบันทึกย่อที่เกี่ยวข้องนั้น~มีไว้สำหรับพี่น้องผู้สืบทอดทั่วไป (หมายถึงองค์ประกอบที่มาหลังจากสิ่งนี้ แต่ไม่จำเป็นทันทีหลังจากนั้น) และเป็นตัวเลือก CSS3 +สำหรับพี่น้องคนต่อไปและเป็น CSS2.1

ดูCombinator พี่น้องที่อยู่ติดกันจากSelectors ระดับที่ 3และ5.7 เตอร์พี่น้องที่อยู่ติดกันจากการ Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) สเปก


14
จากมาตรฐาน CSS3: องค์ประกอบที่แสดงโดยสองลำดับใช้ร่วมกันพาเรนต์เดียวกันในแผนผังเอกสารและองค์ประกอบที่แสดงด้วยลำดับแรกนำหน้า (ไม่จำเป็นต้องทันที) องค์ประกอบที่แสดงโดยลำดับที่สอง
โกหก,

26
@Lie Ryan: ใช่ แต่จุด cletus ทำในคำตอบของเขาคือคุณไม่ได้เลือกองค์ประกอบก่อนหน้า
BoltClock

42
นี่คือตัวอย่างที่ฉันทำเพื่อดูว่าสิ่งนี้ทำได้และทำไม่ได้ jsfiddle.net/NuuHy/1
Abacus

7
ฟังก์ชั่น jquery มีประโยชน์สำหรับสิ่งนี้คือ prev () ตัวอย่างเช่น $ ("# the_element"). prev (). css ("background-color", "red")
Satbir Kira

1
สิ่งนี้อาจช่วยได้: stackoverflow.com/questions/42680881/…
samnau

234

ฉันพบวิธีที่จะจัดรูปแบบพี่น้องก่อนหน้าทั้งหมด (ตรงข้าม~) ที่อาจทำงานได้ขึ้นอยู่กับสิ่งที่คุณต้องการ

สมมติว่าคุณมีรายการลิงก์และเมื่อวางเมาส์บนลิงก์ลิงก์ก่อนหน้าทั้งหมดควรเปลี่ยนเป็นสีแดง คุณสามารถทำได้เช่นนี้:

/* 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
คุณสามารถเพิ่มคำอธิบายว่ามันทำงานอย่างไร (ดูเหมือนว่าคุณใช้สไตล์กับรายการทั้งหมดและรายการต่อไปนี้ แต่สามารถอธิบายได้อย่างชัดเจน)
อัล

1
ทางออกที่ดีเลิศ ไม่จำเป็นต้องเรียงลำดับองค์ประกอบใหม่ในมาร์กอัปหรือสร้างการแสดงผล (ผ่านfloat:right) มันต้องมีการยุบช่องว่างระหว่างหน่วย / คำและช่องว่างภายในแทนที่จะเป็นระยะขอบ แต่มันทำงานได้อย่างสมบูรณ์แบบ!
Steven Vachon

7
ใช่แล้ว แต่ก่อนหน้านั้นจำเป็นต้องใช้เวลาส่วนใหญ่ไม่ใช่ทุกอย่างที่ผ่านมา!
azerafati

41
ลิงก์ทั้งหมดจะเปลี่ยนเป็นสีแดงหากฉันวางเมาส์เหนือช่องว่างระหว่างพวกเขาสำหรับฉัน
ลินน์

3
@ ลินน์คำตอบมีเพียงรหัสเพื่อทำให้ลิงค์ก่อนหน้าเป็นสีแดงเมื่อเลื่อน สไตล์เพิ่มเติมขึ้นอยู่กับกรณีการใช้งานของคุณ สำหรับองค์ประกอบการจัดอันดับดาว (ซึ่งฉันคิดว่าเป็นกรณีทั่วไป) คุณจะต้องกำจัดพื้นที่นั้นและทำให้ลิงก์ที่อยู่ใกล้เคียงเป็นสีแดง
mantish

164

Selectors ระดับ 4 แนะนำ:has() (ก่อนหน้านี้ตัวบ่งชี้เรื่อง!) ซึ่งจะช่วยให้คุณเลือกพี่น้องก่อนหน้าด้วย:

previous:has(+ next) {}

... แต่ในขณะที่เขียนมันเป็นระยะทางไกลเกินกว่าขอบตกเลือดเพื่อรองรับเบราว์เซอร์


51
"Bleeding edge สำหรับการสนับสนุนเบราว์เซอร์"อาจเป็นการกล่าวเกินจริง ในขณะที่เขียนสิ่งนี้ Chrome แม้แต่รุ่นล่าสุดไม่สามารถใช้:has()คลาสหลอกได้
Reed Martin

33
@ReedMartin - นั่นเป็นเหตุผลที่ฉันพูดระยะทางเกินขอบเลือดออก
Quentin

12
": ไม่มีการทำเครื่องหมายเป็นส่วนหนึ่งของโปรไฟล์ตัวเลือกแบบไดนามิกซึ่งหมายความว่าไม่สามารถใช้ภายในสไตล์ชีตได้เฉพาะกับฟังก์ชั่นเช่น document.querySelector ()" - developer.mozilla.org/en-US/docs/Web/CSS/:has
Arch Linux Tux

1
@ArchLinuxTux: "ข้อ จำกัด นี้ถูกลบออกไป" ดังนั้นกาลครั้งหนึ่งเราอาจใช้คุณลักษณะนี้: D
Jacob van Lingen

@JacobvanLingen - caniuse.com/#feat=css-has - ไม่มีเบราว์เซอร์ที่รองรับในปัจจุบัน
เควนติน

153

พิจารณาorderคุณสมบัติของโครงร่างแบบยืดหยุ่นและกริด

ฉันจะมุ่งเน้นไปที่ flexbox ในตัวอย่างด้านล่าง แต่แนวคิดเดียวกันนี้ใช้กับกริด


ด้วย flexbox ตัวเลือกพี่น้องก่อนหน้านี้สามารถจำลองได้

โดยเฉพาะorderคุณสมบัติยืดหยุ่นสามารถย้ายองค์ประกอบไปรอบ ๆ หน้าจอ

นี่คือตัวอย่าง:

คุณต้องการให้องค์ประกอบ A เปลี่ยนเป็นสีแดงเมื่อองค์ประกอบ B ถูกโฮเวอร์

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

ขั้นตอน

  1. ทำulภาชนะบรรจุแบบยืดหยุ่น

    ul { display: flex; }

  1. กลับคำสั่งของพี่น้องในเครื่องหมาย

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

  1. ใช้ตัวเลือกพี่น้องเพื่อกำหนดเป้าหมายองค์ประกอบ A ( ~หรือ+จะทำ)

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

  1. ใช้orderคุณสมบัติflex เพื่อเรียกคืนลำดับของพี่น้องบนหน้าจอแสดงผล

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

... และvoilà! ตัวเลือกพี่น้องก่อนหน้านี้ถือกำเนิดขึ้น (หรืออย่างน้อยจำลอง)

นี่คือรหัสเต็ม:

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 แสดงลำดับ: orderคุณสมบัติ

โดยปกติแล้วรายการ Flex จะแสดงและจัดวางตามลำดับเดียวกับที่ปรากฏในเอกสารต้นฉบับ orderคุณสมบัติสามารถใช้ในการเปลี่ยนการสั่งซื้อนี้

orderควบคุมคุณสมบัติลำดับที่รายการดิ้นปรากฏภายในภาชนะดิ้นโดยการกำหนดให้พวกเขากลุ่มลำดับ ใช้<integer>ค่าเดียวซึ่งระบุกลุ่มลำดับที่รายการ flex อยู่

orderค่าเริ่มต้นสำหรับรายการ flex ทั้งหมดคือ 0

ยังเห็นorderในตาราง CSS เค้าโครงข้อมูลจำเพาะ


ตัวอย่างของ "selector sibling selectors ก่อนหน้า" ที่สร้างขึ้นด้วยorderคุณสมบัติflex

.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


A Side Note - ความเชื่อที่ล้าสมัยสองเรื่องเกี่ยวกับ CSS

Flexbox กำลังสลายความเชื่อที่มีมานานเกี่ยวกับ CSS

หนึ่งความเชื่อดังกล่าวคือตัวเลือกพี่น้องก่อนหน้านี้เป็นไปไม่ได้ใน CSS

ที่จะบอกว่าความเชื่อนี้เป็นที่แพร่หลายจะเป็นการพูดน้อย นี่คือตัวอย่างของคำถามที่เกี่ยวข้องกับ Stack Overflow เพียงอย่างเดียว:

ตามที่อธิบายไว้ข้างต้นความเชื่อนี้ไม่เป็นความจริงทั้งหมด ตัวเลือกพี่น้องก่อนหน้านี้สามารถจำลองใน CSS โดยใช้orderคุณสมบัติflex

z-indexตำนาน

ความเชื่อที่มีมานานแล้วอีกอย่างหนึ่งก็คือมันใช้งานได้z-indexกับองค์ประกอบที่วางตำแหน่ง

ในความเป็นจริงเวอร์ชันล่าสุดของสเป็ค - ร่างของ W3C Editor - ยังคงยืนยันสิ่งนี้เป็นจริง:

9.9.1 การระบุระดับสแต็ก: z-index คุณสมบัติ

z-index

  • ค่า: อัตโนมัติ | | สืบทอด
  • เริ่มต้น: อัตโนมัติ
  • ใช้กับ: องค์ประกอบตำแหน่ง
  • สืบทอดมา: ไม่
  • เปอร์เซ็นต์: N / A
  • สื่อ: ภาพ
  • ค่าที่คำนวณได้: ตามที่ระบุ

(เน้นเพิ่ม)

อย่างไรก็ตามในความเป็นจริงข้อมูลนี้ล้าสมัยและไม่ถูกต้อง

องค์ประกอบที่เป็นรายการดิ้นหรือรายการตารางสามารถสร้างบริบทซ้อนแม้ในขณะที่เป็นpositionstatic

4.3 Flex Item Z- การสั่งซื้อ

รายการ Flex สีเหมือนกับบล็อกแบบอินไลน์ยกเว้นการสั่งซื้อเอกสารที่สั่งการแก้ไขถูกนำมาใช้ในสถานที่ของการสั่งซื้อเอกสารดิบและz-indexค่าอื่น ๆ กว่าautoสร้างบริบทซ้อนแม้ว่ามีpositionstatic

5.4 การสั่งซื้อแกน Z: z-indexคุณสมบัติ

การสั่งซื้อภาพวาดของรายการตารางเป็นเหมือนกับบล็อกแบบอินไลน์ยกเว้นการสั่งซื้อเอกสารเพื่อแก้ไขที่ใช้ในสถานที่ของการสั่งซื้อเอกสารดิบและz-indexค่าอื่น ๆ กว่าautoสร้างบริบทซ้อนแม้ว่า มีpositionstatic

นี่คือตัวอย่างของz-indexการทำงานกับไอเท็มเฟล็กซ์ที่ไม่มีตำแหน่ง: https://jsfiddle.net/m0wddwxs/


15
orderคุณสมบัติไม่ได้แก้ปัญหาเพราะมันมีจุดมุ่งหมายเพียงเพื่อเปลี่ยนภาพการสั่งซื้อจึงไม่คืนค่าเดิมsemanticalลำดับที่คุณถูกบังคับให้เปลี่ยนแปลงใน HTML สำหรับวิธีแก้ปัญหานี้ในการทำงาน
Marat Tanalin

2
@Marat Tanalin: สำหรับ 90% ของกรณีการใช้งานสมมติว่าการสนับสนุนเบราว์เซอร์ไม่ใช่ปัญหานี่จะใช้งานได้ดี ส่วนที่เหลือ 10% ของกรณีการใช้งานเป็น 1) กรณีที่เปลี่ยนลำดับภาพไม่ใช่วิธีแก้ปัญหาหรือ 2) กรณีที่ไม่เกี่ยวข้องกับ CSS เลย โชคดีสำหรับ # 2 selectors-4 มี: มี () และมันก็ขึ้นอยู่กับนักพัฒนาของไลบรารีตัวเลือกที่จะนำไปใช้
BoltClock

5
โปรดทราบว่า CSS2.2 ED ที่คุณอ้างถึงนั้นยังคงเป็น CSS2 และเฟล็กบ็อกซ์และโครงร่างกริดจะไม่มีอยู่ใน CSS2 เท่าที่เกี่ยวข้องกับ CSS2 ข้อมูลนั้นมีอยู่จริง อย่างน้อยที่สุดข้อความอาจถูกปรับปรุงเพื่อพูดถึงว่าดัชนี z อาจนำไปใช้กับองค์ประกอบประเภทอื่น ๆ ในระดับอนาคตของ CSS เช่นเดียวกับที่กล่าวว่าคุณสมบัติอื่น ๆ อาจสร้างบริบทการซ้อนเช่นความทึบ
BoltClock

3
ในกรณีที่ทุกคนกำลังมีปัญหาในการทำความเข้าใจเมื่อz-indexจะทำงานแม้เมื่อ "omg ไม่มีการpositionระบุ!" สเปคกล่าวถึงแนวคิดของบริบทการซ้อนซึ่งมีการอธิบายอย่างดีจากบทความนี้ใน MDN
Rogier Spieker

3
@Michael_B ยินดีต้อนรับ! ฉันจัดการกับผู้มีส่วนหน้าจำนวนมากไม่รู้เรื่องนี้ อีกสิ่งหนึ่งที่ฉันอยากจะพูดถึงตัวเลือกพี่น้องก่อนหน้านี้แบบ fauxยังใช้งานได้ดีกับfloat: right(หรือวิธีการอื่น ๆ เพื่อย้อนกลับการเรียงลำดับซึ่งflex/orderมีผลข้างเคียงน้อย (อย่างน้อย?) วิปริตสองตัวแสดงให้เห็นถึงfloat: rightวิธีการและการสาธิตdirection: rtl
Rogier Spieker

69

ฉันมีคำถามเดียวกัน แต่แล้วฉันก็มีช่วงเวลา "duh" แทนที่จะเขียน

x ~ y

เขียน

y ~ x

เห็นได้ชัดว่าการจับคู่นี้ "x" แทนที่จะเป็น "y" แต่มันตอบว่า "มีการแข่งขันหรือไม่?" คำถามและการสำรวจเส้นทาง DOM อย่างง่ายอาจนำคุณไปยังองค์ประกอบที่เหมาะสมมีประสิทธิภาพมากกว่าการวนซ้ำใน javascript

ฉันรู้ว่าคำถามเดิมเป็นคำถาม CSS ดังนั้นคำตอบนี้อาจไม่เกี่ยวข้องอย่างสมบูรณ์ แต่ผู้ใช้ Javascript รายอื่นอาจสะดุดกับคำถามผ่านทางการค้นหาอย่างที่ฉันทำ


18
ฉันเชื่อว่าใช้งานได้เมื่อ y สามารถพบได้ง่าย ปัญหาคือถ้า y สามารถพบได้เทียบกับ x และในการย้อนกลับคุณไม่สามารถหา y เพราะคุณต้องค้นหา x ก่อน นี่เป็นเรื่องของการอ้างอิงถึงคำถามที่ว่าก่อนหน้านี้มีพี่น้องมากกว่าที่จะเป็นพี่น้องกัน แต่อาจจะสมัครเป็นพี่น้องต่อไปนี้
เดวิด

19
คุณเป็นคนที่ใจดี (ขออภัยไม่สามารถต้านทานได้) ประเด็นก็คือบางครั้งคุณเพียงแค่ต้องรู้ว่า "มีอยู่จริงหรือไม่?" เวลาอื่นคุณสามารถใช้ ": ก่อน" เพื่อวางบางสิ่งระหว่างองค์ประกอบสองอย่าง ในที่สุดหากคุณจำเป็นต้องวางใน jQuery การใช้ find ("y ~ x"). prev () ง่ายกว่าทางเลือกอื่น
ไบรอันลาเซน

156
แนวคิดของตัวเลือกพี่น้องก่อนหน้าคือมันจะเลือกองค์ประกอบก่อนหน้า น่าเสียดายที่การย้อนกลับดังที่อธิบายไว้ที่นี่ไม่ได้ให้ฟังก์ชันการทำงานนี้
Zenexer

14
ขอบคุณ @ Zenexer สำหรับการชี้แจงว่าคำตอบนี้ไม่ได้ให้คำตอบที่แท้จริงกับคำถามเดิมฉันเริ่มรู้สึกว่าตัวเองโง่ที่คิดว่าy ~ xจะแก้ปัญหาของฉันได้อย่างไร
Jaime Hablutzel

4
ฉันเข้าใจแนวคิดเบื้องหลังคำตอบนี้อย่างไรก็ตามการให้เหตุผลในคำตอบนั้นไม่สมเหตุสมผล ตัวเลือกy ~ xไม่ตอบ "มีการแข่งขันหรือไม่?" คำถามเพราะตัวเลือกสองตัวที่ให้ที่นี่หมายถึงสิ่งที่แตกต่างอย่างสิ้นเชิง ไม่มีทางใดที่y ~ xจะสามารถสร้างการแข่งขันให้กับทรีย่อย<root><x/><y/></root>ได้ หากคำถามคือ "ไม่มี y" yแล้วเลือกเป็นเพียง หากคำถามคือ "y มีอยู่แล้วที่ได้รับ x ในตำแหน่งใด ๆ ?" ถ้าคุณต้องการตัวเลือกทั้งคู่ (แม้ว่าบางทีฉันแค่ nitpicking ณ จุดนี้ ... )
BoltClock

25

สองเทคนิค โดยทั่วไปการกลับคำสั่ง HTML ขององค์ประกอบที่คุณต้องการใน HTML และใช้ตัวดำเนินการ
~ พี่น้องถัดไป :

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>


25

+สำหรับพี่น้องคนต่อไป มีเทียบเท่าสำหรับพี่น้องก่อนหน้า?

คุณสามารถใช้ตัวเลือกขวานสองตัว: !และ?

มี2ตัวเลือกพี่น้องที่ตามมาใน CSS ธรรมดา:

  • +เป็นตัวเลือกพี่น้องที่ตามมาทันที
  • ~เป็นตัวเลือกพี่น้องใด ๆ ที่ตามมา

ใน CSS ธรรมดามีไม่มีตัวเลือกพี่น้องก่อนหน้านี้

อย่างไรก็ตามในไลบรารี CSS post-processor axมีตัวเลือก sibling ก่อนหน้านี้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>


3
สิ่งนี้ทำให้ฉันมีข้อผิดพลาดทางไวยากรณ์เมื่อฉันพยายามที่จะใช้มันบน sass ภายในโครงการราง
alex

25
axeเป็น CSS post-processor มันไม่ได้ใช้ไวยากรณ์เดียวกับตัวประมวลผลล่วงหน้า CSS เช่น Sass, Less หรือ Stylus
Rounin

1
@Rounin คุณต้องการเพิ่มลิงก์เอกสารหรือไม่ ฉันไม่พบax -post-processor
Dionys

@Dionys - ขอบคุณที่ให้ความสนใจ axเป็นโครงการที่ฉันเริ่มในปลายปี 2559 เมื่อฉันไม่รู้ ES2015 และแม้แต่สิ่งของใน JS ก็ยังใหม่สำหรับฉัน พื้นที่เก็บข้อมูล GitHub อยู่ที่นี่: github.com/RouninMedia/axe ฉันตั้งใจจะกลับมาที่จุดนี้ (ฉันได้พัฒนาบางสิ่งที่เรียกว่าax-bladeซึ่งเทียบเท่ากับ CSS ของเหตุการณ์จาวาสคริปต์) แต่ฉันต้องทำงานให้เสร็จในโครงการอื่น (codenamed ashiva ) ก่อน
Rounin

17

โซลูชัน flexbox อื่น

คุณสามารถใช้ลำดับขององค์ประกอบที่ตรงกันข้ามใน 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>


16

ไม่มีวิธีที่เป็นทางการที่จะทำในขณะนี้ แต่คุณสามารถใช้เคล็ดลับเล็ก ๆ น้อย ๆ เพื่อให้บรรลุนี้! โปรดจำไว้ว่ามันเป็นการทดลองและมีข้อ จำกัด บางอย่าง ... (ตรวจสอบลิงค์นี้หากคุณกังวลเกี่ยวกับความเข้ากันได้ของระบบนำทาง)

สิ่งที่คุณสามารถทำได้คือใช้ตัวเลือก CSS3: คลาส pseudo ที่เรียกว่า 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>

ข้อ จำกัด

  • คุณไม่สามารถเลือกองค์ประกอบก่อนหน้าตามคลาสขององค์ประกอบถัดไป
  • นี่เป็นสิ่งเดียวกันสำหรับคลาสหลอก

1
@Ian เนื่องจาก:nth-child(-n+4)เป็นคลาสหลอกที่ต้องใช้กับตัวเลือกเพื่อให้สามารถทำงานได้อย่างถูกต้อง หากคุณไม่โน้มน้าวใจให้ลองทดสอบโดยใช้ซอของฉันและคุณจะเห็นว่ามันไม่ทำงาน
0x1gene

1
ที่จริงแล้วคุณสามารถไปที่โหนดชนิดอิสระโดยใช้*ตัวเลือก แต่มันเป็นวิธีปฏิบัติที่ไม่ดีอย่างน่าสะพรึงกลัว
Josh Burgess

1
นี่คือคำตอบที่เหมาะกับฉันไม่แน่ใจว่าทำไมมันไม่ได้รับการโหวตสูงกว่าหรือยอมรับ
Jake Cattrall

1
ที่จริงแล้วมันไม่ทำงานสำหรับโหนดที่แตกต่างกัน: jsfiddle.net/aLhv9r1w/316 โปรดอัปเดตคำตอบของคุณ :)
Jamie Barker

1
ฉันมีตัวเลือกที่ซับซ้อน แต่สมมุติว่ามันli#someListItemและฉันต้องการโหนดก่อนหน้า (ซึ่งเป็นวิธีที่ฉันตีความ "ก่อนหน้า") - ฉันไม่เห็นว่าข้อมูลที่คุณให้ไว้สามารถช่วยฉันแสดงความรู้สึกผ่าน CSS ได้อย่างไร คุณแค่เลือกพี่น้อง n คนแรกและคิดว่าฉันรู้จัก n ตามตรรกะนี้ตัวเลือกใด ๆ อาจทำเคล็ดลับและเลือกองค์ประกอบที่ฉันต้องการ (เช่น: ไม่ ())
bitoolean

4

หากคุณทราบตำแหน่งที่แน่นอนการ:nth-child()ยกเว้นแบบรวมของพี่น้องต่อไปนี้จะใช้ได้

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

ซึ่งจะเลือกทั้งหมดliก่อน 3 (เช่น 1 และ 2) แต่ในความคิดของฉันนี้ดูน่าเกลียดและมี usecase แน่นมาก

คุณสามารถเลือก nth-child จากขวาไปซ้าย:

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

ซึ่งทำเช่นเดียวกัน


3

ไม่มันไม่สามารถทำได้ผ่าน CSS มันใช้เวลา "แคสเคด" ถึงหัวใจ ;-)


อย่างไรก็ตามหากคุณสามารถเพิ่มJavaScriptลงในหน้าของคุณได้jQueryเล็กน้อยสามารถนำคุณไปสู่เป้าหมายสุดท้ายได้
คุณสามารถใช้ jQuery findเพื่อทำการ "ดูล่วงหน้า" ในองค์ประกอบเป้าหมาย / คลาส / id ของคุณจากนั้นย้อนรอยเพื่อเลือกเป้าหมายของคุณ
จากนั้นคุณใช้ jQuery เพื่อเขียน DOM (CSS) อีกครั้งสำหรับองค์ประกอบของคุณ

จากคำตอบของ Mike Brant คำตอบ jQuery ต่อไปนี้อาจช่วยได้

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

นี่เป็นครั้งแรกเลือกทั้งหมดของที่ทำตามได้ทันที<ul> จากนั้นก็เป็น "backtracks" เพื่อเลือกs ก่อนหน้าทั้งหมดจากชุดนั้น<p>
<p><ul> s

อย่างมีประสิทธิภาพ "พี่น้องก่อนหน้า" ได้รับการคัดเลือกผ่าน jQuery
ตอนนี้ใช้.cssฟังก์ชั่นเพื่อส่งผ่านค่าใหม่ของ CSS สำหรับองค์ประกอบนั้น


ในกรณีของผมกำลังมองหาวิธีที่จะเลือก DIV กับประชาชนได้เป็น#full-widthแต่ถ้ามันมี (อ้อม) DIV .companiesลูกหลานที่มีระดับของ

ฉันควบคุม HTML ทั้งหมดภายใต้.companiesแต่ไม่สามารถแก้ไข HTML ใด ๆ ข้างต้นได้
และน้ำตกมีทิศทางเดียวเท่านั้น: ลง

ดังนั้นฉันสามารถเลือกทั้งหมด#full-widthได้
หรือฉันเลือกได้.companiesว่าทำตามก#full-width.
แต่ฉันไม่สามารถเลือกเฉพาะรายการ#full-widthที่ดำเนินการต่อ .companiesได้

และอีกครั้งฉันไม่สามารถเพิ่มได้ .companiesสูงขึ้นใน HTML ส่วนหนึ่งของ HTML นั้นถูกเขียนจากภายนอกและห่อโค้ดของเราไว้

แต่ด้วย jQuery ฉันสามารถเลือก#full-widths ที่ต้องการจากนั้นกำหนดสไตล์ที่เหมาะสม:

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

สิ่งนี้จะค้นหาทั้งหมด#full-width .companiesและเลือกเฉพาะที่.companiesคล้ายกับวิธีใช้ตัวเลือกเพื่อกำหนดเป้าหมายองค์ประกอบเฉพาะในมาตรฐานใน CSS
จากนั้นก็จะใช้.parentsเป็น "เปลี่ยนใจ" และเลือกพ่อแม่ของ ALL .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
. ค้นหา : รับลูกหลานของแต่ละองค์ประกอบในชุดปัจจุบันขององค์ประกอบที่ตรงกันกรองโดยตัวเลือกวัตถุ jQuery หรือองค์ประกอบ
. parent : รับพี่น้องก่อนหน้าทันทีของแต่ละองค์ประกอบในชุดขององค์ประกอบที่ตรงกัน หากมีการเลือกตัวเลือกใดตัวเลือกนี้จะดึงข้อมูลรุ่นก่อนหน้านี้เฉพาะเมื่อตรงกับตัวเลือกนั้น (กรองผลลัพธ์เพื่อรวมองค์ประกอบ / ตัวเลือกที่ระบุไว้เท่านั้น)
. css : ตั้งค่าคุณสมบัติ CSS หนึ่งรายการขึ้นไปสำหรับชุดองค์ประกอบที่ตรงกัน


สิ่งนี้ไม่เกี่ยวข้องกับคำถาม แน่นอนเป็นไปได้ที่ใช้ JS และคุณไม่จำเป็นต้องมี jQuery สำหรับสิ่งนี้ ( previousElementSibling)
Fabian von Ellerts

1
@FabianvonEllerts ฉันตอบคำถามของ OP โดยตรงในบรรทัดแรกของคำตอบของฉัน ตามคำตอบของฉันมันเป็นไปไม่ได้เลยที่CSS จากนั้นฉันก็เตรียมเส้นทางที่เป็นไปได้1 ทางเพื่อให้บรรลุเป้าหมายโดยใช้เทคโนโลยี (JS | JQuery) ที่ผู้ใช้ CSS อาจคุ้นเคยและสามารถเข้าถึงได้ ตัวอย่างเช่นเว็บไซต์ WordPress หลายแห่งมี JQuery ดังนั้นจึงเป็นจุดเริ่มต้นที่ง่าย: ใช้งานง่ายจดจำและขยายต่อไป มันจะไม่รับผิดชอบที่จะตอบเพียงแค่ไม่โดยไม่ต้องให้ทางเลือกอื่นในการบรรลุเป้าหมาย ฉันแบ่งปันสิ่งที่ฉันเรียนรู้และใช้เมื่อฉันมีคำถามเดียวกัน
SherylHohman

previousElementSibling()สำหรับผู้ที่คุ้นเคยกับฟังก์ชั่นดั้งเดิมของ JS DOM สามารถให้เส้นทางอื่นที่ไม่ใช่ CSS ไปข้างหน้า
SherylHohman

ฉันพบ CSS HACKS อื่น ๆ ที่น่าสนใจมาก แต่สำหรับกรณีการใช้งานเฉพาะของฉันพวกเขาไม่ได้ทำงาน (ตกอยู่ในหมวดหมู่ caveats) หรือซับซ้อนเกินไป สำหรับคนอื่นที่ตกอยู่ในสถานการณ์เดียวกันมันยุติธรรมที่จะแบ่งปันวิธีที่ง่ายต่อการใช้งานที่สามารถทำงานได้ซึ่งวิธีการแก้ปัญหาข้างต้นล้มเหลวหรือยากเกินไปที่จะนำไปใช้ / บำรุงรักษา CSS HACKS จำนวนมากถูกแชร์ งานนี้ไม่ครอบคลุม ไม่มีคำตอบใช้ตัวเลือก+(ไม่มีอยู่) ที่ OP ขอมาโดยเฉพาะ ลองพิจารณาคำตอบนี้ว่า "แฮ็ค" JS อยู่ที่นี่เพื่อช่วยคนอื่นเวลาที่ฉันใช้เพื่อหาทางแก้ไข
SherylHohman

2

ไม่มี "ก่อนหน้า" ตัวเลือกพี่น้องเป็นที่น่าเสียดาย แต่คุณสามารถเป็นไปได้ยังได้รับผลกระทบเดียวกันโดยใช้การจัดตำแหน่ง (เช่นลอยไปทางขวา) ขึ้นอยู่กับสิ่งที่คุณพยายามจะทำ

ในกรณีของฉันฉันต้องการระบบการจัดอันดับ CSS 5 ดาวเป็นหลัก ฉันต้องการสี (หรือสลับไอคอน) ดาวก่อนหน้า โดยการลอยองค์ประกอบแต่ละอันให้ถูกต้องฉันจะได้รับเอฟเฟกต์เดียวกัน (html สำหรับดวงดาวจึงต้องเขียนว่า 'ถอยหลัง')

ฉันใช้ FontAwesome ในตัวอย่างนี้และแลกเปลี่ยนระหว่าง unicodes ของ fa-star-o และ fa-star 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

2

ขึ้นอยู่กับวัตถุประสงค์ที่แน่นอนของคุณมีวิธีการใช้ประโยชน์ของตัวเลือกหลักโดยไม่ต้องใช้ตัวเลือกหนึ่ง (แม้ว่าจะมีอยู่) ...

บอกว่าเรามี:

<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 สำหรับผู้ที่ไม่มีองค์ประกอบ UL (หรือแท็กอื่น ๆ ) ภายใน LIs


2

ฉันต้องการวิธีแก้ไขเพื่อเลือกพี่น้องก่อนหน้านี้ ฉันคิดวิธีแก้ปัญหานี้โดยใช้ส่วนประกอบ React และ Styled-component นี่ไม่ใช่ทางออกที่แน่นอนของฉัน (นี่คือจากหน่วยความจำชั่วโมงต่อมา) ฉันรู้ว่ามีข้อบกพร่องในฟังก์ชั่น 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;
    }
`;

-1

ฉันมีปัญหาที่คล้ายกันและพบว่าปัญหาในลักษณะนี้สามารถแก้ไขได้ดังนี้

  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>

หวังว่าจะช่วยใครซักคน


1
มันเป็นเคล็ดลับเดียวกับคำตอบที่เก่ากว่าจากเธรดเดียวกัน: stackoverflow.com/a/27993987/717732
quetzalcoatl
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.