%main#main
.before
.after
%ul#one
%li.one
.container
.notification
%span.before
%span.after
%header
%h2 Messages
%span.timestamp Now
.content
%span.sender Gabrielle Wee
%span.message Check it out! ✨
%span.more 2 more messages from Gabrielle
%li.two
.container
.notification
%span.before
%span.after
%li.three
.container
.notification
%span.before
%span.after
%ul#two
%li.one
.container
.notification
%span.before
%span.after
%header
%h2 Calendar
%span.timestamp 1h ago
.content
%span.event WWDC 2018
%span.date June 4, 2018 at 10:00 AM
%span.more 2 more invitations
%li.two
.container
.notification
%span.before
%span.after
%li.three
.container
.notification
%span.before
%span.after
%ul#three
%li.one
.container
.notification
%span.before
%span.after
%header
%h2 Twitter
%span.timestamp 2h ago
.content
%span.user Gabrielle Wee
%span.message Dark Mode for iOS would be so cool!
%span.more 2 more notifications
%li.two
.container
.notification
%span.before
%span.after
%li.three
.container
.notification
%span.before
%span.after
View Compiled
$p: 16px;
*, *:before, *:after { box-sizing: border-box; }
::selection { background: none; }
body, html { height: 100vh; }
body {
display: flex;
justify-content: center;
background: #151F33;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
"Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans",
"Droid Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: $p;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
}
@media screen and (min-height: 480px) {
body {
align-items: center;
align-content: center;
}
}
.before, .after {
will-change: opacity;
display: block;
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
}
.before {
z-index: -1;
background: #151F33 url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/345377/mojave-night.jpg') no-repeat center center / cover;
}
.after {
z-index: -2;
background: #B27247 url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/345377/mojave-day.jpg') no-repeat center center / cover;
}
main {
opacity: 0;
will-change: opacity;
width: 100%;
max-width: 400px;
padding: $p/2;
.before, .after {
position: fixed;
}
}
ul {
opacity: 0;
will-change: opacity, transform;
perspective: 800px;
margin-bottom: $p;
li {
position: relative;
padding: $p/2;
&:not(:first-child) {
position: absolute;
width: 100%;
top: 0;
left: 0;
.notification {
.before, .after {
filter: blur($p);
}
}
}
&:nth-child(1) {
z-index: 3;
.notification {
background-color: rgba(white, 0.7);
.before, .after {
filter: saturate(130%) blur($p);
}
}
}
&:nth-child(2) {
transform: translateY($p) translateZ(#{-$p*4});
z-index: 2;
.notification {
background-color: rgba(white, 0.6);
}
}
&:nth-child(3) {
transform: translateY(#{$p*2}) translateZ(#{-$p*8});
z-index: 1;
.notification {
background-color: rgba(white, 0.5);
}
}
}
}
.container {
clip-path: inset(0 0 0 0 round $p $p $p $p);
}
.notification {
position: relative;
overflow: hidden;
height: 116px;
padding: $p;
border-radius: $p;
background-color: rgba(white, 0.9);
color: black;
header, .more {
opacity: 0.75;
}
header {
display: flex;
justify-content: space-between;
padding-bottom: $p*.5;
font-size: $p*.75;
h2 {
text-transform: uppercase;
}
.timestamp {
text-transform: lowercase;
}
}
.content {
span {
display: block;
line-height: 1.4;
}
.message {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.sender, .event {
font-weight: 600;
}
.more {
margin-top: $p*.25;
font-size: $p*.75;
}
}
.before, .after {
left: calc(50% - 50vw);
}
}
View Compiled
const main = document.querySelector("#main");
const elems = document.querySelectorAll(".notification");
const getTop = el => {
const before = el.querySelector(".before");
const after = el.querySelector(".after");
let viewportOffset = el.getBoundingClientRect();
let elemTop = viewportOffset.top;
before.style.top = "-" + elemTop + "px";
after.style.top = "-" + elemTop + "px";
}
const lightToDark = () => {
const tl = new TimelineMax();
const groups = ["#one", "#two", "#three"];
tl
.set(".before", {opacity:0})
.set(groups, {opacity:0,y:60})
.to(main, 0.5, {opacity:1})
.staggerTo(groups, 0.5, {opacity:1,ease:Power3.easeOut}, 0.2)
.staggerTo(groups, 1, {y:0,ease:Power3.easeOut}, 0.2, '-=1')
.to(".before", 2, {opacity:1})
.to(".after", 2, {opacity:0}, '-=1')
.to(".notification", 0.25, {color:"#1b1e29"}, '-=3')
.to(".notification", 1.75, {color:"white"}, '-=2.75')
.to(".one .notification", 1, {backgroundColor:"rgba(17,19,26,0.6)"}, '-=3')
.to(".one .notification", 1, {backgroundColor:"rgba(0,0,0,0.5)"}, '-=2.5')
.to(".two .notification", 1, {backgroundColor:"rgba(17,19,26,0.5)"}, '-=3')
.to(".two .notification", 1, {backgroundColor:"rgba(0,0,0,0.4)"}, '-=2.5')
.to(".three .notification", 1, {backgroundColor:"rgba(17,19,26,0.4)"}, '-=3')
.to(".three .notification", 1, {backgroundColor:"rgba(0,0,0,0.3)"}, '-=2.5')
;
}
imagesLoaded(main, {background:true}, () => {
elems.forEach(el => {
getTop(el);
window.addEventListener("resize", function() {
setTimeout(() => {
getTop(el);
}, 250);
});
});
window.requestAnimationFrame(lightToDark);
});
This Pen doesn't use any external CSS resources.