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
, #cube
est 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>
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; }
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.
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:
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>
_
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?
Seulement cela a fonctionné pour moi:
#container:hover .cube { background-color: yellow; }
Où .cube
est la classe CssClass du #cube
.
Testé dans Firefox, Chrome et Edge.
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:
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.