Skip to content

Instantly share code, notes, and snippets.

@bebetor
Created February 26, 2022 08:40
Show Gist options
  • Save bebetor/bec7e9cc2a6ef1bbb6120025c68396d1 to your computer and use it in GitHub Desktop.
Save bebetor/bec7e9cc2a6ef1bbb6120025c68396d1 to your computer and use it in GitHub Desktop.
Scroll Snap Experiment
main
section.pane
h1 Adventure Awaits
ul.carousel
button.theme-toggle
| Toggle Theme
const images = [
"https://source.unsplash.com/oaEpgHCgTT8",
"https://source.unsplash.com/9v_xYRu_laY",
"https://source.unsplash.com/qrPqGP-SG8w",
"https://source.unsplash.com/zshyCr6HGw0",
"https://source.unsplash.com/-g7axSVst6Y",
"https://source.unsplash.com/fTKkJL5Xjw8",
"https://source.unsplash.com/sPXGnvwOjdU"
];
const carousel = document.querySelector('.carousel');
const carouselItems = document.createDocumentFragment();
images.forEach((item, index) => {
// Set up elements (tags)
const listItem = document.createElement('li');
const figure = document.createElement("figure");
const link = document.createElement("a");
const image = document.createElement("img");
// Set up element attributes
listItem.classList.add('carousel-item');
link.href = images[index];
link.target = '_blank';
image.src = `${images[index]}/600x600`;
image.loading = 'lazy';
image.alt = ""; // Note: for production, we'd want to set actual per-image alt text
// Put the list items together in the <ul>
figure.appendChild(image);
link.appendChild(figure);
listItem.appendChild(link);
carouselItems.appendChild(listItem);
});
carousel.appendChild(carouselItems);
// Light and dark mode
const getTheme = () => {
return localStorage.getItem('theme') || 'dark';
}
const colorScheme = document.querySelector('meta[name="color-scheme"]');
const applyTheme = (theme) => {
document.body.className = theme;
colorScheme.content = theme;
localStorage.setItem('theme', theme);
}
const themeToggleButton = document.querySelector('.theme-toggle');
let theme = getTheme();
applyTheme(theme);
themeToggleButton.addEventListener('click', () => {
const newTheme = theme === 'light' ? 'dark' : 'light';
applyTheme(newTheme);
theme = newTheme;
})

Scroll Snap Experiment

Experiment using CSS scroll snapping in a carousel, along with a light/dark mode toggle.

A Pen by bebetor on CodePen.

License.

:root {
--gap: 10px;
--carousel-count: 4;
--black: #1e1d26;
--white: #f7f7f7;
--light-blue: #b6b9bf;
--blue: #334668;
--dark-blue: #262733;
--light-gray: #eaeaea;
--background-image: url('https://source.unsplash.com/g30P1zcOzXo');
--gradient: linear-gradient(rgba(253, 253, 255, 0.52), rgba(0, 0, 0, 0.55));
--button-background: var(--light-gray);
color-scheme: dark light; // prefer dark mode
}
html,
body {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
/* Scrollbar styles - https://www.digitalocean.com/community/tutorials/css-scrollbars */
/* Works on Firefox */
* {
scrollbar-width: thin;
}
/* Works on Chrome, Edge, and Safari */
*::-webkit-scrollbar {
height: 8px;
}
*::-webkit-scrollbar-track {
background-color: lightgray;
border-radius: 6px;
@media (prefers-color-scheme: dark) {
background-color: #a2a2a2;
}
}
*::-webkit-scrollbar-thumb {
background-color: gray;
border-radius: 6px;
@media (prefers-color-scheme: dark) {
background-color: #6a6a6a;
}
}
body {
font-family: 'Yeseva One', serif;
width: 100%;
min-height: 100vh;
&.light {
--text: var(--blue);
--background: var(--white);
--carousel-background: var(--light-gray);
}
&.dark {
--text: var(--light-blue);
--background: var(--black);
--carousel-background: var(--dark-blue);
--gradient: linear-gradient(rgba(148, 155, 193, 0.52), rgba(11, 18, 38, 0.55));
}
color: var(--text);
background-color: var(--background);
background-image: var(--gradient), var(--background-image);
background-size: cover;
background-repeat: no-repeat;
@media (min-width: 800px) {
--gap: 20px;
}
}
h1 {
font-size: 1.3rem;
margin: 0 0 2rem;
@media (min-width: 800px) {
font-size: 2.5rem;
}
}
img {
max-width: 100%;
height: auto;
}
main {
max-width: 90vw;
margin: 3rem auto;
display: flex;
flex-direction: column;
gap: 40px;
@media (min-width: 800px) {
margin: 4rem auto;
max-width: 80vw;
}
@media (min-width: 1200px) {
max-width: calc(1000px + ((var(--carousel-count) - 1) * var(--gap)));
max-width: 800px;
}
}
.pane {
background-color: var(--carousel-background);
border-radius: 3px;
box-shadow: 0px 2px 20px rgba(0, 0, 0, 0.36);
padding: 3rem;
mix-blend-mode: hard-light;
}
.carousel {
overflow-x: auto;
overflow-y: hidden;
overscroll-behavior-x: contain;
-webkit-overflow-scrolling: touch; // For iOS
scroll-behavior: smooth;
list-style-type: none;
display: grid;
grid-auto-columns: 300px;
grid-template-rows: 300px;
grid-auto-flow: column;
gap: var(--gap);
margin: 0;
scroll-snap-type: x mandatory;
scroll-padding: 12px;
padding: 0 12px 20px;
}
.carousel-item {
scroll-snap-align: start;
margin: 8px 0;
a {
display: inline-block;
outline-offset: 6px;
&:focus,
&:focus-visible {
outline: 2px dashed gray;
}
&:focus:not(:focus-visible) {
outline: 0;
}
}
figure {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
img {
display: block;
width: 100%;
height: 100%;
opacity: 0.8;
object-fit: cover;
background-image:
linear-gradient(
to bottom,
hsl(0 0% 10%),
hsl(0 0% 20%)
);
border-radius: 5px;
transition: opacity 0.3s ease-in, transform 0.4s ease-in;
&:hover {
opacity: 1;
transform: scale(1.1);
}
}
}
.theme-toggle {
font-family: "Oswald";
text-transform: uppercase;
color: var(--dark-blue);
background-color: var(--button-background);
border: 2px solid transparent;
padding: 8px 12px;
border-radius: 3px;
transition: all 0.3s ease;
max-width: 150px;
margin-left: auto;
&:hover {
background-color: #c1c1c1;
border: 2px solid #c1c1c1;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment