Bagaimana cara menata elemen induk saat mengarahkan elemen anak?

160

Saya tahu bahwa tidak ada pemilih induk CSS , tetapi apakah mungkin untuk menata elemen pengasuhan saat melayang elemen anak tanpa pemilih seperti itu?

Untuk memberikan contoh: pertimbangkan tombol hapus yang ketika diarahkan akan menyorot elemen yang akan dihapus:

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

Dengan menggunakan CSS murni, bagaimana cara mengubah warna latar belakang bagian ini ketika mouse di atas tombol?

NGLN
sumber
3
Kemungkinan rangkap dari apakah ada pemilih induk CSS?
TylerH
Solusi yang memungkinkan: stackoverflow.com/q/39374918/3597276
Michael Benjamin

Jawaban:

134

Nah, pertanyaan ini ditanyakan berkali-kali sebelumnya, dan jawaban singkatnya adalah: Tidak dapat dilakukan dengan CSS murni. Ada dalam namanya: Cascading Style Sheets hanya mendukung gaya dalam arah cascading, bukan ke atas.

Tetapi dalam kebanyakan situasi di mana efek ini diinginkan, seperti dalam contoh yang diberikan, masih ada kemungkinan untuk menggunakan karakteristik kaskade ini untuk mencapai efek yang diinginkan. Pertimbangkan markup pseudo ini:

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

Triknya adalah memberi saudara kandung ukuran dan posisi yang sama seperti orang tua dan untuk gaya saudara kandung bukan orang tua. Ini akan terlihat seperti orang tua ditata!

Sekarang, bagaimana gaya saudara kandungnya?

Ketika anak itu melayang, orang tuanya juga, tetapi saudara kandungnya tidak. Hal yang sama berlaku untuk saudara kandung. Ini menyimpulkan dalam tiga jalur pemilih CSS yang mungkin untuk menata saudara:

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

Jalur yang berbeda ini memungkinkan beberapa kemungkinan bagus. Misalnya, melepaskan trik ini pada contoh dalam hasil pertanyaan dalam biola ini :

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

Contoh gambar gaya induk

Jelas, dalam banyak kasus, trik ini tergantung pada penggunaan posisi absolut untuk memberi saudara kandung ukuran yang sama seperti orang tua, dan masih membiarkan anak muncul di dalam orang tua.

Kadang-kadang perlu untuk menggunakan jalur pemilih yang lebih berkualitas untuk memilih elemen tertentu, seperti yang ditunjukkan dalam biola ini yang mengimplementasikan trik beberapa kali dalam menu pohon. Cukup bagus kok.

NGLN
sumber
1
Ini bagus untuk disorot, tetapi tidak akan berfungsi jika Anda mencoba mengubah warna font, benarkan?
Jahanzeb Khan
1
@JahanzebKhan Mengubah warna font tidak masalah .
NGLN
117

Saya tahu ini adalah pertanyaan lama, tapi saya berhasil melakukannya tanpa anak semu (tapi pembungkus semu).

Jika Anda mengatur orang tua menjadi tanpa pointer-events, dan kemudian anak divdengan pointer-eventsset ke auto, itu berfungsi :)
Perhatikan bahwa <img>tag (misalnya) tidak melakukan trik.
Juga ingat untuk mengatur pointer-eventsuntuk autoanak-anak lain yang memiliki pendengar acara mereka sendiri, atau jika tidak mereka akan kehilangan fungsi klik mereka.

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>

Sunting:
Seperti yang dikatakan oleh Shadow Wizard : perlu disebutkan ini tidak akan bekerja untuk IE10 dan di bawah ini. (FF dan Chrome versi lama juga, lihat di sini )

guy_m
sumber
3
Layak untuk disebutkan ini tidak akan bekerja untuk IE10 dan di bawah ini. (FF dan Chrome versi lama juga, lihat di sini )
Shadow Wizard adalah Ear For You
2
Mengatur acara pointer ke none juga berarti bahwa pendengar acara pada elemen itu tidak akan berfungsi ..!
rhazen
1
@ rhazen Anda memang benar. Meskipun dari pengalaman saya, penggunaan ini biasanya terhubung ke satu area / elemen klik, sehingga Anda dapat menetapkan pendengar klik untuk parent
guy_m
Bagaimana kalau saya punya dua level, parent, child1, dan child of child1. Saya menambahkan pointer-events tidak ke induk dan pointer-events secara otomatis ke child. Saya ingin mengarahkan mouse ke child1 kecuali child of child 1. Demo di sini: codepen.io/lion5893/pen/WNQgyVx
Nam Lê Quý
13

Pendekatan lain yang lebih sederhana (untuk pertanyaan lama) ..
adalah menempatkan elemen sebagai saudara kandung dan menggunakan:

Selektor Adjacent Adjacent ( +) atau Seluler Adven Sibling ( ~)

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

masukkan deskripsi gambar di sini

Demo Fiddle di sini .

Onur Yıldırım
sumber
1
Perlu dicatat bahwa ini hanya berfungsi # gadget datang setelah #control di DOM (yaitu, Anda tidak dapat memengaruhi saudara kandung sebelumnya, hanya mengikuti saudara kandung)
Gio
10

tidak ada pemilih CSS untuk memilih induk dari anak yang dipilih.

Anda bisa melakukannya dengan JavaScript

Kae Verens
sumber
3
benar. sesuatu seperti $ (child) .hover (function () {$ (this) .closest (parentSelector) .addClass ('hoverClass')}, function () {$ (this) .closest (parentSelector) .removeClass ('hoverClass' )});
Aamir Afridi
8
@ AmirAfridi Itu bukan JS murni, Anda harus menggunakan jQuery dengan itu.
Ivotje50
6

Seperti disebutkan sebelumnya "tidak ada pemilih CSS untuk memilih orang tua dari anak yang dipilih".

Jadi kamu juga:


Berikut adalah contoh untuk javascript / jQuery solusi

Di sisi javascript:

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

Dan di sisi CSS, Anda akan memiliki sesuatu seperti ini:

.is-hover {
  background-color: red;
}
Remy Lagerweij
sumber
3

Solusi ini sepenuhnya tergantung pada desain, tetapi jika Anda memiliki div induk yang Anda ingin mengubah latar belakang ketika melayang-layang anak Anda dapat mencoba untuk meniru orangtua dengan ::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: "";
}

Lihat contoh biola lengkap di sini

Jan Mellström
sumber
-1

Solusi jquery sederhana bagi mereka yang tidak membutuhkan solusi css murni:

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

Sanogoals
sumber
-8

Ini sangat mudah dilakukan di Sass! Jangan mempelajari JavaScript untuk ini. Pemilih & di sass melakukan hal ini.

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

admazzola
sumber
6
-1 Sass tidak menambahkan lebih banyak fungsi ke css, itu hanya membuat menulis lebih mudah. Apa pun yang dapat Anda lakukan di sass dapat dilakukan dalam css dan sebaliknya.
Dastur
3
@Durur Diberikan variabel dan mixin, saya akan mengatakan Sass menambahkan banyak sekali ke CSS. Anda dapat melakukan semuanya dalam CSS, dengan cara yang sama Anda masih bisa menulis perangkat lunak canggih menggunakan bahasa C. lama modern menambahkan banyak tanpa mengaktifkan sesuatu yang tidak dapat dilakukan sebelumnya. Sama dengan Sass dan CSS.
Cobus Kruger
6
@Cobus Kruger Anda sebagian benar, tetapi Anda tidak dapat membuat perbandingan itu. Sedangkan bahasa seperti c ++ c # dan javascript mungkin berbasis C, mereka tidak berubah menjadi C sebelum runtime. Sass dikonversi dalam css sebelum runtime sehingga Anda tidak pernah benar-benar memuat stylesheet sass, hanya css.
Dastur