CSS3 transition on click using pure CSS
Solution 1
If you want a css only solution you can use active
.crossRotate:active {
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
}
But the transformation will not persist when the activity moves. For that you need javascript (jquery click and css is the cleanest IMO).
$( ".crossRotate" ).click(function() {
if ( $( this ).css( "transform" ) == 'none' ){
$(this).css("transform","rotate(45deg)");
} else {
$(this).css("transform","" );
}
});
Solution 2
Method #1: CSS :focus
pseudo-class
As pure CSS solution, you could achieve sort of the effect by using a tabindex
attribute for the image, and :focus
pseudo-class as follows:
<img class="crossRotate" src="http://placehold.it/100" tabindex="1" />
.crossRotate {
outline: 0;
/* other styles... */
}
.crossRotate:focus {
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
Note: Using this approach, the image gets rotated onclick (focused), to negate the rotation, you'll need to click somewhere out of the image (blured).
Method #2: Hidden input & :checked
pseudo-class
This is one of my favorite methods. In this approach, there's a hidden checkbox input and a <label>
element which wraps the image.
Once you click on the image, the hidden input is checked because of using for
attribute for the label.
Hence by using the :checked
pseudo-class and adjacent sibling selector +
, we could get the image to be rotated:
<input type="checkbox" id="hacky-input">
<label for="hacky-input">
<img class="crossRotate" src="http://placehold.it/100">
</label>
#hacky-input {
display: none; /* Hide the input */
}
#hacky-input:checked + label img.crossRotate {
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
WORKING DEMO #2 (Applying the rotate
to the label gives a better experience).
Method #3: Toggling a class via JavaScript
If using JavaScript/jQuery is an option, you could toggle a .active
class by .toggleClass()
to trigger the rotation effect, as follows:
$('.crossRotate').on('click', function(){
$(this).toggleClass('active');
});
.crossRotate.active {
/* vendor-prefixes here... */
transform: rotate(45deg);
}
Solution 3
Voila!
div {
background-color: red;
color: white;
font-weight: bold;
width: 48px;
height: 48px;
transform: rotate(360deg);
transition: transform 0.5s;
}
div:active {
transform: rotate(0deg);
transition: 0s;
}
<div></div>
Solution 4
You can also affect differente DOM elements using :target pseudo class. If an element is the destination of an anchor target it will get the :target pseudo element.
<style>
p { color:black; }
p:target { color:red; }
</style>
<a href="#elem">Click me</a>
<p id="elem">And I will change</p>
Here is a fiddle : https://jsfiddle.net/k86b81jv/
Solution 5
As jeremyjjbrow said, :active
pseudo won't persist. But there's a hack for doing it on pure css. You can wrap it on a <a>
tag, and apply the :active
on it, like this:
<a class="test">
<img class="crossRotate" src="images/cross.png" alt="Cross Menu button" />
</a>
And the css:
.test:active .crossRotate {
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
}
Try it out... It works (at least on Chrome)!
Related videos on Youtube
user2498890
Updated on October 02, 2021Comments
-
user2498890 over 2 years
I'm trying to get an image (a plus symbol) to rotate 45 degrees to create a cross symbol. I have so far managed to achieve this using the code below but its working on hover, I wanted to have it rotate on click.
Is there a simple way of doing so using CSS?
My code is:
CSS
img { display: block; margin: 20px; } .crossRotate { -webkit-transition-duration: 1s; -moz-transition-duration: 1s; -o-transition-duration: 1s; transition-duration: 1s; -webkit-transition-property: -webkit-transform; -moz-transition-property: -moz-transform; -o-transition-property: -o-transform; transition-property: transform; } .crossRotate:hover { -webkit-transform: rotate(45deg); -ms-transform: rotate(45deg); transform: rotate(45deg); }
HTML
<body> <img class="crossRotate" src="images/cross.png" alt="Cross Menu button" /> </body>
Here is the jsfiddle demo.
-
jeremyjjbrown about 10 yearsThis is one of the better questions I have seen from a newcomer to SO.
-
-
LcSalazar about 10 yearsNo, only chrome... Didn't notice that. Nice call
-
jeremyjjbrown about 10 yearsJust checking, it's easy to get burned on stuff like that.
-
jeremyjjbrown about 10 yearsHave you put this to production anywhere?
-
user2498890 about 10 yearsDoesn't seem to work on Firefox, works on Chrome & Safari... on Firefox you need to click and hold to get it to turn fully?
-
Hashem Qolami about 10 years@jeremyjjbrown, Sorry I didn't understand what exactly you mean. Here is the updated demo. Added
-moz
prefix for thetransform
property. -
jeremyjjbrown about 10 yearsI'm asking if you would feel comfortable with using this solution in a production environment? I'm just curious.
-
user2498890 about 10 yearsUsing that jQuery is fine, I've done what you said and it works as I want it, one more thing, so you click it once and it rotates by 45 degrees one way, how would you code it so that you click again and it goes back 45 degrees to its original position? Thanks for your help
-
Hashem Qolami about 10 years@jeremyjjbrown I avoid rotating images in my projects :) I'm just trying to show the ability of CSS.
-
jeremyjjbrown about 10 yearsAgreed, switching them is probably cleaner. I was just wondering how robust you thought using the tabindex in that way is.
-
user2498890 about 10 yearsThat doesn't seem to of done it, just doing the original 45 degree rotation on click. Just need it to rotate by 45 degrees and then -45 degrees the next time its clicked and then just repeat that sequence...
-
jeremyjjbrown about 10 yearsTry again, I tested on your fiddle. be sure to add the class to the image and remove the active css rule
-
user2498890 about 10 yearsOk that is working how I want it just that you have to click and hold to achieve that as it is, i just want to click once and then click again to get it to go back -45deg, thanks for your help :)
-
jeremyjjbrown about 10 yearsI added a fiddle based on yours. BTW, you get rep for accepting an answer.
-
user2498890 about 10 yearsBrilliant, got it - didn't realise the CSS had changed, mine was conflicting it. Thanks so much for your help!
-
equaeghe about 7 yearsWith Method #2, you can put the input inside the label, and then you can simplify the CSS a bit.
-
Tmh almost 4 yearsWhat if i want to rotate only 180deg?