web-dev-qa-db-ja.com

Divがホバーされたときに他の要素に影響を与える方法

これは非常に基本的な質問だと思いますが、どうすればよいのかわかりません。

私がやりたいことは、特定のdivがホバーされたとき、それは別のdivのプロパティに影響を与えるでしょう。

たとえば、 この簡単な例 で、#cubeの上にマウスを移動するとbackground-colorが変更されますが、#containerの上に移動すると#cubeに影響があります。

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>
364
Trufa

立方体がコンテナのすぐ内側にある場合:

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

立方体がコンテナの隣にある場合(コンテナ終了タグの後):

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

キューブがコンテナ内のどこかにある場合:

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

キューブがコンテナの兄弟である場合:

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

この特定の例では、次のものを使用できます。

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

cubecontainerの子であるため、これは機能します。より複雑なシナリオでは、JavaScriptを使用する必要があります。

37
Emmett

兄弟セレクターを使用することは、特定の要素にカーソルを合わせたときに他の要素をスタイリングするための一般的なソリューションです(but動作する他の要素は、DOMの指定された要素の後に続きます。ホバーされた要素の前に他の要素を実際に配置する必要がある場合、何ができますか?次のような信号バー評価ウィジェットを実装するとします。

Signal bar rating widget

これは、CSS flexboxモデルを使用して flex-directionreverseに設定することにより、実際に簡単に行うことができます。 DOMで再。上記のスクリーンショットは、純粋なCSSで実装されたこのようなウィジェットのものです。

Flexboxは非常によくサポートされています 現代のブラウザの95%。

.rating {
  display: flex;
  flex-direction: row-reverse;
  width: 9rem;
}
.rating div {
  flex: 1;
  align-self: flex-end;
  background-color: black;
  border: 0.1rem solid white;
}
.rating div:hover {
  background-color: lightblue;
}
.rating div[data-rating="1"] {
  height: 5rem;
}
.rating div[data-rating="2"] {
  height: 4rem;
}
.rating div[data-rating="3"] {
  height: 3rem;
}
.rating div[data-rating="4"] {
  height: 2rem;
}
.rating div[data-rating="5"] {
  height: 1rem;
}
.rating div:hover ~ div {
  background-color: lightblue;
}
<div class="rating">
  <div data-rating="1"></div>
  <div data-rating="2"></div>
  <div data-rating="3"></div>
  <div data-rating="4"></div>
  <div data-rating="5"></div>
</div>
28
Dan Dascalescu

MikeとRobertcの役に立つ投稿に感謝します。

HTMLに2つの要素があり、一方の要素に:hoverを適用し、もう一方の要素にスタイル変更を適用する場合は、2つの要素、つまり親、子、または兄弟を直接関連付ける必要があります。これは、2つの要素が一方が他方の内側にあるか、両方が同じより大きな要素に含まれている必要があることを意味します。

私のユーザーが私のサイトを読み、強調表示された用語の上に:hoverを読むとき、私はブラウザの右側のボックスに定義を表示したいと思いました。したがって、 'definition'要素を 'text'要素内に表示したくありませんでした。

私はほとんどあきらめて、ちょうど私のページにジャバスクリプトを追加しました、しかし、これはそれをぶつけた未来です!必要な効果を得るために要素をどこに配置する必要があるのか​​をCSSやHTMLのバックサッシュに我慢する必要はありません。結局私達は妥協した。

ファイル内の実際のHTML要素は、有効な:hoverが互いにターゲットとなるようにネストされているか、単一の要素に含まれている必要がありますが、css position属性を使用して任意の要素を表示できます。私はpositionを使用しました:HTMLドキュメント内の位置に関係なく、:hoverアクションのターゲットをユーザーの画面上の希望する場所に配置するように修正しました。

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

この例では、:hover内の要素からの#explainBoxコマンドのターゲットは、#explainBoxまたは#explainBox内になければなりません。技術的にはHTML文書内の不要な位置に配置されていても、#definitionsに割り当てられた位置属性は、強制的にそれを目的の場所(#explainBoxの外側)に表示するようにします。

私は、複数のHTML要素に対して同じ#idを使用するのは悪い形式と考えられていることを理解しています。ただし、この場合、#lightのインスタンスは、一意的な#id 'd要素内のそれぞれの位置により、独立して記述できます。この場合にid#lightを繰り返さない理由はありますか?

6
rick

これだけが私のために働きました:

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

.cube#cubeのCssClassです。

Firefox Chrome 、および Edge でテスト済み。

4
CyberHawk

これは、特定のセレクタを考慮せずに、メイン要素の:hover状態を使用するだけで、他の要素に影響を与えることを可能にする別のアイデアです。

このために、私はカスタムプロパティ(CSS変数)の使用に頼ります。 specification で読むことができるので:

カスタムプロパティは通常のプロパティなので、どの要素でも宣言でき、解決されます通常の継承およびカスケード規則.. 。

アイデアは、メイン要素内でカスタムプロパティを定義し、それらを子要素をスタイルするために使用することです。これらのプロパティは継承されるため、ホバー時にメイン要素内でそれらを変更するだけです。

これが一例です。

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

ホバーと組み合わせた特定のセレクターを使用するよりも、これが優れているのはなぜですか?

この方法を検討するのに適したものにする少なくとも2つの理由があります。

  1. 同じスタイルを共有するネストされた要素が多数ある場合は、ホバーにそれらすべてをターゲットとする複雑なセレクタが不要になります。カスタムプロパティを使用して、親要素の上に移動したときに値を変更するだけです。
  2. カスタムプロパティは、任意のプロパティの値およびその部分的な値を置き換えるために使用できます。たとえば、色のカスタムプロパティを定義し、それをborderlinear-gradientbackground-colorbox-shadowなどの中で使用することができます。これにより、これらのすべてのプロパティをホバーにリセットすることを回避できます。

これはもっと複雑な例です:

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

上記のとおり、さまざまな要素の多くのプロパティを変更するために必要なのは1つのCSS宣言だけです。

0
Temani Afif