UNPKG

@evermade/overflow-slider

Version:

Accessible slider that is powered by overflow: auto.

843 lines (702 loc) 16.1 kB
/* =========================================================================== Base =========================================================================== */ :root { --slide-gap: 1rem; --color-primary: #f04d37; --color-primary-dark: #d13c26; --color-grey-50: hsla(0, 0%, 0%, 0.05); --color-grey-100: hsla(0, 0%, 0%, 0.1); --color-grey-600: hsla(0, 0%, 0%, 0.6); --color-grey-700: hsla(0, 0%, 0%, 0.7); --color-grey-800: hsla(0, 0%, 0%, 0.8); --color-white: #fff; --color-black: #000; --font-family-sans: -apple-system, "BlinkMacSystemFont", "Segoe UI", "Roboto", "Helvetica", "Arial", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; --font-family-mono: "Monaco", "Consolas", "Andale Mono", "DejaVu Sans Mono", monospace; --font-size-sm: 0.875rem; --font-size-md: 1rem; --font-size-lg: 1.125rem; --font-size-xl: 1.25rem; --font-size-body: var(--font-size-lg); --line-height-sm: 1.25; --line-height-md: 1.5; --max-width-md: 42rem; --max-width-lg: 60rem; --max-width-xl: 72rem; --transition-duration-md: 0.25s; } /* Reset */ body, h1, h2, h3, h4, h5, h6, p, li, figure, figcaption, blockquote, dl, dd { margin: 0; } [hidden] { display: none !important; } /* Box sizing */ html { box-sizing: border-box; } /** * Inherit box-sizing to make it easier to change the property * for components that leverage other behavior. */ *, *::before, *::after { box-sizing: inherit; } /* Base styles */ html { font-size: 100%; } body, button, input, optgroup, select, textarea { color: var(--color-grey-800); font-family: var(--font-family-sans); font-size: var(--font-size-body); line-height: var(--line-height-md); word-wrap: break-word; } body { background-color: #fff; } a { color: var(--color-primary-dark); /* transition: all var(--transition-duration-md) ease-in-out; */ } a:hover, a:focus-visible { color: var(--color-primary); } :focus-visible { outline: 2px solid var(--color-primary); } a:hover, a:active { outline: 0; } button, .button { background: var(--color-primary); border: 0; border-radius: 0; color: var(--color-white); display: inline-block; font-weight: 500; padding: 0.5rem 1rem; text-decoration: none; } button:hover, .button:hover, button:active, .button:active, button:focus, .button:focus { background-color: var(--color-primary-dark); color: var(--color-white); } .actions { margin-block: 2rem; display: flex; flex-wrap: wrap; gap: .5rem; } .code-example { display: block; background: var(--color-grey-800); font-family: var(--font-family-mono); color: var(--color-white); padding: 1.5rem; font-size: 0.9375rem; line-height: 1.5; overflow-x: auto; border-radius: 3px; margin-top: 2rem; &:not(:last-child) { margin-bottom: 1rem; } /* Keep original line breaks */ white-space: pre-wrap; /* Set tab size */ tab-size: 4; } /* Animations */ @keyframes fancy-animate-in { 0% { opacity: 0; transform: translateY(1rem) scale(0.85); } 100% { opacity: 1; transform: translateY(0) scale(1); } } @keyframes fancy-animate-out { 0% { opacity: 1; transform: translateY(0) scale(1); } 100% { opacity: 0; transform: translateY(1rem) scale(0.85); } } /* Icons */ .icon { fill: currentcolor; display: inline-block; height: 1em; pointer-events: none; position: relative; top: -0.0625em; vertical-align: middle; width: 1em; } /* Components */ .site-main, .site-footer { margin-left: auto; margin-right: auto; max-width: var(--max-width-lg); padding: 0 1.5rem 3rem; } .site-footer { padding-top: 0; font-size: 0.9375rem; } .entry__content > * { margin-left: 0; margin-right: auto; max-width: var(--max-width-lg); margin-top: 1rem; } .entry__content h1 + * { margin-top: 1.5rem; } .entry__content > *:first-child { margin-top: 0; } .entry__content > *:last-child { margin-bottom: 0; } .entry__section + .entry__section { margin-top: 3rem; } .entry__section h2 { margin-bottom: 1.5rem; } .entry__item + .entry__item { margin-top: 3rem; } .entry__item h3 { margin-bottom: .25rem; } body { counter-reset: section; /* Initialize the main counter */ } h2 { counter-reset: subsection; /* Reset the subsection counter for each new h2 */ counter-increment: section; /* Increment the main counter for each h2 */ } h2:before { content: counter(section) ". "; /* Display the counter before the h2 content */ } h3 { counter-increment: subsection; /* Increment the subsection counter for each h3 */ } h3:before { content: counter(section) "." counter(subsection) " "; /* Display the combined counters before the h3 content */ } /* Utilities */ .screen-reader-text { border: 0; clip: rect(1px, 1px, 1px, 1px); clip-path: inset(50%); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; word-wrap: normal !important; } .screen-reader-text:focus { background-color: var(--color-primary); clip: auto !important; clip-path: none; color: var(--color-white); display: block; font-size: var(--font-size-md); font-weight: 700; height: auto; outline-offset: -2px; padding: 1rem 1.5rem; text-decoration: none; width: fit-content; z-index: 100000; position: relative; margin-top: 1rem; margin-bottom: 1rem; } .overflow-hidden { overflow: hidden; } /* =========================================================================== Menu =========================================================================== */ .site-header__inner { display: flex; flex-direction: column; justify-content: flex-start; align-items: flex-start; gap: 1rem; flex-wrap: wrap; margin-left: auto; margin-right: auto; max-width: var(--max-width-lg); padding: 1.5rem 1.5rem; } @media (min-width: 768px) { .site-header__inner { gap: 1.5rem; } } .site-branding, .site-branding * { line-height: 0; display: block; } .site-branding .site-logo { display: flex; align-items: center; gap: .75rem; text-decoration: none; } .site-logo svg { width: 32px; height: 32px; } .site-logo span { font-size: 14px; text-decoration: none; color: var(--color-grey-800); } /* =========================================================================== Content =========================================================================== */ .overflow-slider { margin-top: 1.5rem; gap: 1rem; } .overflow-slider__autoplay { --autoplay-bg-color: #e5e5e5; --autoplay-progress-color: #303030; --autoplay-icon-color: #303030; cursor: pointer; border-radius: 50%; position: relative; display: inline-flex; align-items: center; justify-content: center; width: 2.5rem; height: 2.5rem; border: none; background: var(--autoplay-bg-color); color: var(--autoplay-icon-color); /* ensure the pseudo-element paints on its own layer */ will-change: background; } .overflow-slider__autoplay::before { content: ""; position: absolute; inset: 0; border-radius: 50%; /* draw the circular progress using conic-gradient */ background: conic-gradient( var(--autoplay-progress-color) calc(var(--autoplay-delay-progress) * 1%), transparent 0 ); /* rotate so “0%” starts at top */ transform: rotate(-90deg); } .overflow-slider__autoplay::after { content: ""; position: absolute; border-radius: 50%; left: 10%; width: 80%; height: 80%; top: 10%; background: var(--autoplay-bg-color); } .overflow-slider__autoplay:hover, .overflow-slider__autoplay:focus { background: var(--color-primary); } .overflow-slider__autoplay:hover::before, .overflow-slider__autoplay:focus::before { background: transparent; } .overflow-slider__autoplay:hover::after, .overflow-slider__autoplay:focus::after { background: transparent; } .overflow-slider__autoplay svg { position: absolute; z-index: 2; width: 1.25rem; height: 1.25rem; left: 50%; top: 50%; transform: translate(-50%, -50%); } .example-item { aspect-ratio: 3/4; width: 240px; max-width: 90vw; background: var(--color-grey-100); border-radius: 3px; outline-offset: -2px; display: flex; align-items: center; justify-content: center; font-size: 3rem; font-weight: 700; color: #fff; text-decoration: none; } .example-item:hover, .example-item:focus { color: #fff; } .example-item--1 { background: hsla(0, 0%, 0%, 0.1); } .example-item--2 { background: hsla(0, 0%, 0%, 0.125); } .example-item--3 { background: hsla(0, 0%, 0%, 0.15); } .example-item--4 { background: hsla(0, 0%, 0%, 0.175); } .example-item--5 { background: hsla(0, 0%, 0%, 0.2); } .example-item--6 { background: hsla(0, 0%, 0%, 0.225); } .example-item--7 { background: hsla(0, 0%, 0%, 0.25); } .example-item--8 { background: hsla(0, 0%, 0%, 0.275); } .example-item--9 { background: hsla(0, 0%, 0%, 0.3); } .example-item--10 { background: hsla(0, 0%, 0%, 0.325); } .example-item--11 { background: hsla(0, 0%, 0%, 0.35); } .example-item--12 { background: hsla(0, 0%, 0%, 0.375); } .example-item--13 { background: hsla(0, 0%, 0%, 0.4); } .example-container-2-perfect-fit { grid-template-columns: repeat(var(--slider-slides-count, 1), calc( ( var(--slider-container-width, 900px) / 3 ) - 2/3 * var(--slide-gap, 1rem))); } .example-container-1-dots { scroll-snap-type: x mandatory; grid-template-columns: repeat(var(--slider-slides-count, 1), var(--slider-container-width, 900px)); } .example-container-1-autoplay-wrap-view, .example-container-1-autoplay-wrap-slide { margin-top: 16px; } .example-container-1-dots .example-item { aspect-ratio: 16/7; width: 100%; } .example-container-1-infinite > * { width: var(--slider-container-width, 400px); aspect-ratio: 16/8; } .example-container-1-fade-wrap { position: relative; } .example-container-2-perfect-fit .example-item { aspect-ratio: 1/1; width: 100%; } .example-container-2-varying-widths .example-item { aspect-ratio: unset; height: 300px; } .example-container-2-varying-widths .example-item--1 { width: 120px; } .example-container-2-varying-widths .example-item--2 { width: 200px; } .example-container-2-varying-widths .example-item--3 { width: 90px; } .example-container-2-varying-widths .example-item--4 { width: 4800px; } .example-container-2-varying-widths .example-item--5 { width: 170px; } .example-container-2-varying-widths .example-item--6 { width: 100px; } .example-container-2-varying-widths .example-item--8 { width: 280px; } .example-container-3-scroll-snapping-mandatory { scroll-snap-type: x mandatory; } .example-container-3-scroll-snapping-proximity { scroll-snap-type: x proximity; } .example-container-3-entrance-animation a { animation: slideEntrance, slideEntrance; animation-direction: normal, reverse; animation-timeline: view(inline); animation-range: entry, exit; } @keyframes slideEntrance { 0% { transform: scale(.75); opacity: 0; } 100% { transform: scale(1); opacity: 1; } } .overflow-slider__dots { margin-top: 1.5rem; } .overflow-slider__arrows { margin-top: 1.5rem; } .overflow-slider__scroll-indicator { margin-top: 1rem; } .overflow-slider__arrows-button { background: transparent; padding: 0; } .overflow-slider__arrows-button:hover, .overflow-slider__arrows-button:focus { background: transparent !important; } .overflow-slider__arrows-button svg { fill: var(--color-grey-800); width: 1.625rem !important; height: 1.625rem !important; } .example-container-1-classname-opacity .example-item { transition: .5s ease-in-out; } .example-container-1-classname-opacity .is-visible { opacity: 1; } .example-container-1-classname-opacity .is-hidden { opacity: 0; } .example-container-1-classname-partly { width: 100vw; margin-inline-start: calc(-50vw + 50%); scroll-snap-type: x mandatory; } @media (min-width: 768px) { .example-container-1-classname-partly .example-item { width: calc( ( var( --slider-container-target-width ) / 4 ) - ( 3 / 4 * var( --slide-gap ) ) ); } .example-container-1-classname-partly .example-item { transition: .2s ease-in-out; } .example-container-1-classname-partly .is-visible { opacity: 1; /* transform: scale(1); */ } .example-container-1-classname-partly .is-partly-visible { opacity: .5; /* transform: scale(0.85); */ } .example-container-1-classname-partly .is-hidden { opacity: .2; /* transform: scale(0); */ } /* =========================================================================== Example 4: Filters =========================================================================== */ .example-4-filters-wrapper { display: flex; align-items: center; gap: .5rem; margin-top: 1.5rem; position: relative; } .example-container-4-filters { gap: .75rem; margin: 0; } .example-4-filters-previous, .example-4-filters-next { transition: .1s ease-in-out; position: absolute; top: 0; bottom: 0; width: var(--example-4-arrow-size); display: flex; align-items: center; background: #fff; padding-inline: .5rem; z-index: 1; } .example-4-filters-previous { left: 0; } [dir="rtl"] .example-4-filters-previous { right: 0; left: auto; } .example-4-filters-next { right: 0; } [dir="rtl"] .example-4-filters-next { left: 0; right: auto; } .example-4-filters-previous:has([data-has-content="false"]), .example-4-filters-next:has([data-has-content="false"]) { opacity: 0; pointer-events: none; visibility: hidden; } .example-filter { padding: .5rem 1rem; border-radius: 2rem; background: var(--color-grey-100); cursor: pointer; color: var(--color-grey-800); white-space: nowrap; text-decoration: none; } .example-filter:hover, .example-filter:focus-visible { background: var(--color-grey-800); color: var(--color-white); } /* =========================================================================== Example 4: Grid On Desktop =========================================================================== */ @media (min-width: 768px) { .example-container-4-grid-or-slider { width: 100%; max-width: 100%; grid-template-columns: repeat(4, minmax(0, 1fr)); grid-auto-flow: row; overflow: clip; } .example-container-4-grid-or-slider .example-item { width: 100%; } } /* =========================================================================== Example 4: Full Width =========================================================================== */ .example-container-4-full-width { width: 100vw; margin-inline-start: calc(-50vw + 50%); scroll-snap-type: x mandatory; } /* =========================================================================== Example 4: Synced Sliders =========================================================================== */ .example-container-4-thumbnails-wrapper { } .example-container-4-synced-main { grid-template-columns: repeat(var(--slider-slides-count, 1), var(--slider-container-width, 900px)); scroll-snap-type: x mandatory; } .example-container-4-synced-main .example-item { aspect-ratio: 16/8; width: 100%; max-width: 100%; } .example-container-4-synced-thumbnails { scroll-snap-type: x proximity; } .example-container-4-synced-thumbnails .example-item { aspect-ratio: 1/1; font-size: 1.5rem; width: 120px; opacity: .5; cursor: pointer; } .example-container-4-synced-thumbnails .example-item:hover { opacity: .875; } .example-container-4-synced-thumbnails .example-item[aria-current="true"] { opacity: 1 !important; background: var(--color-grey-800); color: #fff; } /* =========================================================================== Example 4: Hero =========================================================================== */ .example-container-4-hero__wrapper { position: relative; } .example-container-4-hero { --slider-gap: 0; gap: 0; scroll-snap-type: x mandatory; } .example-container-4-hero > * { width: var(--slider-container-width, 900px); aspect-ratio: 16/9; } .example-container-4-hero__autoplay { position: absolute; bottom: 1rem; right: 1rem; } .example-container-4-hero__dots { z-index: 10; position: absolute; bottom: 1rem; left: 50%; transform: translateX(-50%); --overflow-slider-dot-inactive-color: rgba(0, 0, 0, 0.2); --overflow-slider-dot-active-color: rgba(0, 0, 0, .8); }