Skip to content

Instantly share code, notes, and snippets.

@chrisbautista
Created April 19, 2022 02:06
Show Gist options
  • Select an option

  • Save chrisbautista/67d4d49b741f1d08dd811337482d238b to your computer and use it in GitHub Desktop.

Select an option

Save chrisbautista/67d4d49b741f1d08dd811337482d238b to your computer and use it in GitHub Desktop.
Mobile - Gallery
<!--
Gallery list challenge
- mobile width
- arrow btns
- pages
- styled slides
TODO:
drag/swipe handling
-->
<div class="gallery-wrapper">
<input type="checkbox" class="mode" checked="true">
<div class="gallery">
<figure>
<img src="https://assets.codepen.io/652/the-lucky-neko-CM7a-XBD4AU-unsplash.jpg" alt="a white kitten with brown and black spots sitting with its paws slightly outstretched. " title="Photo by The Lucky Neko for Unsplash">
<figcaption><span data-type="cat">🙀</span> Ollie <div>12 Weeks</div>
</figcaption>
</figure>
<figure>
<img src="https://assets.codepen.io/652/karsten-winegeart-NE0XGVKTmcA-unsplash.jpg" alt="a brown French bulldog puppy laying down and looking up with a hopeful look in its eyes. " title="Photo by Karsten Winegeart for Unsplash">
<figcaption><span data-type="dog">🐶</span> Barney <div>9 Weeks</div>
</figcaption>
</figure>
<figure>
<img src="https://assets.codepen.io/652/kabo-NjWZ07sPEJE-unsplash.jpg" alt="A large long-haired orange cat with a white belly. " title="Photo by Kabo for Unsplash">
<figcaption><span data-type="cat">🙀</span> Walter <div>5 Years</div>
</figcaption>
</figure>
<figure>
<img src="https://assets.codepen.io/652/giacomo-lucarini-7M0SG3ZKdlE-unsplash.jpg" alt="A light brown, long-haired chihuahua sitting next to three rubber duckies. " title="Photo by Giacomo Lucarini for Unsplash">
<figcaption><span data-type="dog">🐶</span> Miss Sunshine <div>2 Years</div>
</figcaption>
</figure>
<figure>
<img src="https://assets.codepen.io/652/sergey-semin-Y0WXj3xqJz0-unsplash.jpg" alt="A tabby kitten with green eyes. " title="Photo by Sergey Semin for Unsplash">
<figcaption><span data-type="cat">🙀</span> Reese <div>8 Weeks</div>
</figcaption>
</figure>
<figure>
<img src="https://assets.codepen.io/652/jordan-bigelow-X5VoG4MA5aI-unsplash.jpg" alt="A light brown puppy standing on a white and tan woven pet bed. " title="Photo by Sergey Semin for Unsplash">
<figcaption><span data-type="dog">🐶</span> Bruce <div>10 Weeks<div>
</figcaption>
</figure>
</div>
<div class="arrows">
<button name="left-btn" class="arrow-left">
<span class="icon material-icons-outlined">
arrow_back
</span>
<span class="visuallyhidden">Left</span>
</button>
<button name="right-btn" class="arrow-right"><span class="icon material-icons-outlined">
arrow_forward
</span>
<span class="visuallyhidden">Right</span>
</button>
</div>
<div class="pages">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span class="follow"></span>
</div>
<button class="home">
<span class="icon-home material-icons-outlined">home</span>
</button>
</div>
let index = 0;
const gallery = document.querySelector(".gallery");
const follow = document.querySelector(".follow");
const pages = document.querySelectorAll(".pages span:not(.follow)");
const slides = document.querySelectorAll("figure");
const numSlides = slides.length;
const offset = 360;
const arrowLeft = document.querySelector(".arrow-left");
const arrowRight = document.querySelector(".arrow-right");
const mode = document.querySelector(".mode");
const home = document.querySelector(".home");
function init() {
home.addEventListener("click", (e) => {
e.preventDefault();
e.stopPropagation();
index = 0;
mode.checked = true;
jumpToPage(index);
});
arrowLeft.addEventListener("click", (e) => {
prevPage();
});
arrowRight.addEventListener("click", (e) => {
nextPage();
});
pages.forEach((node, i) => {
node.addEventListener("click", (e) => {
jumpToPage(i);
});
});
slides.forEach((node, i) => {
node.querySelector("img").addEventListener("click", (e) => {
e.preventDefault();
e.stopPropagation();
if (!mode.checked) {
return;
}
mode.checked = false;
jumpToPage(i);
});
});
renderButtons();
}
function jumpToPage(ii) {
index = ii;
gallery.style.left = `${offset * (ii * -1)}px`;
restartAnimation(follow);
pages.forEach((node) => node.classList.remove("active"));
pages[ii].classList.add("active");
renderButtons();
}
function nextPage() {
if (index >= numSlides - 1) {
index = numSlides - 1;
return;
}
index++;
gallery.style.left = `${offset * (index * -1)}px`;
restartAnimation(follow);
pages.forEach((node) => node.classList.remove("active"));
pages[index].classList.add("active");
renderButtons();
}
function prevPage() {
if (index <= 0) {
index = 0;
return;
}
index--;
restartAnimation(follow);
gallery.style.left = `${offset * (index * -1)}px`;
pages.forEach((node) => node.classList.remove("active"));
pages[index].classList.add("active");
renderButtons();
}
function restartAnimation(el) {
el.style.animation = "none";
el.offsetHeight; /* trigger reflow */
el.style.animation = null;
}
function renderButtons() {
if (index <= 0) {
arrowLeft.classList.add("disabled");
} else {
arrowLeft.classList.remove("disabled");
}
if (index >= numSlides - 1) {
arrowRight.classList.add("disabled");
} else {
arrowRight.classList.remove("disabled");
}
}
init();
@import url("https://fonts.googleapis.com/css?family=Merriweather:400,400i,700");
@import url("https://fonts.googleapis.com/icon?family=Material+Icons");
@import url("https://fonts.googleapis.com/icon?family=Material+Icons+Outlined");
body {
font-family: Merriweather, serif;
background: radial-gradient(#545454, #141414);
}
.visuallyhidden {
position: fixed;
top: -9999px;
left: -9999px;
display: none;
z-index: 9999;
}
div,
figure,
img,
figcaption {
box-sizing: border-box;
}
.main {
content: " ";
box-shadow: inset 0 0 2000px rgba(255, 255, 255, 0.5);
filter: blur(10px);
width: 360px;
height: 650px;
background: rgba(255, 255, 255, 0.2);
border-radius: 16px;
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(5px);
-webkit-backdrop-filter: blur(5px);
border: 1px solid rgba(255, 255, 255, 0.3);
}
.gallery-wrapper {
width: 360px;
height: 650px;
margin: 4rem auto 0;
//background-color: blue;
overflow: hidden;
border-radius: 2rem;
position: relative;
border: 18px solid rgba(255, 255, 255, 0.2);
outline: 1px solid #999;
}
.gallery {
width: auto;
height: 650px;
display: inline-flex;
position: absolute;
left: 0;
top: 0;
transition: left 0.3s ease-out, height 0.3s ease-out, width 0.3s ease-out;
}
figure {
width: 360px;
height: 100%;
margin: 0;
transition: width 0.3s ease-out;
img {
width: 100%;
height: auto;
}
figcaption {
background-color: var(--caption-color);
color: var(--caption-fg-color);
height: 40%;
font-size: 2.5rem;
letter-spacing: 1px;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
padding: 3.5rem 4.3rem 0 4.3rem;
transform: translateY(-5px);
word-break: break-word;
flex-direction: column;
span {
content: "🙀";
display: inline-flex;
width: 50px;
height: 40px;
transform: scale(0.5);
margin-left: -17px;
}
div {
width: 100%;
font-size: 1rem;
margin-left: 2px;
}
}
}
.arrows {
position: absolute;
width: 100%;
top: 375px;
left: 0;
display: flex;
justify-content: space-between;
button {
width: 40px;
height: 40px;
border: 0;
border-radius: 50%;
margin: 0 0.6rem;
background-color: transparent;
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8));
display: flex;
justify-content: center;
align-items: center;
&.disabled {
visibility: hidden;
pointer-events: none;
}
&:hover {
cursor: pointer;
& > .icon {
cursor: pointer;
}
}
.icon {
cursor: pointer;
font-size: 2.5rem;
color: rgba(204, 204, 204, 0.9);
}
}
}
.pages {
position: absolute;
width: 100%;
top: 351px;
left: 0;
display: flex;
justify-content: center;
padding: 0 5rem;
position: relative;
span {
width: 15px;
height: 15px;
background-color: #ccc;
border-radius: 50%;
margin: 0 5px;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2);
cursor: pointer;
&.active ~ .follow {
-webkit-animation: attention 0.3s ease-in-out 2 both;
animation: attention 0.3s ease-in-out 2 both;
}
&.active:nth-child(1) ~ &.follow {
left: 86px;
}
&.active:nth-child(2) ~ .follow {
left: 111px;
}
&.active:nth-child(3) ~ .follow {
left: 136px;
}
&.active:nth-child(4) ~ .follow {
left: 161px;
}
&.active:nth-child(5) ~ .follow {
left: 186px;
}
&.active:nth-child(6) ~ .follow {
left: 211px;
}
}
span.follow {
width: 16px;
height: 16px;
position: absolute;
background-color: #343434;
left: 86px;
transition: left 0.2s ease-in;
box-shadow: none;
}
}
figure {
&:nth-child(1) {
--caption-color: #454241;
--caption-fg-color: #f8f9fb;
text-shadow: 0 0 8px rgba(0, 0, 0, 0.3);
}
&:nth-child(2) {
--caption-color: #503605;
--caption-fg-color: #f8f9fb;
}
&:nth-child(3) {
--caption-color: #562723;
--caption-fg-color: #f8f9fb;
}
&:nth-child(4) {
--caption-color: #2e2a00;
--caption-fg-color: #f8f9fb;
}
&:nth-child(5) {
--caption-color: #544d46;
--caption-fg-color: #f8f9fb;
}
&:nth-child(6) {
--caption-color: #974c07;
--caption-fg-color: #f8f9fb;
}
}
@-webkit-keyframes attention {
0% {
-webkit-transform: scale(1);
transform: scale(1);
}
50% {
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
100% {
-webkit-transform: scale(1);
transform: scale(1);
}
}
@keyframes attention {
0% {
-webkit-transform: scale(1);
transform: scale(1);
}
50% {
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
100% {
-webkit-transform: scale(1);
transform: scale(1);
}
}
.mode {
position: absolute;
top: 0;
visibility: hidden;
}
.mode:checked {
& ~ .gallery {
width: 100%;
height: 100%;
display: flex;
flex-direction: row;
background-color: #f8f9fb;
flex-wrap: wrap;
padding: 36px;
justify-content: center;
figure {
width: 110px;
height: 110px;
margin: 0 8px 16px 8px;
transition: left 0.5s ease-out;
img {
width: 100%;
height: auto;
border-radius: 5px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
}
figcaption {
display: none;
}
}
}
& ~ .arrows {
display: none;
}
& ~ .pages {
display: none;
}
& ~ .home {
display: none;
}
}
.home {
position: absolute;
width: 50px;
height: 50px;
padding: 0;
border: 0;
background: transparent;
display: inline-block;
top: 10px;
left: 10px;
z-index: 40;
color: #464646;
cursor: pointer;
span {
font-size: 2rem;
}
}
<link href="https://fonts.googleapis.com/css?family=Roboto:400,400italic,500,500italic,700,700italic" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment