Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Sphinxxxx/5573d79794ed524740ef2de9dffb0b4b to your computer and use it in GitHub Desktop.
Save Sphinxxxx/5573d79794ed524740ef2de9dffb0b4b to your computer and use it in GitHub Desktop.
#CodePenChallenge Grid Based Carousel
.carousel(data-carousel-loop)
nav.nav
a.prev Prev
a.next Next
dl.slides
div
dt #[del Grid Based] #[ins Flexbox] Carousel
dd How to? Here's the gist.
dd.code P.S. Feel free to tap around
div
dt For starters
dd Create a grid out of a wrapping container.
dd.code display: grid;
div
dt Moving on
dd Detail a single column which spans to cover the entirety of the container.
dd.code grid-template-columns: 100%;
div
dt Plot twist!
dd Specify how additional grid items should be added in new columns instead of new rows.
dd.code grid-auto-flow: column;
div
dt Almost there
dd Detail the width of the implicit columns to match the width of the only explicit column.
dd.code grid-auto-columns: 100%;
div
dt Finishing up
dd Hide horizontal overflow on the wrapping container.
dd.code overflow-x: hidden;
div
dt And that is all
dd Okay, there is plenty more behind this pen... The entire project is based on the mentioned grid properties though.
dd
(function() {
function $(selector, context) {
return (context || document).querySelector(selector);
}
function $$(selector, context) {
return [].slice.call( (context || document).querySelectorAll(selector) );
}
function addEvent(target, type, handler) {
target.addEventListener(type, handler, false);
}
function initCarousel(caro) {
const slides = $('.slides', caro),
prev = $('.prev', caro),
next = $('.next', caro),
loop = caro.hasAttribute('data-carousel-loop');
let current = 0;
addEvent(prev, 'click', handleButton);
addEvent(next, 'click', handleButton);
function handleButton(e) {
// prevent bubbling up of the click event
// otherwise the click will be heard by the card as well and trigger a second handleUpdate()
e.stopPropagation();
// handle the update based on current slide and direction
handleUpdate(e.currentTarget === next);
}
addEvent(caro, 'click', handleCard);
function handleCard(e) {
// similar to handleButton(), but check whether the click is heard on the left/right half of the slide
const bounds = caro.getBoundingClientRect(),
rightSide = (e.clientX > (bounds.left + bounds.width/2));
handleUpdate(rightSide);
}
function handleUpdate(goNext) {
const slidesCount = slides.childElementCount;
current += goNext ? 1 : -1;
if(loop) {
current = current % slidesCount;
while(current < 0) { current += slidesCount; }
}
else {
current = Math.max(0, Math.min(current, slidesCount-1));
}
//console.log(current);
slides.style.transform = `translateX(${current * -100}%)`;
}
}
$$('.carousel').forEach(initCarousel);
})();
@import url('https://fonts.googleapis.com/css?family=Fira+Mono|Montserrat');
/* Default carousel style */
.carousel {
position: relative;
width: 40em;
height: 25em;
max-width: 80%;
max-height: 80vh;
background: white;
box-shadow: 0 0 4px 0 gray;
//Hide horizontal overflow, effectively hiding all columns except one
overflow-x: hidden;
/* Essential properties for the carousel */
.slides {
/*
//Position the sections in a grid
display: grid;
height: 100%;
//Include a single column layout, with implicit tracks added horizontally instead of vertically
grid-template-columns: 100%;
//Have the columns, implicit or explcit, spread to cover 100% of the container
grid-auto-flow: column;
grid-auto-columns: 100%;
//*/
//* Works in IE
display: flex;
height: 100%;
flex-flow: row nowrap;
> * {
flex: 0 0 100%;
}
//*/
//We'll use translateX() to flip through the carousel
transition: transform .5s;
}
.nav {
display: flex;
position: absolute;
left:.5em; bottom:.5em;
z-index: 1;
opacity: .5;
transition: opacity .3s;
.prev, .next {
position: relative;
display: inline-block;
height: 2em;
width: 2em;
overflow: hidden;
cursor: pointer;
&::after {
content: '❮';
display: block;
position: absolute;
top:0;left:0;bottom:0;right:0;
background: black;
color: white;
font-size: 2em;
text-align: center;
line-height: 1;
}
}
.next {
margin-left: .25em;
&::after { content: '❯'; }
}
}
&:hover nav {
opacity: 1;
}
}
/* Page-specific styles */
body {
display: flex;
height: 100vh;
margin: 0;
justify-content: center;
align-items: center;
font-family: Montserrat, sans-serif;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"><circle cx="90%" cy="80%" r="15%" fill="%230041F3"/><circle cx="0" cy="0" r="40%" fill="%23EE0034"/></svg>') center/contain no-repeat;
}
dl {
margin: 0;
> div {
display: flex;
flex-flow: column nowrap;
justify-content: space-around;
align-items: center;
font-size: 2em;
}
dt {
font-weight: bold;
text-transform: uppercase;
transform: rotate(-5deg);
}
dd {
margin: 0 1em;
text-align: center;
//IE..
max-width: 100%;
&.code {
padding: .2em .57em;
font-family: monospace;
font-size: .8em;
background: black;
color: gainsboro;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment