Czy mogę uzyskać efekt kliknięcia w CSS?

335

Mam element obrazu, który chcę zmienić po kliknięciu.

<img id="btnLeft">

To działa:

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

Ale potrzebuję:

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

Ale to oczywiście nie działa. Czy w ogóle możliwe jest onclickzachowanie w CSS (tj. Bez użycia JavaScript)?

Alegro
źródło
7
:activedziała, gdy mysz jest wciśnięta. W zależności od tego, co próbujesz zrobić, możesz być w stanie sprawić, że będzie działać przy użyciu pseudoklasy CSS4 :target.
bfavaretto
2
:targetnie jest nowością w Selektorach 4. Jest dostępny od Selektorów 3, które były już rekomendacją na rok w momencie pisania.
BoltClock

Odpowiedzi:

314

Najbliższe, które otrzymasz :active:

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

Będzie to jednak obowiązywać tylko wtedy, gdy przycisk myszy zostanie przytrzymany. Jedynym sposobem na zastosowanie stylu i zachowanie go po kliknięciu jest użycie JavaScript.

Bojangles
źródło
@ Sparky672, Prawie wszystko: caniuse.com/#feat=css-sel2 (IE7 obsługuje: również aktywne, ale nie ma go na liście, ponieważ nie obsługuje niektórych innych selektorów)
jrajav
@Kiyura, chyba wszystko oprócz kilku błędów w IE 8 i nowszych .
Sparky
13
Ta odpowiedź jest nieaktualna. Zobacz odpowiedź TylerH, aby znaleźć rozwiązanie tylko w CSS.
Maximillian Laumeister
Jest jeszcze prostsze rozwiązanie tylko do CSS niż hack do zaznaczania TylerH.
David Ljung Madison Stellar
348

Odpowiedź od 2019 r .:

Najlepszym sposobem (właściwie jedynym sposobem *) na symulację rzeczywistego zdarzenia kliknięcia przy użyciu tylko CSS (zamiast najechania myszką na element lub aktywowania elementu, gdy nie masz mouseUp ), jest użycie hackowania pola wyboru. Działa poprzez dołączenie a labeldo <input type="checkbox">elementu za pomocą for=""atrybutu etykiety .

Ta funkcja ma szeroką obsługę przeglądarki ( :checkedpseudo-klasa to IE9 +).

Stosować tę samą wartość do <input>„s atrybut ID i towarzyszącej <label>” s for=""atrybutu, i można powiedzieć, przeglądarkę do ponownego stylu etykieta na kliknięcia z :checkedpseudo-klasie, dzięki temu, że kliknięcie etykiety sprawdzi i odznacz "powiązany"<input type="checkbox"> .

* Można symulować „wybrane” zdarzenie za pośrednictwem :activelub :focuspseudo-klasy w IE7 + (np za pomocą przycisku, który jest zwykle 50pxszeroki, można zmienić jego szerokość, natomiast active: #btnControl:active { width: 75px; }), ale te nie są prawdziwe „kliknięcie” wydarzenia. Są one „aktywne” przez cały czas wybierania elementu (na przykład przez Tabbing za pomocą klawiatury), co nieco różni się od zdarzenia prawdziwego kliknięcia, które uruchamia akcję - zazwyczaj - mouseUp.


Podstawowe demo hacka pola wyboru (podstawowa struktura kodu o co pytasz):

Tutaj umieściłem etykietę zaraz po danych wejściowych w znacznikach. Jest tak, że mogę użyć sąsiedniego selektora rodzeństwa ( +klawisza), aby zaznaczyć tylko etykietę, która następuje bezpośrednio po moim polu #demowyboru. Ponieważ :checkedpseudoklasa dotyczy pola wyboru,#demo:checked + label będzie obowiązywać tylko wtedy, gdy pole wyboru jest zaznaczone.

Demo zmiany rozmiaru obrazu po kliknięciu, o co pytasz:

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

Biorąc to pod uwagę, złe wieści. Ponieważ etykieta może być skojarzona tylko z jedną kontrolką formularza na raz , oznacza to, że nie można po prostu wrzucić przycisku do <label></label>tagów i nazwać go dniem. Jednak możliwe użyć CSS, aby etykieta wyglądała i zachowywała się dość blisko tego, jak przycisk HTML wygląda i zachowuje się.

Demo naśladujące efekt kliknięcia przycisku, wykraczający poza to, o co pytasz:

Większość CSS w tym demo służy tylko do stylizacji elementu etykiety. Jeśli tak naprawdę nie potrzebujesz przycisku , a wystarczy dowolny stary element, możesz usunąć prawie wszystkie style z tej wersji demo, podobnie jak w mojej drugiej wersji powyżej.

Zauważysz również mam jedną właściwość ustaloną z góry w tam -moz-outline-radius. Jakiś czas temu Mozilla dodała tę niesamowitą nieokreśloną właściwość do Firefoksa, ale ludzie z WebKit zdecydowali, że nie zamierzają jej dodawać , niestety. Więc rozważ tę linię CSS jako progresywne ulepszenie dla osób korzystających z Firefoksa.

TylerH
źródło
2
Niesamowite! Ale czy istnieje sposób, aby cofnąć zmiany również po kliknięciu gdzie indziej niż na przycisku input / image /? Użyłem twojego przykładu, aby utworzyć wyskakujące pole i chcę, aby zniknęło, gdy użytkownicy klikną pustą stronę. Dzięki!
mxmehl,
1
@mxmehl Jeśli chcesz, aby kliknęli w określone miejsce, prawdopodobnie możesz to zrobić z innym sąsiednim elementem rodzeństwa. Jeśli jednak chcesz przywrócić to ustawienie, klikając dowolne miejsce na pustym ekranie, prawdopodobnie będziesz potrzebować detektorów zdarzeń JavaScript. Pamiętaj, że jest to hack i nie jest to „najlepszy” sposób na stworzenie „interaktywnego” doświadczenia; to co JS jest za . Oto jak to zrobić, jeśli jesteś ograniczony do korzystania wyłącznie z CSS. :-)
TylerH
5
To rozwiązanie jest nadal fajne, ale kiedy przeczytałem „Odpowiedź z 2017 roku”, spodziewałem się czegoś naprawdę fajnego (jak funkcja CSS3, która w końcu uzyskała szeroką obsługę przeglądarki), a nie wielkiego, starego hacka do zaznaczania, który istnieje od 2011 roku … Nieco rozczarowany .
Christallkeks,
3
@Christallkeks Jeśli CSS doda coś (prawdopodobnie nie zrobi tego; interaktywność wykracza poza cel CSS), zaktualizuję odpowiedź, aby to uwzględnić. W tej chwili nagłówek „Odpowiedź z 2017 r.” Informuje ludzi, że ta odpowiedź jest najbardziej aktualna, więc na pierwszy rzut oka nie spojrzą na to, że odpowiedź została opublikowana w 2015 r. , Zastanawiam się, czy istnieje już nowa funkcja ".
TylerH
1
@MuhammadSaqib Tak, powinien działać na każdej przeglądarce mobilnej, która obsługuje :checked.
TylerH
78

Możesz użyć pseudoklasy :targetdo naśladowania zdarzenia kliknięcia, dam ci przykład.

#something {
  display: none;
}

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

Oto jak to wygląda: http://jsfiddle.net/TYhnb/

Należy zauważyć, że ogranicza się to tylko do hiperłącza, więc jeśli chcesz użyć innego niż hiperłącze, takiego jak przycisk, możesz go nieco zhakować, na przykład zaprojektować hiperłącze, aby wyglądało jak przycisk.

Hendra Uzia
źródło
8
Jak odwrócić akcję?
Ansyori,
Myślałem, że nie możesz celować w coś, co nie było wyświetlane.
Hazior
38

Jeśli dasz elementowi tabindex, możesz użyć:focus pseudoklasy do symulacji kliknięcia.

HTML

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

CSS

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

http://jsfiddle.net/NaTj5/

Blake Plumb
źródło
2
to działa dość dobrze! podczas korzystania tabindex=-1z przedmiotu można nadal ustawiać ostrość, ale tylko myszą, a nie klawiaturą, co w tym przypadku jest lepsze. możesz również użyć outline:0stylu, aby usunąć niebieską ramkę, gdy jest skupiony
Stefan Paul Noack
35

Edycja: Odpowiedzi przed OP wyjaśnił, czego chce. Poniższe informacje dotyczą kliknięcia onclick podobnego do skryptów javascript, a nie:active pseudoklasy.

Można to osiągnąć tylko za pomocą Javascript lub Checkbox Hack

Hack pola wyboru zasadniczo polega na kliknięciu etykiety, która „sprawdza” pole wyboru, umożliwiając stylizację etykiety według własnego uznania.

demo

Andy
źródło
1
Możesz również dołączyć swoje dane wejściowe do etykiety, aby nie musieć używać idatrybutów do ich łączenia.
sztaplowane
12

TylerH udzielił naprawdę dobrej odpowiedzi, a ja po prostu musiałem zaktualizować tę ostatnią wersję przycisku.

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

Syn
źródło
Nicea: aktywne style; o co mi chodziło, ale trochę się spieszyłem, gdy budowałem ich wygląd.
TylerH,
9

Co powiesz na czyste rozwiązanie CSS bez bycia hackowanym?

wprowadź opis zdjęcia tutaj

.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 ma świetną odpowiedź, ale jest to dość złożone rozwiązanie. Mam rozwiązanie dla tych z Was, którzy chcą po prostu prostego efektu „kliknięcia” z czystym css bez dodatkowych elementów.

Będziemy po prostu używać przejść css. Prawdopodobnie możesz zrobić podobnie z animacjami.

Sztuką jest zmienić opóźnienie przejścia, aby trwało, gdy użytkownik kliknie.

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

Tutaj dodam także klasę „klikniętą”, aby w razie potrzeby javascript mógł także zapewnić efekt. Korzystam z filtru cienia 0 pikseli, ponieważ w ten sposób podświetli moją przezroczystą grafikę na niebiesko.

Mam tutaj filtr zerowy, aby nie zadziałał. Po zwolnieniu efektu mogę dodać przejście z opóźnieniem, aby zapewnić przyjemny efekt „kliknięcia”.

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

To pozwala mi skonfigurować go tak, aby kliknięcie przycisku przez użytkownika podświetlało kolor niebieski, a następnie powoli zanikało (oczywiście można było również użyć innych efektów).

Chociaż jesteś tutaj ograniczony w tym sensie, że animacja do podświetlenia jest natychmiastowa, nadal zapewnia pożądany efekt. Prawdopodobnie możesz użyć tej sztuczki z animacją, aby uzyskać płynniejsze ogólne przejście.

wprowadź opis zdjęcia tutaj

wprowadź opis zdjęcia tutaj

Braden Rockwell Napier
źródło
FWIW złożoność jest niezbędna do ustanowienia trwałego efektu kliknięcia. Jeśli chcesz po prostu zrobić coś tymczasowo, który nie zachowuje swojego stanu, to jedno lub wiele innych rozwiązań jest w porządku i zgadzam się zdecydowanie mniej skomplikowane.
TylerH
Zgoda. Wszystko, czego potrzebujesz, aby wynik końcowy był i zawsze dobrze znać wszystkie opcje. To na pewno świetny wątek dla tych. Prawdopodobnie warty jest cały średni artykuł omawiający każdy z nich i zalety każdego z nich!
Braden Rockwell Napier
8

Okej, to może stary post ... ale był pierwszym rezultatem w Google i postanowiłem stworzyć własny miks na ten temat jako ...

PIERWSZE KORZYSTAM Z OSTROŚCI

Powodem tego jest to, że działa ładnie w przykładzie, który pokazuję, jeśli ktoś chce zdarzenia typu myszy, użyj aktywnej

KOD HTML:

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

KOD 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 FIDDLE LINK: http://jsfiddle.net/00wwkjux/

Więc dlaczego zamieszczam to w starym wątku, no cóż, ponieważ tutaj przykłady są różne i pomyślałem, aby przekazać je społeczności, która jest działającym przykładem.

Jak już odpowiedział twórca wątku, chcą, aby efekt trwał tylko podczas zdarzenia kliknięcia. Teraz, choć nie jest to dokładnie takie potrzeby, jest blisko. Aktywne będzie animowane, gdy mysz będzie w pozycji opuszczonej, a wszelkie zmiany, które trzeba będzie trwać dłużej, należy wprowadzić w javascript.

Zły 84
źródło
1
Dla każdego, kto czyta, tak czy inaczej, aby się przełączyć? A może to wymaga zbyt wiele od css lol?
DardanM,
O ile mi wiadomo, focus / active / hover jest tak blisko, jak to tylko możliwe z css .. Możesz być w stanie zrobić coś fantazyjnego z opcją / wybierz typ kodu .. Ale jeszcze nie próbowałem / potrzebowałem tego jeszcze
Zły 84
7

Ostrzeżenie! Szczególnie prosta odpowiedź poniżej! :)

Ty rzeczywiście mogą mieć zmiany, który utrzymuje się (takie jak blok / popup, że pojawia się i pozostaje widoczne po kliknięciu) z tylko CSS (oraz bez użycia hack pole wyboru) Wbrew temu, co wielu z (inaczej poprawna) odpowiada tutaj roszczenia, jak długo ponieważ potrzebujesz tylko uporu podczas najechania kursorem.

Spójrz więc na odpowiedzi Bojangles i TylerH, jeśli te działają dla Ciebie, ale jeśli chcesz prostej odpowiedzi zawierającej tylko CSS, która będzie wyświetlać blok po kliknięciu (a nawet może sprawić, że blok zniknie za pomocą kolejnego kliknięcia), to zobacz to rozwiązanie.

Miałem podobną sytuację, potrzebowałem wyskakującego okienka z onClick, w którym nie mogłem dodać żadnego JS ani zmienić znaczników / HTML (rozwiązanie naprawdę CSS) i jest to możliwe z pewnymi zastrzeżeniami. Nie możesz użyć sztuczki: target, która może stworzyć fajne wyskakujące okienko, chyba że możesz zmienić kod HTML (aby dodać „id”), aby go nie było.

W moim przypadku wyskakujące okienko div było zawarte w innym divie i chciałem, aby wyskakujące okienko pojawiało się nad innym divem, i można to zrobić za pomocą kombinacji: active i: 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;
}

Przykład (a także taki, który umożliwia kliknięcie wyskakującego okienka, aby zniknęło) w:

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

Wstawiłem także przykładowy fragment kodu poniżej, ale pozycjonowanie w piaskownicy stackoverflow jest dziwne, więc musiałem umieścić tekst „kliknij tutaj” po wewnętrznej części DIV, co zwykle nie jest potrzebne.

/* 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
źródło
1
(ponownie: nasza dyskusja na temat komentarza wcześniej) Dywizja informacyjna nie pozostaje widoczna po mouseUp w Firefoksie. Chociaż pozostaje widoczny obok mouseUp w innych przeglądarkach (IE, Edge, Chrome), nie utrzymuje się, gdy mysz zostanie wyjęta z pudełka w dowolnej innej przeglądarce, co zapobiega uznaniu go za prawdziwe zdarzenie „kliknięcia” ( np. trwała zmiana).
TylerH,
2

Mam poniższy kod do najechania myszą i kliknięcia myszą i działa:

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

a ten kod ukrywa obraz po kliknięciu:

.thumbnail:active span {
    visibility: hidden;
}
Pir Fahim Shah
źródło
2

Miałem problem z elementem, który musiał zostać zabarwiony na CZERWONO po najechaniu kursorem i być NIEBIESKI na kliknięciu podczas najechania kursorem. Aby to osiągnąć za pomocą css, potrzebujesz na przykład:

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

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

Zmagałem się przez jakiś czas, dopóki nie odkryłem, że problemem jest kolejność selektorów CSS. Problem polegał na tym, że zmieniałem miejsca i aktywny selektor nie działał. Potem dowiedziałem się, że :hovernajpierw :active.

Alreadytakenindeed
źródło
-3

możesz użyć: target

dla ogólnego celu

:cel

lub filtruj według nazwy klasy

.classname: cel

lub filtruj według nazwy 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
źródło
2
Odpowiedź pokazująca, jak korzystać, :targetjest już opublikowana, więc nie trzeba jej więcej. Ponadto pytający pyta, jak uzyskać efekt „kliknięcia”, a nie pokazywać / ukrywać inne elementy.
Ason
Jest to również bardziej efekt „onload” niż „onclick”.
TylerH