Lorsque vous cliquez sur button
, vous constatez que la pseudoclasse :active
est déclenchée pour le parent div
. Existe-t-il un moyen CSS pur (ou une bibliothèque JS) de pseudo-classe :active
ne basculant pas sur un clic button
?
J'ai essayé z-index
, position: absolute & fixed
et sans succès.
De la spec :
Les sélecteurs ne définissent pas si le parent d'un élément qui est ": actif" ou ": survolé" est également dans cet état.
Cela signifie que cela dépend de la mise en œuvre. Si une implémentation a choisi d'agir de cette manière (comme le font évidemment les navigateurs actuels), rien dans la norme ne peut changer cela.
Avec CSS4, vous pourrez peut-être:
.parent:active:not(:has(:active)) {
color: red;
}
mais ce n'est ni disponible ni encore finalisé.
Je ne pense pas que la pseudo-classe :has
sera un jour disponible dans les feuilles de style. Si les navigateurs décident finalement de l'implémenter, ce ne sera probablement que pour les API JS telles que querySelector
.
Cependant, j'ai beaucoup plus d'espoir pour :focus-within
, qui semble beaucoup plus simple à mettre en œuvre.
#parent:active:not(:focus-within) {
background-color: red;
}
Bien entendu, cela empêchera uniquement l'application de :active
à #parent
lorsque vous cliquerez sur un élément activable comme un bouton. Vous pouvez rendre d'autres éléments focalisables en ajoutant tabindex = "-1"
Malheureusement, :focus-within
n'est pas largement supporté, mais vous pouvez utiliser un JS polyfill .
#parent {
border: 1px solid black;
width: 300px;
height: 300px;
}
#parent:active:not(.focus-within) {
background-color: red;
}
<script src="https://Gist.githubusercontent.com/aFarkas/a7e0d85450f323d5e164/raw/"></script>
<div id="parent">
<button>Click me</button>
<p tabindex="-1">Or me</p>
</div>
Github n'autorise pas la création de liens hypertextes. Par conséquent, l'extrait de code ci-dessus risque de ne pas fonctionner à moins que vous copiez le fichier polyfill sur votre serveur et que vous l'utilisiez.
Au lieu de div:active {...}
, vous devriez coder div:active:not(:hover) {...}
et le background-color
reste inchangé.
(ancien extrait supprimé)
METTRE &AGRAVE; JOUR
Pour conserver le comportement principal div
et une approche plus générique, je crée généralement plusieurs couches.
Vérifiez l'extrait de code ci-dessous, basculer sur green
sert simplement à prouver que cela fonctionne alors que position
et abolute
sont juste rapides et sales pour l'instant:
#layer-data {
width: 200px;
height: 200px;
background-color: #eee;
border: 1px solid black;
}
#layer-data:active {
background-color: red
}
#layer-btns:active {
background-color: green
}
#layer-btns {
z-index: 1;
position: absolute;
top: 1px;
left: 1px;
background: transparent;
padding: 5px;
width: auto;
height: auto
}
#layer-data {
z-index: 0;
position: absolute;
top: 0;
left: 0;
text-align: center;
line-height: 200px
}
<div id="layer-btns">
<button>Qlick me</button>
<br/>
<button>Qlick me too</button>
<br/>
<button>Qlick me three</button>
</div>
<div id="layer-data">
some data-layer
</div>
La pseudo-classe: active s'applique lorsqu'un élément est activé par l'utilisateur. Par exemple, entre les moments où l'utilisateur appuie sur le bouton de la souris et le relâche. Sur les systèmes dotés de plusieurs boutons de souris: Actif s'applique uniquement au bouton d'activation principal ou principal (généralement le bouton de souris "gauche"), ainsi qu'à ses alias.
Il peut y avoir des limites spécifiques au langage du document ou à la mise en œuvre sur lesquelles les éléments peuvent devenir: actifs. Par exemple, [HTML5] définit une liste d'éléments activables.
Le parent d'un élément qui correspond à: actif correspond également à: actif. Il n'y a donc aucun moyen
voici une solution jquery au lieu d'utiliser la pseudo-classe css :active
$(document).ready(function() {
$('button').mousedown(function(e){
e.stopPropagation();
console.log('i got clicked');
});
$('div').mousedown(function(e){
$('div').css('background', 'red')
}).mouseup(function(e){
$('div').css('background', '#eee')
});
$(document).mouseup(function(e){
$('div').css('background', '#eee')
});
});
div {
width: 200px;
height: 200px;
background-color: #eee;
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<button>Qlick me</button>
</div>
Cela peut ou peut ne pas fonctionner pour vous, mais c’est comme cela que je le réalise avec du CSS pur. Le seul inconvénient est la dépendance de focus-within
qui n'est pas prise en charge par IE ou Edge.
.parent {
transition: background-color;
}
.parent:active:not(:focus-within) {
background-color: red;
transition-delay: 1ms; // Delay one cycle to allow child to focus
}
Ce qui se passe ici, c'est que l'élément parent obtiendra l'état actif, de même que l'enfant sur lequel l'utilisateur aura cliqué. La seule différence est que le focus s'appliquera à l'élément enfant, mais uniquement sur le cycle suivant. Pour contourner les animations de ce processus en 2 étapes, appliquez un délai de 1 ms. Au cycle suivant, l'élément sera actif, mais le focus sera appliqué à l'enfant. Ainsi, le parent n'appliquera pas la transition. J'imagine que animation delay: 1ms
fonctionnerait de la même manière.
Une autre solution consiste à attribuer à l’élément un attribut tabindex=-1
et à l’utiliser.
.parent {
transition: background-color;
}
.parent:active:focus {
background-color: red;
}
Le seul problème avec ceci est le fait que cela peut changer le comportement de navigation du clavier et repose également sur du HTML. Si vous voulez utiliser le clavier, utilisez tabindex=0
ou une valeur autre que -1
. Mais il n'y a pas de JS utilisé.
Il existe des polyfill sympas pour focus-within
que vous pouvez utiliser pour IE/Edge, mais qui iraient en dehors de "CSS uniquement".
Mais, nous pouvons réunir les deux pour créer ceci:
.parent {
transition: background-color;
}
.parent[tabindex]:active:focus {
background-color: red;
}
.parent:active:not(:focus):not(:focus-within) {
background-color: red;
transition-delay: 1ms;
}
Cela fonctionne sur IE11, Edge et Chrome.
Autant que je sache, l'état actif va bouillonner. Tous les nœuds parents auront donc un état actif.
Par conséquent, je ne fais pas maintenant d'une solution CSS pure. Vous pouvez éviter une solution javascript (ce que je suppose, c'est ce que vous cherchez vraiment), en modifiant le balisage de sorte que la div ayant un état actif ne soit plus un parent du bouton. Vous pouvez en faire des frères et soeurs, par exemple.
La partie CSS de cette solution est alors en train de corriger la mise en page, de sorte qu’il semble être la même chose maintenant qu’ils sont en train de sibilings comme ce qu’elle faisait quand ils étaient parent> enfant.
Je crains que je ne vous offre pas de solution plus spécifique sans voir ce que vous travaillez en train de bricoler.
Les pseudo-éléments CSS sont extrêmement utiles: ils nous permettent de créer des triangles CSS pour les info-bulles et d'effectuer un certain nombre d'autres tâches simples tout en évitant le recours à des éléments HTML supplémentaires. Jusqu'à présent, ces propriétés CSS de pseudo-éléments étaient inaccessibles par JavaScript, mais il existe maintenant une méthode pour les obtenir!
Vérifie ça:
Il ne semble pas y avoir de moyen CSS pour gérer ce cas. (pas sûr de CSS4, comme suggéré par Amit.) Voici donc la méthode JQuery.
L'idée est de gérer les événements de souris et de souris à 3 niveaux:
HTML:
<div>
<button class="btn1">Qlick me1</button>
<button class="btn2">Qlick me2</button>
</div>
JQuery:
$(function(){
$('div').each(function(e){
$(this).mousedown(function(e){
$(this).addClass("activeClass");
}).mouseup(function(e){
$(this).removeClass("activeClass");
});
});
$('div .btn1').each(function(e){
$(this).mousedown(function(e){
e.stopPropagation();
}).mouseup(function(e){
e.stopPropagation();
});
});
$('div :not(.btn1)').each(function(e){
$(this).mousedown(function(e){
$(this).parent().addClass("activeClass");
}).mouseup(function(e){
$(this).parent().removeClass("activeClass");
});
});
});
CSS:
div {
width: 200px;
height: 200px;
background-color: #eee;
border: 1px solid black;
}
.activeClass {
background-color: red;
}
essaye ça
html:
<div class="current" id="current">
<button id="btnclick" >Qlick me</button>
</div>
script css:
div {
width: 200px;
height: 200px;
background-color: #eee;
border: 1px solid black;
}
.current_active{
background-color: red;
}
jquery:
$("#btnclick").click(function(){
$("#current").toggleClass("current_active");
});
ps: inclure le fichier de bibliothèque jquery