From our sponsor: Chromatic - Visual testing for Storybook, Playwright & Cypress. Catch UI bugs before your users do.
Today we want to share a little 3D concept for an image slideshow (or similar) with you. The idea is to reveal thumbnails using a neat effect: the current image will be “opened” in the middle and the thumbnails view will unfold in 3D.
3D is absolutely in right now. With CSS 3D transforms we can explore new ways of playing with space and create depth and realism to normally flat elements.
Check out the following inspiring concepts on Dribbble:
- Pinch to unlock by Adrien Olczak
- Pinch out to unlock by Adrien Olczak
- Slide to unlock (fold out) by Craig ‘iPhaze’ Philips
- UX/iOS/UI iPhone idea with video process by Cuberto
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.
(Vendor prefixes will be omitted in the following, but you’ll of course find them in the files.)
Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.
For this effect we want to have a simple initial structure, a structure that might be used in an image slideshow. This structure will get transformed, so that we can create the 3D animation.
So, from the following structure
<div id="th-wrap" class="th-wrap"> <!-- current image --> <img src="images/1.jpg"/> <!-- thumbnails view --> <div class="th-inner"> <ul> <li> <a href="#"> <img src="images/thumbs/1.jpg" /> </a> </li> <li> <!-- ... --> </li> <li> <!-- ... --> </li> <li> <!-- ... --> </li> <!-- ... --> </ul> </div> </div>
we want to create this structure:
<div id="th-wrap" class="th-wrap th-active"> <div class="th-part"></div> <div class="th-part"> <div class="th-inner"> <ul> <!-- ... --> </ul> <div class="th-overlay"></div> </div> </div> <div class="th-part"> <div class="th-inner" style="display: block; "> <ul> <!-- ... --> </ul> <div class="th-overlay"></div> </div> </div> <div class="th-part"></div> </div>
The divisions with the class th-part will be the parts that will animate. Each one of the parts will have a height of half of the whole wrapper (150 pixels):
.th-wrap .th-part { width: 100%; height: 150px; position: relative; overflow: hidden; background: #f0f0f0; }
The two outer ones (the ones with no content) will have the current slideshow image as background image:
.th-wrap .th-part:nth-child(1), .th-wrap .th-part:nth-child(4) { background: #000 url(../images/1.jpg) no-repeat top left; z-index: 100; } .th-wrap .th-part:nth-child(4) { transform: translateY(-300px); background-position: bottom left; }
The last one also needs to be pulled up because we want it to touch the upper one.
The second and third part will contain the th-inner division from the initial structure and we’ll rotate them in 3D:
.th-wrap .th-part:nth-child(2){ transform-origin: center bottom; transform: translateY(-150px) translateZ(-150px) rotateX(-90deg); } .th-wrap .th-part:nth-child(3) { transform-origin: center top; transform: translateY(-150px) translateZ(-150px) rotateX(90deg); }
The idea is that we duplicate the content and pull the one of the second copy up (we set a margin of -150 pixels to the th-inner div of the second one):
.th-wrap .th-part:nth-child(3) .th-inner{ margin-top: -150px; }
When we click on the button to toggle the view, we will add the class th-active to the wrapper:
.th-wrap.th-active .th-part:nth-child(2), .th-wrap.th-active .th-part:nth-child(3){ transform: translateY(-150px) translateZ(0px) rotateX(0deg); } .th-wrap.th-active .th-part:nth-child(1), .th-wrap.th-active .th-part:nth-child(4){ transform: translateY(-150px); }
Of course, we’ll need to add some transitions to the respective elements. The first transition is for all the parts, but then we’ll redefine the timing functions for some cases so that we have a smooth experience. The key here is to understand that the transition defined for the th-part class will be applied when the thumbnail view closes, since we have a redefined transition for the active one. So, when we open the thumbnails view, we want the 2nd and 3rd part to have a ease-in-out timing function:
.th-wrap .th-part { transition: all 500ms ease-out; } .th-wrap .th-part:nth-child(1), .th-wrap .th-part:nth-child(4) { transition: all 480ms ease-in-out; } .th-wrap.th-active .th-part:nth-child(2), .th-wrap.th-active .th-part:nth-child(3) { transition-timing-function: ease-in-out; } .th-wrap.th-active .th-part:nth-child(1), .th-wrap.th-active .th-part:nth-child(4) { transition: all 400ms ease-in-out; }
The tweaking of timing and timing functions depends on the translation values of the parts. If they would be narrower, the difference might be a bit less.
And that’s the important bits and pieces. In the demo we’ll have a slideshow mockup with a button that we will be able to activate. We’ll use some JS magic to add the active class to the wrapper and change the structure to the four parts with the double thumbnails content.
For browsers that don’t support the new CSS properties, we’ll simply show/hide the thumbnails view without any fancy effect.
I hope you find this concept inspiring!
is it only me or this effect didn’t work properly? 🙁
What exactly are you seeing? Thanks, cheers, ML
On Chrome it’s perfect. On firefox it splits in the middle in the animation. Doesn’t work on Opera for me.
awsome… Love it!!!!
Hi Mary………Its simply awesome……….Thank you so much for sharing the source code. I am always looking forward to your tweets….
Warm Regards,
Sachin Walvekar
It stops working for me after a few times with Firefox 14.0.1 on Windows 7 (nothing happens on click). Works fine with Chrome, as well as IE 9 and Opera (latter two without transitions, though).
Wonderful !! Thank you! I use Firefox and it works great.
Thanks for the tutorial,
This is AWESOME.
That’s it no more words to say.. 🙂
Hi ML, I really love and enjoy your fabulous work! I just wonder if you can do some experiement work on such effect as in this website : http://xiuxiu.web.meitu.com/main.html?menu1=puzzle
This is a very popular Chinese site for image manipulation. The puzzle part is not for puzzle game but for combining several images together to form a new image. Although it is in Chinese, I think it is quite easy to go ahead even without text.
It is made with Adobe flash. I am quite interested whether we can have similar feature with CSS + jQuery or some good approach other than Flash.
No luck: The page says “CSS 3D transforms are not supported in your browser”.
I use Chrome!
Hi Bertil, thanks for your feedback! Can you tell me which version of Chrome you are using (and which OS)? Thanks a lot, cheers, ML
I see a similar bug in Chrome when it’s running without hardware accelerated 3D. The pinch effect does not appear. You can test this on Windows by making a shortcut for the Chrome app, get properties, and edit the “Target” value to something like this:
C:\Users\YOURNAME\AppData\Local\Google\Chrome\Application\chrome.exe -disable-accelerated-compositing
Very nice. I would hate to have to pinch to unlock my iOS device – as beautiful as those concepts are.
AWESOME!
And i love the javascripy message 🙂
the demo does also not work for me, neither on Chrome 21.0.11.80.83 nor on FF16a2
FF 14.0.1, GH 21.0.1180.83
working ideal
Thank you, Mary! As always it’s a great perfomance!
Hi Mary,
I have one of the latest version of Chrome (21.0.1180.83 m) and the demo incorrectly labels my browser not supporting 3D Tranforms; any ideas, if on my end, that would happen?
If your computer supports it, you can try enabling hardware acceleration. But, my guess is that, unless you already turned this off yourself, your computer/browser combo won’t support it.
This Script does not works properly in any of the Browser . I Believe some admin can Replace it. with Proper Script .
Great effect though I find it hard to see where you would use this on a commercial site.
Very nice effect, inspirative design for new functional use
I do not understand how it was possible that this file “3D Restaurant Menu Concept” “3D Restaurant Menu Concept” will work perfectly in Internet Explorer 9 if indicated that only works well in other browsers.
Don’t work in Chrome Versión 23.0.1271.64 m windows 7 ultimate and linux mint 13 maya xfce.