Bagaimana memengaruhi elemen lain saat satu elemen melayang


459

Apa yang ingin saya lakukan adalah ketika seseorang divmelayang, itu akan mempengaruhi properti orang lain div.

Sebagai contoh, dalam demo JSFiddle ini , ketika Anda mengarahkan kursor #cubeitu mengubahbackground-color tetapi apa yang saya inginkan adalah ketika saya mengarahkan kursor #container, #cubeterpengaruh.

div {
  outline: 1px solid red;
}
#container {
  width: 200px;
  height: 30px;
}
#cube {
  width: 30px;
  height: 100%;
  background-color: red;
}
#cube:hover {
  width: 30px;
  height: 100%;
  background-color: blue;
}
<div id="container">

  <div id="cube">
  </div>

</div>

Jawaban:


986

Jika kubus langsung di dalam wadah:

#container:hover > #cube { background-color: yellow; }

Jika kubus di sebelah (setelah tag penutup wadah) wadah:

#container:hover + #cube { background-color: yellow; }

Jika kubus ada di suatu tempat di dalam wadah:

#container:hover #cube { background-color: yellow; }

Jika kubus adalah saudara kandung wadah:

#container:hover ~ #cube { background-color: yellow; }

107
Jangan lupa kombinator saudara kandung umum ~untuk 'cube adalah suatu tempat setelah wadah di DOM dan berbagi orang tua'
robertc

3
Itu keren sekali. Apakah ada sumber di mana saya dapat menemukan informasi lebih lanjut tentang itu? Apakah didukung oleh semua browser, apakah itu CSS3? Akan menyenangkan untuk memiliki lebih banyak info tentang itu. Terima kasih banyak!
Anonim

2
+1 Jawaban bagus @Mike. Bagaimana jika di #containersebelah #cube, yaitu #containermengikuti #cube?
PeterKA

4
Apa yang harus dilakukan jika elemen melayang-layang di dalam wadah (yang ingin kita pengaruhi) ??? Sebagai contoh: #cube: hover #container {Some CSS Effects}
Hanzallah Afgan

2
Jawaban yang bagus !! Bagaimana jika saya ingin mengubah orang tua ketika saya membawa anak itu. Saya pikir tidak ada pemilih untuk itu.
Mikel

41

Dalam contoh khusus ini, Anda dapat menggunakan:

#container:hover #cube {
    background-color: yellow;   
}

Contoh ini hanya berfungsi karena cubeanak container. Untuk skenario yang lebih rumit, Anda harus menggunakan CSS yang berbeda, atau menggunakan JavaScript.


35

Menggunakan pemilih saudara adalah solusi umum untuk menata elemen-elemen lain ketika melayang di atas elemen tertentu, tetapi hanya berfungsi jika elemen-elemen lain mengikuti elemen yang diberikan pada DOM . Apa yang bisa kita lakukan ketika elemen-elemen lain sebenarnya harus ada sebelum elemen yang melayang? Katakanlah kita ingin menerapkan widget peringkat bar sinyal seperti yang di bawah ini:

Widget peringkat bilah sinyal

Ini benar-benar dapat dilakukan dengan mudah menggunakan model flexbox CSS, dengan mengatur flex-directionke reverse, sehingga elemen ditampilkan dalam urutan yang berlawanan dari yang ada di DOM. Tangkapan layar di atas adalah dari widget seperti itu, diimplementasikan dengan CSS murni.

Flexbox didukung dengan sangat baik oleh 95% browser modern.


Mungkinkah ini diedit agar sorotan tidak hilang saat memindahkan mouse dari 1 bilah ke bilah lainnya? Kedipannya sedikit mengganggu.
Cerbrus

@Cerbrus: Menambahkan solusi yang tidak menyembunyikan hover ketika mouse berada di antara bar. Kelemahannya adalah lebar batang tidak lagi sama.
Dan Dascalescu

1
Coba ini di cuplikan pertama Anda: pada .rating div, hapus margin, dan tambahkanborder-right: 4px solid white;
Cerbrus

1
Arah fleksibel (tidak didukung dengan baik untuk IE) ATAU 1) hitam secara default 2) semuanya biru pada mouse di atas wadah 3) hitam untuk saudara berikutnya di bar hover :)
Stephane Mathis

Saya membuat biola ini yang (setidaknya bagi saya) membuatnya sedikit lebih jelas tentang apa yang terjadi di sini. jsfiddle.net/maxshuty/cj55y33p/3
maxshuty

8

Terima kasih banyak kepada Mike dan Robertc untuk posting bermanfaat mereka!

Jika Anda memiliki dua elemen dalam HTML Anda dan Anda ingin :hoverlebih dari satu dan menargetkan perubahan gaya di yang lain, dua elemen harus terkait langsung - orang tua, anak-anak atau saudara kandung. Ini berarti bahwa kedua elemen harus satu di dalam yang lain atau keduanya harus terkandung dalam elemen yang lebih besar yang sama.

Saya ingin menampilkan definisi dalam kotak di sisi kanan browser ketika pengguna saya membaca situs saya dan :hoverlebih dari istilah yang disorot; oleh karena itu, saya tidak ingin elemen 'definisi' ditampilkan di dalam elemen 'teks'.

Saya hampir menyerah dan baru saja menambahkan javascript ke halaman saya, tetapi ini adalah masa depan! Kita tidak harus memasang back sass dari CSS dan HTML memberitahu kita di mana kita harus meletakkan elemen kita untuk mencapai efek yang kita inginkan! Pada akhirnya kami berkompromi.

Sementara elemen HTML aktual dalam file harus bersarang atau terkandung dalam satu elemen untuk menjadi :hovertarget yang valid satu sama lain, positionatribut css dapat digunakan untuk menampilkan elemen apa pun di mana pun Anda inginkan. Saya menggunakan posisi: tetap untuk menempatkan target :hovertindakan saya di tempat yang saya inginkan di layar pengguna terlepas dari lokasinya di dokumen HTML.

Html:

<div id="explainBox" class="explainBox"> /*Common parent*/

  <a class="defP" id="light" href="http://en.wikipedia.or/wiki/Light">Light                            /*highlighted term in text*/
  </a> is as ubiquitous as it is mysterious. /*plain text*/

  <div id="definitions"> /*Container for :hover-displayed definitions*/
    <p class="def" id="light"> /*example definition entry*/ Light:
      <br/>Short Answer: The type of energy you see
    </p>
  </div>

</div>

Css:

/*read: "when user hovers over #light somewhere inside #explainBox
    set display to inline-block for #light directly inside of #definitions.*/

#explainBox #light:hover~#definitions>#light {
  display: inline-block;
}

.def {
  display: none;
}

#definitions {
  background-color: black;
  position: fixed;
  /*position attribute*/
  top: 5em;
  /*position attribute*/
  right: 2em;
  /*position attribute*/
  width: 20em;
  height: 30em;
  border: 1px solid orange;
  border-radius: 12px;
  padding: 10px;
}

Dalam contoh ini target :hoverperintah dari elemen di dalam #explainBoxharus #explainBoxatau juga di dalam #explainBox. Atribut posisi yang ditetapkan untuk #definisi memaksanya muncul di lokasi yang diinginkan (di luar #explainBox) meskipun secara teknis terletak di posisi yang tidak diinginkan dalam dokumen HTML.

Saya mengerti itu dianggap bentuk buruk untuk menggunakan yang sama #iduntuk lebih dari satu elemen HTML; akan tetapi, dalam hal ini contoh-contoh #lightdapat dijelaskan secara independen karena posisi masing-masing dalam #idelemen unik . Apakah ada alasan untuk tidak mengulangi id #lightkasus ini?


Jawaban yang cukup panjang untuk poin yang pendek, tapi inilah jsfiddle darinya jsfiddle.net/ubershmekel/bWgq6/1
ubershmekel

1
beberapa browser akan panik ketika Anda menggunakan IDbeberapa kali yang sama . Cukup gunakan a class.
Serj Sagan

6

Hanya ini yang berhasil untuk saya:

#container:hover .cube { background-color: yellow; }

Di mana .cubeCssClass dari #cube.

Diuji di Firefox , Chrome dan Edge .


4

Berikut adalah gagasan lain yang memungkinkan Anda untuk memengaruhi elemen lain tanpa mempertimbangkan pemilih tertentu dan hanya dengan menggunakan :hoverstatus elemen utama.

Untuk ini, saya akan mengandalkan penggunaan properti khusus (variabel CSS). Seperti yang dapat kita baca dalam spesifikasi :

Sifat kustom sifat biasa , sehingga mereka dapat dideklarasikan pada setiap elemen, diselesaikan dengan normal warisan dan kaskade aturan ...

Idenya adalah untuk mendefinisikan properti khusus dalam elemen utama dan menggunakannya untuk menata elemen anak dan karena properti ini diwariskan, kita hanya perlu mengubahnya di dalam elemen utama di hover.

Berikut ini sebuah contoh:

#container {
  width: 200px;
  height: 30px;
  border: 1px solid var(--c);
  --c:red;
}
#container:hover {
  --c:blue;
}
#container > div {
  width: 30px;
  height: 100%;
  background-color: var(--c);
}
<div id="container">
  <div>
  </div>
</div>

Mengapa ini bisa lebih baik daripada menggunakan pemilih tertentu yang dikombinasikan dengan hover?

Saya dapat memberikan setidaknya 2 alasan yang membuat metode ini bagus untuk dipertimbangkan:

  1. Jika kami memiliki banyak elemen bersarang yang memiliki gaya yang sama, ini akan menghindari kami pemilih kompleks untuk menargetkan semuanya pada hover. Menggunakan properti Kustom, kami cukup mengubah nilai saat melayang di elemen induk.
  2. Properti kustom dapat digunakan untuk menggantikan nilai properti apa pun dan juga nilai parsialnya. Sebagai contoh kita dapat mendefinisikan properti kustom untuk warna dan kami menggunakannya dalam border, linear-gradient, background-color, box-shadowdll Hal ini akan menghindari kita reseting semua sifat ini di hover.

Ini adalah contoh yang lebih kompleks:

.container {
  --c:red;
  width:400px;
  display:flex;
  border:1px solid var(--c);
  justify-content:space-between;
  padding:5px;
  background:linear-gradient(var(--c),var(--c)) 0 50%/100% 3px no-repeat;
}
.box {
  width:30%;
  background:var(--c);
  box-shadow:0px 0px 5px var(--c);
  position:relative;
}
.box:before {
  content:"A";
  display:block;
  width:15px;
  margin:0 auto;
  height:100%;
  color:var(--c);
  background:#fff;
}

/*Hover*/
.container:hover {
  --c:blue;
}
<div class="container">
<div class="box"></div>
<div class="box"></div>
</div>

Seperti yang dapat kita lihat di atas, kita hanya perlu satu deklarasi CSS untuk mengubah banyak properti elemen yang berbeda.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.