Posso ter um efeito onclick em CSS?

335

Eu tenho um elemento de imagem que desejo alterar ao clicar.

<img id="btnLeft">

Isso funciona:

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

Mas o que eu preciso é:

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

Mas, isso não funciona, obviamente. É possível ter onclickcomportamento em CSS (ou seja, sem usar JavaScript)?

Alegro
fonte
7
:activefunciona enquanto o mouse está pressionado. Dependendo do que você está tentando fazer, você poderá fazê-lo funcionar usando a pseudo classe CSS4 :target.
bfavaretto
2
:targetnão é novidade para os seletores 4. Está disponível desde os seletores 3, que já era uma recomendação há um ano no momento da redação deste artigo.
BoltClock

Respostas:

314

O mais próximo que você vai chegar é :active:

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

No entanto, isso só aplicará o estilo quando o botão do mouse for pressionado. A única maneira de aplicar um estilo e mantê-lo aplicado ao clicar é usar um pouco de JavaScript.

Bojangles
fonte
@ Sparky672, praticamente tudo: caniuse.com/#feat=css-sel2 (IE7 suportes: muito ativo, mas não está na lista porque ele não suporta alguns dos outros seletores)
jrajav
@ Kiyura, acho que tudo, exceto alguns bugs no IE 8 e acima .
Sparky
13
Esta resposta está desatualizada. Veja a resposta de TylerH para uma solução apenas de CSS para isso.
Maximillian Laumeister
Existe uma solução apenas de CSS ainda mais fácil do que o hack de TylerH.
David Ljung Madison Stellar
348

Resposta a partir de 2019:

A melhor maneira (na verdade, a única maneira *) de simular um evento de clique real usando apenas CSS (em vez de passar o mouse sobre um elemento ou torná-lo ativo, onde você não tem mouseUp ) é usar a caixa de seleção hack. Ele funciona anexando a labela um <input type="checkbox">elemento através do for=""atributo do rótulo .

Esse recurso possui amplo suporte ao navegador (a :checkedpseudo classe é o IE9 +).

Aplique o mesmo valor para um <input>'s atributo ID e um acompanhante <label>' s for=""atributo, e você pode dizer ao navegador para re-estilo da etiqueta no clique com o :checkedpseudo-classe, graças ao fato de que, ao clicar uma etiqueta irá verificar e desmarque a "associado" <input type="checkbox">.

* Você pode simular um evento "selecionado" por meio do :activeou :focuspseudo-classe no IE7 + (por exemplo, para um botão que é normalmente 50pxgrande, você pode mudar a sua largura, enquanto active: #btnControl:active { width: 75px; }), mas aqueles que não são verdadeiras "clique" eventos. Eles ficam "ativos" o tempo todo em que o elemento é selecionado (como Tabpressionar o teclado), que é um pouco diferente de um evento de clique real, que aciona uma ação - normalmente - mouseUp.


Demonstração básica do hack da caixa de seleção (a estrutura básica do código para o que você está pedindo):

Aqui posicionei o rótulo logo após a entrada na minha marcação. Isso é para que eu possa usar o seletor de irmão adjacente (a +tecla) para selecionar apenas o rótulo que segue imediatamente minha #democaixa de seleção. Como a :checkedpseudo-classe se aplica à caixa de seleção, #demo:checked + labelela só será aplicada quando a caixa de seleção estiver marcada.

Demonstração para redimensionar uma imagem ao clicar, e é isso que você está perguntando:

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

Com isso dito, não é uma má notícia. Como um rótulo pode ser associado apenas a um controle de formulário por vez , isso significa que você não pode simplesmente soltar um botão dentro das <label></label>tags e chamá-lo por dia. No entanto, nós podemos usar alguns CSS para tornar o rótulo e se comportam bastante perto de como um botão HTML parece e se comporta.

Demonstração para imitar o efeito de clique no botão, acima e além do que você está perguntando:

A maior parte do CSS nesta demonstração é apenas para estilizar o elemento label. Se você realmente não precisar de um botão , e qualquer elemento antigo for suficiente, poderá remover quase todos os estilos desta demonstração, semelhante à minha segunda demonstração acima.

Você também notará que eu tenho uma propriedade prefixada lá -moz-outline-radius,. Há algum tempo, a Mozilla adicionou essa incrível propriedade não especificada ao Firefox, mas o pessoal do WebKit decidiu que não a adicionaria , infelizmente. Portanto, considere essa linha de CSS apenas um aprimoramento progressivo para pessoas que usam o Firefox.

TylerH
fonte
2
Impressionante! Mas existe uma maneira de reverter as alterações também ao clicar em outro lugar que não seja na entrada / imagem / botão? Usei seu exemplo para criar um campo pop-up e quero que ele desapareça quando os visitantes clicarem na página em branco. Obrigado!
Mxmehl #
1
@mxmehl Se você quiser que eles cliquem em um local específico, você pode fazê-lo com outro elemento irmão adjacente, provavelmente. No entanto, se você quiser reverter apenas clicando em qualquer lugar da tela em branco, provavelmente precisará de ouvintes de eventos JavaScript. Lembre-se, isso é um truque e não é a melhor maneira de criar uma experiência "interativa"; é para isso que serve o JS . É assim que você deve fazer se estiver restrito a usar apenas CSS. :-)
TylerH
5
Essa solução ainda é boa, mas quando eu li a "resposta 2017", eu esperava algo realmente interessante (como um recurso CSS3 que finalmente ganhou amplo suporte ao navegador), não o grande e antigo hackbox que existe desde 2011 ... Um pouco decepcionado .
precisa
3
@Christallkeks Se o CSS adicionar algo (provavelmente não o fará; a interatividade está além do escopo do objetivo do CSS), atualizarei a resposta para incluí-lo. Tal como está, a manchete "resposta de 2017" é informar às pessoas que essa resposta é a mais atualizada, de modo que, de relance, elas não olhem para o fato de que a resposta foi publicada em 2015 e pronto "oh , Gostaria de saber se já existe um novo recurso ".
TylerH
1
@MuhammadSaqib Sim, ele deve funcionar em qualquer navegador móvel compatível :checked.
TylerH
78

Você pode usar pseudo classe :target para imitar o evento click, deixe-me dar um exemplo.

#something {
  display: none;
}

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

Veja como é: http://jsfiddle.net/TYhnb/

Uma coisa a observar, isso é limitado apenas ao hiperlink; portanto, se você precisar usar outro que não seja o hiperlink, como um botão, convém invadir um pouco, como estilizar um hiperlink para parecer um botão.

Hendra Uzia
fonte
8
Como invertemos a ação?
Ansyori
Eu pensei que você não poderia segmentar algo que não foi exibido.
Hazior 18/08/19
38

Se você der o elemento a tabindex, poderá usar a :focuspseudo classe para simular um clique.

HTML

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

CSS

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

http://jsfiddle.net/NaTj5/

Blake Plumb
fonte
2
isso funciona razoavelmente bem! quando você usa tabindex=-1o item, ainda é focalizável, mas apenas pelo mouse, não pelo teclado, o que é melhor nesse caso. você também pode usar um outline:0estilo para remover a borda azul quando focada
Stefan Paul Noack
35

Edit: Respondido antes do OP esclarecer o que ele queria. A seguir, um onclick semelhante ao javascripts onclick, não o:active pseudo classe.

Isso só pode ser alcançado com Javascript ou o Checkbox Hack

O hack da caixa de seleção basicamente permite que você clique em um rótulo, que "marca" uma caixa de seleção, permitindo que você estilize o rótulo como desejar.

A demo

Andy
fonte
1
Você também pode incluir sua entrada dentro do rótulo para não precisar usar idatributos para ligá-los.
Stackable
12

TylerH deu uma resposta muito boa, e eu apenas tive que atualizar a versão do último botão.

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

Um filho
fonte
Nice: estilos ativos; o que eu estava procurando, mas estava um pouco apressado ao criar a aparência deles.
TylerH
9

Que tal uma solução CSS pura sem ser (isso) hacky?

insira a descrição da imagem aqui

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

O @TylerH tem uma ótima resposta, mas é uma solução bastante complexa. Eu tenho uma solução para aqueles que desejam apenas um simples efeito "onclick" com CSS puro, sem um monte de elementos extras.

Nós simplesmente usaremos transições CSS. Você provavelmente poderia fazer o mesmo com as animações.

O truque é alterar o atraso da transição para que dure quando o usuário clicar.

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

Aqui também adiciono a classe "clicada" para que o javascript também possa fornecer o efeito, se necessário. Eu uso o filtro de sombra de 0px porque destacará o gráfico transparente azul fornecido desta maneira para o meu caso.

Eu tenho um filtro em 0s aqui para que não entre em vigor. Quando o efeito é liberado, posso adicionar a transição com um atraso para que ele forneça um bom efeito "clicado".

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

Isso me permite configurá-lo para que, quando o usuário clicar no botão, realce o azul e desapareça lentamente (você pode, é claro, usar outros efeitos também).

Embora você esteja limitado aqui no sentido de que a animação a destacar é instantânea, ela ainda fornece o efeito desejado. Você provavelmente poderia usar esse truque com animação para produzir uma transição geral mais suave.

insira a descrição da imagem aqui

insira a descrição da imagem aqui

Braden Rockwell Napier
fonte
FWIW, a complexidade é o que é necessário para instituir um efeito de clique persistente . Se você quiser apenas fazer algo temporariamente que não retenha seu estado, esta ou muitas outras soluções são boas e eu concordo definitivamente menos complexo.
TylerH 21/05/19
Acordado. Tudo no que você precisa que o resultado final seja e sempre bom conhecer todas as opções. Este é um ótimo tópico para aqueles, com certeza. Provavelmente vale a pena um artigo médio inteiro abordando cada um e os benefícios de cada um!
Braden Rockwell Napier
8

Ok, este talvez seja um post antigo ... mas foi o primeiro resultado no google e decidiu fazer o seu próprio mix neste ..

PRIMEIRO, USAREI O FOCO

A razão para isso é que ele funciona bem para o exemplo que estou mostrando, se alguém quiser um evento do tipo mouse down, use active

O CÓDIGO HTML:

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

O CÓDIGO 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');   }

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

Então, por que estou postando isso em um tópico antigo, bem, porque os exemplos aqui variam e pensei em fornecer um de volta à comunidade, que é um exemplo de trabalho.

Como já foi respondido pelo criador do thread, ele deseja que o efeito dure apenas durante o evento click. Agora, embora isso não seja exato para essa necessidade, está próximo. O active será animado enquanto o mouse estiver pressionado e quaisquer alterações que você precise que durem mais precisam ser feitas com javascript.

Angry 84
fonte
1
Para quem está lendo, de qualquer maneira, para alternar? Ou isso é pedir muito de css lol?
DardanM
Até onde eu sei, o foco / ativo / foco é o mais próximo possível do CSS. Você pode fazer algo sofisticado com uma opção / selecionar o tipo de código. Mas ainda não tentou / precisava disso
irritado 84
7

Aviso! Resposta particularmente simples abaixo! :)

Na verdade, você pode ter uma alteração que persista (como um bloco / pop-up que aparece e permanece visível após um clique) apenas com CSS (e sem usar o hack da caixa de seleção), apesar do que muitas das respostas (de outra forma corretas) aqui reivindicam, desde pois você só precisa de persistência durante o foco.

Portanto, dê uma olhada nas respostas de Bojangles e TylerH, se elas funcionarem para você, mas se você quiser uma resposta simples e apenas CSS que manterá um bloco visível depois de ser clicado (e até pode fazer com que o bloco desapareça com um clique de acompanhamento), então veja esta solução.

Eu tive uma situação semelhante, precisava de uma div pop-up com o onClick, onde não era possível adicionar nenhum JS ou alterar a marcação / HTML (uma solução verdadeiramente CSS) e isso é possível com algumas ressalvas. Você não pode usar o truque: target, que pode criar um bom pop-up, a menos que você possa alterar o HTML (para adicionar um 'id'), para que isso ocorra.

No meu caso, a div pop-up estava contida na outra div, e eu queria que o pop-up aparecesse em cima da outra div, e isso pode ser feito usando uma combinação de: active e: 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;
}

Exemplo (bem como um que permite clicar no pop-up para fazê-lo desaparecer) em:

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

Também inseri um exemplo de trecho de código abaixo, mas o posicionamento na sandbox stackoverflow é estranho, então tive que colocar o texto 'clique aqui' após o innerDiv, o que normalmente não é necessário.

/* 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
fonte
1
(re: nossa discussão sobre comentários anteriormente) A div info não permanece visível após o mouse no Firefox. Embora permaneça visível após o mouseUp em outros navegadores (IE, Edge, Chrome), ele não persiste quando o mouse é retirado da caixa em qualquer outro navegador, impedindo que seja considerado um evento real 'onclick' ( por exemplo, uma mudança persistente).
TylerH
2

Eu tenho o código abaixo para passar o mouse e clicar com o mouse e funciona:

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

e esse código oculta a imagem quando você clica nela:

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

Eu tive um problema com um elemento que precisava ser colorido de VERMELHO ao passar o mouse e ser AZUL ao clicar ao passar o mouse. Para conseguir isso com o css, você precisa, por exemplo:

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

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

Eu lutei por algum tempo até descobrir que a ordem dos seletores de CSS era o problema que eu estava tendo. O problema era que troquei de lugar e o seletor ativo não estava funcionando. Então eu descobri que :hoverir primeiro e depois :active.

Já se tornou independente
fonte
-3

você pode usar: target

para alvo geral

:alvo

ou filtrar pelo nome da classe

.classname: target

ou filtrar pelo nome do ID

#idname: target

<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
fonte
2
Uma resposta mostrando como usar :targetjá está publicada, portanto, não há mais necessidade. Além disso, o questionador pergunta como obter um efeito "onclick", não mostra / oculta outros elementos.
Ason
Isso é mais um efeito "onload" do que "onclick" também.
TylerH