Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Auto Save

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <main>
	<h1>❤️ CSS Grid Slider w/ Variables</h1>

	<p>With the magic of <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout" target="_blank" rel="noopener">CSS Grid</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Scroll_Snap/Basic_concepts" target="_blank" rel="noopener">CSS Scroll Snap</a>, and <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties" target="_blank" rel="noopener">CSS Variables</a> (plus a dash of <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:where" target="_blank" rel="noopener"><code>:where()</code> for specificity)</a>, you can make a dead-simple, ultra-lightweight, fully-customizable CSS slider with just a few lines of code.</p>
	<p>✏️ Try making edits in the <strong>CSS panel</strong> to see how it works.</p>
	
	<ul class="slider colors">
		<li>Slide #1</li>
		<li>Slide #2</li>
		<li>Slide #3</li>
		<li>Slide #4</li>
		<li>Slide #5</li>
		<li>Slide #6</li>
		<li>Slide #7</li>
	</ul>
	
	<p>You can adjust <code>--slider-visible-slides</code> to change the number of slides visible at one time. (Fun&nbsp;Fact: Floating point values work too! The slider after this only shows 1⅔ slides at a time…)</em></p>
	<ul class="slider slider--cool">
		<li>Slide #1</li>
		<li>Slide #2</li>
		<li>Slide #3</li>
		<li>Slide #4</li>
		<li>Slide #5</li>
		<li>Slide #6</li>
		<li>Slide #7</li>
	</ul>

	<p>You can also use <code>--slider-gutter</code> to adjust the gutter (spacing) between each slide—or you could set it to 0 to remove the space if you want. It all works!</p>
	<ul class="slider slider--gray">
		<li>Slide #1</li>
		<li>Slide #2</li>
		<li>Slide #3</li>
		<li class="js-scroll-to-center">Slide #4</li>
		<li>Slide #5</li>
		<li>Slide #6</li>
		<li>Slide #7</li>
	</ul>

	<p>Oh yeah, and did I mention with a little JavaScript (<a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/scroll" target="_blank" rel="noopener"><code>Element.scroll()</code></a>) you can have your sliders centered on an active slide immediately on page load. How cool is that?!</p>
	<p>👌 It’s amazing what you can do these days.</p>

	<h2>Code</h2>
	<h3>CSS</h3>
<pre><code>:where(.slider) {
	/* Change these to adjust your slider. */
	--slider-visible-slides: 3;
	--slider-gutter: 10px;
	--slider-scrollbar-size: 15px;

	/* Math... */
	--slider-slide-width: calc((100% - (var(--slider-visible-slides) - 1) * var(--slider-gutter)) / var(--slider-visible-slides));

	/* Put it all together! */
	display: grid;
	grid: 1fr / auto-flow var(--slider-slide-width);
	grid-gap: var(--slider-gutter);
	margin: 0;
	padding: 0 0 var(--slider-scrollbar-size);
	overflow: scroll;
	list-style: none;
	scroll-snap-type: x mandatory;
	overscroll-behavior: contain;
}

:where(.slider > *) {
	margin: 0;
	padding: 0;
	scroll-snap-align: start;
}</code></pre>
	<h3>JavaScript</h3>
<pre><code>[...document.querySelectorAll('.js-scroll-to-center')].forEach((el) => {
	el.parentNode.scroll({ left: el.offsetLeft - el.parentNode.offsetWidth / 2 + el.offsetWidth / 2 });
});</code></pre>
	
	<h2>References</h2>
	<ul>
		<li>🙌 <a href="https://twitter.com/_ynotdraw/status/1424779601805553667" target="_blank" rel="noopener">Tony Ward’s tweet about these styles for his image uploader</a></li>
		<li>🙏 <a href="https://twitter.com/argyleink" target="_blank" rel="noopener">Adam Argyle’s constant CSS inspiration</a></li>
		<li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout" target="_blank" rel="noopener">MDN: CSS Grid Layout</a></li>
		<li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Scroll_Snap/Basic_concepts" target="_blank" rel="noopener">MDN: Basic concepts of CSS Scroll Snap</a></li>
		<li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties" target="_blank" rel="noopener">MDN: Using CSS custom properties (variables)</a></li>
		<li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:where" target="_blank" rel="noopener">MDN: :where()</a></li>
		<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/scroll" target="_blank" rel="noopener">MDN: Element.scroll()</a></li>
	</ul>
</main>

              
            
!

CSS

              
                
/**
 * CSS Grid Slider.
 * ------------------------------
 * Use :where() to reduce specificity, so
 * other classes can override these styles.
 */
:where(.slider) {
	/* Change these to adjust your slider. */
	--slider-visible-slides: 3;
	--slider-gap: 10px;
	--slider-scrollbar-size: 15px;

	/* Math... */
	--slider-slide-width: calc((100% - (var(--slider-visible-slides) - 1) * var(--slider-gap)) / var(--slider-visible-slides));

	/* Put it all together! */
	display: grid;
	position: relative;
	grid-auto-columns: var(--slider-slide-width);
	grid-auto-flow: column;
	gap: var(--slider-gap);
	margin: 0;
	padding: 0 0 var(--slider-scrollbar-size);
	overflow: auto;
	list-style: none;
	scroll-snap-type: x mandatory;
	overscroll-behavior-x: contain;
}

:where(.slider > *) {
	margin: 0;
	padding: 0;
	scroll-snap-align: start;
}



/* ------------------------------ */
/* Demo Styles                    */
/* ------------------------------ */

.slider li {
	padding: 1rem;
	border: 2px solid black;
}

.slider--cool {
	--slider-visible-slides: 2;
	margin-block: 1rem;
}

.slider--cool li {
	border-radius: 5px;
	border-color: lightblue;
	background: blue;
	color: white;
}

.slider--gray {
	--slider-visible-slides: 1.667;
	--slider-gap: 30px;
	margin-block: 1rem;
	text-align: center;
}

.slider--gray li {
	border: 0;
	background: lightgray;
	scroll-snap-align: center;
}



/* ------------------------------ */
/* Reset Styles                   */
/* ------------------------------ */

html {
	box-sizing: border-box;
}

*,
::after,
::before {
	box-sizing: inherit;
}

body {
	margin: 1rem auto 3rem;
	line-height: 1.4;
	tab-size: 4;
}

main {
	display: block;
	max-width: 42rem;
	margin: 0 auto;
	padding-right: 1rem;
	padding-left: 1rem;
}

h2 {
	 margin-top: 3rem;
}

pre {
	padding: 1rem;
	overflow: auto;
	border: 1px solid #ccc;
	-webkit-overflow-scroll: touch;
}

.colors > *:nth-child(7n + 1) { background-color: red; }
.colors > *:nth-child(7n + 2) { background-color: orange; }
.colors > *:nth-child(7n + 3) { background-color: yellow; }
.colors > *:nth-child(7n + 4) { background-color: green; }
.colors > *:nth-child(7n + 5) { background-color: blue; }
.colors > *:nth-child(7n + 6) { background-color: indigo; }
.colors > *:nth-child(7n + 7) { background-color: violet; }

              
            
!

JS

              
                /**
 * Center active slides on page load.
 */
[...document.querySelectorAll('.js-scroll-to-center')].forEach((el) => {
	el.parentNode.scroll({ left: el.offsetLeft - el.parentNode.offsetWidth / 2 + el.offsetWidth / 2 });
});

              
            
!
999px

Console