<html>
<head>
<script src="https://rawgithub.com/ai/autoprefixer-rails/master/vendor/autoprefixer.js"></script>
<meta name="description" content="clip-path paralaxed paging scrollers">
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, width=device-width, maximum-scale=1">
<title>clip-path paralaxed paging scrollers</title>
<style type="unprocessed" id="AutoprefixerIn">%css%</style>
<style id="AutoprefixerOut"></style>
<script>
AutoprefixerSettings = { browsers: ['last 2 versions'] };
document.getElementById("AutoprefixerOut").innerHTML = autoprefixer.process(document.getElementById("AutoprefixerIn").innerHTML, AutoprefixerSettings).css;
</script>
</head>
<body>
<input class="demo" name="type" type="radio">
<label class="label">1/9</label>
<input class="demo" name="type" type="radio">
<label class="label">1/3</label>
<input class="demo" name="type" type="radio" checked>
<label class="label">1/2</label>
<input class="demo" name="type" type="radio">
<label class="label">3/4</label>
<input class="demo" name="type" type="radio">
<label class="label">7/8</label>
<div class="pager pager--overlap">
<div class="pages">
<div class="page">
<div class="page-laxwrap">
<div class="page-lax">
</div>
</div>
<div class="page-scrollport">
<div class="page-scrollbox">
<div class="content">page 1</div>
</div>
</div>
</div>
<div class="page">
<div class="page-laxwrap">
<div class="page-lax">
</div>
</div>
<div class="page-scrollport">
<div class="page-scrollbox">
<div class="content">page 2</div>
</div>
</div>
</div>
<div class="page">
<div class="page-laxwrap">
<div class="page-lax">
</div>
</div>
<div class="page-scrollport">
<div class="page-scrollbox">
<div class="content">page 3</div>
</div>
</div>
</div>
<div class="page">
<div class="page-laxwrap">
<div class="page-lax">
</div>
</div>
<div class="page-scrollport">
<div class="page-scrollbox">
<div class="content">page 4</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
@import url('https://necolas.github.io/normalize.css/7.0.0/normalize.css');
:root {
--viewportHeight: 100vh;
--pageHeight: var(--viewportHeight);
--pageWidth: 100vw;
/* flex row isn't causing the layout so need to hard set based upon page amount */
--pageAmount: 4;
/* 0 - infinite */
/* 0 = fixed, infinite = scrollMove, 1 = halfScroll */
--mag: 1;
/* this is half gap in use */
--gap: 1rem;
}
*,
*::before,
*::after {
box-sizing: inherit;
flex-shrink: 0;
flex-shrink: 0;
}
html {
box-sizing: border-box;
}
html,
body {
overflow: hidden;
overscroll-behavior: none;
font-weight: bold;
}
.pager {
--bottomScrollOffset: 50px;
position: fixed;
z-index: 1;
top: 0;
left: calc(-1 * var(--pageWidth));
right: calc(-1 * var(--pageWidth));
height: calc(var(--pageHeight) + var(--bottomScrollOffset));
overflow-x: scroll;
overflow-y: hidden;
overscroll-behavior: contain;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
overflow-scrolling: touch;
}
.pages {
height: var(--pageHeight);
position: relative;
display: flex;
align-items: stretch;
justify-content: start;
/* force start for chrome */
scroll-snap-align: start;
padding-left: var(--pageWidth);
}
.page {
height: var(--pageHeight);
width: var(--pageWidth);
position: relative;
z-index: 1;
scroll-snap-align: start;
scroll-snap-stop: always;
clip-path:
polygon(
0% 0%,
100% 0%,
100% 100%,
0% 100%);
clip-path: inset(0);
clip-path: padding-box;
border-radius: calc(2 * var(--gap));
border: var(--gap) solid transparent;
}
.page-laxwrap {
pointer-events: none;
visibility: hidden;
position: absolute;
z-index: 1;
top: calc(-1 * var(--gap));
left: calc(-1 * (var(--pageWidth) + var(--gap)));
width: calc(3 * var(--pageWidth));
height: var(--pageHeight);
perspective: 1px;
}
.page:last-child .page-laxwrap {
margin-right: calc(-3 * var(--pageWidth));
}
.page-lax {
visibility: visible;
width: calc(1 * var(--pageWidth));
height: var(--pageHeight);
position: sticky;
left: calc(1 * var(--pageWidth));
transform-origin: center center;
transform: translateZ(-4px) scale(5);
transform: translateZ(-.5px) scale(1.5);
transform: translateZ(-1px) scale(2);
transform: translateZ(-.25px) scale(1.25);
transform: translateZ(calc(var(--mag) * -1px)) scale(calc(var(--mag) + 1));
background-size: cover;
background-position: center;
}
.page:nth-of-type(1) .page-lax { background-image: url('//placekitten.com/992/1208'); }
.page:nth-of-type(2) .page-lax { background-image: url('//placekitten.com/901/1202'); }
.page:nth-of-type(3) .page-lax { background-image: url('//placekitten.com/952/1201'); }
.page:nth-of-type(4) .page-lax { background-image: url('//placekitten.com/802/1302'); }
.pages {
width: calc(var(--pageWidth) * (1 + var(--pageAmount)));
}
.page-scrollport {
position: absolute;
z-index: 2;
top: 0;
left: 0;
height: 100%;
width: 100%;
overflow-y: scroll;
overflow-x: hidden;
overscroll-behavior: auto contain;
overflow-scrolling: touch;
color: #fff;
}
.page-scrollbox {
min-height: calc(var(--pageHeight) * 1.2);
-border: .5rem solid rgba(255,0,0,.325);
}
.content {
/* skin */
height: var(--pageHeight);
display: flex;
flex-flow: column;
align-items: center;
justify-content: center;
}
/* DEMO STUFFS */
.demo:nth-of-type(1):checked ~ .pager { --mag: .125; }
.demo:nth-of-type(2):checked ~ .pager { --mag: .5; }
.demo:nth-of-type(3):checked ~ .pager { --mag: 1; }
.demo:nth-of-type(4):checked ~ .pager { --mag: 3; }
.demo:nth-of-type(5):checked ~ .pager { --mag: 7; }
/*2 = 2/3 */
/*3 = 3/4 */
/*4 = 4/5 */
.label,
.demo {
position: fixed;
top: 2rem;
left: 2rem;
z-index: 2;
color: #fff;
}
.label { left: 3.5rem;}
.demo:nth-of-type(2),.label:nth-of-type(2) {top: 3.5rem; }
.demo:nth-of-type(3),.label:nth-of-type(3) {top: 5rem; }
.demo:nth-of-type(4),.label:nth-of-type(4) {top: 6.5rem; }
.demo:nth-of-type(5),.label:nth-of-type(5) {top: 8rem; }
function setHeight() {
var HTML = document.documentElement;
var heightEl = document.createElement('div');
heightEl.style.visibility = 'hidden';
heightEl.style.position = 'absolute';
heightEl.style.height = '100vh';
HTML.appendChild(heightEl);
var heightElHeight = window.getComputedStyle(heightEl).height;
var ratioHeight = window.innerHeight / parseInt(heightElHeight,10);
if (ratioHeight !== 1) {
var newHeight = (ratioHeight * 100) + 'vh';
HTML.style.setProperty('--viewportHeight', newHeight);
}
HTML.removeChild(heightEl);
}
document.addEventListener('DOMContentLoaded', function() {
setHeight();
// cause re-layout of pages to analyze scroll end boundary correctly, because transform makes it think its bigger than it is :(
var pages = document.querySelector('.pages .page:last-child');
pages.style.width = '0px';
setTimeout(function(){
pages.style.width = '';
},100);
});
window.addEventListener("orientationchange", function() {
setHeight();
});
Output
300px
You can jump to the latest bin by adding /latest
to your URL
Keyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |