Bir öğe üzerine geldiğinde diğer öğeler nasıl etkilenir?


459

Yapmak istediğim, belli divbir noktaya geldiğinde, bir başkasının özelliklerini etkiler div.

Örneğin, bu JSFiddle demo , sizi vurgulu üzerinde #cubedeğişeceği background-colorama ne istiyorum ben vurgulu üzerinde zaman ki #container, #cubeetkilenir.

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>

Yanıtlar:


988

Küp doğrudan kabın içindeyse:

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

Küp yanındaysa (kapsayıcı etiketi kapattıktan sonra) kapsayıcı:

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

Küp kabın içinde bir yerdeyse:

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

Küp kabın bir kardeşi ise:

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

107
~'Küp
DOM'da

3
Bu oldukça havalı. Bununla ilgili daha fazla bilgi bulabileceğim bir kaynak var mı? Tüm tarayıcılar tarafından destekleniyor mu, CSS3 mi? Bu konuda biraz daha bilgi sahibi olmak harika olurdu. Çok teşekkürler!
İsimsiz

2
+1 Harika cevap @Mike. Ne #containeryanındadır için #cube, yani #containerşu #cube?
PeterKA

4
Üzerine gelinen eleman kabın içindeyse (etkilenmek istediğimiz) ne yapmalı ??? Örneğin: #cube: vurgulu #container {Bazı CSS Efektleri}
Hanzallah Afgan

2
İyi cevap !! Çocuğu üzerine geldiğimde ebeveyni değiştirmek istersem ne olur? Bence bunun için bir seçici yok.
Mikel

41

Bu belirli örnekte şunları kullanabilirsiniz:

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

Bu örnek sadece cubebir çocuk olduğu için işe yarıyor container. Daha karmaşık senaryolar için farklı CSS kullanmanız veya JavaScript kullanmanız gerekir.


35

Kardeş seçiciyi kullanmak, belirli bir öğenin üzerine geldiğinde diğer öğeleri şekillendirmek için genel çözümdür, ancak yalnızca diğer öğeler DOM'da verilen öğeyi takip ederse çalışır . Vurgulanan unsurdan önce diğer unsurlar olması gerektiğinde ne yapabiliriz? Diyelim ki aşağıdaki gibi bir sinyal çubuğu derecelendirme widget'ı uygulamak istiyoruz:

Sinyal çubuğu derecelendirme widget'ı

Bu aslında ayarlayarak, CSS FlexBox modeli kullanılarak kolayca yapılabilir flex-directionüzere reverseelemanlar onlar DOM konum birinden zıt sırayla görüntülenir böylece. Yukarıdaki ekran görüntüsü, saf CSS ile uygulanan böyle bir widget'tan.

Flexbox, modern tarayıcıların% 95'i tarafından çok iyi desteklenmektedir .


Fareyi 1 çubuktan diğerine hareket ettirdiğinizde vurgu kaybolmayacak şekilde bu düzenlenebilir mi? Yanıp sönme biraz dikkat dağıtıcı.
Cerbrus

@Cerbrus: Fare çubuklar arasında olduğunda fareyle üzerine gelmeyen bir çözüm eklendi. Dezavantajı çubukların genişliğinin artık eşit olmamasıdır.
Dan Dascalescu

1
Bunu ilk snippet'inizde deneyin: açık .rating div, marjı kaldırın ve ekleyinborder-right: 4px solid white;
Cerbrus

1
Esnek yön (IE için iyi desteklenmez) VEYA 1) varsayılan olarak siyah 2) farenin üzerinde kap üzerinde mavi olan 3) fareyle üzerine gelindiğinde bir sonraki kardeş için siyah :)
Stephane Mathis

(En azından benim için) burada neler olduğu konusunda biraz daha apaçık olan bu kemanı yaptım. jsfiddle.net/maxshuty/cj55y33p/3
maxshuty

8

Mike ve Robertc'e yardımcı gönderileri için teşekkür ederiz!

HTML'nizde iki öğe varsa ve :hoverbir tanesinin üzerinde ve diğerinde bir stil değişikliğini hedeflemek istiyorsanız , iki öğenin doğrudan ilişkili olması gerekir - ebeveynler, çocuklar veya kardeşler. Bu, iki öğenin ya birbirinin içinde olması ya da her ikisinin de aynı daha büyük öğenin içinde olması gerektiği anlamına gelir.

Kullanıcıları sitemde ve :hovervurgulanan terimler üzerinden okurken, tarayıcının sağ tarafındaki bir kutuda tanımları görüntülemek istedim ; bu nedenle, 'tanım' öğesinin 'metin' öğesinin içinde görüntülenmesini istemedim.

Neredeyse vazgeçtim ve sadece sayfama javascript ekledim, ama bu gelecekteki dang! İstediğimiz etkileri elde etmek için elementlerimizi nereye yerleştirmemiz gerektiğini söyleyen CSS ve HTML'den geri sass koymak zorunda kalmamalıyız! Sonunda uzlaştık.

Dosyadaki gerçek HTML öğelerinin :hoverbirbiri için geçerli hedefler olması için iç içe yerleştirilmesi veya tek bir öğede yer alması gerekirken , css positionözniteliği istediğiniz herhangi bir öğeyi görüntülemek için kullanılabilir. Pozisyon kullandım: :hovereylemimin hedefini , HTML belgesindeki konumundan bağımsız olarak kullanıcının ekranında istediğim yere yerleştirmek için düzeltildi .

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

Bu örnekte, :hoveriçindeki bir öğeden gelen komutun hedefi #explainBoxya içinde #explainBoxya da içinde olmalıdır #explainBox. #Definitions'a atanan konum öznitelikleri #explainBox, teknik olarak HTML belgesi içinde istenmeyen bir konumda olmasına rağmen , istenen konumda (dışarıda ) görünmeye zorlar .

#idBirden fazla HTML öğesi için aynı kullanmanın kötü form olarak kabul edildiğini anlıyorum ; bununla birlikte, bu durumda, örnekleri #lightbenzersiz #idelemanlardaki ilgili konumlarından dolayı bağımsız olarak tarif edilebilir . id #lightBu durumda tekrar etmemek için herhangi bir neden var mı ?


Böyle kısa bir nokta için oldukça uzun bir cevap, ama işte bunun bir jsfiddle jsfiddle.net/ubershmekel/bWgq6/1
ubershmekel

1
bazı tarayıcılar aynı IDbirden çok kez kullandığınızda çıldırır . Sadece a class.
Serj Sagan

6

Sadece bu benim için çalıştı:

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

.cubeCssClass nerede #cube.

Firefox , Chrome ve Edge'de test edildi .


4

Burada, belirli bir seçiciyi düşünmeden ve yalnızca :hoverana öğenin durumunu kullanarak diğer öğeleri etkilemenize izin veren başka bir fikir var .

Bunun için özel özelliklerin (CSS değişkenleri) kullanımına güveneceğim. Şartnamede okuyabileceğimiz gibi :

Özel özellikler sıradan özelliklerdir , bu nedenle herhangi bir öğede bildirilebilir , normal miras ve basamaklı kurallarla çözülür ...

Buradaki fikir, ana öğe içindeki özel özellikleri tanımlamak ve bunları alt öğeleri biçimlendirmek için kullanmaktır ve bu özellikler devralındığından bunları fareyle üzerine gelindiğinde ana öğe içinde değiştirmeniz gerekir.

İşte bir örnek:

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

Neden bu, vurgulu ile birlikte belirli bir seçici kullanmaktan daha iyi olabilir?

Bu yöntemi iyi bir yöntem haline getirmek için en az 2 neden sağlayabilirim:

  1. Aynı stilleri paylaşan birçok iç içe öğemiz varsa, bu, karmaşık seçiciyi fareyle üzerine gelmemize engel olur. Özel özellikleri kullanarak, üst öğenin üzerine geldiğinizde değeri değiştiririz.
  2. Özel bir özellik, herhangi bir özelliğin değerini ve ayrıca kısmi değerini değiştirmek için kullanılabilir. Örneğin bir renk için özel bir özellik tanımlayabilir ve biz içinde kullanmak border, linear-gradient, background-color, box-shadowvb Bu vurgulu tüm bu özellikleri Sıfırlanmasını bizi önleyecektir.

İşte daha karmaşık bir örnek:

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

Yukarıda görebildiğimiz gibi, farklı elemanların birçok özelliğini değiştirmek için sadece bir CSS bildirimine ihtiyacımız var .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.