CSS3 Hover Effect Transitions, Transformations, Animations
This post is all about CSS3 effect examples. We’re going to find out more about hover effect transitions, transformations and animations. All of them come with visual examples. I’ve also included the source code. Feel free to use and adjust the code provided on whatever you are planning to do. CSS3 is great. It makes designing websites really fun, easy, fast, efficient and it also enhances the user experience, because you can create some neat stuff without the use of javascript or heavy flash animations.
Vendor prefixes: Everything you need to know!
Before we begin, I want to give you a proper overview about the vendor prefixes [-webkit-
|-moz-
|-o-
|-ms-
] you see throughout this page. The reason is, you really don’t need to use all of them in every case. For example, Firefox can handle transforms since 10/2012 without -moz-
, but if you want IE9 support, you need to include -ms-
for transforms. I will only include vendor prefixes, where it makes sense for current and future use. If you are concerned about backward compatibility, consult this list and add what you need.
type include backw.compatibility for version release date transform (2d) -webkit- -moz-
-o-
-ms-FF <= 15
Opera <= 12
IE 910/2012
10/2012
03/2011transform (3d) -webkit- -moz- FF <= 15 10/2012 transition -webkit-
(for Android/Blackberry)-moz-
-o-FF <= 15
Opera <= 1210/2012
10/2012animation -webkit- -moz- FF <= 15 10/2012 backface-visibility -webkit- -moz- FF <= 15 10/2012 @keyframes -webkit- -o- Opera <= 12 10/2012 box-shadow - -webkit-
(for various browsers)various various
As you can see, there is no need anymore for this crazy vendor-prefix-hype you’ll find all over the internet. With most modern browsers updating automatically (or at least semi-automatically) to the newest version, those days belong to the past. Generally speaking, just add -webkit-
in addition to the non-prefixed version and you are good. With that out of the way, here we go! Let’s dive into the world of CSS3.
01: Image size
.image:hover {-webkit-transform:scale(1.2); transform:scale(1.2);} .image {-webkit-transition: all 0.7s ease; transition: all 0.7s ease;}
02: Zoom in
.container:hover .image {-webkit-transform:scale(1.3); transform:scale(1.3);} .container {overflow:hidden; width:200px; height:150px;} .image {-webkit-transition: all 0.7s ease; transition: all 0.7s ease;}
03: Zoom out
.container:hover .image {-webkit-transform:scale(1); transform:scale(1);} .container {overflow:hidden; width:200px; height:150px;} .image {-webkit-transform:scale(1.3); transform:scale(1.3); -webkit-transition: all 0.7s ease; transition: all 0.7s ease;}
04: Border radius and shadow effect
.image:hover {border-radius:50%; box-shadow: 0 10px 6px -6px grey;} .image {-webkit-transition: all 0.7s ease; transition: all 0.7s ease;}
05: Border radius distortion
.image:hover {border-top-left-radius: 120px; border-bottom-right-radius: 120px; border-top-right-radius: 15px; border-bottom-left-radius: 15px;} .image {border-bottom-left-radius: 120px; border-top-right-radius: 120px; border-bottom-right-radius: 15px; border-top-left-radius: 15px; -webkit-transition: all 0.7s ease; transition: all 0.7s ease;}
06: Border radius distortion II
.image:hover {border-top-left-radius: 30px 120px; border-bottom-right-radius: 30px 120px; border-bottom-left-radius: 15px; border-top-right-radius: 15px;} .image {border-top-left-radius: 15px; border-top-right-radius: 120px 30px; border-bottom-left-radius: 120px 30px; border-bottom-right-radius: 15px; -webkit-transition: all 0.7s ease; transition: all 0.7s ease;}
07: Glowing border
.image:hover {-webkit-box-shadow: 0px 0px 15px 10px rgba(255, 255, 255, .75); box-shadow: 0px 0px 15px 10px rgba(255, 255, 255, .75);} .image {-webkit-box-shadow: 0px 0px 15px 5px rgba(0, 185, 233, .75); box-shadow: 0px 0px 15px 5px rgba(0, 185, 233, .75); -webkit-transition: all 0.7s ease; transition: all 0.7s ease;}
08: Rotation (2D)
.image:hover {-webkit-transform: rotate(45deg); transform: rotate(45deg);} .image {-webkit-transition: all 0.7s ease; transition: all 0.7s ease;}
09: Skew
.image:hover {-webkit-transform: skew(0deg,20deg); transform: skew(0deg,20deg);} .image {-webkit-transition: all 0.7s ease; transition: all 0.7s ease;}
10: Translate and opacity
.image:hover {-webkit-transform: translate(20px,-50px); transform: translate(20px,-50px); opacity: 0.4;} .image {opacity: 1; -webkit-transition: all 0.7s ease; transition: all 0.7s ease;}
11: Flip
.container:hover .image{-webkit-transform: rotateY(180deg); -webkit-transform-style: preserve-3d; transform: rotateY(180deg); transform-style: preserve-3d;} .container .image, .container:hover .image {-webkit-transition: all 0.7s ease; transition: all 0.7s ease;}/* Note: You could, of course, target the image class directly with "image:hover". However, using the hover on the parent container is preferred here, because it results in a smoother flip animation in all modern browsers. Make sure the container has the same width and height as the image. */
12: Vertical card flip
James Star
CSS
.carddiv {width:200px; height:150px; position:relative; -webkit-transform-style: preserve-3d; -webkit-transform-origin: 100% 75px; -webkit-transition: all 0.7s ease; transform-style: preserve-3d; transform-origin: 100% 75px; transition: all 0.7s ease;} .container:hover .carddiv {-webkit-transform: rotateX(-180deg); transform: rotateX(-180deg);} .frontofcard, .backofcard {width:200px; height:150px; position:absolute; left:0; -webkit-backface-visibility:hidden; backface-visibility:hidden;} .backofcard {padding-top:50px; -webkit-transform: rotateX(180deg); transform: rotateX(180deg);}HTML
<div class="container"><div class="carddiv"></div><img class="frontofcard" src="img" alt="img"> <p class="backofcard">Text</p></div>/* Note: Keep in mind, that IE does NOT support "transform-style: preserve-3d;" yet, so IE-users will just see a basic vertical image flip animation without additional use of javascript/jQuery. This may change in the future. */
13: Transformation
.image:hover {-webkit-box-shadow: 0px 0px 15px 15px #fff; box-shadow: 0px 0px 15px 15px #fff; border-radius:50%; opacity: 0.6; -webkit-transform: rotate(720deg); transform: rotate(720deg);} .image {opacity: 1; -webkit-transition: all 0.7s ease; transition: all 0.7s ease;}
14: 3D text
James Star
.text:hover {text-shadow: 0 1px 0 #666, 0 2px 0 #555, 1px 3px 0 #444, 2px 4px 0 #333, 3px 5px 0 #222, 4px 6px 1px #111, 0 0 5px rgba(0,0,0,.6), 0 1px 3px rgba(0,0,0,.5), 1px 3px 5px rgba(0,0,0,.4), 3px 5px 10px rgba(0,0,0,.3), 5px 10px 10px rgba(0,0,0,.2), 10px 20px 20px rgba(0,0,0,.1);} .text {-webkit-transition: all 0.7s ease; transition: all 0.7s ease;}
15: Blur
James Star
.text:hover {color: rgba(0,0,0,0); text-shadow: 0 0 20px #FBFE8B;} .text {color: #FBFE8B; -webkit-transition: all 0.7s ease; transition: all 0.7s ease;}/* Note: If you use this in a production environment, keep in mind that the text will vanish in most IE versions, including IE 11. Workaround: To achieve a blur effect, you can try:Note II: There is also a blur filter for this very effect. However, at the time of writing this (december 2013), the solution above is better for overall crossbrowser support than using the blur filter. This may change in the future. */
- a blurry fallback image + easing.
- adding "filter: progid:DXImageTransform.Microsoft.Blur(pixelradius=5);" for older IE versions (no support in IE 10 and up, wouldn't bother).
- make yourself familiar using SVG (Scalable Vector Graphics) filter effects.
16: Glowing text
James Star
.text:hover {text-shadow: 0px 0 15px #fff;} .text {-webkit-transition: all 0.7s ease; transition: all 0.7s ease;}
17: Image with text overlay – fade effect
CSS
.container {position:relative;} .textbox:hover {opacity:1;} .text {padding-top: 50px;} .textbox {width:200px; height:150px; position:absolute; top:0; left:0; opacity:0; border-radius:5px; background-color: rgba(0,0,0,0.75); -webkit-box-shadow: 0px 0px 15px 2px rgba(255,255,255,.75); box-shadow: 0px 0px 15px 2px rgba(255,255,255,.75); -webkit-transition: all 0.7s ease; transition: all 0.7s ease;}HTML
<div class="container"><img src="" alt=""> <div class="textbox"></div><p class="text">TEXT</p></div>
18: Image with text overlay – scale effect
CSS
.container {position:relative;} .container .textbox {width:200px; height:150px; position:absolute; top:0; left:0; -webkit-transform: scale(0); transform: scale(0); border-radius:5px; background-color: rgba(0,0,0,0.75); -webkit-box-shadow: 0px 0px 15px 2px rgba(255,255,255,.75); box-shadow: 0px 0px 15px 2px rgba(255,255,255,.75);} .container:hover .textbox {-webkit-transform: scale(1); transform: scale(1);} .text {padding-top: 50px;} .textbox {-webkit-transition: all 0.7s ease; transition: all 0.7s ease;}HTML
<div class="container"><img src="" alt=""> <div class="textbox"></div><p class="text">TEXT</p></div>
19: Image with text overlay – text slide effect
CSS
.container {position:relative; overflow:hidden;} .container .textbox {width:200px; height:150px; position:absolute; top:0; left:0; margin-top:-160px; border-radius:5px; background-color: rgba(0,0,0,0.75); -webkit-box-shadow: inset 0px 0px 5px 2px rgba(255,255,255,.75); box-shadow: inset 0px 0px 5px 2px rgba(255,255,255,.75);} .container:hover .textbox {margin-top:0;} .text {padding-top: 50px;} .textbox {-webkit-transition: all 0.7s ease; transition: all 0.7s ease;}HTML
<div class="container"><img src="" alt=""> <div class="textbox"></div><p class="text">TEXT</p></div>
20: Image and text slide hover effect
CSS
.container {position:relative; overflow:hidden; width:200px; height:150px;} .container .textbox {position:absolute; top:0; left:0; width:200px; height:150px; margin-left:-210px;} .container:hover .textbox {margin-left:0;} .container img {margin-left:0;} .container:hover img {margin-left:210px;} .text {padding-top: 50px;} .container img, .textbox {-webkit-transition: all 0.7s ease; transition: all 0.7s ease;}HTML
<div class="container"><img src="" alt=""> <div class="textbox"></div><p class="text">TEXT</p></div>/* Note: In order to slide to the left, change the following values: .container .textbox {margin-left:210px;}, .container:hover img {margin-left:-210px;} */
A word on different kinds of easing
If you looked at some of the source codes above, you might have noticed that all examples are using the CSS3 timing function ease
with a transition time of .7 seconds. I did this to emphasize the actual effect, not the transition function behind it. However, you can not only adjust the transition time, but also the way the transition is handled by the browser. Here are some of your options with an explanation of what it actually does:
ease
: The animation accelerates quickly but slows down considerably near the end.ease-in-out
: The animation starts and ends slow.ease-in
: The animation starts very slow and reaches full speed in the end.ease-out
: The animation starts at full speed but slows down gradually.linear
: The animation has the same speed from start to end (no easing at all).
You prefer visual examples? Here you go:
Hover here
ease
ease-in-out
ease-in
ease-out
linear
custom
Chances are, this is all you’ll ever need. However, if you are some kind of perfectionist, a real crack or just need to have something timed exactly the way you like, you can use your own custom animation transition using cubic-bezier()
. To use it, just replace the word ease
in the examples given with something like cubic-bezier(1,-0.75,0.5,1.2)
. The first two values and last two values are nothing more than two simple control points presented as (x1,y1,x2,y2) on the function graph. No matter what, the function starts at (0,0) and ends at (1,1). But with these two control points, you can influence the path of how it gets from (0,0) to (1,1). Play with the numbers to adjust the timing function to your needs. For example, using cubic-bezier(0.42,0,1,1)
has the same effect as ease-in
while cubic-bezier(0,0,0.58,1)
has the same effect as ease-out
.
To see it in action, let’s use example 11: Transformation with cubic-bezier(1,-0.75,0.5,1.2)
instead of ease
.
11: Transformation: | 11: Transformation: |
21: Fading two images
CSS
.container {position:relative; width:200px; height:150px;} .container img {position:absolute; top:0; left:0; -webkit-transition: opacity 1.1s ease; transition: opacity 1.1s ease;} .container:hover .image1 {opacity:0;}HTML
<div class="container"><img class="image2" src="img2" alt=""> <img class="image1" src="img1" alt=""></div>
22: Basic CSS3 image slider (without javascript!)
CSS
.container {position:relative; width:200px; height:150px;} .container img {position:absolute; top:0; left:0;} .container:hover img {-webkit-animation-name: slider; -webkit-animation-timing-function: ease; -webkit-animation-duration: 10s; -webkit-animation-iteration-count: infinite; animation-name: slider; animation-timing-function: ease; animation-duration: 10s; animation-iteration-count: infinite;} @-webkit-keyframes slider {0% {opacity:1;} 20% {opacity:0;} 80% {opacity:0;} 100% {opacity:1;}} @keyframes slider {0% {opacity:1;} 20% {opacity:0;} 80% {opacity:0;} 100% {opacity:1;}} .container img:nth-child(1) {-webkit-animation-delay: 8s; animation-delay: 8s;} .container img:nth-child(2) {-webkit-animation-delay: 6s; animation-delay: 6s;} .container img:nth-child(3) {-webkit-animation-delay: 4s; animation-delay: 4s;} .container img:nth-child(4) {-webkit-animation-delay: 2s; animation-delay: 2s;} .container img:nth-child(5) {-webkit-animation-delay: 0s; animation-delay: 0s;}HTML
<div class="container"><img src="img5" alt="img5"> <img src="img4" alt="img4"> <img src="img3" alt="img3"> <img src="img2" alt="img2"> <img src="img1" alt="img1"></div>
23: Advanced CSS3 image slider (without javascript!)
CSS
.container {position:relative; width:200px; height:150px;} .container img {position:absolute; top:0; left:0; opacity:0;} .container:hover img {-webkit-animation-name: slider; -webkit-animation-timing-function: ease; -webkit-animation-duration: 10s; -webkit-animation-iteration-count: infinite; animation-name: slider; animation-timing-function: ease; animation-duration: 10s; animation-iteration-count: infinite;} @-webkit-keyframes slider {0% {opacity:0;-webkit-transform: rotate(0) scale(0.5) skew(30deg,20deg);} 20% {opacity:1;-webkit-transform: rotate(0) scale(1) skew(0deg,0deg);} 30% {opacity:0;-webkit-transform: rotate(-360deg) scale(0) skew(0deg,0deg);} 100% {opacity:0;-webkit-transform: rotate(0) scale(0.5) skew(30deg,20deg);}} @keyframes slider {0% {opacity:0;transform: rotate(0) scale(0.5) skew(30deg,20deg);} 20% {opacity:1;transform: rotate(0) scale(1) skew(0deg,0deg);} 30% {opacity:0;transform: rotate(-360deg) scale(0) skew(0deg,0deg);} 100% {opacity:0;transform: rotate(0) scale(0.5) skew(30deg,20deg);}} .container img:nth-of-type(1) {-webkit-animation-delay: 8s;animation-delay: 8s;} .container img:nth-of-type(2) {-webkit-animation-delay: 6s;animation-delay: 6s;} .container img:nth-of-type(3) {-webkit-animation-delay: 4s;animation-delay: 4s;} .container img:nth-of-type(4) {-webkit-animation-delay: 2s;animation-delay: 2s;} .container img:nth-of-type(5) {-webkit-animation-delay: 0s;animation-delay: 0s;} .container .hovertext {position: absolute; top:60px; left:30px; font-size:1.5em; color: rgba(255,255,255,1); -webkit-transition: all 0.7s ease; transition: all 0.7s ease;} .container:hover .hovertext {top:20px; color: rgba(255,255,255,0); -webkit-transition: all 0.7s ease; transition: all 0.7s ease;}HTML
<div class="container"><img src="img5" alt="img5"> <img src="img4" alt="img4"> <img src="img3" alt="img3"> <img src="img2" alt="img2"> <img src="img1" alt="img1"> <p class="hovertext">Hover here</p></div>
24: Shake it!
@-webkit-keyframes shakeit {0% { -webkit-transform: rotate(0deg) translate(2px, 1px); } 10% { -webkit-transform: rotate(2deg) translate(1px, 2px); } 20% { -webkit-transform: rotate(-2deg) translate(3px, 0px) ; } 30% { -webkit-transform: rotate(0deg) translate(0px, -2px); } 40% { -webkit-transform: rotate(-2deg) translate(-1px, 1px); } 50% { -webkit-transform: rotate(2deg) translate(1px, -2px); } 60% { -webkit-transform: rotate(0deg) translate(3px, -1px); } 70% { -webkit-transform: rotate(2deg) translate(-2px, -1px); } 80% { -webkit-transform: rotate(-2deg) translate(1px, 1px); } 90% { -webkit-transform: rotate(0deg) translate(-2px, -2px); } 100% { -webkit-transform: rotate(2deg) translate(-1px, 2px); }} @keyframes shakeit {0% { transform: rotate(0deg) translate(2px, 1px); } 10% { transform: rotate(2deg) translate(1px, 2px); } 20% { transform: rotate(-2deg) translate(3px, 0px) ; } 30% { transform: rotate(0deg) translate(0px, -2px); } 40% { transform: rotate(-2deg) translate(-1px, 1px); } 50% { transform: rotate(2deg) translate(1px, -2px); } 60% { transform: rotate(0deg) translate(3px, -1px); } 70% { transform: rotate(2deg) translate(-2px, -1px); } 80% { transform: rotate(-2deg) translate(1px, 1px); } 90% { transform: rotate(0deg) translate(-2px, -2px); } 100% { transform: rotate(2deg) translate(-1px, 2px); }} .shakeit img:hover {-webkit-animation-name: shakeit; -webkit-animation-duration: 1s; -webkit-animation-timing-function: linear; -webkit-animation-iteration-count: infinite; animation-name: shakeit; animation-duration: 1s; animation-timing-function: linear; animation-iteration-count: infinite;}
25: Changing colors
Hover here
@-webkit-keyframes changes {0% {box-shadow: 0px 0px 15px #FFFFFF; background-color: #000000;} 10% {box-shadow: 0px 0px 15px #2F4F4F; background-color: #0000FF;} 20% {box-shadow: 0px 0px 15px #800080; background-color: #FF00FF;} 30% {box-shadow: 0px 0px 15px #FF0000; background-color: #008080;} 40% {box-shadow: 0px 0px 15px #FFFF00; background-color: #00FF00;} 50% {box-shadow: 0px 0px 15px #000000; background-color: #FFFFFF;} 60% {box-shadow: 0px 0px 15px #0000FF; background-color: #FFFF00;} 70% {box-shadow: 0px 0px 15px #FF00FF; background-color: #FF0000;} 80% {box-shadow: 0px 0px 15px #008080; background-color: #800080;} 90% {box-shadow: 0px 0px 15px #00FF00; background-color: #2F4F4F;} 100% {box-shadow: 0px 0px 15px #FFFFFF; background-color: #000000;}} @keyframes changes {0% {box-shadow: 0px 0px 15px #FFFFFF; background-color: #000000;} 10% {box-shadow: 0px 0px 15px #2F4F4F; background-color: #0000FF;} 20% {box-shadow: 0px 0px 15px #800080; background-color: #FF00FF;} 30% {box-shadow: 0px 0px 15px #FF0000; background-color: #008080;} 40% {box-shadow: 0px 0px 15px #FFFF00; background-color: #00FF00;} 50% {box-shadow: 0px 0px 15px #000000; background-color: #FFFFFF;} 60% {box-shadow: 0px 0px 15px #0000FF; background-color: #FFFF00;} 70% {box-shadow: 0px 0px 15px #FF00FF; background-color: #FF0000;} 80% {box-shadow: 0px 0px 15px #008080; background-color: #800080;} 90% {box-shadow: 0px 0px 15px #00FF00; background-color: #2F4F4F;} 100% {box-shadow: 0px 0px 15px #FFFFFF; background-color: #000000;}} .changes:hover {-webkit-animation-name: changes; -webkit-animation-duration: 10s; -webkit-animation-timing-function: linear; -webkit-animation-iteration-count: infinite; animation-name: changes; animation-duration: 10s; animation-timing-function: linear; animation-iteration-count: infinite;}
26: Textarea transformation
.container {width:200px; height:150px; position:relative;} .textarea {background-color:#FFF; top:50px; left:25px; width:160px; height:35px; position:absolute; border: 2px solid #333; box-shadow: 0px 0px 15px #000; -webkit-transition: all 0.7s ease; transition: all 0.7s ease;} .textarea:focus {background-color:#000030; top:0; left:0; height:150px; width:200px; border-radius:5px; border: 2px solid #d4d0ba; box-shadow: 0px 0px 15px #FFFFFF;}
27: Expanding codeblock
← Codeblock
CSS
.container {position:relative;} .container:after {text-align: center; position: absolute; background:#999; top: 17px; right: -28px; width: 120px; height: 1.6em; font-size: 1.1em; content: "TEXT"; -webkit-transform: rotate(45deg); transform: rotate(45deg);} .outer, .outer:hover {-webkit-transition: all 0.7s ease; transition: all 0.7s ease;} .outer{color: #000; background: #DDD; overflow: hidden;} .outer:hover {color: #FFF; background: #666; overflow: hidden;} .inner {max-height: 110px; overflow: auto; -webkit-transition: max-height 1.7s ease; transition: max-height 1.7s ease;} .outer:hover > .inner {max-height: 1200px; -webkit-transition: max-height 3.5s ease 0.7s; transition: max-height 3.5s ease 0.7s;}HTML
<div class="container outer"> <div class="inner">Content with test-linebreaks: <br><br><br><br><br><br><br> Content ends here</div> </div>
28: CSS Tooltip
Got it!
CSS
.tooltip {position: relative; opacity: 0; color: #FFF; top: -100px; left: 0px; width: 180px; padding: 10px; border-radius: 25px; -webkit-border-radius: 25px; background-color: rgba(0,0,30,0.5); -webkit-box-shadow: 0px 0px 15px 2px rgba(255,255,255,.75); box-shadow: 0px 0px 15px 2px rgba(255,255,255, .75); -webkit-transition: .5s; transition: .5s; -webkit-transform: rotateY(180deg); transform: rotateY(180deg);} .container .tooltip:after {position: absolute; top: 100%; left: 45%; height: 0; width: 0; border: 6px solid transparent; border-top: 6px solid rgba(0, 0, 30, 0.5); content: "Awesome!"; white-space: nowrap; color:#DDD;} .container:hover .tooltip {opacity: 1; top: -225px; -webkit-transform: rotateY(0deg); transform: rotateY(0deg);}HTML
<div class="container"><img src="" alt=""> <div class="tooltip"></div><p class="tooltiptxt">Got it!</p></div>
I hope you enjoyed it and learned something. If you feel like sharing or commenting, I invite you to do so. Have a nice day.
Thank you! This was the most helpful explanation I’ve seen all day!
Thanks a lot James! You’re amazing
This one has a shortcut on my desktop. Really cool and understandable code without JS. Thx.
thanks a lot
Awesome interactive without using javascript and fun to use… Nice work…
awesome things….
thank you
Nice for sharing!
Nice site! I’ve learn more than in W3school.