A tutorial about how to create 3D thumbnail hover effects with CSS 3D transforms
and jQuery.
Today we want to show you how to create some
exciting 3D hover effects using CSS3 and jQuery. This idea is inspired by the
cool hover effect that you can find on the page of the Google
SketchUp Showcase.
In our examples, we’ll use thumbails that will
reveal some more information on hover. We will create a structure with jQuery
that will allow making the image appear as folded or bended when we hover over
it. For the hover effects we will use CSS 3D transforms.
The images used in the demos are by Angelo
González and they are licensed under the Creative Commons Attribution 2.0 Generic (CC BY
2.0) License.
We will omit vendor prefixes in this tutorial. But
you’ll of course find them in the files.
The Markup
The markup for the thumbnail structure will be as follows:
< div id = "grid" class = "main" > < div class = "view" > < div class = "view-back" > < span data-icon = "A" >566</ span > < span data-icon = "B" >124</ span > < a href = "http://www.flickr.com/photos/ag2r/5439506585/in/photostream" >→</ a > </ div > < img src = "images/1.jpg" /> </ div > < div class = "view" > <!-- ... --> </ div > <!-- ... --> </ div > |
Each thumbnail goes into a division with another
division for the details (view-back). The structure that we want to create for
each division with the class view
using JavaScript is the following:
< div class = "view" > < div class = "view-back" > <!-- ... --> </ div > < div class = "slice s1" style = "background-image: url(images/1.jpg); " > < span class = "overlay" ></ span > < div class = "slice s2" style = "background-image: url(images/1.jpg); " > < span class = "overlay" ></ span > < div class = "slice s3" style = "background-image: url(images/1.jpg); " > < span class = "overlay" ></ span > < div class = "slice s4" style = "background-image: url(images/1.jpg); " > < span class = "overlay" ></ span > < div class = "slice s5" style = "background-image: url(images/1.jpg); " > < span class = "overlay" ></ span > </ div > <!-- /s5 --> </ div > <!-- /s4 --> </ div > <!-- /s3 --> </ div > <!-- /s2 --> </ div > <!-- /s1 --> </ div > <!-- /view --> |
Each slice will have the respective image as it’s
background image and since we have a nested structure, this will allow us to
control the effect. Additionally, we’ll add an overlay span that we’ll use to
make the effects more realistic.
Our JavaScript function looks as follows:
$.fn.hoverfold = function ( args ) { this .each( function () { $( this ).children( '.view' ).each( function () { var $item = $( this ), img = $item.children( 'img' ).attr( 'src' ), struct = '<div class="slice s1">' ; struct += '<div class="slice s2">' ; struct += '<div class="slice s3">' ; struct += '<div class="slice s4">' ; struct += '<div class="slice s5">' ; struct += '</div>' ; struct += '</div>' ; struct += '</div>' ; struct += '</div>' ; struct += '</div>' ; var $struct = $( struct ); $item.find( 'img' ).remove().end().append( $struct ).find( 'div.slice' ).css( 'background-image' , 'url(' + img + ')' ).prepend( $( '<span class="overlay" ></span>' ) ); } ); }); };
Now we can have a lot of hover fun! Let’s first define some common styles and
then we’ll go through the first example.
|
.view { width : 316px ; height : 216px ; margin : 10px ; float : left ; position : relative ; border : 8px solid #fff ; box-shadow : 1px 1px 2px rgba( 0 , 0 , 0 , 0.05 ); background : #333 ; perspective : 500px ; } |
The slices will need some 3D properties and a
transition:
.view .slice{ width : 60px ; height : 100% ; z-index : 100 ; transform-style : preserve-3d ; transform-origin : left center ; transition : transform 150 ms ease-in-out; } |
The part of the description that get’s revealed
when we push the slices to the side will have the following style:
.view div.view-back{ width : 50% ; height : 100% ; position : absolute ; right : 0 ; background : #666 ; z-index : 0 ; } |
Let’s style the spans and the link:
.view-back span { display : block ; float : right ; padding : 5px 20px 5px ; width : 100% ; text-align : right ; font-size : 16px ; color : rgba( 255 , 255 , 255 , 0.6 ); } .view-back span:first-child { padding-top : 20px ; } .view-back a { display : bock; font-size : 18px ; color : rgba( 255 , 255 , 255 , 0.4 ); position : absolute ; right : 15px ; bottom : 15px ; border : 2px solid rgba( 255 , 255 , 255 , 0.3 ); border-radius : 50% ; width : 30px ; height : 30px ; line-height : 22px ; text-align : center ; font-weight : 700 ; } .view-back a:hover { color : #fff ; border-color : #fff ; } |
For the icon before the spans we’ll use an icon
font that we’ve created with Fontello. Since we have added a data-icon
attribute to the spans, we can use the pseudo-class :before to display it:
1
2
3
4
5
6
7
8
|
.view-back span[data- icon ]:before { content : attr (data- icon ); font-family : 'icons' ; color : #aaa ; color : rgba( 255 , 255 , 255 , 0.2 ); text-shadow : 0 0 1px rgba( 255 , 255 , 255 , 0.2 ); padding-right : 5px ; } |
All, except the first slice, need to be moved to
the right (remember, we have a nested structure):
1
2
3
4
5
6
|
.view .s 2 , .view .s 3 , .view .s 4 , .view .s 5 { transform : translateX ( 60px ); } |
Let’s set the respective background positions of
each slice for the background image:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
.view .s 1 { background-position : 0px 0px ; } .view .s 2 { background-position : -60px 0px ; } .view .s 3 { background-position : -120px 0px ; } .view .s 4 { background-position : -180px 0px ; } .view .s 5 { background-position : -240px 0px ; } |
The overlays will initially have an opacity of 0
and we’ll add a transition and change the opacity level on hover:
1
2
3
4
5
6
7
8
9
10
11
|
.view .overlay { width : 60px ; height : 100% ; opacity : 0 ; position : absolute ; transition : opacity 150 ms ease-in-out; } .view:hover .overlay { opacity : 1 ; } |
Let’s just fix the position and z-index for the
image (just so that we don’t see the back part on top and for the fallback). And
we’ll also add a transition for browsers that don’t support 3D transforms:
1
2
3
4
5
|
.view img { position : absolute ; z-index : 0 ; transition : left 0.3 s ease-in-out; } |
In case we see that a browser does not support all
those fancy 3D properties, we’ll simply load an additional stylesheet called fallback.css which will have the following
content:
1
2
3
4
5
6
7
8
9
10
11
|
.view { overflow : hidden ; } .view:hover img { left : -85px ; } .view div.view-back { background : #666 ; } |
This will make the image slide to the left when we
hover.
Now, let’s take a look at the example!
Example
For this example we will want to create a folding
effect. For that we’ll adjust the perspective value of the view division and the
transition for all the divisions:
1
2
3
4
5
6
7
|
.view { perspective : 1050px ; } .view div { transition : all 0.3 s ease-in-out; } |
The second, third, forth and fifth slice will be
translated and rotated in 3D, creating the fold effect:
1
2
3
4
5
6
7
8
9
10
|
.view:hover .s 2 { transform : translate 3 d( 59px , 0 , 0 ) rotate 3 d( 0 , 1 , 0 , -45 deg); } .view:hover .s 3 , .view:hover .s 5 { transform : translate 3 d( 59px , 0 , 0 ) rotate 3 d( 0 , 1 , 0 , 90 deg); } .view:hover .s 4 { transform : translate 3 d( 59px , 0 , 0 ) rotate 3 d( 0 , 1 , 0 , -90 deg); } |
Each of these slices will be moved to the left. It
should be the value of their widths but we want to avoid showing a little gap,
so we use 59px. The second slice will be rotated -45 degrees, making it turn
towards the left. The forth slice rotates the other way and the third and fifth
will both rotate 90 degrees. Remember, we are in a nested structure. Once we
rotate a parent, the children will all be rotated.
To make things look a bit more realistic, we’ll add
some gradients to the overlays:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
.view .s 2 > .overlay { background : linear-gradient( right , rgba( 0 , 0 , 0 , 0.05 ) 0% ,rgba( 0 , 0 , 0 , 0 ) 100% ); } .view .s 3 > .overlay { background : linear-gradient( left , rgba( 255 , 255 , 255 , 0 ) 0% , rgba( 255 , 255 , 255 , 0.2 ) 100% ); } .view .s 4 > .overlay { background : linear-gradient( right , rgba( 0 , 0 , 0 , 0.6 ) 0% ,rgba( 0 , 0 , 0 , 0.2 ) 100% ); } .view .s 5 > .overlay { background : linear-gradient( left , rgba( 0 , 0 , 0 , 0.8 ) 0% ,rgba( 0 , 0 , 0 , 0 ) 100% ); } |
The detail part of the thumbnail that get’s
revealed when we hover, will also have a background gradient, since we want to
simulate a shadow falling on it:
1
2
3
|
.view div.view-back{ background : linear-gradient( left , #0a0a0a 0% , #666666 100% ); } |
And that’s it! Check out the other examples and go
nuts! There are many different possibilities for fooling around with this.
I hope you find it inspiring!
I hope you find it inspiring!
Check out Richard Bennett’s version that works on a
click/touch event.
No comments:
Post a Comment