<div class="scroll-area">
<div class="box box__bg_photo"><p>aaa</p><p>bbb</p></div>
<div class="box box__bg_gray"><p>aaa</p><p>bbb</p></div>
<div class="box box__bg_black"><p>aaa</p><p>bbb</p></div>
</div>
body {
margin: 0;
padding: 0;
}
.scroll-area {
width: 100%;
height: 100vh;
overflow: auto;
-webkit-scroll-behavior: smooth;
scroll-behavior: smooth;
-webkit-scroll-snap-type: mandatory;
scroll-snap-type: mandatory;
-webkit-scroll-snap-points-y: repeat(100%);
scroll-snap-points-y: repeat(100%);
}
.box {
width: 100%;
height: 100vh;
color: #fff;
font-size: 100px;
display: flex;
align-items: center; /* 縦方向中央揃え */
justify-content: center; /* 横方向中央揃え */
flex-direction: column;
}
.box__bg_black {
background-color: #333;
}
.box__bg_gray {
background-color: #ccc;
}
.box__bg_photo {
background-image: url(https://mae.chab.in/wp-content/uploads/2015/09/QsjPn.jpg);
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
p {
margin: 0;
padding: 0;
line-height: 1;
}
/*! znapscroll: scroll Snap Points Polyfill
* Author: Sergi Meseguer @zigotica
* Version: 0.1.0
*/
var znapscroll = (function(w, d){
// Enable strict mode
'use strict';
/* configure target classes for wrapper and children */
var ZNAP = 'znapscroll';
var GALLERY = 'gallery';
var BOX = 'box';
var H = 'horizontal-gallery';
/* no need to edit past this point */
var isScrollSnapSupported = 'scrollSnapType' in document.documentElement.style ||
'webkitScrollSnapType' in document.documentElement.style ||
!('classList' in document.createElement('_'));
// if browser already supports CSS scroll Snap Points, or it is too old:
var nonPolyfillable = isScrollSnapSupported || !Element.prototype.addEventListener || !window.requestAnimationFrame;
var scrolling = false;
var raf = null;
var timer = null;
var ready = false;
var onready = function( fn ){
document.addEventListener( 'readystatechange', function() {
fn();
ready = true;
}, false);
};
var zcroll = function( obj, Duration, To, Dir, cb ) {
scrolling = true;
timer = new Date();
raf = requestAnimationFrame(step);
var Initial = obj['scroll' + Dir],
Distance = Math.abs( Initial - To ),
StepDistance= Distance / (Duration / 15);
function step () {
var From = obj['scroll' + Dir],
distance = Math.abs( From - To ),
Direction = (To - From > 0) ? 1 : -1,
nextPosition= From + ( Direction * StepDistance );
if ( distance > StepDistance && new Date() - timer < Duration) {
raf = requestAnimationFrame(step);
obj['scroll' + Dir] = nextPosition;
}
else {
obj['scroll' + Dir] = To;
cancelAnimationFrame( raf );
raf = null;
timer = null;
cb();
}
}
};
var handler = function(){
if( scrolling === true ) {
return;
}
var $par = this,
dir = $par.classList.contains(H) ? 'Left' : 'Top',
off = $par.classList.contains(H) ? 'Width' : 'Height';
$par.removeEventListener('scroll', handler, false);
setTimeout(function(){
var From = $par['scroll' + dir],
elmOff = $par['offset' + off],
newPage = Math.round( From / elmOff),
To = newPage * elmOff;
// snap to view, animated
zcroll(
$par,
100,
To,
dir,
function(){
scrolling = false;
$par.addEventListener('scroll', handler, false);
}
);
}, 500);
};
var setup = function( obj ){
var $obj = obj,
$par = obj.parentElement,
dir = $par.classList.contains(H) ? 'Left' : 'Top',
$chi = $obj.getElementsByClassName( BOX ),
num = $chi.length;
$obj.style["overflow"] = "hidden";
if(dir === 'Left') {
$par.style["overflow-x"] = "auto";
$obj.style.width = num * 100 + '%';
for (var i = 0, LEN = $chi.length; i < LEN; i++) {
$chi[i].style.width = 100 / num + '%';
}
}
else {
$par.style["overflow-y"] = "auto";
$obj.style.height = num * 100 + '%';
for (var i = 0, LEN = $chi.length; i < LEN; i++) {
$chi[i].style.height = 100 / num + '%';
}
}
// listen to scroll
$par.addEventListener('scroll', handler, false);
};
var run = function(){
var galleries = d.getElementsByClassName( GALLERY );
for (var i = 0, LEN = galleries.length; i < LEN; i++) {
if( !galleries[i].classList.contains(ZNAP) ) {
galleries[i].classList.add( ZNAP );
setup( galleries[i] );
}
}
};
var prepare = function(){
if(nonPolyfillable) {
return;
}
if( ready === true ) {
run();
}
else {
onready(function() {
run();
});
}
};
var destroy = function( context ){
if(nonPolyfillable) {
return;
}
var elm = ( context )? context : d;
var ZNAPABLE = elm.getElementsByClassName( ZNAP );
for (var LEN = ZNAPABLE.length, i = LEN - 1; i >= 0; i--) {
var o = ZNAPABLE[i],
p = o.parentElement;
// remove class and event listener
p.removeEventListener('scroll', handler, false);
o.classList.remove( ZNAP );
}
};
// explicitly make prepare/destroy public methods
return {
prepare : prepare,
destroy: destroy
};
}(window, window.document));
znapscroll.prepare();
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.