<svg aria-hidden="true" style="position: absolute; width: 0; height: 0; overflow: hidden;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<symbol id="icon-cross" viewBox="0 0 32 32">
<title>close</title>
<path d="M31.7 25.7L22 16l9.7-9.7a1 1 0 0 0 0-1.4L27.1.3a1 1 0 0 0-1.4 0L16 10 6.3.3a1 1 0 0 0-1.4 0L.3 4.9a1 1 0 0 0 0 1.4L10 16 .3 25.7a1 1 0 0 0 0 1.4l4.6 4.6a1 1 0 0 0 1.4 0L16 22l9.7 9.7a1 1 0 0 0 1.4 0l4.6-4.6a1 1 0 0 0 0-1.4z"/>
</symbol>
</defs>
</svg>
<div class="page" data-modal-state="closed">
<div class="container">
<div class="card-slider">
<div class="card-wrapper"><article class="card">
<picture class="card__background">
<img src="https://source.unsplash.com/random">
</picture>
<div class="card__category">
consulta
</div>
<h3 class="card__title">Asesoría Angelical</h3>
<div class="card__duration">
Duración: 3 horas
</div>
</article></div>
<div class="card-wrapper"><article class="card">
<picture class="card__background">
<img src="https://source.unsplash.com/random">
</picture>
<div class="card__category">
consulta
</div>
<h3 class="card__title">Asesoría Angelical</h3>
<div class="card__duration">
Duración: 3 horas
</div>
</article></div>
<div class="card-wrapper"><article class="card">
<picture class="card__background">
<img src="https://source.unsplash.com/random">
</picture>
<div class="card__category">
consulta
</div>
<h3 class="card__title">Asesoría Angelical</h3>
<div class="card__duration">
Duración: 3 horas
</div>
</article></div>
<div class="card-wrapper"><article class="card">
<picture class="card__background">
<img src="https://source.unsplash.com/random">
</picture>
<div class="card__category">
consulta
</div>
<h3 class="card__title">Asesoría Angelical</h3>
<div class="card__duration">
Duración: 3 horas
</div>
</article></div>
<div class="card-wrapper"><article class="card">
<picture class="card__background">
<img src="https://source.unsplash.com/random">
</picture>
<div class="card__category">
consulta
</div>
<h3 class="card__title">Asesoría Angelical</h3>
<div class="card__duration">
Duración: 3 horas
</div>
</article></div>
</div>
</div>
<div class="overlay"></div>
<div class="modal-wrapper">
<div class="modal">
<button class="modal__close-button" type="button">
<svg class="icon icon-cross"><use xlink:href="#icon-cross"></use></svg>
</button>
<div class="modal__scroll-area">
<header class="modal__header">
<div class="card__background">
<img src="https://source.unsplash.com/random">
</div>
<div class="card__category">
consulta
</div>
<h1 class="card__title">Asesoría Angelical</h1>
<div class="card__duration">
Duración: 3 horas
</div>
</header>
<main class="modal__content">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Possimus quo sint debitis? Dolorem est at voluptatum obcaecati tempore eaque perferendis. Totam at consectetur commodi porro atque eligendi rerum vero nam?</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Possimus quo sint debitis? Dolorem est at voluptatum obcaecati tempore eaque perferendis. Totam at consectetur commodi porro atque eligendi rerum vero nam?</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Possimus quo sint debitis? Dolorem est at voluptatum obcaecati tempore eaque perferendis. Totam at consectetur commodi porro atque eligendi rerum vero nam?</p>
</main>
</div>
</div>
</div>
</div>
@import url('https://fonts.googleapis.com/css?family=Poppins');
$background-color: #2fd4dc;
$card__border-radius: 20px;
$card__modal-max-width: 500px;
$card__modal-height: 90vh;
$card__modal-header-height: 300px;
html, body {
font-family: 'Poppins', sans-serif;
}
*, *::before, *::after {
box-sizing: border-box;
}
.no-scroll {
overflow: hidden;
}
.container {
background: pink;
padding: 2em;
min-height: 100vh;
display: flex;
}
.icon {
display: inline-block;
width: 1em;
height: 1em;
stroke-width: 0;
stroke: currentColor;
fill: currentColor;
}
.blend-image {
filter: brightness(250%) grayscale(100%);
mix-blend-mode: screen;
}
.center-image {
width: 100%;
min-height: 100%;
position: absolute;
top: 50%;
transform: translateY(-50%);
object-fit: cover;
}
.slick-slide {
padding: 2em .5em;
}
.card-slider {
margin: auto;
width: 100%;
}
.card {
background: #fff;
display: flex;
padding: 2em;
flex-direction: column;
align-items: flex-start;
justify-content: flex-end;
border-radius: $card__border-radius;
overflow: hidden;
position: relative;
z-index: 1;
height: 350px;
box-shadow: 0 30px 50px -25px rgba(0,0,0,0.25);
> * {
transition: opacity 350ms;
}
&--opened > *{
opacity: 0;
}
}
.card__background {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
overflow: hidden;
background: $background-color;
z-index: -1;
text-align: left;
img {
@extend .center-image;
@extend .blend-image;
}
&::after {
content:'';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: linear-gradient(to top, #fff 0, rgba(255,255,255,0) 70%);
}
}
.card__category {
text-transform: uppercase;
color: #fff;
background: $background-color;
font-size: 0.85em;
font-weight: 600;
padding: 0.2em 0.5em 0.25em;
}
.card__title {
text-transform: uppercase;
margin: 0.5em 0;
color: #2e5f80;
}
.card__duration {
color: #6f7070;
}
.modal-wrapper, .overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
.modal-wrapper {
display: flex;
}
.overlay {
background: rgba(0,0,0,0.5);
transition: opacity 150ms ease;
}
.modal {
overflow: hidden;
position: relative;
margin: auto;
width: 90vw;
height: $card__modal-height;
max-width: $card__modal-max-width;
background: #fff;
border-radius: $card__border-radius;
}
.modal__scroll-area {
height: inherit;
overflow: auto;
border-radius: inherit;
position: relative;
z-index: 1;
}
.modal__close-button {
background: transparent;
border: none;
margin-bottom: auto;
color: #2e5f80;
position: absolute;
top: 0;
right: 0;
padding: 2em;
z-index: 2;
}
.modal__header {
text-align: center;
position: relative;
display: flex;
padding: .5em;
flex-direction: column;
justify-content: flex-end;
align-items: center;
min-height: $card__modal-header-height;
z-index: 1;
}
.modal__content {
padding: 2em;
color: #666;
line-height: 1.5;
}
[data-modal-state="closed"] {
.modal-wrapper {
pointer-events: none;
}
.overlay {
pointer-events: none;
}
.modal {
opacity: 0;
}
.overlay {
opacity: 0;
}
}
[data-modal-state="opening"],[data-modal-state="closing"]{
.modal__header, .modal__content, .modal__close-button {
opacity: 0;
}
}
[data-modal-state="opening"]{
.overlay {
transition: opacity 500ms ease;
}
}
[data-modal-state="closing"]{
.overlay {
opacity: 0;
transition: opacity 500ms ease;
}
}
[data-modal-state="open"] {
.modal__header, .modal__content {
transition: opacity 450ms;
}
}
View Compiled
jQuery('.card-slider').slick({
slidesToShow:3,
autoplay: true,
slidesToScroll:1,
dots: false,
responsive:[
{
breakpoint: 768,
settings: {
slidesToShow: 2
}
},
{
breakpoint: 600,
settings: {
slidesToShow: 1
}
}
]
});
let cards = document.querySelectorAll('.card');
let card;
let modal = document.querySelector('.modal');
let closeButton = document.querySelector('.modal__close-button');
let page = document.querySelector('.page');
const cardBorderRadius = 20;
const openingDuration = 600; //ms
const closingDuration = 600; //ms
const timingFunction = 'cubic-bezier(.76,.01,.65,1.38)';
var Scrollbar = window.Scrollbar;
Scrollbar.init(document.querySelector('.modal__scroll-area'));
function flipAnimation(first, last, options) {
let firstRect = first.getBoundingClientRect();
let lastRect = last.getBoundingClientRect();
let deltas = {
top: firstRect.top - lastRect.top,
left: firstRect.left - lastRect.left,
width: firstRect.width / lastRect.width,
height: firstRect.height / lastRect.height
};
return last.animate([{
transformOrigin: 'top left',
borderRadius:`
${cardBorderRadius/deltas.width}px / ${cardBorderRadius/deltas.height}px`,
transform: `
translate(${deltas.left}px, ${deltas.top}px)
scale(${deltas.width}, ${deltas.height})
`
},{
transformOrigin: 'top left',
transform: 'none',
borderRadius: `${cardBorderRadius}px`
}],options);
}
cards.forEach((item)=>{
item.addEventListener('click',(e)=>{
jQuery('.card-slider').slick('slickPause');
card = e.currentTarget;
page.dataset.modalState = 'opening';
card.classList.add('card--opened');
card.style.opacity = 0;
document.querySelector('body').classList.add('no-scroll');
let animation = flipAnimation(card,modal,{
duration: openingDuration,
easing: timingFunction,
fill:'both'
});
animation.onfinish = ()=>{
page.dataset.modalState = 'open';
animation.cancel();
};
});
});
closeButton.addEventListener('click',(e)=>{
page.dataset.modalState = 'closing';
document.querySelector('body').classList.remove('no-scroll');
let animation = flipAnimation(card,modal,{
duration: closingDuration,
easing: timingFunction,
direction: 'reverse',
fill:'both'
});
animation.onfinish = ()=>{
page.dataset.modalState = 'closed';
card.style.opacity = 1;
card.classList.remove('card--opened');
jQuery('.card-slider').slick('slickPlay');
animation.cancel();
};
});