Can I have an onclick effect in CSS?

373

I have an image element that I want to change on click.

<img id="btnLeft">

This works:

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

But what I need is:

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

But, it doesn't work, obviously. Is it possible at all to have onclick behavior in CSS (i.e. without using JavaScript)?

This question is tagged with html css onclick

~ Asked on 2012-11-29 16:27:58

The Best Answer is


360

The closest you'll get is :active:

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

However this will only apply the style when the mouse button is held down. The only way to apply a style and keep it applied onclick is to use a bit of JavaScript.

~ Answered on 2012-11-29 16:29:28


402

Answer as of 2020:

The best way (actually the only way*) to simulate an actual click event using only CSS (rather than just hovering on an element or making an element active, where you don't have mouseUp) is to use the checkbox hack. It works by attaching a label to an <input type="checkbox"> element via the label's for="" attribute.

This feature has broad browser support (the :checked pseudo-class is IE9+).

Apply the same value to an <input>'s ID attribute and an accompanying <label>'s for="" attribute, and you can tell the browser to re-style the label on click with the :checked pseudo-class, thanks to the fact that clicking a label will check and uncheck the "associated" <input type="checkbox">.

* You can simulate a "selected" event via the :active or :focus pseudo-class in IE7+ (e.g. for a button that's normally 50px wide, you can change its width while active: #btnControl:active { width: 75px; }), but those are not true "click" events. They are "live" the entire time the element is selected (such as by Tabbing with your keyboard), which is a little different from a true click event, which fires an action on - typically - mouseUp.


Basic demo of the checkbox hack (the basic code structure for what you're asking):

_x000D_
_x000D_
label {
    display: block;
    background: lightgrey;
    width: 100px;
    height: 100px;
}

#demo:checked + label {
    background: blue;
    color: white;
}
_x000D_
<input type="checkbox" id="demo"/>
<label for="demo">I'm a square. Click me.</label>
_x000D_
_x000D_
_x000D_

Here I've positioned the label right after the input in my markup. This is so that I can use the adjacent sibling selector (the + key) to select only the label that immediately follows my #demo checkbox. Since the :checked pseudo-class applies to the checkbox, #demo:checked + label will only apply when the checkbox is checked.

Demo for re-sizing an image on click, which is what you're asking:

_x000D_
_x000D_
#btnControl {
    display: none;
}

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

With that being said, there is some bad news. Because a label can only be associated with one form control at a time, that means you can't just drop a button inside the <label></label> tags and call it a day. However, we can use some CSS to make the label look and behave fairly close to how an HTML button looks and behaves.

Demo for imitating a button click effect, above and beyond what you're asking:

_x000D_
_x000D_
#btnControl {
    display: none;
}

.btn {
    width: 60px;
    height: 20px;
    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:20px;
}

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


.btn:active {
    margin-left: 1px 1px 0;
    box-shadow: -1px -1px 1px #000;
    outline: 1px solid black;
    -moz-outline-radius: 5px;
    background-image: linear-gradient(to top, #f4f5f5, #dfdddd);
}

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

Most of the CSS in this demo is just for styling the label element. If you don't actually need a button, and any old element will suffice, then you can remove almost all of the styles in this demo, similar to my second demo above.

You'll also notice I have one prefixed property in there, -moz-outline-radius. A while back, Mozilla added this awesome non-spec property to Firefox, but the folks at WebKit decided they aren't going to add it, unfortunately. So consider that line of CSS just a progressive enhancement for people who use Firefox.

~ Answered on 2015-09-22 16:01:45


Most Viewed Questions: