วิธีการจัดรูปแบบองค์ประกอบหลักเมื่อวางเมาส์เหนือองค์ประกอบลูก?


160

ฉันรู้ว่าไม่มีตัวเลือกพาเรนต์ CSSแต่มันเป็นไปได้หรือไม่ที่จะจัดสไตล์อิลิเมนต์การเลี้ยงดูเมื่อโฮเวอร์องค์ประกอบลูกโดยไม่มีตัวเลือกดังกล่าว?

ในการให้ตัวอย่าง: พิจารณาปุ่มลบที่เมื่อโฮเวอร์จะเน้นองค์ประกอบที่กำลังจะถูกลบ:

<div>
    <p>Lorem ipsum ...</p>
    <button>Delete</button>
</div>

ด้วย CSS บริสุทธิ์วิธีเปลี่ยนสีพื้นหลังของส่วนนี้เมื่อเมาส์อยู่เหนือปุ่ม


3
เป็นไปได้ที่ซ้ำกันมีตัวเลือกพาเรนต์ CSS หรือไม่
TylerH

วิธีแก้ปัญหาที่เป็นไปได้: stackoverflow.com/q/39374918/3597276
Michael Benjamin

คำตอบ:


134

ก่อนหน้านี้คำถามนี้ถูกถามมาหลายครั้งและคำตอบทั่วไปสั้น ๆ ก็คือมันไม่สามารถทำได้โดย CSS บริสุทธิ์ มันอยู่ในชื่อ: สไตล์ชีทแบบเรียงซ้อนรองรับเฉพาะสไตล์ในทิศทางแบบเรียงซ้อนเท่านั้น

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

<parent>
    <sibling></sibling>
    <child></child>
</parent>

เคล็ดลับคือการให้พี่น้องมีขนาดและตำแหน่งเท่ากันกับผู้ปกครองและกำหนดลักษณะของพี่น้องแทนผู้ปกครอง นี้จะมีลักษณะเหมือนพ่อแม่ที่มีสไตล์!

ตอนนี้วิธีการจัดสไตล์พี่น้อง?

เมื่อเด็กโฮเวอร์ผู้ปกครองก็เช่นกัน แต่พี่น้องไม่ได้เป็นเช่นนั้น เช่นเดียวกันสำหรับพี่น้อง สรุปในสามเส้นทาง CSS ตัวเลือกที่เป็นไปได้สำหรับจัดแต่งทรงผมพี่น้อง

parent sibling { }
parent sibling:hover { }
parent:hover sibling { }

เส้นทางที่แตกต่างเหล่านี้ช่วยให้มีความเป็นไปได้ที่ดี ตัวอย่างเช่นปล่อยเคล็ดลับนี้ในตัวอย่างในคำถามผลลัพธ์ในซอนี้ :

div {position: relative}
div:hover {background: salmon}
div p:hover {background: white}
div p {padding-bottom: 26px}
div button {position: absolute; bottom: 0}

สไตล์ภาพตัวอย่างผู้ปกครอง

เห็นได้ชัดว่าในกรณีส่วนใหญ่เคล็ดลับนี้ขึ้นอยู่กับการใช้การกำหนดตำแหน่งแบบสัมบูรณ์เพื่อให้พี่น้องมีขนาดเท่ากันกับผู้ปกครองและยังคงปล่อยให้เด็ก ๆ

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


1
สิ่งนี้เป็นสิ่งที่ดีสำหรับการเน้น แต่จะไม่ทำงานถ้าคุณลองเปลี่ยนสีตัวอักษรใช่ไหม
Jahanzeb Khan

1
@JahanzebKhan เปลี่ยนสีตัวอักษรจะไม่มีปัญหา
NGLN

116

ฉันรู้ว่ามันเป็นคำถามเก่า แต่ฉันก็ทำได้โดยไม่ต้องมีลูกหลอก (แต่เป็น wrapper หลอก)

หากคุณตั้งค่าพาเรนต์เป็นไม่pointer-eventsและจากนั้นเด็กที่divมีการpointer-eventsตั้งค่าจะautoใช้งานได้ :)
โปรดทราบว่า<img>แท็ก (เช่น) จะไม่ใช้กลอุบาย
นอกจากนี้อย่าลืมตั้งค่าpointer-eventsให้autoกับเด็กคนอื่นที่มีฟังเหตุการณ์ของตัวเองมิฉะนั้นพวกเขาจะสูญเสียฟังก์ชันการคลิก

div.parent {  
    pointer-events: none;
}

div.child {
    pointer-events: auto;
}

div.parent:hover {
    background: yellow;
}    
<div class="parent">
  parent - you can hover over here and it won't trigger
  <div class="child">hover over the child instead!</div>
</div>

แก้ไข:
ตามที่Shadow Wizard ได้กล่าวไว้โปรดทราบ: มันมีค่าที่จะกล่าวถึงสิ่งนี้จะไม่ทำงานสำหรับ IE10 และด้านล่าง (FF และ Chrome เวอร์ชันเก่าด้วยดูที่นี่ )


3
น่าจะพูดถึงเรื่องนี้จะไม่ทำงานสำหรับ IE10 และด้านล่าง (FF และ Chrome เวอร์ชันเก่าดูที่นี่ด้วย )
Shadow Wizard เป็นหูสำหรับคุณ

2
การตั้งค่ากิจกรรมตัวชี้เป็นไม่มีก็หมายความว่าผู้ฟังเหตุการณ์ในองค์ประกอบนั้นจะไม่ทำงาน .. !
rhazen

1
@rhazen คุณพูดถูก แม้ว่าจากประสบการณ์ของฉันการใช้งานนี้มักจะเชื่อมต่อกับพื้นที่การคลิก / องค์ประกอบเดียวดังนั้นคุณสามารถกำหนดฟังการคลิกให้กับผู้ปกครอง
guy_m

ถ้าฉันมีสองระดับ, ผู้ปกครอง, ลูก 1 และลูกของเด็ก 1 ฉันเพิ่มตัวชี้เหตุการณ์ที่ไม่มีไปยังผู้ปกครองและตัวชี้เหตุการณ์อัตโนมัติเพื่อลูก ฉันต้องการโฮเวอร์เพื่อ child1 ยกเว้นลูกของเด็ก 1 สาธิตที่นี่: codepen.io/lion5893/pen/WNQgyVx
Nam LêQuý

13

อีกวิธีที่ง่ายกว่า (สำหรับคำถามเก่า) ..
คือการวางองค์ประกอบเป็นพี่น้องและใช้:

ตัวเลือกพี่น้องที่อยู่ติดกัน ( +) หรือ ตัวเลือกพี่น้องทั่วไป ( ~)

<div id="parent">
  <!-- control should come before the target... think "cascading" ! -->
  <button id="control">Hover Me!</button>
  <div id="target">I'm hovered too!</div>
</div>
#parent {
  position: relative;
  height: 100px;
}

/* Move button control to bottom. */
#control {
  position: absolute;
  bottom: 0;
}

#control:hover ~ #target {
  background: red;
}

ป้อนคำอธิบายรูปภาพที่นี่

สาธิตซอนี่


1
น่าสังเกตว่านี่ใช้งานได้เท่านั้น #targets มาหลังจาก #control ใน DOM (นั่นคือคุณไม่สามารถส่งผลกระทบต่อพี่น้องคนก่อน ๆ ได้ แต่ติดตามพี่น้องคนเดียวเท่านั้น)
Gio

10

ไม่มีตัวเลือก CSS สำหรับการเลือกพาเรนต์ของชายด์ที่เลือก

คุณสามารถทำได้ด้วย JavaScript


3
จริง บางอย่างเช่น $ (child) .hover (function () {$ (this) .closest (parentSelector) .addClass ('hoverClass')}, function () {$ (this) .closest (parentSelector) .removeClass ('hoverClass' )});
Aamir Afridi

8
@AamirAfridi นั้นไม่ใช่ JS ที่บริสุทธิ์ แต่คุณต้องใช้ jQuery ด้วย
Ivotje50

6

ดังกล่าวก่อนหน้า "ไม่มีตัวเลือก CSS สำหรับการเลือกพาเรนต์ของชายด์ที่เลือก"

ดังนั้นคุณ:


นี่คือตัวอย่างสำหรับโซลูชันjavascript / jQuery

ทางด้านจาวาสคริปต์:

$('#my-id-selector-00').on('mouseover', function(){
  $(this).parent().addClass('is-hover');
}).on('mouseout', function(){
  $(this).parent().removeClass('is-hover');
})

และในด้าน CSS คุณมีสิ่งนี้:

.is-hover {
  background-color: red;
}

3

การแก้ปัญหานี้ขึ้นอยู่อย่างเต็มที่ในการออกแบบ แต่ถ้าคุณมี div ผู้ปกครองที่คุณต้องการเปลี่ยนพื้นหลังเมื่อโฉบเด็กคุณสามารถพยายามที่จะเลียนแบบของพ่อแม่ด้วยการ/::after::before

<div class="item">
    design <span class="icon-cross">x</span>
</div>

CSS:

.item {
    background: blue;
    border-radius: 10px;
    position: relative;
    z-index: 1;
}
.item span.icon-cross:hover::after {
    background: DodgerBlue;
    border-radius: 10px;
    display: block;
    position: absolute;
    z-index: -1;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    content: "";
}

ดูตัวอย่างซอเต็มรูปแบบได้ที่นี่


-1

jquery solution ง่ายๆสำหรับผู้ที่ไม่ต้องการโซลูชัน css บริสุทธิ์:

    $(".letter").hover(function() {
      $(this).closest("#word").toggleClass("hovered")
    });
.hovered {
  background-color: lightblue;
}

.letter {
  margin: 20px;
  background: lightgray;
}

.letter:hover {
  background: grey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="word">
  <div class="letter">T</div>
  <div class="letter">E</div>
  <div class="letter">S</div>
  <div class="letter">T</div>
</div>


-8

นี่เป็นเรื่องง่ายมากที่จะทำใน Sass! อย่าขุดคุ้ย JavaScript สำหรับสิ่งนี้ & ตัวเลือกใน sass ทำสิ่งนี้ทุกประการ

http://thesassway.com/intermediate/referencing-parent-selectors-using-ampersand


6
-1 Sass ไม่ได้เพิ่มฟังก์ชั่นเพิ่มเติมให้กับ css เพียงแค่ทำให้การเขียนง่ายขึ้น อะไรก็ตามที่คุณสามารถทำได้ใน sass นั้นสามารถทำได้ทั้งใน css และ Visa
Dastur

3
@Dastur ด้วยตัวแปรและมิกซ์อินฉันจะบอกว่า Sass เพิ่มสิ่งที่น่ากลัวให้กับ CSS คุณสามารถทำได้ทั้งหมดใน CSS ในลักษณะเดียวกับที่คุณยังสามารถเขียนซอฟต์แวร์ที่ซับซ้อนโดยใช้ภาษาซีแบบธรรมดาธรรมดาภาษาสมัยใหม่เพิ่มจำนวนมากโดยไม่ต้องเปิดใช้งานบางอย่างที่ไม่สามารถทำได้มาก่อน เหมือนกันกับ Sass และ CSS
Cobus Kruger

6
@Cobus Kruger ถูกต้อง แต่คุณไม่สามารถทำการเปรียบเทียบนั้นได้ ในขณะที่ภาษาอย่าง c ++ c # และ javascript อาจใช้ภาษา C แต่จะไม่เปลี่ยนเป็น C ก่อนรันไทม์ Sass ถูกแปลงเป็น css ก่อนรันไทม์ดังนั้นคุณไม่เคยโหลดสไตล์ชีต sass ของคุณอย่างแท้จริงเพียงแค่ css หนึ่งแผ่น
Dastur
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.