CSS3 transition on click using pure CSS

217,807

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","" );
    }
});

Fiddle

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

WORKING DEMO.

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

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

WORKING DEMO.

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)!

Share:
217,807

Related videos on Youtube

user2498890
Author by

user2498890

Updated on October 02, 2021

Comments

  • user2498890
    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
      jeremyjjbrown about 10 years
      This is one of the better questions I have seen from a newcomer to SO.
  • LcSalazar
    LcSalazar about 10 years
    No, only chrome... Didn't notice that. Nice call
  • jeremyjjbrown
    jeremyjjbrown about 10 years
    Just checking, it's easy to get burned on stuff like that.
  • jeremyjjbrown
    jeremyjjbrown about 10 years
    Have you put this to production anywhere?
  • user2498890
    user2498890 about 10 years
    Doesn'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
    Hashem Qolami about 10 years
    @jeremyjjbrown, Sorry I didn't understand what exactly you mean. Here is the updated demo. Added -moz prefix for the transform property.
  • jeremyjjbrown
    jeremyjjbrown about 10 years
    I'm asking if you would feel comfortable with using this solution in a production environment? I'm just curious.
  • user2498890
    user2498890 about 10 years
    Using 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
    Hashem Qolami about 10 years
    @jeremyjjbrown I avoid rotating images in my projects :) I'm just trying to show the ability of CSS.
  • jeremyjjbrown
    jeremyjjbrown about 10 years
    Agreed, switching them is probably cleaner. I was just wondering how robust you thought using the tabindex in that way is.
  • user2498890
    user2498890 about 10 years
    That 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
    jeremyjjbrown about 10 years
    Try again, I tested on your fiddle. be sure to add the class to the image and remove the active css rule
  • user2498890
    user2498890 about 10 years
    Ok 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
    jeremyjjbrown about 10 years
    I added a fiddle based on yours. BTW, you get rep for accepting an answer.
  • user2498890
    user2498890 about 10 years
    Brilliant, got it - didn't realise the CSS had changed, mine was conflicting it. Thanks so much for your help!
  • equaeghe
    equaeghe about 7 years
    With Method #2, you can put the input inside the label, and then you can simplify the CSS a bit.
  • Tmh
    Tmh almost 4 years
    What if i want to rotate only 180deg?