Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Auto Save

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <div class="contentContainer"> 
	<div class="arrow"><span class="arrow-symbol"></span><span class="drag-cta">Pull</span></div>
    <div class="contentCopy">
    <h1 class="title">On the Road Again...</h1>
    <article class="copy">
			<p><b>REFRESH TO REPLAY</b></p>
			Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce pharetra congue metus vel dignissim. Phasellus orci est, faucibus a sem sed, interdum lacinia odio. Sed arcu ipsum, vestibulum vitae fermentum at, tincidunt id nibh. Fusce eu mauris eget ante elementum tincidunt. Morbi leo risus, blandit vel molestie ac, aliquet sed neque. Cras venenatis urna vel mi ullamcorper iaculis. Donec vel lobortis elit. Suspendisse potenti.<br><br>Cras blandit magna mollis, rutrum diam non, pulvinar mauris. Vivamus erat sem, volutpat non velit sed, elementum rhoncus dolor. Praesent elementum, eros et sollicitudin malesuada, magna diam interdum risus, eu volutpat velit nisi ut est. Sed aliquet feugiat nulla, at eleifend felis consequat vitae. Proin varius odio quis nisi ultrices convallis. Aliquam vehicula ligula et urna elementum, vitae tempor mi accumsan. Aliquam nibh nulla, congue eget eros commodo, commodo condimentum est.<br><br>Ut sagittis tortor id odio sagittis, ac rhoncus quam pellentesque. Ut commodo, turpis ac posuere gravida, libero ipsum sagittis diam, ut ullamcorper ligula augue et lorem. Donec euismod odio porttitor turpis volutpat, vel posuere velit fermentum. Morbi tempus neque vel nulla tincidunt, eu malesuada metus convallis. Nullam elementum nulla non erat blandit, non lacinia mauris auctor. Pellentesque a hendrerit lorem, vel iaculis dolor. Etiam ut mi vitae enim facilisis porta. Vivamus vehicula mi id elit gravida pellentesque. Maecenas porta ultricies nulla varius molestie. Phasellus nec imperdiet mi. Nam fermentum ante eget lacus dictum, quis viverra enim porta. Fusce accumsan nec magna sollicitudin ultricies. Nulla in diam vestibulum, dictum urna id, ultrices tortor. Mauris lacinia semper enim. Nulla consequat tortor velit, at ultrices tortor pellentesque nec.<br><br>Integer suscipit pretium massa, vitae sollicitudin dui dictum non. Morbi metus lacus, vehicula malesuada posuere quis, luctus in ante. Pellentesque sollicitudin rutrum imperdiet. Vivamus volutpat metus magna, tristique congue nulla cursus eget. Nullam lacus mi, fringilla eget sagittis sit amet, vulputate eu felis. Suspendisse id aliquet arcu, ac gravida nisi. Morbi eu feugiat mi, et egestas lorem. Praesent vel nisi ac nunc rhoncus ultricies. Phasellus feugiat euismod tincidunt. Suspendisse id felis scelerisque nisi mollis mattis. Quisque rutrum est nunc, auctor adipiscing erat consequat et. Curabitur vitae adipiscing odio. Aenean non blandit sem. Nulla facilisi.<br><br>Nulla sagittis scelerisque risus ac facilisis. Pellentesque mollis lacus sed purus bibendum mattis. Etiam ut dolor hendrerit, volutpat purus eget, consequat magna. Phasellus scelerisque erat risus, non dignissim ante fermentum semper. Aliquam non mauris ornare, condimentum eros tempor, bibendum erat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse potenti. Morbi at auctor purus, nec lobortis tortor. Mauris sodales ante sed velit condimentum congue vel eu lacus. Nam ac magna metus. Duis tincidunt volutpat nisi at iaculis.<br><br>Aliquam dignissim eros id erat molestie fermentum. Aenean laoreet mauris dui, vel laoreet urna rutrum a. Nullam sagittis metus sit amet libero faucibus hendrerit. Nam eget malesuada ligula, at interdum ante. Donec tempor a risus eget consectetur. In hac habitasse platea dictumst. Maecenas molestie iaculis pretium. Cras quis leo in erat luctus rhoncus eget ac turpis. Aliquam volutpat quam lobortis quam faucibus gravida.</article>
    </div>
	<section class="headerContainer">
		
		
		<div class="bkg"></div>
	</section>
	
	</div>
              
            
!

CSS

              
                
		
		
/* #Prototype Styles
================================================== */		
html, body{ background-color:gray; overflow:hidden; }
        
.scroll{ overflow:scroll; -webkit-overflow-scrolling:touch;  }  
        

body
{ 
	
	background-repeat: no-repeat;
	background-position: top center;
	width:100%;
	background-size:cover;
	height:100%;
	min-height:1000px;
	overflow:hidden;
	font-family: 'Playfair Display', 'Georgia', 'Times New Roman';
	color:#FFFFFF;
	background-color:#fff;
    
}

header
{
	
	margin-top:30px;
	position:absolute;
	z-index:5;
	width:420px;
	padding-top:10px;
	padding-bottom:10px;

}

h1{
	
	font-size:64px;
	font-weight:900;
    
	margin-left:30px;
}

h3{
	
	font-size:16px;
	letter-spacing:-1.5px;
	margin-top:5px;
	margin-left:35px;
}
        
	/* hardware accelatator class */	
	.trans3d
	{
		-webkit-transform-style: preserve-3d;
		-webkit-transform: translate3d(0, 0, 0);
		-moz-transform-style: preserve-3d;
		-moz-transform: translate3d(0, 0, 0);
		-ms-transform-style:preserve-3d;
		-ms-transform: translate3d(0, 0, 0);
		transform-style:preserve-3d;
		transform: translate3d(0, 0, 0);

	}
	
	.contentContainer
	{
		position:absolute;
		
        width:100%;
        height:100%;
       
	}
	
	.headerContainer
	{
		position:absolute;
		
        width:100%;
        height:100%;
        background-color:#000;
       
	}
        
    .headerContainer .bkg
	{
		position:absolute;
		
        width:100%;
        height:100%;
        
        background-image: url(http://johnblazek.net/codepen-resources/pull-refresh/images/image1.jpg);
        background-size:cover;
        background-position:center center;
        opacity:.5;
    }
        
   .title
    {
        left:50%;
        width:1000px;
        text-align:center;
        margin-left:-500px;
        position:absolute;
        z-index:1;
        margin-top:100px;
        -webkit-user-select: none;
        -moz-user-select: none;
        -ms-user-select: none;
        user-select: none;
        
    } 
     
        
    .arrow
    {
        top:50%;
        left:50%;
        width:71px;
        height:91px;
        text-align:center;
        margin-left:-35px;
        position:absolute;
        perspective:1000;
        z-index:1;
        
        cursor:-webkit-grab;
        cursor:-moz-grab;
        cursor:-ms-grab;
        cursor:-o-grab;
        
    }
        
    .grabbing{ cursor:-webkit-grabbing; }    
        
    .arrow .arrow-symbol
    {
        
        width:71px;
        height:71px;
         margin-left:-35px;
        position:absolute;
        background-size:71px;
        background-repeat:no-repeat;
        background-position:top center;
        background-image:url(http://www.johnblazek.net/codepen-resources/pull-refresh/images/arrow.svg);
    }    
        
    .arrow .drag-cta
    {
        position:absolute;
        bottom:0;
        width:100%;
        text-align:center;
        margin-left:-35px;
    }
        
    .contentCopy{
    
        width:100%;
        min-height:1000px;
        position:absolute;
        background-color:#eee;
        color:#FFF;
        z-index:30;
        padding-bottom:100px;
        display:block;
    }
        
        .contentCopy .copy
        {
             color:#333; 
           
            width:1000px;
            margin:200px auto 0 auto;
            position:relative;
            line-height:24px;
            
        }
	
	    @media (max-width: 1001px) { 
            .title{ font-size:36px; width:80%; margin-left:-40%; margin-top:50px;}
             .contentCopy{ width:100%; }
             .contentCopy .copy{ width:90%; margin-left:5%;  }
            }
              
            
!

JS

              
                // blocks the document from overscrolling.
        document.addEventListener('touchmove', function (e) { if ( view == 'header' ){ e.preventDefault(); } }, false);
        
		// set and cache variables
		var w, container, arrow, bkg, contentCopy, title, copy;
        var view = 'header';
        var useFilters = true;
        
		// start er up!
        $(document).ready( init )
		
        
        
        function init()
		{
			w            = $(window);
            d            = $(document);
			container    = $( '.contentContainer' );
			header       = $( '.headerContainer' );
            arrow        = $('.arrow');
            cta          = arrow.find('.drag-cta');
            symbol       = arrow.find('.arrow-symbol');
            bkg          = header.find('.bkg');
			contentCopy  = $('.contentCopy');
            title        = contentCopy.find('.title');
            copy         = contentCopy.find('.copy');
            dragLimitMax = false;
            
            // start touch or mouedown event based on device...
            if (getDevice()) arrow.bind( 'touchstart', onTouchStart );
            else arrow.bind( 'mousedown', onTouchStart );
            
            // resizer event declaration
            w.resize(resizer);
            resizer();		
		}
        
        // return the arrow Y position
        function returnArrowY($e)
        {
            // set Y value based off window and arrow height
            var $y = $e - (w.height() * .5) - (arrow.height() *.5);
            
            // if y < than 0 force it to 0.
            if ($y < 0) $y = 0;
            
            // return value
            return $y;
        };
        
        // return the background ration... different because we aren't pulling the arrow location
        function returnBkgY($e)
        {
            var $y = $e - (w.height() * .5);
            if ($y < 0) $y = 0;
            return $y;
        };
        
        // bind the move and end events on touchstart/mousedown
        function bindEvents()
        {
            if ( getDevice() )
            {
                // on touch
                d.bind( 'touchmove', onTouchMove );
                d.bind( 'touchend', onTouchEnd ); 
            }
            else 
            {
                // desktop
                d.bind( 'mousemove', onTouchMove );
                d.bind( 'mouseup', onTouchEnd );
            };  
        };
        
        // unbind the move and end events on touchend/mouseup
        function unbindEvents()
        {
            if ( getDevice() )
             {
                 d.unbind( 'touchmove', onTouchMove );
                 d.unbind( 'touchend', onTouchEnd );
             }
            else 
            {
                d.unbind( 'mousemove', onTouchMove );
                d.unbind( 'mouseup', onTouchEnd );
            };   
        }
        
        // on touch start / mouse up
        function onTouchStart(e)
        {
            console.log( 'touchstart', e );
            
            arrow.addClass('grabbing');
            
            bindEvents();
        }
        
        // on touch move / mouse move once touch has been initiated
        function onTouchMove(e)
        {
            console.log('touchmove', e);
             
            var $pageY;
            var $minDrag = w.height() * .75;
            
            // if touches use the touches event, other wise use the standard pageY event
            if (getDevice()) $pageY = e.originalEvent.touches[0].pageY;
            else $pageY = e.pageY;
            
            // set values
            var $y          = returnArrowY($pageY); // get the arrow Ratio
            var $bkgY       = returnBkgY($pageY);   // get the bkgground Ratio
            var $s          = 1 + ($y * .01);       // positive Y Movement
            var $arrowScale = 1 - ($y *.001);        // negative Y Movement
            var $bkgScale   = 1 + ($bkgY * .001);   // bkgScale proporational ratio
            var $blur       = $s * 1.5;               // blur value
            var $contrast   = ($bkgScale);          // contrast value
            var $titleY = -(w.height() * .75) + ($y * .5);  // title proporational ratio
            
            var $fsObj; // fullscreen movement object declaration
            if (useFilters)
            {
                if ( getDevice() ) $fsObj = { ease:Quint.easeOut, scale:$bkgScale };
                else $fsObj = { ease:Quint.easeOut, '-webkit-filter': 'blur('+ $blur +'px) contrast('+ $contrast +')', scale:$bkgScale };
            } else $fsObj = { ease:Quint.easeOut, scale:$bkgScale };
             // move arrow & content
            TweenMax.to( arrow, .1, { y:$y, scale:$arrowScale });
            TweenMax.to( title, .1, { y:$titleY });
            
            var $oldDragLimitMax = dragLimitMax;
            if( $pageY > $minDrag) dragLimitMax = true;// cta.text('Release!')
            else dragLimitMax = false;
            
            if ($oldDragLimitMax != dragLimitMax)
            {
                if( $pageY > $minDrag) 
                {
                    cta.text( 'Release!' );
                    TweenMax.to( symbol, .5, { ease:Back.easeOut, rotationX:180 } )   
                }
                else 
                {
                    cta.text('Pull');
                    TweenMax.to( symbol, .5, { ease:Back.easeOut, rotationX:0 } )  
                }
            }; 
            
            // mobile really can't handle a fullscreen div filter, so we only apply to the desktop
            TweenMax.to( header, .25, $fsObj );
        }
        function onTouchEnd(e)
        {
             console.log('touchend', e )
             
             var $pageY;
             var $minDrag = w.height() * .75;
             
             unbindEvents();
            
             if ( getDevice() )$pageY = e.originalEvent.changedTouches[0].pageY;
             else $pageY = e.pageY;
           
            // reset to full upright and locked position.
            TweenMax.to( arrow, 1, { y:0, ease:Elastic.easeOut, scale:1, overwrite:true  } )
            TweenMax.to( header, 1.5, { ease:Quint.easeOut, scale:1, '-webkit-filter': 'blur(0px) contrast(1)'  } );
            
            // if our distance is further than the min drag amount, SUCCESS!
            if( $pageY > $minDrag)
            {
                view = 'article'; // so we know which view we are in
                
                TweenMax.to( contentCopy, 1, { ease:Elastic.easeOut, y:0 } );
                TweenMax.to( title, 1, { ease:Elastic.easeOut, y:0,  color:'#333', onComplete:resizer } );
                
                $('html, body').addClass( 'scroll' );
                
                
            }
            else
            {
                view = 'header'; // so we know which view we are in
               
                TweenMax.to( title, 1, { ease:Elastic.easeOut, y:-w.height() * .75,  color:'#FFF' } );
                TweenMax.from( copy, 1, { ease:Expo.easeOut, y:w.height(), autoAlpha:0 } );
            };
        }
        
        // resizer events.
        function resizer()
        {
            if ( view == 'header' )
            {
                TweenMax.set(contentCopy, { y:w.height() });
			    TweenMax.set( title, { y:-w.height() * .75 } );
            }
            else
            {
               TweenMax.set( contentCopy, { y:0 } );
               TweenMax.set( title, { y:0 } ); 
                
               
                $('html, body').height(contentCopy.height() + 100);
               
            };
        };
		
		// helper to get us a random int if needed
		function getRandomInt( $n )
		{
			return Math.floor((Math.random()*$n)+1);	
		}
        
        // Returns the device. I forget where this is from, sorry.  I didn't do it.
        function getDevice()
	    {
		  var check = false;
		  (function(a){if(/(android|ipad|playbook|silk|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera);
		return check;
	};
		
              
            
!
999px

Console