[html] Can I have an onclick effect in CSS?

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 related to html css onclick

The answer is


I have the below code for mouse hover and mouse click and it works:

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

and this code hides the image when you click on it:

.thumbnail:active span {
    visibility: hidden;
}

If you give the element a tabindex then you can use the :focus pseudo class to simulate a click.

HTML

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

CSS

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

http://jsfiddle.net/NaTj5/


Edit: Answered before OP clarified what he wanted. The following is for an onclick similar to javascripts onclick, not the :active pseudo class.

This can only be achieved with either Javascript or the Checkbox Hack

The checkbox hack essentially gets you to click on a label, that "checks" a checkbox, allowing you to style the label as you wish.

The demo


You can use pseudo class :target to mimic on click event, let me give you an example.

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

Here's how it looks like: http://jsfiddle.net/TYhnb/

One thing to note, this is only limited to hyperlink, so if you need to use on other than hyperlink, such as a button, you might want to hack it a little bit, such as styling a hyperlink to look like a button.


I had a problem with an element which had to be colored RED on hover and be BLUE on click while being hovered. To achieve this with css you need for example:

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

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

I struggled for some time until I discovered that the order of CSS selectors was the problem I was having. The problem was that I switched the places and the active selector was not working. Then I found out that :hover to go first and then :active.


TylerH made a really good answer, I just had to give that last button a visual update.

_x000D_
_x000D_
.btn {
    border-radius: 5px;
    padding: 10px 30px;
    box-shadow: 1px 1px 1px #000;
    background-image: linear-gradient(to bottom, #eee, #ddd);
}

.btn:hover {
    background-image: linear-gradient(to top, #adf, #8bf);
}

.btn:active {
    margin: 1px 1px 0;
    box-shadow: -1px -1px 1px #000;
}

#btnControl {
    display: block;
    visibility: hidden;
}
_x000D_
<input type="checkbox" id="btnControl"/>
<label class="btn" for="btnControl">Click me!</label>
_x000D_
_x000D_
_x000D_


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.


How about a pure CSS solution without being (that) hacky?

enter image description here

_x000D_
_x000D_
.page {_x000D_
  position: fixed;_x000D_
  top: 0;_x000D_
  bottom: 0;_x000D_
  right: 0;_x000D_
  left: 0;_x000D_
  background-color: #121519;_x000D_
  color: whitesmoke;_x000D_
}_x000D_
_x000D_
.controls {_x000D_
  display: flex;_x000D_
  align-items: center;_x000D_
  justify-content: center;_x000D_
  height: 100%;_x000D_
  width: 100%;_x000D_
}_x000D_
_x000D_
.arrow {_x000D_
  cursor: pointer;_x000D_
  transition: filter 0.3s ease 0.3s;_x000D_
}_x000D_
_x000D_
.arrow:active {_x000D_
  filter: drop-shadow(0 0 0 steelblue);_x000D_
  transition: filter 0s;_x000D_
}
_x000D_
<body class="page">_x000D_
  <div class="controls">_x000D_
    <div class="arrow">_x000D_
      <img src="https://i.imgur.com/JGUoNfS.png" />_x000D_
    </div>_x000D_
  </div>_x000D_
</body>
_x000D_
_x000D_
_x000D_

@TylerH has a great response but its a pretty complex solution. I have a solution for those of you that just want a simple "onclick" effect with pure css without a bunch of extra elements.

We will simply use css transitions. You could probably do similar with animations.

The trick is to change the delay for the transition so that it will last when the user clicks.

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

Here I add the "clicked" class as well so that javascript can also provide the effect if it needs to. I use 0px drop-shadow filter because it will highlight the given transparent graphic blue this way for my case.

I have a filter at 0s here so that it wont take effect. When the effect is released I can then add the transition with a delay so that it will provide a nice "clicked" effect.

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

This allows me to set it up so that when the user clicks the button, it highlights blue then fades out slowly (you could, of course, use other effects as well).

While you are limited here in the sense that the animation to highlight is instant, it does still provide the desired effect. You could likely use this trick with animation to produce a smoother overall transition.

enter image description here

enter image description here


Okay, this maybe an old post... but was first result in google and decided to make your own mix on this as..

FIRSTLY I WILL USE FOCUS

The reason for this is that it works nicely for the example i'm showing, if someone wants a mouse down type event then use active

THE HTML CODE:

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

THE CSS CODE:

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

So why am i posting this in an old thread, well because the examples here vary and i thought to provide one back to the community which is a working example.

As already answered by the thread creator, they only want the effect to last during the click event. Now while this is not exact for that need, its close. active will animate while the mouse is down and any changes that you need to have last longer need to be done with javascript.


you can use :target

or to filter by class name, use .classname:target

or filter by id name using #idname:target

_x000D_
_x000D_
#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;
}
_x000D_
  
<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>
_x000D_
_x000D_
_x000D_


Warning! Particularly simple answer below! :)

You actually can have a change that persists (such as a block/popup that appears and stays visible after a click) with only CSS (and without using the checkbox hack) despite what many of the (otherwise correct) answers here claim, as long as you only need persistence during the hover.

So take a look at Bojangles and TylerH's answers if those work for you, but if you want a simple and CSS only answer that will keep a block visible after being clicked on (and even can have the block disappear with a followup click), then see this solution.

I had a similar situation, I needed a popup div with onClick where I couldn't add any JS or change the markup/HTML (a truly CSS solution) and this is possible with some caveats. You can't use the :target trick that can create a nice popup unless you can change the HTML (to add an 'id') so that was out.

In my case the popup div was contained inside the other div, and I wanted the popup to appear on top of the other div, and this can be done using a combination of :active and :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;
}

Example (as well as one that allows clicking on the popup to make it disappear) at:

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

I've also inserted a code snippet example below, but the positioning in the stackoverflow sandbox is weird so I had to put the 'click here' text after the innerDiv, which isn't normally needed.

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


Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to onclick

How to use onClick with divs in React.js React prevent event bubbling in nested components on click React onClick function fires on render Run php function on button click Passing string parameter in JavaScript function Simple if else onclick then do? How to call a php script/function on a html button click Change Button color onClick RecyclerView onClick javascript get x and y coordinates on mouse click