Могу ли я иметь эффект onclick в CSS?

336

У меня есть элемент изображения, который я хочу изменить при нажатии.

<img id="btnLeft">

Это работает:

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

Но то, что мне нужно, это:

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

Но это не работает, очевидно. Можно ли вообще иметь onclickповедение в CSS (т.е. без использования JavaScript)?

Аллегро
источник
7
:activeработает, когда мышь не работает. В зависимости от того, что вы пытаетесь сделать, вы можете заставить его работать, используя псевдокласс CSS4 :target.
bfavaretto
2
:targetне является новым для Селекторов 4. Он был доступен начиная с Селекторов 3, который на момент написания уже был рекомендацией в течение года.
BoltClock

Ответы:

315

Самое близкое, что вы получите :active:

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

Однако этот стиль будет применяться только тогда, когда нажата кнопка мыши. Единственный способ применить стиль и оставить его примененным по клику - это использовать немного JavaScript.

Bojangles
источник
@ Sparky672, почти все: caniuse.com/#feat=css-sel2 (IE7 поддерживает: active тоже, но не указан, потому что не поддерживает некоторые другие селекторы)
jrajav
@Kiyura, я думаю, все, кроме некоторых ошибок в IE 8 и выше .
Sparky
13
Этот ответ устарел. Смотрите ответ TylerH для решения этого вопроса только для CSS.
Максимилиан Ломейстер
Есть даже более простое решение только для CSS, чем взломать флажок TylerH.
Дэвид Люнг Мэдисон
349

Ответ от 2019 года:

Лучший способ (на самом деле единственный способ *) имитировать фактическое событие нажатия, используя только CSS (вместо простого наведения на элемент или активизации элемента, когда у вас нет mouseUp ), - использовать хак с флажком . Это работает путем присоединения labelк <input type="checkbox">элементу через for=""атрибут метки .

Эта функция имеет широкую поддержку браузера ( :checkedпсевдокласс IE9 +).

Применить такое же значение , к <input>«s атрибут ID и сопровождающим <label>» s for=""атрибута, и вы можете сказать браузеру , чтобы повторно стиле этикетки по щелчку с :checkedпсевдо-класса, благодаря тому , что при нажатии на метку будет проверять и снимите «связанный» <input type="checkbox">.

* Вы можете смоделировать «выбранное» событие с помощью :activeили :focusпсевдокласса в IE7 + (например, для кнопки, которая обычно 50pxширока, вы можете изменить ее ширину, пока active:) #btnControl:active { width: 75px; }, но это не настоящие события «щелчка». Они «живут» все время, когда элемент выбран (например, Tabс помощью клавиатуры), что немного отличается от события истинного щелчка, которое запускает действие - как правило - mouseUp.


Базовая демонстрация взлома флажков (базовая структура кода для того, что вы спрашиваете):

Здесь я разместил метку сразу после ввода в моей разметке. Это сделано для того, чтобы я мог использовать соседний селектор ( +ключ), чтобы выбрать только метку, которая следует сразу за моим #demoфлажком. Поскольку :checkedпсевдокласс применяется к флажку, он #demo:checked + labelбудет применяться только тогда, когда флажок установлен.

Демонстрация изменения размера изображения при нажатии, о чем вы просите:

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

При этом , как говорится, есть это плохие новости. Поскольку ярлык может быть связан только с одним элементом управления формы за раз , это означает, что вы не можете просто вставить кнопку в <label></label>теги и вызвать ее в день. Тем не менее, мы можем использовать немного CSS, чтобы ярлык выглядел и вел себя довольно близко к тому, как выглядит и ведет себя кнопка HTML.

Демонстрация для имитации эффекта нажатия кнопки, сверх того, что вы просите:

Большая часть CSS в этой демонстрации предназначена только для стилизации элемента label. Если вам на самом деле не нужна кнопка , и достаточно старого элемента, тогда вы можете удалить почти все стили в этой демонстрации, аналогично моей второй демонстрации выше.

Вы также заметите, что у меня есть одно свойство с префиксом -moz-outline-radius. Некоторое время назад Mozilla добавила это удивительное неспецифическое свойство в Firefox, но ребята из WebKit решили, что , к сожалению, добавлять его не собираются . Так что считайте эту линию CSS просто прогрессивным улучшением для людей, которые используют Firefox.

TylerH
источник
2
Потрясающие! Но есть ли способ отменить изменения также при нажатии в другом месте, кроме кнопки ввода / изображения /? Я использовал ваш пример для создания всплывающего поля и хочу, чтобы оно исчезло, когда посетители нажимают на пустую страницу. Спасибо!
mxmehl
1
@mxmehl Если вы хотите, чтобы они щелкали в определенном месте, вы могли бы сделать это с другим соседним элементом, вероятно. Однако, если вы хотите, чтобы он вернулся, просто щелкнув в любом месте на пустом экране, вам, вероятно, понадобятся прослушиватели событий JavaScript. Помните, что это взлом, а не «лучший» способ создать «интерактивный» опыт; это то, что JS является для . Это как сделать это, если вы ограничены использованием только CSS. :-)
TylerH
5
Это решение все еще хорошо, но когда я прочитал «ответ 2017 года», я ожидал чего-то действительно крутого (например, функции CSS3, которая наконец-то получила широкую поддержку браузера), а не грандиозного старого хака с чекбоксами, существующего с 2011 года ... Несколько разочарован ,
Christallkeks
3
@Christallkeks Если CSS добавляет что-то (вероятно, нет; интерактивность выходит за рамки цели CSS), я обновлю ответ, чтобы включить это. В нынешнем виде заголовок «Ответ на 2017 год» должен дать людям понять, что этот ответ является самым актуальным, поэтому сразу они не будут смотреть на факт, что ответ был опубликован в 2015 году, и продолжат: «о Интересно, есть ли новая функция еще ".
TylerH
1
@MuhammadSaqib Да, он должен работать на любом мобильном браузере, который поддерживает :checked.
TylerH
78

Вы можете использовать псевдокласс :targetдля имитации события нажатия, приведу пример.

#something {
  display: none;
}

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

Вот как это выглядит: http://jsfiddle.net/TYhnb/

Стоит отметить, что это ограничено только гиперссылкой, поэтому, если вам нужно использовать другую ссылку, например, гиперссылку, например кнопку, вы можете немного ее взломать, например, стилизовать гиперссылку, чтобы она выглядела как кнопка.

Хендра Узия
источник
8
Как мы можем изменить действие?
Ансёри
Я думал, что вы не можете нацелить что-то, что не отображалось.
Hazior
39

Если вы дадите элементу a, tabindexто вы можете использовать :focusпсевдокласс для имитации щелчка.

HTML

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

CSS

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

http://jsfiddle.net/NaTj5/

Блейк Пламб
источник
2
это работает достаточно хорошо! при использовании tabindex=-1элемент все еще может быть сфокусирован, но только мышью, а не клавиатурой, что лучше в этом случае. Вы также можете использовать outline:0стиль, чтобы убрать синюю рамку, когда сфокусированы
Stefan Paul Noack
35

Изменить: Ответил, прежде чем ОП уточнил, что он хотел. Следующее предназначено для onclick, похожего на javascripts onclick, а не для :activeпсевдокласса.

Это может быть достигнуто только с помощью Javascript или Checkbox Hack

Хак с флажком, по сути, заставляет вас щелкнуть ярлык, который «проверяет» флажок, позволяя стилизовать ярлык по вашему желанию.

демо

Энди
источник
1
Вы также можете включить свои данные внутри метки, чтобы вам не приходилось использовать idатрибуты для их связывания.
26
12

TylerH сделал действительно хороший ответ, и мне просто пришлось обновить эту последнюю версию кнопки.

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

Сын
источник
Приятно: активные стили; то, что я собирался, но был немного спешил, когда выстраивал их внешний вид.
TylerH
9

Как насчет чистого решения CSS без хакерства?

введите описание изображения здесь

.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 имеет отличный отклик, но это довольно сложное решение. У меня есть решение для тех из вас, кто просто хочет простой эффект "onclick" с чистым CSS без множества дополнительных элементов.

Мы просто будем использовать CSS-переходы. Вы могли бы сделать то же самое с анимацией.

Хитрость заключается в том, чтобы изменить задержку перехода, чтобы она продолжалась, когда пользователь щелкает.

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

Здесь я также добавляю класс "clicked", чтобы javascript мог также обеспечить эффект, если это необходимо. Я использую фильтр теней 0px, потому что он выделит прозрачную графику синим цветом для моего случая.

У меня есть фильтр на 0 с здесь, чтобы он не вступил в силу. Когда эффект отпущен, я могу добавить переход с задержкой, чтобы он обеспечивал хороший эффект «щелчка».

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

Это позволяет мне настроить его так, чтобы, когда пользователь нажимает кнопку, он подсвечивался синим цветом, а затем медленно исчезал (вы, конечно, могли бы использовать и другие эффекты).

Хотя вы ограничены в том смысле, что анимация для выделения является мгновенной, она все же обеспечивает желаемый эффект. Скорее всего, вы могли бы использовать этот трюк с анимацией для получения более плавного общего перехода.

введите описание изображения здесь

введите описание изображения здесь

Брэден Роквелл Нейпир
источник
ПОЭТОМУ сложность - это то, что необходимо для создания постоянного эффекта щелчка. Если вы просто хотите временно сделать что-то, что не сохраняет свое состояние, это или многие другие решения подойдут, и я согласен, что определенно менее сложный.
TylerH
Согласовано. Все, что вам нужно, чтобы конечный результат был и всегда было полезно знать все варианты. Это отличная тема для тех, кто точно. Вероятно, стоит целая средняя статья, рассказывающая о каждой из них и о преимуществах каждой из них!
Брэдэн Роквелл Нейпир
8

Хорошо, это может быть старый пост ... но был первый результат в Google и решил сделать свой собственный микс на этом как ..

В первую очередь, я буду использовать фокус

Причина в том, что это хорошо работает для примера, который я показываю, если кто-то хочет событие типа мыши, тогда используйте active

HTML-код:

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

КОД 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/

Итак, почему я публикую это в старой ветке, хорошо, потому что примеры здесь различаются, и я подумал предоставить один обратно сообществу, которое является рабочим примером.

Как уже ответил создатель потока, они хотят, чтобы эффект длился только во время события click. Теперь, хотя это не точно для этой необходимости, его закрыть. active будет анимироваться, пока мышь не нажимает, и любые изменения, которые вам нужны, должны длиться дольше с помощью javascript.

Angry 84
источник
1
Для всех, кто читает, в любом случае, чтобы заставить его переключаться? Или это слишком много спрашивает из CSS LOL?
DardanM
Насколько я знаю, фокус / активный / наведение примерно настолько близок, насколько вы можете получить с помощью css. Возможно, вы сможете сделать что-то необычное с опцией / выбрать тип кода. Но пока не пробовали / не нуждались в этом
Сердитый 84
7

Предупреждение! Особенно простой ответ ниже! :)

Вы действительно можете иметь изменения, которые сохраняются (например, блок / всплывающее окно, которое появляется и остается видимым после щелчка) только с CSS (и без использования хака с флажками), несмотря на то, что многие из (иначе правильных) ответов здесь утверждают, пока так как вам нужно только настойчивость во время наведения.

Так что взгляните на ответы Bojangles и TylerH, если они вам подходят, но если вы хотите получить простой и CSS-ответ, который оставит блок видимым после нажатия (и даже может заставить блок исчезнуть при последующем щелчке), затем увидеть это решение.

У меня была похожая ситуация, мне нужно было всплывающее окно div с onClick, где я не мог добавить JS или изменить разметку / HTML (действительно решение CSS), и это возможно с некоторыми предостережениями. Вы не можете использовать трюк: target, который может создать приятное всплывающее окно, если вы не можете изменить HTML (чтобы добавить 'id'), чтобы его не было.

В моем случае всплывающий элемент div содержался внутри другого элемента div, и я хотел, чтобы всплывающее окно отображалось поверх другого элемента div, и это можно сделать с помощью комбинации: active и: 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;
}

Пример (а также тот, который позволяет нажать на всплывающее окно, чтобы оно исчезло) по адресу:

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

Я также вставил приведенный ниже пример фрагмента кода, но расположение в изолированной программной среде stackoverflow странное, поэтому мне пришлось поместить текст «click here» после innerDiv, который обычно не требуется.

/* 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 />

Дэвид Люнг Мэдисон Стеллар
источник
1
(re: наше обсуждение комментариев ранее) Информационный div не остается видимым после mouseUp в Firefox. Несмотря на то, что он остается видимым после mouseUp в других браузерах (IE, Edge, Chrome), он не сохраняется, когда мышь перемещается из коробки в любом другом браузере, что предотвращает его реальное событие «onclick» ( например постоянное изменение).
TylerH
2

У меня есть код ниже для наведения мыши и щелчка мыши, и это работает:

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

и этот код скрывает изображение, когда вы нажимаете на него:

.thumbnail:active span {
    visibility: hidden;
}
Пир Фахим Шах
источник
2

У меня была проблема с элементом, который должен был быть КРАСНЫМ при наведении курсора и быть СИНИМ при нажатии при наведении курсора. Для достижения этого с помощью CSS вам нужно, например:

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

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

Некоторое время я боролся, пока не обнаружил, что проблема с порядком выбора CSS была моей проблемой. Проблема была в том, что я поменялся местами, а активный селектор не работал. Потом я узнал, что :hoverидти первым, а потом :active.

Alreadytakenindeed
источник
-3

Вы можете использовать: цель

для общей цели

: цель

или фильтр по имени класса

.classname: мишень

или фильтр по имени

#idname: мишень

<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>
Хатем Бадави
источник
2
Ответ, показывающий, как использовать :target, уже опубликован, так что больше не нужно. Кроме того, спрашивающий спрашивает, как получить эффект «onclick», а не показать / скрыть другие элементы.
Асон
Это скорее эффект «onload», чем «onclick».
TylerH