Puis-je avoir un effet onclick en CSS?

335

J'ai un élément d'image que je souhaite modifier en cliquant.

<img id="btnLeft">

Cela marche:

#btnLeft:hover {
    width:70px;
    height:74px;
}

Mais ce dont j'ai besoin c'est:

#btnLeft:onclick {
    width:70px;
    height:74px;
}

Mais ça ne marche pas, évidemment. Est-il possible d'avoir un onclickcomportement en CSS (c'est-à-dire sans utiliser JavaScript)?

Alegro
la source
7
:activefonctionne lorsque la souris est enfoncée. Selon ce que vous essayez de faire, vous pourrez peut-être le faire fonctionner en utilisant la pseudo-classe CSS4 :target.
bfavaretto
2
:targetn'est pas nouveau pour Selectors 4. Il est disponible depuis Selectors 3, qui était déjà une recommandation d'un an au moment de la rédaction.
BoltClock

Réponses:

314

Le plus proche que vous obtiendrez est :active:

#btnLeft:active {
    width: 70px;
    height: 74px;
}

Cependant, cela n'appliquera le style que lorsque le bouton de la souris est maintenu enfoncé. La seule façon d'appliquer un style et de le maintenir appliqué en un clic est d'utiliser un peu de JavaScript.

Bojangles
la source
@ Sparky672, à peu près tout: caniuse.com/#feat=css-sel2 (IE7 prend en charge: actif aussi mais n'est pas répertorié car il ne prend pas en charge certains des autres sélecteurs)
jrajav
@Kiyura, je suppose que tout, sauf quelques bugs dans IE 8 et supérieur .
Sparky
13
Cette réponse est dépassée. Voir la réponse de TylerH pour une solution CSS uniquement à cela.
Maximillian Laumeister
Il existe une solution CSS plus simple que le piratage des cases à cocher de TylerH.
David Ljung Madison Stellar
349

Réponse à partir de 2019:

La meilleure façon (en fait la seule façon *) de simuler un événement de clic réel en utilisant uniquement CSS (plutôt que de simplement survoler un élément ou de rendre un élément actif, où vous n'avez pas mouseUp ) est d'utiliser le hack de case à cocher. Il fonctionne en attachant un labelà un <input type="checkbox">élément via l' for=""attribut de l'étiquette .

Cette fonctionnalité prend en charge un large navigateur (la :checkedpseudo-classe est IE9 +).

Appliquer la même valeur à un <input>« s attribut ID et un accompagnant <label>l » for=""attribut, et vous pouvez dire au navigateur de nouveau style l'étiquette , cliquez avec le :checkedpseudo-classe, grâce au fait que cliquer sur une étiquette cocher et décocher la "associé" <input type="checkbox">.

* Vous pouvez simuler un événement « choisi » par le :activeou :focuspseudo-classe dans IE7 + (par exemple un bouton qui est normalement 50pxlarge, vous pouvez modifier sa largeur tout active: #btnControl:active { width: 75px; }), mais ceux qui ne sont pas vraies événements « cliquez sur ». Ils sont "en direct" pendant toute la durée de sélection de l'élément (par exemple, Tabavec bing avec votre clavier), ce qui est un peu différent d'un véritable événement de clic, qui déclenche une action sur - généralement - mouseUp.


Démo de base du hack de case à cocher (la structure de code de base pour ce que vous demandez):

Ici, j'ai positionné l'étiquette juste après l'entrée dans mon balisage. C'est pour que je puisse utiliser le sélecteur de frère adjacent (la +clé) pour sélectionner uniquement l'étiquette qui suit immédiatement ma #democase à cocher. Étant donné que la :checkedpseudo-classe s'applique à la case à cocher, #demo:checked + labelne s'applique que lorsque la case à cocher est cochée.

Démo pour redimensionner une image au clic, c'est ce que vous demandez:

#btnControl {
    display: none;
}

#btnControl:checked + label > img {
    width: 70px;
    height: 74px;
}
<input type="checkbox" id="btnControl"/>
<label class="btn" for="btnControl"><img src="http://placekitten.com/200/140" id="btnLeft" /></label>

Cela étant dit, il y a de mauvaises nouvelles. Étant donné qu'une étiquette ne peut être associée qu'à un seul contrôle de formulaire à la fois , cela signifie que vous ne pouvez pas simplement déposer un bouton à l'intérieur des <label></label>balises et l'appeler un jour. Cependant, nous pouvons utiliser du CSS pour donner à l'étiquette un aspect et un comportement assez proches de l'apparence et du comportement d'un bouton HTML.

Démo pour imiter un effet de clic de bouton, au-delà de ce que vous demandez:

La plupart du CSS de cette démo sert uniquement à styliser l'élément d'étiquette. Si vous n'avez pas vraiment besoin d'un bouton et que n'importe quel ancien élément suffira, vous pouvez supprimer presque tous les styles de cette démo, similaire à ma deuxième démo ci-dessus.

Vous remarquerez également que j'ai une propriété préfixée là - dedans, -moz-outline-radius. Il y a quelque temps, Mozilla a ajouté cette superbe propriété non spécifiée à Firefox, mais les gens de WebKit ont décidé de ne pas l'ajouter , malheureusement. Considérez donc cette ligne de CSS comme une amélioration progressive pour les personnes qui utilisent Firefox.

TylerH
la source
2
Impressionnant! Mais existe-t-il un moyen d'annuler les modifications également en cliquant ailleurs que sur le bouton d'entrée / image /? J'ai utilisé votre exemple pour créer un champ contextuel et je veux qu'il disparaisse lorsque les visiteurs cliquent sur la page vierge. Merci!
mxmehl
1
@mxmehl Si vous voulez qu'ils cliquent à un endroit spécifique, vous pouvez probablement le faire avec un autre élément frère adjacent. Cependant, si vous souhaitez qu'il revienne simplement en cliquant n'importe où sur l'écran qui est vide, vous aurez probablement besoin d'écouteurs d'événements JavaScript. Rappelez-vous, c'est un hack et ce n'est pas la "meilleure" façon de créer une expérience "interactive"; c'est ce que JS est pour . Voici comment procéder si vous êtes limité à utiliser uniquement du CSS. :-)
TylerH
5
Cette solution est toujours agréable, mais quand je lis "réponse 2017", je m'attendais à quelque chose de vraiment cool (comme une fonctionnalité CSS3 qui a finalement obtenu une large prise en charge du navigateur), pas le grand vieux hack de case à cocher qui existe depuis 2011 ... Un peu déçu .
Christallkeks
3
@Christallkeks Si CSS ajoute quelque chose (ce ne sera probablement pas le cas, l'interactivité dépasse le cadre de CSS), je mettrai à jour la réponse pour l'inclure. Dans l'état actuel des choses, le titre de la «réponse 2017» est de faire savoir aux gens que cette réponse est la plus récente, donc d'un coup d'œil, ils ne regarderont pas le fait que la réponse a été publiée en 2015 et « , Je me demande si une nouvelle fonctionnalité existe encore ".
TylerH
1
@MuhammadSaqib Oui, cela devrait fonctionner sur n'importe quel navigateur mobile compatible :checked.
TylerH
78

Vous pouvez utiliser une pseudo-classe :targetpour imiter l'événement click, laissez-moi vous donner un exemple.

#something {
  display: none;
}

#something:target {
  display: block;
}
<a href="#something">Show</a>
<div id="something">Bingo!</div>

Voici à quoi cela ressemble: http://jsfiddle.net/TYhnb/

Une chose à noter, cela n'est limité qu'aux hyperliens, donc si vous devez utiliser un autre lien que l'hyperlien, comme un bouton, vous voudrez peut-être le pirater un peu, comme le style d'un hyperlien pour ressembler à un bouton.

Hendra Uzia
la source
8
Comment inverser l'action?
Ansyori
Je pensais que vous ne pouviez pas cibler quelque chose qui n'était pas affiché.
Hazior
38

Si vous donnez l'élément a, tabindexvous pouvez utiliser la :focuspseudo-classe pour simuler un clic.

HTML

<img id="btnLeft" tabindex="0" src="http://placehold.it/250x100" />

CSS

#btnLeft:focus{
    width:70px;
    height:74px;
}

http://jsfiddle.net/NaTj5/

Blake Plumb
la source
2
cela fonctionne assez bien! lorsque vous utilisez tabindex=-1l'élément est toujours focalisable, mais uniquement par la souris, pas le clavier, ce qui est mieux dans ce cas. vous pouvez également utiliser un outline:0style pour supprimer la bordure bleue lorsque vous vous concentrez
Stefan Paul Noack
35

Edit: Répondu avant que OP ne précise ce qu'il voulait. Ce qui suit est pour un onclick similaire à javascripts onclick, pas la :activepseudo-classe.

Cela ne peut être réalisé qu'avec Javascript ou le Checkbox Hack

Le hack de case à cocher vous permet essentiellement de cliquer sur une étiquette, qui "vérifie" une case à cocher, vous permettant de styliser l'étiquette comme vous le souhaitez.

La démo

Andy
la source
1
Vous pouvez également inclure votre entrée dans l'étiquette afin de ne pas avoir à utiliser d' idattributs pour les lier ensemble.
stackular
12

TylerH a fait une très bonne réponse, et je n'ai eu qu'à mettre à jour cette dernière version du bouton.

#btnControl {
    display: none;
}

.btn {
    width: 60px;
    height: 30px;
    background: silver;
    border-radius: 5px;
    padding: 1px 3px;
    box-shadow: 1px 1px 1px #000;
    display: block;
    text-align: center;
    background-image: linear-gradient(to bottom, #f4f5f5, #dfdddd);
    font-family: arial;
    font-size: 12px;
    line-height:30px;
}

.btn:hover {
    background-image: linear-gradient(to bottom, #c3e3fa, #a5defb);
}

.btn:active {
    margin: 1px 1px 0;
    box-shadow: -1px -1px 1px #000;
    background-image: linear-gradient(to top, #f4f5f5, #dfdddd);
}

#btnControl:checked + label {
    width: 70px;
    height: 74px;
    line-height: 74px;
}
<input type="checkbox" id="btnControl"/>
<label class="btn" for="btnControl">Click me!</label>

Un fils
la source
Nice: styles actifs; ce que je cherchais, mais a été un peu précipité lors de la construction de leur apparence.
TylerH
9

Que diriez-vous d'une solution CSS pure sans être (que) hacky?

entrez la description de l'image ici

.page {
  position: fixed;
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
  background-color: #121519;
  color: whitesmoke;
}

.controls {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  width: 100%;
}

.arrow {
  cursor: pointer;
  transition: filter 0.3s ease 0.3s;
}

.arrow:active {
  filter: drop-shadow(0 0 0 steelblue);
  transition: filter 0s;
}
<body class="page">
  <div class="controls">
    <div class="arrow">
      <img src="https://i.imgur.com/JGUoNfS.png" />
    </div>
  </div>
</body>

@TylerH a une excellente réponse mais c'est une solution assez complexe. J'ai une solution pour ceux d'entre vous qui veulent juste un simple effet "onclick" avec du css pur sans un tas d'éléments supplémentaires.

Nous utiliserons simplement les transitions css. Vous pourriez probablement faire de même avec des animations.

L'astuce consiste à modifier le délai de la transition afin qu'il dure lorsque l'utilisateur clique.

.arrowDownContainer:active,
.arrowDownContainer.clicked {
  filter: drop-shadow(0px 0px 0px steelblue);
  transition: filter 0s;
}

Ici, j'ajoute également la classe "cliquée" afin que javascript puisse également fournir l'effet si nécessaire. J'utilise un filtre ombre portée 0px car il mettra en surbrillance le bleu graphique transparent donné de cette façon pour mon cas.

J'ai un filtre à 0s ici pour qu'il ne prenne pas effet. Lorsque l'effet est libéré, je peux ensuite ajouter la transition avec un retard afin qu'elle fournisse un bel effet "cliqué".

.arrowDownContainer {
  cursor: pointer;
  position: absolute;
  bottom: 0px;
  top: 490px;
  left: 108px;
  height: 222px;
  width: 495px;
  z-index: 3;
  transition: filter 0.3s ease 0.3s;
}

Cela me permet de le configurer de sorte que lorsque l'utilisateur clique sur le bouton, il surligne le bleu puis s'éteint lentement (vous pouvez bien sûr utiliser d'autres effets également).

Bien que vous soyez limité ici dans le sens où l'animation à mettre en évidence est instantanée, elle fournit toujours l'effet souhaité. Vous pouvez probablement utiliser cette astuce avec l'animation pour produire une transition globale plus fluide.

entrez la description de l'image ici

entrez la description de l'image ici

Braden Rockwell Napier
la source
FWIW la complexité est ce qui est nécessaire pour instituer un effet de clic persistant . Si vous voulez simplement faire quelque chose temporairement qui ne conserve pas son état, cette solution ou bien d'autres solutions conviennent et je suis définitivement moins complexe.
TylerH
D'accord. Tout ce dont vous avez besoin pour être le résultat final et toujours bon de connaître toutes les options. C'est un excellent fil pour ceux qui sont sûrs. Vaut probablement la peine d'un article moyen entier sur chacun et les avantages de chacun!
Braden Rockwell Napier
8

D'accord, c'est peut-être un vieux post ... mais c'était le premier résultat dans google et j'ai décidé de faire votre propre mix à ce sujet comme ..

D'abord je vais utiliser FOCUS

La raison en est que cela fonctionne bien pour l'exemple que je montre, si quelqu'un veut un événement de type souris, utilisez Active

LE CODE HTML:

<button class="mdT mdI1" ></button>
<button class="mdT mdI2" ></button>
<button class="mdT mdI3" ></button>
<button class="mdT mdI4" ></button>

LE CODE CSS:

/* Change Button Size/Border/BG Color And Align To Middle */
    .mdT {
        width:96px;
        height:96px;
        border:0px;
        outline:0;
        vertical-align:middle;
        background-color:#AAAAAA;
    }
    .mdT:focus {
        width:256px;
        height:256px;
    }

/* Change Images Depending On Focus */
    .mdI1       {   background-image:url('http://placehold.it/96x96/AAAAAA&text=img1');     }
    .mdI1:focus {   background-image:url('http://placehold.it/256x256/555555&text=Image+1');   }
    .mdI2       {   background-image:url('http://placehold.it/96x96/AAAAAA&text=img2');     }
    .mdI2:focus {   background-image:url('http://placehold.it/256x256/555555&text=Image+2');   }
    .mdI3       {   background-image:url('http://placehold.it/96x96/AAAAAA&text=img3');     }
    .mdI3:focus {   background-image:url('http://placehold.it/256x256/555555&text=Image+3');   }
    .mdI4       {   background-image:url('http://placehold.it/96x96/AAAAAA&text=img4');     }
    .mdI4:focus {   background-image:url('http://placehold.it/256x256/555555&text=Image+4');   }

LIEN JS FIDDLE: http://jsfiddle.net/00wwkjux/

Alors pourquoi est-ce que je poste ceci dans un vieux fil de discussion, eh bien parce que les exemples ici varient et j'ai pensé en fournir un à la communauté qui est un exemple de travail.

Comme l'a déjà répondu le créateur du fil, ils ne veulent que l'effet dure pendant l'événement de clic. Maintenant, bien que ce ne soit pas exact pour ce besoin, c'est proche. active s'animera lorsque la souris est enfoncée et toutes les modifications dont vous avez besoin pour durer plus longtemps doivent être effectuées avec javascript.

En colère 84
la source
1
Pour tous ceux qui lisent, de toute façon pour le faire basculer? Ou est-ce trop demander de CSS lol?
DardanM
Pour autant que je sache, le focus / active / hover est à peu près aussi proche que possible avec css .. Vous pourriez être en mesure de faire quelque chose de fantaisiste avec une option / sélectionner le type de code .. Mais je n'ai pas encore essayé / nécessaire
Angry 84
7

Avertissement! Réponse particulièrement simple ci-dessous! :)

Vous pouvez réellement avoir un changement qui persiste (comme un bloc / popup qui apparaît et reste visible après un clic) avec seulement CSS (et sans utiliser le hack de case à cocher) malgré ce que beaucoup de réponses (sinon correctes) prétendent ici, aussi longtemps car vous n'avez besoin que de persévérance pendant le vol stationnaire.

Jetez donc un œil aux réponses de Bojangles et TylerH si celles-ci fonctionnent pour vous, mais si vous voulez une réponse simple et CSS qui gardera un bloc visible après avoir été cliqué (et peut même faire disparaître le bloc avec un clic de suivi), puis voir cette solution.

J'avais une situation similaire, j'avais besoin d'une div popup avec onClick où je ne pouvais pas ajouter de JS ou changer le balisage / HTML (une solution vraiment CSS) et cela est possible avec quelques mises en garde. Vous ne pouvez pas utiliser l'astuce: target qui peut créer une belle fenêtre contextuelle à moins que vous ne puissiez changer le code HTML (pour ajouter un 'id') afin qu'il ne soit pas utilisé.

Dans mon cas, le popup div était contenu dans l'autre div, et je voulais que le popup apparaisse au-dessus de l'autre div, et cela peut être fait en utilisant une combinaison de: active et: hover:

/* Outer div - needs to be relative so we can use absolute positioning */
.clickToShowInfo {
    position: relative;
}
/* When clicking outer div, make inner div visible */
.clickToShowInfo:active .info { display: block; }
/* And hold by staying visible on hover */
.info:hover {
    display: block;
}
/* General settings for popup */
.info {
    position: absolute;
    top: -5;
    display: none;
    z-index: 100;
    background-color: white;
    width: 200px;
    height: 200px;
}

Exemple (ainsi que celui qui permet de cliquer sur la popup pour la faire disparaître) sur:

http://davesource.com/Solutions/20150324.CSS-Only-Click-to-Popup-Div/

J'ai également inséré un exemple d'extrait de code ci-dessous, mais le positionnement dans le bac à sable stackoverflow est étrange, j'ai donc dû mettre le texte `` cliquez ici '' après le innerDiv, ce qui n'est normalement pas nécessaire.

/* Outer div - needs to be relative so we can use absolute positioning */
	.clickToShowInfo {
		position: relative;
	}
	/* When clicking outer div, make inner div visible */
	.clickToShowInfo:active .info { visibility: visible; }
	/* And hold by staying visible on hover */
	.info:hover {
		visibility: visible;
	}
	/* General settings for popup */
	.info {
		position: absolute;
		top: -10;
		visibility: hidden;
		z-index: 100;
		background-color: white;
		box-shadow: 5px 5px 2px #aaa;
		border: 1px solid grey;
		padding: 8px;
		width: 220px;
		height: 200px;
	}
	/* If we want clicking on the popup to close, use this */
	.info:active {
		visibility: hidden;	/* Doesn't work because DCEvent is :active as well */
		height: 0px;
		width: 0px;
		left: -1000px;
		top: -1000px;
	}
<p />
<div class="clickToShowInfo">
	<div class="info">
		Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua
	</div>
	Click here to show info
</div>
<p />

David Ljung Madison Stellar
la source
1
(re: notre discussion de commentaires plus tôt) La div info ne reste pas visible après mouseUp sur Firefox. Bien qu'il reste visible après mouseUp dans d'autres navigateurs (IE, Edge, Chrome), il ne persiste pas lorsque la souris est sortie de la boîte dans un autre navigateur, l'empêchant ainsi d'être considérée comme un véritable événement `` onclick '' ( par exemple un changement persistant).
TylerH
2

J'ai le code ci-dessous pour le survol et le clic de la souris et cela fonctionne:

//For Mouse Hover
.thumbnail:hover span{ /*CSS for enlarged image*/
    visibility: visible;
    text-align:center;
    vertical-align:middle;
    height: 70%;
    width: 80%;
    top:auto;
    left: 10%;
}

et ce code cache l'image lorsque vous cliquez dessus:

.thumbnail:active span {
    visibility: hidden;
}
Pir Fahim Shah
la source
2

J'ai eu un problème avec un élément qui devait être de couleur ROUGE au survol et être BLEU au clic pendant le survol. Pour y parvenir avec css vous avez besoin par exemple:

h1:hover { color: red; } 
h1:active { color: blue; }

<h1>This is a heading.</h1>

J'ai lutté pendant un certain temps jusqu'à ce que je découvre que l' ordre des sélecteurs CSS était le problème que j'avais. Le problème était que j'ai changé de place et que le sélecteur actif ne fonctionnait pas. Ensuite, j'ai découvert que :hoverpour aller d'abord et ensuite :active.

Déjà pris
la source
-3

vous pouvez utiliser: cible

pour cible générale

:cible

ou filtrer par nom de classe

.classname: cible

ou filtrer par nom d'ID

#idname: cible

<style>

#id01:target {      
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
}

.msg{
    display:none;
}

.close{     
    color:white;        
    width: 2rem;
    height: 2rem;
    background-color: black;
    text-align:center;
    margin:20px;
}

</style>


<a href="#id01">Open</a>

<div id="id01" class="msg">    
    <a href="" class="close">&times;</a>
    <p>Some text. Some text. Some text.</p>
    <p>Some text. Some text. Some text.</p>
</div>
Hatem Badawi
la source
2
Une réponse montrant comment utiliser :targetest déjà publiée, donc pas besoin d'une autre. De plus, l'interrogateur demande comment avoir un effet "onclick", pas afficher / masquer d'autres éléments.
Ason
Il s'agit plus d'un effet "onload" que "onclick".
TylerH