web-dev-qa-db-fra.com

Comment affecter d'autres éléments quand une div est survolée

Je pense que c'est une question très fondamentale mais je ne suis pas sûr de savoir comment cela peut être fait.

Ce que je veux faire, c'est quand un certain div est survolé, cela affecterait les propriétés d'un autre div.

Par exemple, dans cet exemple simple , lorsque vous survolez #cube, il modifie le background-color mais ce que je veux, c’est que lorsque je survole #container, #cubeest affecté.

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

Si le cube est directement à l'intérieur du conteneur:

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

Si le cube est à côté (après la fermeture des conteneurs) du conteneur:

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

Si le cube est quelque part dans le conteneur:

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

Si le cube est un frère du conteneur:

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

Dans cet exemple particulier, vous pouvez utiliser:

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

Cela ne fonctionne que puisque cube est un enfant de container. Pour des scénarios plus complexes, vous devrez utiliser javascript.

36
Emmett

L’utilisation du sélecteur de fratrie est la solution générale pour styler d’autres éléments lors du survol d’un élément donné , mais ne fonctionne que si le les autres éléments suivent ceux donnés dans le DOM . Que pouvons-nous faire quand les autres éléments devraient être avant le survol? Supposons que nous voulions implémenter un widget d'évaluation de la barre de signalisation comme celui ci-dessous:

Signal bar rating widget

Cela peut être fait facilement en utilisant le modèle CSS flexbox, en définissant flex-direction à reverse, de sorte que les éléments soient affichés dans l'ordre inverse de celui qu'ils sont dans le DOM. La capture d'écran ci-dessus provient d'un tel widget, implémenté avec du CSS pur.

Flexbox est très bien supporté par 95% des navigateurs modernes.

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

Un grand merci à Mike et Robertc pour leurs messages utiles!

Si vous avez deux éléments dans votre code HTML et que vous voulez :hover sur un élément et que vous souhaitiez modifier le style de l'autre, les deux éléments doivent être directement liés - parents, enfants ou frères et sœurs. Cela signifie que les deux éléments doivent être l'un dans l'autre ou doivent être contenus dans le même élément plus grand.

Je souhaitais afficher les définitions dans une zone à droite du navigateur lorsque mes utilisateurs lisaient sur mon site et :hover sur les termes en surbrillance; par conséquent, je ne voulais pas que l'élément 'definition' soit affiché à l'intérieur de l'élément 'text'.

J'ai failli abandonner et je viens d'ajouter du javascript à ma page, mais c'est l'avenir. Nous ne devrions pas avoir à nous en tenir à la page précédente de CSS et HTML nous indiquant où nous devons placer nos éléments pour obtenir les effets souhaités! À la fin nous avons compromis.

Bien que les éléments HTML réels du fichier doivent être imbriqués ou contenus dans un seul élément pour être des cibles valides :hover, l'attribut css position peut être utilisé pour afficher tout élément. J'ai utilisé position: fixed pour placer la cible de mon action :hover là où je le voulais sur l'écran de l'utilisateur, quel que soit son emplacement dans le document HTML.

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

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

Dans cet exemple, la cible d'une commande :hover à partir d'un élément de #explainBox doit être soit #explainBox, soit également dans #explainBox. Les attributs de position attribués à #definitions l'obligent à apparaître à l'emplacement souhaité (en dehors de #explainBox) même si, techniquement, il se trouve à une position indésirable dans le document HTML.

Je comprends que l’utilisation du même #id pour plus d’un élément HTML est considérée comme une mauvaise forme; cependant, dans ce cas, les instances de #light peuvent être décrites indépendamment en raison de leurs positions respectives dans des éléments uniques #id 'd. Y at-il une raison de ne pas répéter le id#light dans ce cas?

7
rick

Seulement cela a fonctionné pour moi:

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

.cube est la classe CssClass du #cube.

Testé dans Firefox, Chrome et Edge.

5
CyberHawk

Voici une autre idée qui vous permet d’affecter d’autres éléments sans considérer de sélecteur spécifique et en utilisant uniquement l’état :hover de l’élément principal.

Pour cela, je vais utiliser des propriétés personnalisées (variables CSS). Comme on peut le lire dans le spécification :

Les propriétés personnalisées sont les propriétés ordinaires , de sorte qu'elles peuvent être déclarées sur n'importe quel élément, sont résolues avec l'héritage normal et en cascade règles ...

L'idée est de définir des propriétés personnalisées dans l'élément principal et de les utiliser pour mettre en forme des éléments enfants. Comme ces propriétés sont héritées, nous devons simplement les modifier dans l'élément principal au survol.

Voici un exemple:

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

Pourquoi cela peut-il être meilleur que d'utiliser un sélecteur spécifique combiné avec le survol?

Je peux fournir au moins deux raisons pour lesquelles cette méthode est une bonne chose à considérer:

  1. Si nous avons plusieurs éléments imbriqués qui partagent les mêmes styles, cela nous évitera un sélecteur complexe pour les cibler tous en survol. À l'aide des propriétés personnalisées, nous modifions simplement la valeur lorsque vous survolez l'élément parent.
  2. Une propriété personnalisée peut être utilisée pour remplacer une valeur de toute propriété et également une valeur partielle de celle-ci. Par exemple, nous pouvons définir une propriété personnalisée pour une couleur et nous l'utilisons dans un border, linear-gradient, background-color, box-shadow etc. Cela nous évitera de réinitialiser toutes ces propriétés. En vol stationnaire.

Voici un exemple plus complexe:

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

Comme nous pouvons le voir ci-dessus, nous avons seulement besoin d'une déclaration CSS pour modifier de nombreuses propriétés d'éléments différents.

0
Temani Afif