curtain-template
January 7, 2015 | 85 Feedbacks

3D Curtain Template

A list of split blocks that reunite on scrolling, simulating a movement along the z-axis with the help of CSS transformations and jQuery.
Browser support
  • ie
  • Chrome
  • Firefox
  • Safari
  • Opera
9+

The 2-blocks design approach is quite common nowadays. On one side the text paragraph, on the other a visual element. With this nugget we tried to “spice-up” the transition between the sections by simulating a movement along the z-axis while the user is scrolling (or using the 2 navigation buttons).

We didn’t use any CSS 3D property though, just the Scale and Translate transformations, controlled through jQuery.

Image credits: Picjumbo

Creating the structure

The HTML structure is quite basic: for each block of content we created a <section> element containing a div.cd-block and 2 div.cd-half-block. The first .cd-half-block is always empty and is used to set the background-image, while the second contains the text paragraph.

Adding style

On small devices we didn’t implement the curtain effect so you’ll see a basic layout with the list of all the sections (you can give a look at the source code for more details).
On desktop devices (viewport width more than 1170px) we assigned a position: fixed and a top: 0 to the .cd-block elements in order to place them on top of the screen (this way they are one on top of the other). Since their containers – .cd-section – have  a height: 100vh (and position: static) , they still occupy their own space (and that’s way we can scroll the page).
Besides, we assigned a translateX to each .cd-half-block element (translateX(-100%) and translateX(100%) alternatively to :first-of-type and :nth-of-type(2)) so that they are moved outside the viewport.

Events Handling

Each section animation is basically made up of two phases: in the first one, the 2 .cd-half-block elements are moved back in the viewport (the translateX value varies from 100%/-100% to 0); in the second one the .cd-block is scaled down and its opacity is reduced (to simulate a 3D movement).

To do so, we attached the triggerAnimation() function to the window scroll event. When the user scrolls, for each .cd-section element we evaluate – using the animateSection() function – the translateX and scale value according to the window scrollTop (and the section offset().top).

Changelog

May 25, 2015
  • Bug fixed on Chrome 43.0.2357.65
Jan 7, 2015
  • Resource released by CodyHouse

Claudia Romano

Web developer, fan of The Big Bang Theory and good food. Co-founder of CodyHouse and Nucleo. You can follow her on Twitter.

  • http://www.fablescode.com Lester Fabricio Cervantes

    Excelentes tutoriales, siempre con RWD en mente, estructura HTML básica, y los mejores ‘trucos’ css & js. Simplemente excelente trabajo.
    Siempre que estoy atorado en diseño acudo a ustedes, maravilloso chicos.
    PS: I love this site. Excellent & Well explained tutorials.

  • http://freedesign.in/ Siva

    doesn’t work for me :( windows pc, chrome and mozila latest versions.

    • http://codyhouse.co Claudia Romano

      Hey Silva, could you provide more info about the issue? I’ve been testing it on a window machine (both Chrome and Firefox) and it’s works fine. Thanks!

      • http://freedesign.in/ Siva

        hey, i didn’t know what went wrong last time. it works now, smooth like a fine wine. thumbs up!

  • Himansh Anand

    awesome dude…. from where u get these ideas ?? simply awesome.. well done and thanks

  • Muhammad Anwar

    excellent

  • Marlana Mumme Muzny

    I was looking at demo on my android smartphone…no go :(. Have to bring it up on laptop. Seems pretty interesting. Is this mobile compatible?

    • http://codyhouse.co Claudia Romano

      We chose to use a basic layout for the mobile version but yes it’s mobile compatible – just change the media query and everything should work fine!

      • Hove Harbetian

        Great work , if i may ask . how do you apply to make it work on both desk/laptop and mobile ? mostly mobile. many thanks and regards . HOVE

  • vivek

    it didn’t work on safari on windows

    • vivek

      this is the output… works smooth on chrome

      • http://codyhouse.co Claudia Romano

        We didn’t test it on Safari for Windows because it’s an outdated browser ( the last update has been released more than 2 years ago).

        • vivek

          my bad sorry :)

          • udamadu

            You may need to add prefixes for css3 properties.

    • Brian Hinton

      I thought Safari wasn’t updated on Windows anymore?

  • http://cameroncampbell.me/ Cameron Campbell

    Awesome stuff! Any idea why I can’t get it working on this page: http://cameroncampbell.me/curious-themes/

    I took the downloadable source and everything should be linked up properly; the only difference is that’s a WordPress page but it shouldn’t matter since I have your HTML within the template file I’m using. Any ideas why it’s not loading the animations would be awesome!

    • http://cameroncampbell.me/ Cameron Campbell

      Needed to add to CSS:

      body::before {
      /* never visible – this is used in jQuery to check the current MQ */
      content: ‘mobile';
      display: none;
      }
      @media only screen and (min-width: 1170px) {
      body::before {
      /* never visible – this is used in jQuery to check the current MQ */
      content: ‘desktop';
      }
      }

  • http://www.inhiro.com/ InHiro

    Looks cool! I think we’re gonna use this for a simple tutorial-like website for our product. Thanks!

  • Michael Garcia

    Very nice. Any ideas how you would close this with a cd-block and h1 at the end of the scroll?

  • Ronnie_Gardocki

    I think that version with hijacked scroll (one page scroll) will be better, because default chrome scroll just killing coolness of this demo :(
    I will try codepen demo tomorrow.
    Anyway, awesome concept!

    • codeview

      Very nice! Thank you. Exactly what I was needing. If user doesn’t click the arrow buttons in the CodyHouse example (ie: uses middle-mouse button or scrollbar) the effect is sorta useless. Your implementation solves it.

  • John Fawcett

    Cool – I did a _very_ similar effect at http://quiz.j0.hn for a simple dev quiz. It’s interesting how different our solutions were (I went with a CSS-only solution using JS to toggle classes). You can see the source here https://github.com/goodybag/dev-quiz

    • http://codyhouse.co/ Sebastiano Guerriero

      Really nice :)

  • http://andrebartholomeufernandes.com/ André Bartholomeu Fernandes

    so cool tks for that.

  • Andrew Dotson

    Looks great, question though. Why do you prefix all of your class names with cd? Just curious as to the logic with that. I’m assuming to prevent selector conflicts with other libraries and such?

    • http://codyhouse.co/ Sebastiano Guerriero

      Exactly. cd = cody. We often use very common classes, by adding .cd we prevent potential conflicts

  • hami

    dont work on safari and ie11
    just work on firefox and chrome

    • http://codyhouse.co Claudia Romano

      Hi Hami, we tested it on both Safari (for Mac) and IE11 and it works fine. Could you please provide more info about the issue you’re experiencing? Thanks

      • hami

        i test on IE good work but,

        safari on windows8 not work

        screenshot link you can see it

        https://docs.google.com/file/d/0B9cs6I1nsDSiYWNNckpBZWwwZm8/edit?usp=drivesdk

        • hami

          screenshot

          • http://codyhouse.co Claudia Romano

            We didn’t test it on Safari for Windows because it’s an outdated browser ( the last update has been released more than 2 years ago). But it works fine on Safari for Mac! ;)

          • hami

            Thanks and warm regards

  • http://blog.zamartz.com/ zamartz

    How do you make it so that the sections are always on the same side and do not flip/flop every other set of two

  • Murray

    The effect doesn’t work if screen width is less than about 1145 px. This could explain some of the “not working” comments.

    • Ben

      I confirm that…

  • Hove Harbetian

    Great work , it works well on all browsers. if i may ask . how do you apply to make it work on all desk/laptop and mobile ? mostly mobile. many thanks . HOVE posted days ago below

    • http://codyhouse.co Claudia Romano

      We use CSS media queries

      • Ben

        It’s not working on my iPad 2…But I really like the effect, nice job…!

  • designer_jaspal

    Not Working in safari. what to do?

    • http://codyhouse.co Claudia Romano

      Hi, we tested it on Safari (for Mac) and it works fine. Could you provide more info about the issue? Thanks

  • sdfg

    in chrome second down arrow not working

  • Tofanelli

    Hey guys…. what do you think to improve this curtain code and made it looks like this one – http://2015.extralagence.com/ -?? I would love to use this one!!!! =)

  • Tobias

    How would I go about setting it up so the image part would take up 75% of the screen and the text part 25%? I’d like the images to be larger than 50%.

  • Steve Claude Morency

    Hi Claudia! thank you this is a great post!I just started looking into implementing visual sections for cooler displays. My jquery is limited and my css is not that good. How can I customize this so that it doesn’t start at the top but rather a section below other sections? Any help is useful especially when the curtain css tends to override my original css.

    • http://codyhouse.co Claudia Romano

      Hi Steve, glad you like it. In the html file, add your additional content (with no .cd-section class ) on top of the actual content. That should work fine. Hope this helps!

      • Steve Claude Morency

        I did but it keeps sending the h1 “CURTAIN WEBSITE” to the top and doesn’t stay in it’s own section. The curtain also fades out when a new section appears. My goal is to make the curtain only work when you scroll and reach it’s section without interfering with the other ones. This is really advance for my skills but I always try to maneuver things around and try to fix it but this is not simple for me. Thank you Claudia I will keep experimenting until a find a way and any help is useful to understand js and css better.

  • Jason Nelson

    Love the work, but I seem to be having some troubles and I am hoping you can help. I am using this for an interactive poem/fiction. Everything works fine until I get to level 25 (the 25th CD Section) or so. And then everything glitches out.
    I’ve tried various basic fixes like reducing the number of images, but it still starts to break up (only parts of divs and texts show, background goes away etc…) after I scroll to level 25 (basically 25 sections).

    Is there a limit to how many levels this can handle? Is there a way to fix it so it will work for 40 levels or so?
    Maybe I am bumping up against the limits of html and css physics. Any help would be greatly appreciated!

    cheers, Jason

    • http://codyhouse.co Claudia Romano

      Hi Jason, no there should be no limit. Not sure way you’re experiencing it. Are you sure you didn’t make any mistakes in the HTML structure?

      • http://dpoetry.com Jason Nelson

        Yep. I’ve tried just your demo code and it can have as many levels as anyone would want. So perhaps I have done something else wrong. One thing that might be causing the issue is I am putting DIVs into each of the sections, so there are two images on either side that come together. And there will be heaps of other interactive content. I just find it strange that no matter what I add or subject in terms of DIVs and images and some tooltips etc…that it slows down or glitches out at level 25.

        Here is a link to what I am trying to create: http://www.dpoetry.com/entropy/3d-curtain-template/iframe.html

        NOTE: There are broken image tags as I tried removing some of the images to see if that helped and I’ve used an iframe to make sure everything stays in place, plus it’s in beta-beta…so its kinda messy. But you can see what it does at level 25 or so.

  • Adnane ZA

    Very Nice : I like your work ,

    I have A quistion : We can use your products on other platforms Like wordpress for selling or for free ?

  • Hélio Viegas

    Hi, i really like the effect you did but i don’t understand why you embed images in your css….(e.g. background-image: url(“../img/img-1.jpg”);)

    This means every time i need to add a new image i must change the CSS. Good job on the effect though.

  • http://dpoetry.com Jason Nelson

    Just curious if anyone else has any ideas as to why the following problem might be happening. Feel free to check out the example. But I seem to have overloaded or messed up the structure somehow by putting multiple DiVS and images into the sections (to position them and have images on both sides etc….below is the pasted reponse from my conversation with the most awesome Claudia. And excuse the resend, but the artwork is due in two days and I am totally stuck.

    Yep. I’ve tried just your demo code and it can have as many levels as anyone would want. So perhaps I have done something else wrong. One thing that might be causing the issue is I am putting DIVs into each of the sections, so there are two images on either side that come together. And there will be heaps of other interactive content. I just find it strange that no matter what I add or subject in terms of DIVs and images and some tooltips etc…that it slows down or glitches out at level 25.

    Here is a link to what I am trying to create:http://www.dpoetry.com/entropy

    NOTE: There are broken image tags as I tried removing some of the images to see if that helped and I’ve used an iframe to make sure everything stays in place, plus it’s in beta-beta…so its kinda messy. But you can see what it does at level 25 or so.

  • Aline Héau

    Hi Claudia, that’s a great work ! How should I change the code to reverse the effect : scrolling down opens the panels instead of “closing” ?
    Best regards

  • David Champion

    Hi Claudia, what a great piece – thank you. I don’t appear to be having any nav arrows show up though? It scrolls fine, and they are there, when I hover over them and click they do work (they don’t hover different) but they are present, I just can’t see them on the page? I’ve linked to it in the style.css but still can’t find them. Any thoughts as to what I’m doing wrong? David

    • http://codyhouse.co/ Sebastiano Guerriero

      Hi David, have you included the arrows in the img folder? If you have, it may be a problem with z-index. Make sure the arrows z-index is higher than the one of the content

  • Bobby Bowyer

    I can not seem to get hyperlinks to work. There is no pointer in hover

    • Bobby Bowyer

      It’s all good, I was missing a closing div

  • vagiag

    Hello Claudia, first let me congrats you for the awesome work of yours!
    I have a simple question i wanna put an image in the first section but it doesn’t seem to work on i pad the image doesn’t appear at all.
    I try to put it and in the css as a background image with height and width and in the html but i had no luck.

    • http://codyhouse.co Claudia Romano

      Hi, glad you like it! :)
      Try adding in the style.css (or style.scss if you’re using sass):

      That should work!

  • jacmaes

    It suddenly stopped working for me in Chrome 43 beta. I’ve pretty much disabled all my extensions to avoid a potential conflict, but to no avail. No JS error in the console…

  • vladimir

    Hi! Can i to use this layout for the catalog of artwork?

  • http://themeforest.net/user/IG_design/portfolio?ref=IG_design IG Design

    It’s very nice, but stopped to work with last Chrome update. (Version 43.0.2357.65)

    • http://codyhouse.co Claudia Romano

      @labluzzamanlabu:disqus @disqus_8hZpJ3mgSI:disqus Thanks for the heads up! fixed now ;)

      • http://themeforest.net/user/IG_design/portfolio?ref=IG_design IG Design

        Thanks! :)

        • Siddhesh Khelya

          Can you please let me know what exactly was the bug? Thanks a lot :)

      • Labluzzaman Labu

        Thanks again for your outstanding work and support. One more thing can you tell us or fix the height property vh is not working in windows safari browser and sections are not working. It looks like frozen. I tried with em but it’s hard to control sections height in every devices.
        Thanks in advance.

        • http://codyhouse.co Claudia Romano

          Hi, see my reply to hami (below)!

  • Labluzzaman Labu

    Great work & wanted to use in a personal project. But, it seems works fine in Chrome older version but in 43(beta) & 43 (Canary) it stuck. Any idea about it how i recover this problem. Please notify ASAP.
    Thanks for the great work.

  • kelvin atawura

    would this work as a section in a page?

    • http://codyhouse.co Claudia Romano

      I didn’t try, but it should ;)

  • Klaude

    Hi Claudia, great work.

    Do you think that it could be possible to modify the url: 3d-curtain-template/index.html#0 with anchors at each page? with a huge catalog, it would be very interesting to be able tu use links that lands directly to the right page.

    I tried some solutions without succes.
    thx

    • http://codyhouse.co/ Sebastiano Guerriero

      Hi Klaude, you can set different links and maybe replace the arrows with some sort of pagination. However this effect would work nicely only if applied to sections of the same page, as a way to scroll from one section to the next one.

  • Denis Abondancia

    MARAVILHOSO SEU SITE, PARABENS

  • Gamroth

    How i can use the first section behind the cd-section with cd-half-block??

  • jp

    Anyone interested in creating a website for me. I have 5 of them to do and I have been looking for something like this and new with massive effects. or with alcarotrigo… email is jpstar1@aol.com

  • Abdelmalek Te

    Hello, iwant to use this template as facebook application but using the effect for the big screens how can make the change please?
    and thanks for sharing this beautiful template.

  • Rohit Gulati

    Hi First of all congratulations on the awesome work! I have a question though. Is there some way user scroll can be treated as clicking on the vertical nav buttons. I mean whenever the user initiates the scroll, we jump to the next section completely. Basically I want to avoid users being stuck midpage like the screen attached. Many thanks!

  • Luke Smith

    Even if you just pointed me in the right direction, that would be awesome. :)

  • Kevin GIllard

    This is a great animation – we are having problems with Safari Version 9.0.1 on Mac though. The curtains are very glitchy when using the mouse to scroll.

  • Angel Kurten

    Report problem whit collapse bootstrap

  • Nndda Nndda

    Is animation working on IE 11 or lower?

  • Nndda Nndda

    Bind animation on scroll:

    jQuery(document).ready(function($){
    //change this value if you want to change the speed of the scale effect
    var scaleSpeed = 0.3,
    //promenljive potrebne za kontrolu skrola
    delta = 0,
    scrollThreshold = 5,
    //change this value if you want to set a different initial opacity for the .cd-half-block
    boxShadowOpacityInitialValue = 0.7,
    animating = false;
    //bind the animation to the window scroll event
    triggerAnimation();
    $(window).on(‘scroll’, function(){
    //povezivanje skrolovanje tockicem misa kako bi se izbegle nepravilna poravnanja
    $(window).on(‘DOMMouseScroll mousewheel’, scrollHijacking);
    triggerAnimation();
    });
    //check the media query
    var MQ = window.getComputedStyle(document.querySelector(‘body’), ‘::before’).getPropertyValue(‘content’).replace(/”/g, “”).replace(/’/g, “”);
    $(window).on(‘resize’, function(){
    MQ = window.getComputedStyle(document.querySelector(‘body’), ‘::before’).getPropertyValue(‘content’).replace(/”/g, “”).replace(/’/g, “”);
    });

    //move to next/previous section
    $(‘.cd-vertical-nav .cd-prev’).on(‘click’, function(){
    prevSection();
    });
    $(‘.cd-vertical-nav .cd-next’).on(‘click’, function(){
    nextSection();
    });
    $(document).keydown(function(event){
    if( event.which==’38’ ) {
    prevSection();
    event.preventDefault();
    } else if( event.which==’40’ ) {
    nextSection();
    event.preventDefault();
    }
    });

    function triggerAnimation(){
    if(MQ == ‘desktop’) {
    //if on desktop screen – animate sections
    (!window.requestAnimationFrame) ? animateSection() : window.requestAnimationFrame(animateSection);
    } else {
    //on mobile – remove the style added by jQuery
    $(‘.cd-section’).find(‘.cd-block’).removeAttr(‘style’).find(‘.cd-half-block’).removeAttr(‘style’);
    $(window).off(‘DOMMouseScroll mousewheel’, scrollHijacking);

    }
    //update navigation arrows visibility
    checkNavigation();
    }

    function scrollHijacking (event) {
    // on mouse scroll – check if animate section
    if (event.originalEvent.detail 0) {

    // ako je pozicija prozora veca od polovine visine prozora – uracunavaj deltu
    if ( $(window).scrollTop() >= $(window).height()/2 ) { delta–; }

    ( Math.abs(delta) >= scrollThreshold) && prevSection();
    } else {

    // ako je pozicija prozora manja od visine celog dokumenta minus 3/2 visine prozora – uracunavaj deltu
    if ( $(window).scrollTop() = scrollThreshold) && nextSection();
    }
    return false;
    }

    function animateSection () {
    var scrollTop = $(window).scrollTop(),
    windowHeight = $(window).height(),
    windowWidth = $(window).width();

    $(‘.cd-section’).each(function(){
    var actualBlock = $(this),
    offset = scrollTop – actualBlock.offset().top,
    scale = 1,
    translate = windowWidth/2+’px’,
    opacity,
    boxShadowOpacity;

    if( offset >= -windowHeight && offset 0 && offset <= windowHeight ) {
    //the two .cd-half-block are in the center – scale the .cd-block element and reduce the opacity
    translate = 0+'px',
    scale = (1 – ( offset * scaleSpeed/windowHeight)).toFixed(5),
    opacity = ( 1 – ( offset/windowHeight) ).toFixed(5);

    } else if( offset = 0 && offset = $(window).width()/2 ) {
    shadow = 0;
    } else if ( position > 20 ) {
    shadow = boxShadowOpacityInitialValue;
    }

    elem.css({
    ‘-moz-transform': ‘translateX(‘ + value + ‘)’,
    ‘-webkit-transform': ‘translateX(‘ + value + ‘)’,
    ‘-ms-transform': ‘translateX(‘ + value + ‘)’,
    ‘-o-transform': ‘translateX(‘ + value + ‘)’,
    ‘transform': ‘translateX(‘ + value + ‘)’,
    ‘box-shadow’ : ‘0px 0px 40px rgba(0,0,0,’+shadow+’)’
    });
    }

    function scaleBlock(elem, value, opac) {
    elem.css({
    ‘-moz-transform': ‘scale(‘ + value + ‘)’,
    ‘-webkit-transform': ‘scale(‘ + value + ‘)’,
    ‘-ms-transform': ‘scale(‘ + value + ‘)’,
    ‘-o-transform': ‘scale(‘ + value + ‘)’,
    ‘transform': ‘scale(‘ + value + ‘)’,
    ‘opacity': opac
    });
    }

    function nextSection() {
    if (!animating) {
    if ($(‘.cd-section.is-visible’).next().length > 0) smoothScroll($(‘.cd-section.is-visible’).next());
    }
    }

    function prevSection() {
    if (!animating) {
    var prevSection = $(‘.cd-section.is-visible’);
    if(prevSection.length > 0 && $(window).scrollTop() != prevSection.offset().top) {
    smoothScroll(prevSection);
    } else if(prevSection.prev().length > 0 && $(window).scrollTop() == prevSection.offset().top) {
    smoothScroll(prevSection.prev(‘.cd-section’));
    }
    }
    }

    function checkNavigation() {
    ( $(window).scrollTop() $(document).height() – 3*$(window).height()/2 ) ? $(‘.cd-vertical-nav .cd-next’).addClass(‘inactive’) : $(‘.cd-vertical-nav .cd-next’).removeClass(‘inactive’);
    }

    function smoothScroll(target) {
    animating = true;
    $(‘body,html’).animate({‘scrollTop': target.offset().top}, 500, function(){ animating = false; });
    }
    });