Carousels & Sliders
Carousels and sliders present multiple pieces of content in a shared viewport. This guide covers production-ready patterns in plain HTML/CSS, Tailwind CSS, and Bootstrap — including scroll-snap, arrow/dot navigation, auto-play, multi-item layouts, testimonials, thumbnails, hero sliders, and accessibility.
info
A CSS-only horizontal carousel using scroll-snap-type: x mandatory and hidden scrollbars. Each slide snaps to the start of the track on scroll or swipe.
| 1 | <div class="snap-carousel"> |
| 2 | <div class="snap-track"> |
| 3 | <div class="snap-slide" style="background:linear-gradient(135deg,#0f2027,#203a43)"> |
| 4 | <div class="snap-content"> |
| 5 | <span class="snap-tag"> |
| 6 | 01 |
| 7 | </span> |
| 8 | <h3> |
| 9 | Mountain Peaks |
| 10 | </h3> |
| 11 | <p> |
| 12 | Explore the highest summits on Earth. |
| 13 | </p> |
| 14 | </div> |
| 15 | </div> |
| 16 | <div class="snap-slide" style="background:linear-gradient(135deg,#1a0533,#2d1b69)"> |
| 17 | <div class="snap-content"> |
| 18 | <span class="snap-tag"> |
| 19 | 02 |
| 20 | </span> |
| 21 | <h3> |
| 22 | Deep Ocean |
| 23 | </h3> |
| 24 | <p> |
| 25 | Dive into the unknown depths. |
| 26 | </p> |
| 27 | </div> |
| 28 | </div> |
| 29 | <div class="snap-slide" style="background:linear-gradient(135deg,#0c2340,#1e5a8a)"> |
| 30 | <div class="snap-content"> |
| 31 | <span class="snap-tag"> |
| 32 | 03 |
| 33 | </span> |
| 34 | <h3> |
| 35 | Northern Lights |
| 36 | </h3> |
| 37 | <p> |
| 38 | Witness the aurora borealis. |
| 39 | </p> |
| 40 | </div> |
| 41 | </div> |
| 42 | <div class="snap-slide" style="background:linear-gradient(135deg,#2d1810,#5a3a28)"> |
| 43 | <div class="snap-content"> |
| 44 | <span class="snap-tag"> |
| 45 | 04 |
| 46 | </span> |
| 47 | <h3> |
| 48 | Desert Dunes |
| 49 | </h3> |
| 50 | <p> |
| 51 | Traverse endless sand landscapes. |
| 52 | </p> |
| 53 | </div> |
| 54 | </div> |
| 55 | </div> |
| 56 | </div> |
| 1 | .snap-carousel { |
| 2 | width:100%; |
| 3 | overflow:hidden; |
| 4 | padding:0 16px; |
| 5 | font-family:system-ui, |
| 6 | sans-serif |
| 7 | } |
| 8 | .snap-track { |
| 9 | display:flex; |
| 10 | gap:12px; |
| 11 | overflow-x:auto; |
| 12 | scroll-snap-type:x mandatory; |
| 13 | scroll-behavior:smooth; |
| 14 | -webkit-overflow-scrolling:touch; |
| 15 | padding:16px 0; |
| 16 | scrollbar-width:none |
| 17 | } |
| 18 | .snap-track::-webkit-scrollbar { |
| 19 | display:none |
| 20 | } |
| 21 | .snap-slide { |
| 22 | flex:0 0 calc(100% - 32px); |
| 23 | scroll-snap-align:start; |
| 24 | border-radius:12px; |
| 25 | padding:32px 24px; |
| 26 | min-height:180px; |
| 27 | display:flex; |
| 28 | align-items:flex-end; |
| 29 | position:relative; |
| 30 | overflow:hidden |
| 31 | } |
| 32 | .snap-content { |
| 33 | position:relative; |
| 34 | z-index:1 |
| 35 | } |
| 36 | .snap-tag { |
| 37 | font-size:10px; |
| 38 | color:rgba(0, |
| 39 | 255, |
| 40 | 65, |
| 41 | .6); |
| 42 | font-weight:700; |
| 43 | letter-spacing:1px; |
| 44 | display:block; |
| 45 | margin-bottom:8px |
| 46 | } |
| 47 | .snap-content h3 { |
| 48 | font-size:18px; |
| 49 | font-weight:700; |
| 50 | color:#E0E0E0; |
| 51 | margin:0 0 4px |
| 52 | } |
| 53 | .snap-content p { |
| 54 | font-size:12px; |
| 55 | color:rgba(255, |
| 56 | 255, |
| 57 | 255, |
| 58 | .6); |
| 59 | margin:0 |
| 60 | } |
| 1 | <div class="w-full overflow-hidden px-4 font-sans"> |
| 2 | <div class="flex gap-3 overflow-x-auto snap-x snap-mandatory scroll-smooth py-4 scrollbar-hide" style="-webkit-overflow-scrolling:touch;scrollbar-width:none"> |
| 3 | <div class="flex-none w-[calc(100%-32px)] snap-start rounded-xl p-8 min-h-[180px] flex items-end relative overflow-hidden" style="background:linear-gradient(135deg,#0f2027,#203a43)"> |
| 4 | <div class="relative z-10"> |
| 5 | <span class="block text-[10px] font-bold tracking-wider mb-2" style="color:rgba(0,255,65,.6)"> |
| 6 | 01 |
| 7 | </span> |
| 8 | <h3 class="text-lg font-bold text-[#E0E0E0] mb-1"> |
| 9 | Mountain Peaks |
| 10 | </h3> |
| 11 | <p class="text-xs" style="color:rgba(255,255,255,.6)"> |
| 12 | Explore the highest summits on Earth. |
| 13 | </p> |
| 14 | </div> |
| 15 | </div> |
| 16 | <div class="flex-none w-[calc(100%-32px)] snap-start rounded-xl p-8 min-h-[180px] flex items-end relative overflow-hidden" style="background:linear-gradient(135deg,#1a0533,#2d1b69)"> |
| 17 | <div class="relative z-10"> |
| 18 | <span class="block text-[10px] font-bold tracking-wider mb-2" style="color:rgba(0,255,65,.6)"> |
| 19 | 02 |
| 20 | </span> |
| 21 | <h3 class="text-lg font-bold text-[#E0E0E0] mb-1"> |
| 22 | Deep Ocean |
| 23 | </h3> |
| 24 | <p class="text-xs" style="color:rgba(255,255,255,.6)"> |
| 25 | Dive into the unknown depths. |
| 26 | </p> |
| 27 | </div> |
| 28 | </div> |
| 29 | <div class="flex-none w-[calc(100%-32px)] snap-start rounded-xl p-8 min-h-[180px] flex items-end relative overflow-hidden" style="background:linear-gradient(135deg,#0c2340,#1e5a8a)"> |
| 30 | <div class="relative z-10"> |
| 31 | <span class="block text-[10px] font-bold tracking-wider mb-2" style="color:rgba(0,255,65,.6)"> |
| 32 | 03 |
| 33 | </span> |
| 34 | <h3 class="text-lg font-bold text-[#E0E0E0] mb-1"> |
| 35 | Northern Lights |
| 36 | </h3> |
| 37 | <p class="text-xs" style="color:rgba(255,255,255,.6)"> |
| 38 | Witness the aurora borealis. |
| 39 | </p> |
| 40 | </div> |
| 41 | </div> |
| 42 | <div class="flex-none w-[calc(100%-32px)] snap-start rounded-xl p-8 min-h-[180px] flex items-end relative overflow-hidden" style="background:linear-gradient(135deg,#2d1810,#5a3a28)"> |
| 43 | <div class="relative z-10"> |
| 44 | <span class="block text-[10px] font-bold tracking-wider mb-2" style="color:rgba(0,255,65,.6)"> |
| 45 | 04 |
| 46 | </span> |
| 47 | <h3 class="text-lg font-bold text-[#E0E0E0] mb-1"> |
| 48 | Desert Dunes |
| 49 | </h3> |
| 50 | <p class="text-xs" style="color:rgba(255,255,255,.6)"> |
| 51 | Traverse endless sand landscapes. |
| 52 | </p> |
| 53 | </div> |
| 54 | </div> |
| 55 | </div> |
| 56 | </div> |
| 1 | <div class="container-fluid px-3" style="font-family:system-ui,sans-serif"> |
| 2 | <div class="d-flex gap-3 overflow-auto pb-3" style="scroll-snap-type:x mandatory;scroll-behavior:smooth;scrollbar-width:none"> |
| 3 | <div class="flex-shrink-0 rounded-4 p-4 d-flex align-items-end" style="width:calc(100% - 32px);scroll-snap-align:start;min-height:180px;background:linear-gradient(135deg,#0f2027,#203a43)"> |
| 4 | <div> |
| 5 | <span class="d-block text-uppercase fw-bold mb-2" style="font-size:10px;color:rgba(0,255,65,.6)"> |
| 6 | 01 |
| 7 | </span> |
| 8 | <h3 class="h5 fw-bold text-white mb-1"> |
| 9 | Mountain Peaks |
| 10 | </h3> |
| 11 | <p class="small mb-0" style="color:rgba(255,255,255,.6)"> |
| 12 | Explore the highest summits on Earth. |
| 13 | </p> |
| 14 | </div> |
| 15 | </div> |
| 16 | <div class="flex-shrink-0 rounded-4 p-4 d-flex align-items-end" style="width:calc(100% - 32px);scroll-snap-align:start;min-height:180px;background:linear-gradient(135deg,#1a0533,#2d1b69)"> |
| 17 | <div> |
| 18 | <span class="d-block text-uppercase fw-bold mb-2" style="font-size:10px;color:rgba(0,255,65,.6)"> |
| 19 | 02 |
| 20 | </span> |
| 21 | <h3 class="h5 fw-bold text-white mb-1"> |
| 22 | Deep Ocean |
| 23 | </h3> |
| 24 | <p class="small mb-0" style="color:rgba(255,255,255,.6)"> |
| 25 | Dive into the unknown depths. |
| 26 | </p> |
| 27 | </div> |
| 28 | </div> |
| 29 | <div class="flex-shrink-0 rounded-4 p-4 d-flex align-items-end" style="width:calc(100% - 32px);scroll-snap-align:start;min-height:180px;background:linear-gradient(135deg,#0c2340,#1e5a8a)"> |
| 30 | <div> |
| 31 | <span class="d-block text-uppercase fw-bold mb-2" style="font-size:10px;color:rgba(0,255,65,.6)"> |
| 32 | 03 |
| 33 | </span> |
| 34 | <h3 class="h5 fw-bold text-white mb-1"> |
| 35 | Northern Lights |
| 36 | </h3> |
| 37 | <p class="small mb-0" style="color:rgba(255,255,255,.6)"> |
| 38 | Witness the aurora borealis. |
| 39 | </p> |
| 40 | </div> |
| 41 | </div> |
| 42 | <div class="flex-shrink-0 rounded-4 p-4 d-flex align-items-end" style="width:calc(100% - 32px);scroll-snap-align:start;min-height:180px;background:linear-gradient(135deg,#2d1810,#5a3a28)"> |
| 43 | <div> |
| 44 | <span class="d-block text-uppercase fw-bold mb-2" style="font-size:10px;color:rgba(0,255,65,.6)"> |
| 45 | 04 |
| 46 | </span> |
| 47 | <h3 class="h5 fw-bold text-white mb-1"> |
| 48 | Desert Dunes |
| 49 | </h3> |
| 50 | <p class="small mb-0" style="color:rgba(255,255,255,.6)"> |
| 51 | Traverse endless sand landscapes. |
| 52 | </p> |
| 53 | </div> |
| 54 | </div> |
| 55 | </div> |
| 56 | </div> |
An auto-advancing carousel that pauses on hover and resumes on leave. A progress bar visualizes the time remaining before the next slide.
| 1 | <div class="auto-carousel" id="auto-carousel"> |
| 2 | <div class="auto-track" id="auto-track"> |
| 3 | <div class="auto-slide"> |
| 4 | <div class="auto-card g1"> |
| 5 | <div class="auto-body"> |
| 6 | <span class="auto-badge"> |
| 7 | Featured |
| 8 | </span> |
| 9 | <h3> |
| 10 | Design Systems |
| 11 | </h3> |
| 12 | <p> |
| 13 | Build scalable component libraries with consistent tokens and patterns. |
| 14 | </p> |
| 15 | <button class="auto-btn"> |
| 16 | Learn More |
| 17 | </button> |
| 18 | </div> |
| 19 | </div> |
| 20 | </div> |
| 21 | <div class="auto-slide"> |
| 22 | <div class="auto-card g2"> |
| 23 | <div class="auto-body"> |
| 24 | <span class="auto-badge"> |
| 25 | New |
| 26 | </span> |
| 27 | <h3> |
| 28 | Edge Computing |
| 29 | </h3> |
| 30 | <p> |
| 31 | Deploy serverless functions to 200+ edge locations worldwide. |
| 32 | </p> |
| 33 | <button class="auto-btn"> |
| 34 | Learn More |
| 35 | </button> |
| 36 | </div> |
| 37 | </div> |
| 38 | </div> |
| 39 | <div class="auto-slide"> |
| 40 | <div class="auto-card g3"> |
| 41 | <div class="auto-body"> |
| 42 | <span class="auto-badge"> |
| 43 | Popular |
| 44 | </span> |
| 45 | <h3> |
| 46 | AI Workflows |
| 47 | </h3> |
| 48 | <p> |
| 49 | Orchestrate multi-step AI pipelines with automatic retries. |
| 50 | </p> |
| 51 | <button class="auto-btn"> |
| 52 | Learn More |
| 53 | </button> |
| 54 | </div> |
| 55 | </div> |
| 56 | </div> |
| 57 | </div> |
| 58 | <div class="auto-progress"> |
| 59 | <div class="auto-bar" id="auto-bar"> |
| 60 | </div> |
| 61 | </div> |
| 62 | <div class="auto-controls"> |
| 63 | <button class="auto-arrow" id="auto-prev" aria-label="Previous slide"> |
| 64 | <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="14" height="14"> |
| 65 | <polyline points="15 18 9 12 15 6"/> |
| 66 | </svg> |
| 67 | </button> |
| 68 | <div class="auto-dots" id="auto-dots"> |
| 69 | <span class="auto-dot active"> |
| 70 | </span> |
| 71 | <span class="auto-dot"> |
| 72 | </span> |
| 73 | <span class="auto-dot"> |
| 74 | </span> |
| 75 | </div> |
| 76 | <button class="auto-arrow" id="auto-next" aria-label="Next slide"> |
| 77 | <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="14" height="14"> |
| 78 | <polyline points="9 18 15 12 9 6"/> |
| 79 | </svg> |
| 80 | </button> |
| 81 | </div> |
| 82 | </div> |
| 1 | .auto-carousel { |
| 2 | max-width:400px; |
| 3 | margin:16px auto; |
| 4 | border-radius:12px; |
| 5 | border:1px solid #222; |
| 6 | overflow:hidden; |
| 7 | background:#111; |
| 8 | font-family:system-ui, |
| 9 | sans-serif |
| 10 | } |
| 11 | .auto-track { |
| 12 | display:flex; |
| 13 | transition:transform .5s cubic-bezier(.4, |
| 14 | 0, |
| 15 | .2, |
| 16 | 1) |
| 17 | } |
| 18 | .auto-slide { |
| 19 | flex:0 0 100%; |
| 20 | min-width:100% |
| 21 | } |
| 22 | .auto-card { |
| 23 | min-height:220px; |
| 24 | padding:28px; |
| 25 | display:flex; |
| 26 | align-items:flex-end |
| 27 | } |
| 28 | .g1 { |
| 29 | background:linear-gradient(135deg, |
| 30 | #0f2027, |
| 31 | #203a43, |
| 32 | #2c5364) |
| 33 | } |
| 34 | .g2 { |
| 35 | background:linear-gradient(135deg, |
| 36 | #1a0533, |
| 37 | #2d1b69, |
| 38 | #5b2c8e) |
| 39 | } |
| 40 | .g3 { |
| 41 | background:linear-gradient(135deg, |
| 42 | #0c2340, |
| 43 | #1e5a8a, |
| 44 | #2980b9) |
| 45 | } |
| 46 | .auto-body { |
| 47 | position:relative; |
| 48 | z-index:1 |
| 49 | } |
| 50 | .auto-badge { |
| 51 | display:inline-block; |
| 52 | padding:3px 8px; |
| 53 | border-radius:4px; |
| 54 | font-size:9px; |
| 55 | font-weight:700; |
| 56 | text-transform:uppercase; |
| 57 | letter-spacing:.5px; |
| 58 | background:rgba(0, |
| 59 | 255, |
| 60 | 65, |
| 61 | .15); |
| 62 | color:#00FF41; |
| 63 | margin-bottom:10px |
| 64 | } |
| 65 | .auto-body h3 { |
| 66 | font-size:18px; |
| 67 | font-weight:700; |
| 68 | color:#E0E0E0; |
| 69 | margin:0 0 6px |
| 70 | } |
| 71 | .auto-body p { |
| 72 | font-size:12px; |
| 73 | color:rgba(255, |
| 74 | 255, |
| 75 | 255, |
| 76 | .65); |
| 77 | margin:0 0 14px; |
| 78 | line-height:1.5 |
| 79 | } |
| 80 | .auto-btn { |
| 81 | padding:8px 16px; |
| 82 | border-radius:6px; |
| 83 | font-size:11px; |
| 84 | font-weight:600; |
| 85 | background:#00FF41; |
| 86 | color:#0A0A0A; |
| 87 | border:none; |
| 88 | cursor:pointer; |
| 89 | transition:all .2s |
| 90 | } |
| 91 | .auto-btn:hover { |
| 92 | transform:translateY(-1px); |
| 93 | box-shadow:0 4px 12px rgba(0, |
| 94 | 0, |
| 95 | 0, |
| 96 | .3) |
| 97 | } |
| 98 | .auto-progress { |
| 99 | height:3px; |
| 100 | background:#222 |
| 101 | } |
| 102 | .auto-bar { |
| 103 | height:100%; |
| 104 | background:#00FF41; |
| 105 | width:0%; |
| 106 | transition:width 4s linear |
| 107 | } |
| 108 | .auto-bar.playing { |
| 109 | width:100% |
| 110 | } |
| 111 | .auto-controls { |
| 112 | display:flex; |
| 113 | align-items:center; |
| 114 | justify-content:space-between; |
| 115 | padding:12px 16px |
| 116 | } |
| 117 | .auto-arrow { |
| 118 | width:28px; |
| 119 | height:28px; |
| 120 | border-radius:6px; |
| 121 | border:1px solid #333; |
| 122 | background:transparent; |
| 123 | color:#808080; |
| 124 | font-size:14px; |
| 125 | cursor:pointer; |
| 126 | display:flex; |
| 127 | align-items:center; |
| 128 | justify-content:center; |
| 129 | transition:all .2s |
| 130 | } |
| 131 | .auto-arrow:hover { |
| 132 | background:rgba(255, |
| 133 | 255, |
| 134 | 255, |
| 135 | .05); |
| 136 | color:#E0E0E0 |
| 137 | } |
| 138 | .auto-dots { |
| 139 | display:flex; |
| 140 | gap:6px |
| 141 | } |
| 142 | .auto-dot { |
| 143 | width:6px; |
| 144 | height:6px; |
| 145 | border-radius:50%; |
| 146 | background:#333; |
| 147 | transition:all .2s; |
| 148 | cursor:pointer |
| 149 | } |
| 150 | .auto-dot.active { |
| 151 | background:#00FF41; |
| 152 | width:18px; |
| 153 | border-radius:3px |
| 154 | } |
| 1 | const ac=document.getElementById('auto-carousel');const tr=document.getElementById('auto-track');const bar=document.getElementById('auto-bar');const dots=document.querySelectorAll('.auto-dot');let idx=0;const len=dots.length;let timer;let playing=false;function slide(i){bar.classList.remove('playing');void bar.offsetWidth;idx=(i+len)%len;tr.style.transform='translateX(-'+idx*100+'%)';dots.forEach((d,j)=>d.classList.toggle('active',j===idx))}function play(){bar.classList.remove('playing');void bar.offsetWidth;bar.classList.add('playing');playing=true;timer=setTimeout(()=>{slide(idx+1);play()},4000)}function stop(){clearTimeout(timer);bar.classList.remove('playing');playing=false}document.getElementById('auto-prev').addEventListener('click',()=>{slide(idx-1);if(playing)play()});document.getElementById('auto-next').addEventListener('click',()=>{slide(idx+1);if(playing)play()});dots.forEach((d,i)=>d.addEventListener('click',()=>{slide(i);if(playing)play()}));ac.addEventListener('mouseenter',stop);ac.addEventListener('mouseleave',play);play(); |
| 1 | <div class="max-w-[400px] mx-auto mt-4 rounded-xl border border-[#222] overflow-hidden bg-[#111] font-sans group" id="tw-auto"> |
| 2 | <div class="flex transition-transform duration-500" data-track style="transition-timing-function:cubic-bezier(.4,0,.2,1)"> |
| 3 | <div class="flex-none w-full min-w-full"> |
| 4 | <div class="min-h-[220px] p-7 flex items-end" style="background:linear-gradient(135deg,#0f2027,#203a43,#2c5364)"> |
| 5 | <div class="relative z-10"> |
| 6 | <span class="inline-block px-2 py-0.5 rounded text-[9px] font-bold uppercase tracking-wider mb-2.5 bg-[rgba(0,255,65,.15)] text-[#00FF41]"> |
| 7 | Featured |
| 8 | </span> |
| 9 | <h3 class="text-lg font-bold text-[#E0E0E0] mb-1.5"> |
| 10 | Design Systems |
| 11 | </h3> |
| 12 | <p class="text-xs mb-3.5 leading-relaxed" style="color:rgba(255,255,255,.65)"> |
| 13 | Build scalable component libraries with consistent tokens and patterns. |
| 14 | </p> |
| 15 | <button class="px-4 py-2 rounded-md text-[11px] font-semibold bg-[#00FF41] text-[#0A0A0A] hover:-translate-y-0.5 hover:shadow-lg transition-all"> |
| 16 | Learn More |
| 17 | </button> |
| 18 | </div> |
| 19 | </div> |
| 20 | </div> |
| 21 | <div class="flex-none w-full min-w-full"> |
| 22 | <div class="min-h-[220px] p-7 flex items-end" style="background:linear-gradient(135deg,#1a0533,#2d1b69,#5b2c8e)"> |
| 23 | <div class="relative z-10"> |
| 24 | <span class="inline-block px-2 py-0.5 rounded text-[9px] font-bold uppercase tracking-wider mb-2.5 bg-[rgba(0,255,65,.15)] text-[#00FF41]"> |
| 25 | New |
| 26 | </span> |
| 27 | <h3 class="text-lg font-bold text-[#E0E0E0] mb-1.5"> |
| 28 | Edge Computing |
| 29 | </h3> |
| 30 | <p class="text-xs mb-3.5 leading-relaxed" style="color:rgba(255,255,255,.65)"> |
| 31 | Deploy serverless functions to 200+ edge locations worldwide. |
| 32 | </p> |
| 33 | <button class="px-4 py-2 rounded-md text-[11px] font-semibold bg-[#00FF41] text-[#0A0A0A] hover:-translate-y-0.5 hover:shadow-lg transition-all"> |
| 34 | Learn More |
| 35 | </button> |
| 36 | </div> |
| 37 | </div> |
| 38 | </div> |
| 39 | <div class="flex-none w-full min-w-full"> |
| 40 | <div class="min-h-[220px] p-7 flex items-end" style="background:linear-gradient(135deg,#0c2340,#1e5a8a,#2980b9)"> |
| 41 | <div class="relative z-10"> |
| 42 | <span class="inline-block px-2 py-0.5 rounded text-[9px] font-bold uppercase tracking-wider mb-2.5 bg-[rgba(0,255,65,.15)] text-[#00FF41]"> |
| 43 | Popular |
| 44 | </span> |
| 45 | <h3 class="text-lg font-bold text-[#E0E0E0] mb-1.5"> |
| 46 | AI Workflows |
| 47 | </h3> |
| 48 | <p class="text-xs mb-3.5 leading-relaxed" style="color:rgba(255,255,255,.65)"> |
| 49 | Orchestrate multi-step AI pipelines with automatic retries. |
| 50 | </p> |
| 51 | <button class="px-4 py-2 rounded-md text-[11px] font-semibold bg-[#00FF41] text-[#0A0A0A] hover:-translate-y-0.5 hover:shadow-lg transition-all"> |
| 52 | Learn More |
| 53 | </button> |
| 54 | </div> |
| 55 | </div> |
| 56 | </div> |
| 57 | </div> |
| 58 | <div class="h-[3px] bg-[#222]"> |
| 59 | <div data-bar class="h-full bg-[#00FF41] w-0 transition-[width] duration-[4000ms] ease-linear"> |
| 60 | </div> |
| 61 | </div> |
| 62 | <div class="flex items-center justify-between px-4 py-3"> |
| 63 | <button data-prev aria-label="Previous slide" class="w-7 h-7 rounded-md border border-[#333] bg-transparent text-[#808080] flex items-center justify-center hover:bg-white/5 hover:text-[#E0E0E0] transition-all"> |
| 64 | <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 65 | <polyline points="15 18 9 12 15 6"/> |
| 66 | </svg> |
| 67 | </button> |
| 68 | <div class="flex gap-1.5" data-dots> |
| 69 | <span class="w-1.5 h-1.5 rounded-full bg-[#333] cursor-pointer transition-all data-[active=true]:bg-[#00FF41] data-[active=true]:w-[18px] data-[active=true]:rounded-[3px]" data-active="true"> |
| 70 | </span> |
| 71 | <span class="w-1.5 h-1.5 rounded-full bg-[#333] cursor-pointer transition-all data-[active=true]:bg-[#00FF41] data-[active=true]:w-[18px] data-[active=true]:rounded-[3px]"> |
| 72 | </span> |
| 73 | <span class="w-1.5 h-1.5 rounded-full bg-[#333] cursor-pointer transition-all data-[active=true]:bg-[#00FF41] data-[active=true]:w-[18px] data-[active=true]:rounded-[3px]"> |
| 74 | </span> |
| 75 | </div> |
| 76 | <button data-next aria-label="Next slide" class="w-7 h-7 rounded-md border border-[#333] bg-transparent text-[#808080] flex items-center justify-center hover:bg-white/5 hover:text-[#E0E0E0] transition-all"> |
| 77 | <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 78 | <polyline points="9 18 15 12 9 6"/> |
| 79 | </svg> |
| 80 | </button> |
| 81 | </div> |
| 82 | </div> |
| 1 | <div class="mx-auto rounded-3 overflow-hidden border border-secondary" style="max-width:400px;background:#111;font-family:system-ui,sans-serif" id="bs-auto"> |
| 2 | <div class="d-flex" id="bs-auto-track" style="transition:transform .5s cubic-bezier(.4,0,.2,1)"> |
| 3 | <div class="flex-shrink-0" style="min-width:100%"> |
| 4 | <div class="d-flex align-items-end p-4" style="min-height:220px;background:linear-gradient(135deg,#0f2027,#203a43,#2c5364)"> |
| 5 | <div> |
| 6 | <span class="badge mb-2" style="background:rgba(0,255,65,.15);color:#00FF41;font-size:9px;text-transform:uppercase"> |
| 7 | Featured |
| 8 | </span> |
| 9 | <h3 class="h5 fw-bold text-white mb-1"> |
| 10 | Design Systems |
| 11 | </h3> |
| 12 | <p class="small mb-3" style="color:rgba(255,255,255,.65)"> |
| 13 | Build scalable component libraries with consistent tokens and patterns. |
| 14 | </p> |
| 15 | <button class="btn btn-sm fw-semibold" style="background:#00FF41;color:#0A0A0A"> |
| 16 | Learn More |
| 17 | </button> |
| 18 | </div> |
| 19 | </div> |
| 20 | </div> |
| 21 | <div class="flex-shrink-0" style="min-width:100%"> |
| 22 | <div class="d-flex align-items-end p-4" style="min-height:220px;background:linear-gradient(135deg,#1a0533,#2d1b69,#5b2c8e)"> |
| 23 | <div> |
| 24 | <span class="badge mb-2" style="background:rgba(0,255,65,.15);color:#00FF41;font-size:9px;text-transform:uppercase"> |
| 25 | New |
| 26 | </span> |
| 27 | <h3 class="h5 fw-bold text-white mb-1"> |
| 28 | Edge Computing |
| 29 | </h3> |
| 30 | <p class="small mb-3" style="color:rgba(255,255,255,.65)"> |
| 31 | Deploy serverless functions to 200+ edge locations worldwide. |
| 32 | </p> |
| 33 | <button class="btn btn-sm fw-semibold" style="background:#00FF41;color:#0A0A0A"> |
| 34 | Learn More |
| 35 | </button> |
| 36 | </div> |
| 37 | </div> |
| 38 | </div> |
| 39 | <div class="flex-shrink-0" style="min-width:100%"> |
| 40 | <div class="d-flex align-items-end p-4" style="min-height:220px;background:linear-gradient(135deg,#0c2340,#1e5a8a,#2980b9)"> |
| 41 | <div> |
| 42 | <span class="badge mb-2" style="background:rgba(0,255,65,.15);color:#00FF41;font-size:9px;text-transform:uppercase"> |
| 43 | Popular |
| 44 | </span> |
| 45 | <h3 class="h5 fw-bold text-white mb-1"> |
| 46 | AI Workflows |
| 47 | </h3> |
| 48 | <p class="small mb-3" style="color:rgba(255,255,255,.65)"> |
| 49 | Orchestrate multi-step AI pipelines with automatic retries. |
| 50 | </p> |
| 51 | <button class="btn btn-sm fw-semibold" style="background:#00FF41;color:#0A0A0A"> |
| 52 | Learn More |
| 53 | </button> |
| 54 | </div> |
| 55 | </div> |
| 56 | </div> |
| 57 | </div> |
| 58 | <div style="height:3px;background:#222"> |
| 59 | <div id="bs-auto-bar" style="height:100%;background:#00FF41;width:0%;transition:width 4s linear"> |
| 60 | </div> |
| 61 | </div> |
| 62 | <div class="d-flex align-items-center justify-content-between px-3 py-2"> |
| 63 | <button id="bs-auto-prev" class="btn btn-sm btn-dark border-secondary d-flex align-items-center justify-content-center p-1" aria-label="Previous slide"> |
| 64 | <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 65 | <polyline points="15 18 9 12 15 6"/> |
| 66 | </svg> |
| 67 | </button> |
| 68 | <div class="d-flex gap-2" id="bs-auto-dots"> |
| 69 | <span class="rounded-pill" style="width:6px;height:6px;background:#333;cursor:pointer"> |
| 70 | </span> |
| 71 | <span class="rounded-pill" style="width:6px;height:6px;background:#333;cursor:pointer"> |
| 72 | </span> |
| 73 | <span class="rounded-pill" style="width:6px;height:6px;background:#333;cursor:pointer"> |
| 74 | </span> |
| 75 | </div> |
| 76 | <button id="bs-auto-next" class="btn btn-sm btn-dark border-secondary d-flex align-items-center justify-content-center p-1" aria-label="Next slide"> |
| 77 | <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 78 | <polyline points="9 18 15 12 9 6"/> |
| 79 | </svg> |
| 80 | </button> |
| 81 | </div> |
| 82 | </div> |
Display multiple items per viewport with scroll snap. Each card uses flex: 0 0 calc(33.333% - 7px) for three visible items. Ideal for product grids, lesson lists, and card decks.
| 1 | <div class="multi-carousel"> |
| 2 | <div class="multi-track"> |
| 3 | <div class="multi-card"> |
| 4 | <div class="multi-avatar" style="background:#1a1a2e"> |
| 5 | JS |
| 6 | </div> |
| 7 | <div class="multi-info"> |
| 8 | <h5> |
| 9 | JavaScript |
| 10 | </h5> |
| 11 | <span> |
| 12 | 24 lessons |
| 13 | </span> |
| 14 | </div> |
| 15 | </div> |
| 16 | <div class="multi-card"> |
| 17 | <div class="multi-avatar" style="background:#16213e"> |
| 18 | TS |
| 19 | </div> |
| 20 | <div class="multi-info"> |
| 21 | <h5> |
| 22 | TypeScript |
| 23 | </h5> |
| 24 | <span> |
| 25 | 18 lessons |
| 26 | </span> |
| 27 | </div> |
| 28 | </div> |
| 29 | <div class="multi-card"> |
| 30 | <div class="multi-avatar" style="background:#0f3460"> |
| 31 | PY |
| 32 | </div> |
| 33 | <div class="multi-info"> |
| 34 | <h5> |
| 35 | Python |
| 36 | </h5> |
| 37 | <span> |
| 38 | 32 lessons |
| 39 | </span> |
| 40 | </div> |
| 41 | </div> |
| 42 | <div class="multi-card"> |
| 43 | <div class="multi-avatar" style="background:#533483"> |
| 44 | RS |
| 45 | </div> |
| 46 | <div class="multi-info"> |
| 47 | <h5> |
| 48 | Rust |
| 49 | </h5> |
| 50 | <span> |
| 51 | 14 lessons |
| 52 | </span> |
| 53 | </div> |
| 54 | </div> |
| 55 | <div class="multi-card"> |
| 56 | <div class="multi-avatar" style="background:#2d1810"> |
| 57 | GO |
| 58 | </div> |
| 59 | <div class="multi-info"> |
| 60 | <h5> |
| 61 | Go |
| 62 | </h5> |
| 63 | <span> |
| 64 | 20 lessons |
| 65 | </span> |
| 66 | </div> |
| 67 | </div> |
| 68 | <div class="multi-card"> |
| 69 | <div class="multi-avatar" style="background:#1a3a1a"> |
| 70 | SW |
| 71 | </div> |
| 72 | <div class="multi-info"> |
| 73 | <h5> |
| 74 | Swift |
| 75 | </h5> |
| 76 | <span> |
| 77 | 16 lessons |
| 78 | </span> |
| 79 | </div> |
| 80 | </div> |
| 81 | </div> |
| 82 | </div> |
| 1 | .multi-carousel { |
| 2 | width:100%; |
| 3 | overflow:hidden; |
| 4 | font-family:system-ui, |
| 5 | sans-serif |
| 6 | } |
| 7 | .multi-track { |
| 8 | display:flex; |
| 9 | gap:10px; |
| 10 | overflow-x:auto; |
| 11 | scroll-snap-type:x mandatory; |
| 12 | scroll-behavior:smooth; |
| 13 | padding:16px 4px; |
| 14 | scrollbar-width:none |
| 15 | } |
| 16 | .multi-track::-webkit-scrollbar { |
| 17 | display:none |
| 18 | } |
| 19 | .multi-card { |
| 20 | flex:0 0 calc(33.333% - 7px); |
| 21 | scroll-snap-align:start; |
| 22 | background:#111; |
| 23 | border:1px solid #222; |
| 24 | border-radius:10px; |
| 25 | padding:14px; |
| 26 | display:flex; |
| 27 | flex-direction:column; |
| 28 | align-items:center; |
| 29 | gap:10px; |
| 30 | transition:border-color .2s |
| 31 | } |
| 32 | .multi-card:hover { |
| 33 | border-color:rgba(0, |
| 34 | 255, |
| 35 | 65, |
| 36 | .3) |
| 37 | } |
| 38 | .multi-avatar { |
| 39 | width:40px; |
| 40 | height:40px; |
| 41 | border-radius:8px; |
| 42 | display:flex; |
| 43 | align-items:center; |
| 44 | justify-content:center; |
| 45 | font-size:12px; |
| 46 | font-weight:800; |
| 47 | color:rgba(255, |
| 48 | 255, |
| 49 | 255, |
| 50 | .6) |
| 51 | } |
| 52 | .multi-info { |
| 53 | text-align:center |
| 54 | } |
| 55 | .multi-info h5 { |
| 56 | font-size:12px; |
| 57 | font-weight:600; |
| 58 | color:#E0E0E0; |
| 59 | margin:0 0 2px |
| 60 | } |
| 61 | .multi-info span { |
| 62 | font-size:10px; |
| 63 | color:#666 |
| 64 | } |
| 1 | <div class="w-full overflow-hidden font-sans"> |
| 2 | <div class="flex gap-2.5 overflow-x-auto snap-x snap-mandatory scroll-smooth py-4 px-1 scrollbar-hide" style="scrollbar-width:none"> |
| 3 | <div class="flex-none snap-start bg-[#111] border border-[#222] rounded-xl p-3.5 flex flex-col items-center gap-2.5 hover:border-[rgba(0,255,65,.3)] transition-colors" style="flex:0 0 calc(33.333% - 7px)"> |
| 4 | <div class="w-10 h-10 rounded-lg flex items-center justify-center text-xs font-extrabold" style="background:#1a1a2e;color:rgba(255,255,255,.6)"> |
| 5 | JS |
| 6 | </div> |
| 7 | <div class="text-center"> |
| 8 | <h5 class="text-xs font-semibold text-[#E0E0E0] mb-0.5"> |
| 9 | JavaScript |
| 10 | </h5> |
| 11 | <span class="text-[10px] text-[#666]"> |
| 12 | 24 lessons |
| 13 | </span> |
| 14 | </div> |
| 15 | </div> |
| 16 | <div class="flex-none snap-start bg-[#111] border border-[#222] rounded-xl p-3.5 flex flex-col items-center gap-2.5 hover:border-[rgba(0,255,65,.3)] transition-colors" style="flex:0 0 calc(33.333% - 7px)"> |
| 17 | <div class="w-10 h-10 rounded-lg flex items-center justify-center text-xs font-extrabold" style="background:#16213e;color:rgba(255,255,255,.6)"> |
| 18 | TS |
| 19 | </div> |
| 20 | <div class="text-center"> |
| 21 | <h5 class="text-xs font-semibold text-[#E0E0E0] mb-0.5"> |
| 22 | TypeScript |
| 23 | </h5> |
| 24 | <span class="text-[10px] text-[#666]"> |
| 25 | 18 lessons |
| 26 | </span> |
| 27 | </div> |
| 28 | </div> |
| 29 | <div class="flex-none snap-start bg-[#111] border border-[#222] rounded-xl p-3.5 flex flex-col items-center gap-2.5 hover:border-[rgba(0,255,65,.3)] transition-colors" style="flex:0 0 calc(33.333% - 7px)"> |
| 30 | <div class="w-10 h-10 rounded-lg flex items-center justify-center text-xs font-extrabold" style="background:#0f3460;color:rgba(255,255,255,.6)"> |
| 31 | PY |
| 32 | </div> |
| 33 | <div class="text-center"> |
| 34 | <h5 class="text-xs font-semibold text-[#E0E0E0] mb-0.5"> |
| 35 | Python |
| 36 | </h5> |
| 37 | <span class="text-[10px] text-[#666]"> |
| 38 | 32 lessons |
| 39 | </span> |
| 40 | </div> |
| 41 | </div> |
| 42 | <div class="flex-none snap-start bg-[#111] border border-[#222] rounded-xl p-3.5 flex flex-col items-center gap-2.5 hover:border-[rgba(0,255,65,.3)] transition-colors" style="flex:0 0 calc(33.333% - 7px)"> |
| 43 | <div class="w-10 h-10 rounded-lg flex items-center justify-center text-xs font-extrabold" style="background:#533483;color:rgba(255,255,255,.6)"> |
| 44 | RS |
| 45 | </div> |
| 46 | <div class="text-center"> |
| 47 | <h5 class="text-xs font-semibold text-[#E0E0E0] mb-0.5"> |
| 48 | Rust |
| 49 | </h5> |
| 50 | <span class="text-[10px] text-[#666]"> |
| 51 | 14 lessons |
| 52 | </span> |
| 53 | </div> |
| 54 | </div> |
| 55 | <div class="flex-none snap-start bg-[#111] border border-[#222] rounded-xl p-3.5 flex flex-col items-center gap-2.5 hover:border-[rgba(0,255,65,.3)] transition-colors" style="flex:0 0 calc(33.333% - 7px)"> |
| 56 | <div class="w-10 h-10 rounded-lg flex items-center justify-center text-xs font-extrabold" style="background:#2d1810;color:rgba(255,255,255,.6)"> |
| 57 | GO |
| 58 | </div> |
| 59 | <div class="text-center"> |
| 60 | <h5 class="text-xs font-semibold text-[#E0E0E0] mb-0.5"> |
| 61 | Go |
| 62 | </h5> |
| 63 | <span class="text-[10px] text-[#666]"> |
| 64 | 20 lessons |
| 65 | </span> |
| 66 | </div> |
| 67 | </div> |
| 68 | <div class="flex-none snap-start bg-[#111] border border-[#222] rounded-xl p-3.5 flex flex-col items-center gap-2.5 hover:border-[rgba(0,255,65,.3)] transition-colors" style="flex:0 0 calc(33.333% - 7px)"> |
| 69 | <div class="w-10 h-10 rounded-lg flex items-center justify-center text-xs font-extrabold" style="background:#1a3a1a;color:rgba(255,255,255,.6)"> |
| 70 | SW |
| 71 | </div> |
| 72 | <div class="text-center"> |
| 73 | <h5 class="text-xs font-semibold text-[#E0E0E0] mb-0.5"> |
| 74 | Swift |
| 75 | </h5> |
| 76 | <span class="text-[10px] text-[#666]"> |
| 77 | 16 lessons |
| 78 | </span> |
| 79 | </div> |
| 80 | </div> |
| 81 | </div> |
| 82 | </div> |
| 1 | <div class="container-fluid overflow-hidden" style="font-family:system-ui,sans-serif"> |
| 2 | <div class="d-flex gap-2 overflow-auto pb-3" style="scroll-snap-type:x mandatory;scroll-behavior:smooth;scrollbar-width:none"> |
| 3 | <div class="card flex-shrink-0 border-secondary bg-black text-center py-3" style="width:calc(33.333% - 7px);scroll-snap-align:start"> |
| 4 | <div class="mx-auto rounded-2 d-flex align-items-center justify-content-center fw-bold" style="width:40px;height:40px;background:#1a1a2e;color:rgba(255,255,255,.6);font-size:12px"> |
| 5 | JS |
| 6 | </div> |
| 7 | <div class="card-body py-2"> |
| 8 | <h5 class="card-title h6 text-white mb-1" style="font-size:12px"> |
| 9 | JavaScript |
| 10 | </h5> |
| 11 | <p class="card-text mb-0" style="font-size:10px;color:#666"> |
| 12 | 24 lessons |
| 13 | </p> |
| 14 | </div> |
| 15 | </div> |
| 16 | <div class="card flex-shrink-0 border-secondary bg-black text-center py-3" style="width:calc(33.333% - 7px);scroll-snap-align:start"> |
| 17 | <div class="mx-auto rounded-2 d-flex align-items-center justify-content-center fw-bold" style="width:40px;height:40px;background:#16213e;color:rgba(255,255,255,.6);font-size:12px"> |
| 18 | TS |
| 19 | </div> |
| 20 | <div class="card-body py-2"> |
| 21 | <h5 class="card-title h6 text-white mb-1" style="font-size:12px"> |
| 22 | TypeScript |
| 23 | </h5> |
| 24 | <p class="card-text mb-0" style="font-size:10px;color:#666"> |
| 25 | 18 lessons |
| 26 | </p> |
| 27 | </div> |
| 28 | </div> |
| 29 | <div class="card flex-shrink-0 border-secondary bg-black text-center py-3" style="width:calc(33.333% - 7px);scroll-snap-align:start"> |
| 30 | <div class="mx-auto rounded-2 d-flex align-items-center justify-content-center fw-bold" style="width:40px;height:40px;background:#0f3460;color:rgba(255,255,255,.6);font-size:12px"> |
| 31 | PY |
| 32 | </div> |
| 33 | <div class="card-body py-2"> |
| 34 | <h5 class="card-title h6 text-white mb-1" style="font-size:12px"> |
| 35 | Python |
| 36 | </h5> |
| 37 | <p class="card-text mb-0" style="font-size:10px;color:#666"> |
| 38 | 32 lessons |
| 39 | </p> |
| 40 | </div> |
| 41 | </div> |
| 42 | <div class="card flex-shrink-0 border-secondary bg-black text-center py-3" style="width:calc(33.333% - 7px);scroll-snap-align:start"> |
| 43 | <div class="mx-auto rounded-2 d-flex align-items-center justify-content-center fw-bold" style="width:40px;height:40px;background:#533483;color:rgba(255,255,255,.6);font-size:12px"> |
| 44 | RS |
| 45 | </div> |
| 46 | <div class="card-body py-2"> |
| 47 | <h5 class="card-title h6 text-white mb-1" style="font-size:12px"> |
| 48 | Rust |
| 49 | </h5> |
| 50 | <p class="card-text mb-0" style="font-size:10px;color:#666"> |
| 51 | 14 lessons |
| 52 | </p> |
| 53 | </div> |
| 54 | </div> |
| 55 | <div class="card flex-shrink-0 border-secondary bg-black text-center py-3" style="width:calc(33.333% - 7px);scroll-snap-align:start"> |
| 56 | <div class="mx-auto rounded-2 d-flex align-items-center justify-content-center fw-bold" style="width:40px;height:40px;background:#2d1810;color:rgba(255,255,255,.6);font-size:12px"> |
| 57 | GO |
| 58 | </div> |
| 59 | <div class="card-body py-2"> |
| 60 | <h5 class="card-title h6 text-white mb-1" style="font-size:12px"> |
| 61 | Go |
| 62 | </h5> |
| 63 | <p class="card-text mb-0" style="font-size:10px;color:#666"> |
| 64 | 20 lessons |
| 65 | </p> |
| 66 | </div> |
| 67 | </div> |
| 68 | <div class="card flex-shrink-0 border-secondary bg-black text-center py-3" style="width:calc(33.333% - 7px);scroll-snap-align:start"> |
| 69 | <div class="mx-auto rounded-2 d-flex align-items-center justify-content-center fw-bold" style="width:40px;height:40px;background:#1a3a1a;color:rgba(255,255,255,.6);font-size:12px"> |
| 70 | SW |
| 71 | </div> |
| 72 | <div class="card-body py-2"> |
| 73 | <h5 class="card-title h6 text-white mb-1" style="font-size:12px"> |
| 74 | Swift |
| 75 | </h5> |
| 76 | <p class="card-text mb-0" style="font-size:10px;color:#666"> |
| 77 | 16 lessons |
| 78 | </p> |
| 79 | </div> |
| 80 | </div> |
| 81 | </div> |
| 82 | </div> |
A content-focused carousel for quotes and reviews. Slides crossfade every 5 seconds with manual dot navigation and author details.
| 1 | <div class="testi-carousel" id="testi-carousel"> |
| 2 | <div class="testi-slide active" data-testi="0"> |
| 3 | <div class="testi-stars"> |
| 4 | ★★★★★ |
| 5 | </div> |
| 6 | <blockquote class="testi-quote"> |
| 7 | "This design system reduced our component development time by 60%. The token architecture is incredibly well thought out." |
| 8 | </blockquote> |
| 9 | <div class="testi-author"> |
| 10 | <div class="testi-avatar"> |
| 11 | SK |
| 12 | </div> |
| 13 | <div> |
| 14 | <span class="testi-name"> |
| 15 | Sarah Kim |
| 16 | </span> |
| 17 | <span class="testi-role"> |
| 18 | Engineering Lead, Vercel |
| 19 | </span> |
| 20 | </div> |
| 21 | </div> |
| 22 | </div> |
| 23 | <div class="testi-slide" data-testi="1"> |
| 24 | <div class="testi-stars"> |
| 25 | ★★★★★ |
| 26 | </div> |
| 27 | <blockquote class="testi-quote"> |
| 28 | "We migrated our entire frontend in 3 weeks. The component API is consistent and the documentation is outstanding." |
| 29 | </blockquote> |
| 30 | <div class="testi-author"> |
| 31 | <div class="testi-avatar"> |
| 32 | MR |
| 33 | </div> |
| 34 | <div> |
| 35 | <span class="testi-name"> |
| 36 | Marcus Rivera |
| 37 | </span> |
| 38 | <span class="testi-role"> |
| 39 | CTO, Stripe |
| 40 | </span> |
| 41 | </div> |
| 42 | </div> |
| 43 | </div> |
| 44 | <div class="testi-slide" data-testi="2"> |
| 45 | <div class="testi-stars"> |
| 46 | ★★★★★ |
| 47 | </div> |
| 48 | <blockquote class="testi-quote"> |
| 49 | "The accessibility-first approach means we don't have to retrofit a11y later. Every component works with screen readers out of the box." |
| 50 | </blockquote> |
| 51 | <div class="testi-author"> |
| 52 | <div class="testi-avatar"> |
| 53 | AL |
| 54 | </div> |
| 55 | <div> |
| 56 | <span class="testi-name"> |
| 57 | Aisha Liang |
| 58 | </span> |
| 59 | <span class="testi-role"> |
| 60 | Designer, Figma |
| 61 | </span> |
| 62 | </div> |
| 63 | </div> |
| 64 | </div> |
| 65 | <div class="testi-nav"> |
| 66 | <button class="testi-dot active" data-i="0" aria-label="Go to slide 1"> |
| 67 | </button> |
| 68 | <button class="testi-dot" data-i="1" aria-label="Go to slide 2"> |
| 69 | </button> |
| 70 | <button class="testi-dot" data-i="2" aria-label="Go to slide 3"> |
| 71 | </button> |
| 72 | </div> |
| 73 | </div> |
| 1 | .testi-carousel { |
| 2 | max-width:380px; |
| 3 | margin:16px auto; |
| 4 | padding:24px; |
| 5 | background:#111; |
| 6 | border:1px solid #222; |
| 7 | border-radius:12px; |
| 8 | position:relative; |
| 9 | font-family:system-ui, |
| 10 | sans-serif; |
| 11 | min-height:240px |
| 12 | } |
| 13 | .testi-slide { |
| 14 | display:none; |
| 15 | flex-direction:column; |
| 16 | gap:16px; |
| 17 | animation:fadeIn .35s ease |
| 18 | } |
| 19 | .testi-slide.active { |
| 20 | display:flex |
| 21 | } |
| 22 | .testi-stars { |
| 23 | color:#FBBF24; |
| 24 | font-size:14px; |
| 25 | letter-spacing:2px |
| 26 | } |
| 27 | .testi-quote { |
| 28 | font-size:13px; |
| 29 | color:#C0C0C0; |
| 30 | line-height:1.6; |
| 31 | margin:0; |
| 32 | font-style:italic; |
| 33 | border-left:2px solid #00FF41; |
| 34 | padding-left:14px |
| 35 | } |
| 36 | .testi-author { |
| 37 | display:flex; |
| 38 | align-items:center; |
| 39 | gap:10px |
| 40 | } |
| 41 | .testi-avatar { |
| 42 | width:38px; |
| 43 | height:38px; |
| 44 | border-radius:50%; |
| 45 | background:#1A1A2E; |
| 46 | display:flex; |
| 47 | align-items:center; |
| 48 | justify-content:center; |
| 49 | font-size:11px; |
| 50 | font-weight:700; |
| 51 | color:#00FF41 |
| 52 | } |
| 53 | .testi-name { |
| 54 | display:block; |
| 55 | font-size:12px; |
| 56 | font-weight:600; |
| 57 | color:#E0E0E0 |
| 58 | } |
| 59 | .testi-role { |
| 60 | display:block; |
| 61 | font-size:10px; |
| 62 | color:#666; |
| 63 | margin-top:2px |
| 64 | } |
| 65 | .testi-nav { |
| 66 | display:flex; |
| 67 | gap:6px; |
| 68 | justify-content:center; |
| 69 | position:absolute; |
| 70 | bottom:16px; |
| 71 | left:50%; |
| 72 | transform:translateX(-50%) |
| 73 | } |
| 74 | .testi-dot { |
| 75 | width:6px; |
| 76 | height:6px; |
| 77 | border-radius:50%; |
| 78 | border:none; |
| 79 | background:#333; |
| 80 | cursor:pointer; |
| 81 | transition:all .2s; |
| 82 | padding:0 |
| 83 | } |
| 84 | .testi-dot.active { |
| 85 | background:#00FF41; |
| 86 | width:18px; |
| 87 | border-radius:3px |
| 88 | } |
| 89 | @keyframes fadeIn { |
| 90 | from { |
| 91 | opacity:0; |
| 92 | transform:translateY(8px) |
| 93 | } |
| 94 | to { |
| 95 | opacity:1; |
| 96 | transform:translateY(0) |
| 97 | } |
| 98 | } |
| 1 | let tcur=0;const tslides=document.querySelectorAll('[data-testi]');const tdots=document.querySelectorAll('.testi-dot');function tshow(i){tslides.forEach(s=>s.classList.remove('active'));tdots.forEach(t=>t.classList.remove('active'));tslides[i].classList.add('active');tdots[i].classList.add('active');tcur=i}tdots.forEach(t=>t.addEventListener('click',()=>tshow(parseInt(t.dataset.i))));setInterval(()=>tshow((tcur+1)%tslides.length),5000); |
| 1 | <div class="max-w-[380px] mx-auto p-6 bg-[#111] border border-[#222] rounded-xl relative font-sans min-h-[240px]" id="tw-testi"> |
| 2 | <div data-slide class="hidden flex-col gap-4 animate-[fadeIn_.35s_ease]"> |
| 3 | <div class="text-sm tracking-widest" style="color:#FBBF24"> |
| 4 | ★★★★★ |
| 5 | </div> |
| 6 | <blockquote class="text-[13px] leading-relaxed italic pl-3.5 border-l-2 border-[#00FF41] m-0" style="color:#C0C0C0"> |
| 7 | "This design system reduced our component development time by 60%. The token architecture is incredibly well thought out." |
| 8 | </blockquote> |
| 9 | <div class="flex items-center gap-2.5"> |
| 10 | <div class="w-[38px] h-[38px] rounded-full bg-[#1A1A2E] flex items-center justify-center text-[11px] font-bold text-[#00FF41]"> |
| 11 | SK |
| 12 | </div> |
| 13 | <div> |
| 14 | <span class="block text-xs font-semibold text-[#E0E0E0]"> |
| 15 | Sarah Kim |
| 16 | </span> |
| 17 | <span class="block text-[10px] text-[#666] mt-0.5"> |
| 18 | Engineering Lead, Vercel |
| 19 | </span> |
| 20 | </div> |
| 21 | </div> |
| 22 | </div> |
| 23 | <div data-slide class="hidden flex-col gap-4 animate-[fadeIn_.35s_ease]"> |
| 24 | <div class="text-sm tracking-widest" style="color:#FBBF24"> |
| 25 | ★★★★★ |
| 26 | </div> |
| 27 | <blockquote class="text-[13px] leading-relaxed italic pl-3.5 border-l-2 border-[#00FF41] m-0" style="color:#C0C0C0"> |
| 28 | "We migrated our entire frontend in 3 weeks. The component API is consistent and the documentation is outstanding." |
| 29 | </blockquote> |
| 30 | <div class="flex items-center gap-2.5"> |
| 31 | <div class="w-[38px] h-[38px] rounded-full bg-[#1A1A2E] flex items-center justify-center text-[11px] font-bold text-[#00FF41]"> |
| 32 | MR |
| 33 | </div> |
| 34 | <div> |
| 35 | <span class="block text-xs font-semibold text-[#E0E0E0]"> |
| 36 | Marcus Rivera |
| 37 | </span> |
| 38 | <span class="block text-[10px] text-[#666] mt-0.5"> |
| 39 | CTO, Stripe |
| 40 | </span> |
| 41 | </div> |
| 42 | </div> |
| 43 | </div> |
| 44 | <div data-slide class="hidden flex-col gap-4 animate-[fadeIn_.35s_ease]"> |
| 45 | <div class="text-sm tracking-widest" style="color:#FBBF24"> |
| 46 | ★★★★★ |
| 47 | </div> |
| 48 | <blockquote class="text-[13px] leading-relaxed italic pl-3.5 border-l-2 border-[#00FF41] m-0" style="color:#C0C0C0"> |
| 49 | "The accessibility-first approach means we don't have to retrofit a11y later. Every component works with screen readers out of the box." |
| 50 | </blockquote> |
| 51 | <div class="flex items-center gap-2.5"> |
| 52 | <div class="w-[38px] h-[38px] rounded-full bg-[#1A1A2E] flex items-center justify-center text-[11px] font-bold text-[#00FF41]"> |
| 53 | AL |
| 54 | </div> |
| 55 | <div> |
| 56 | <span class="block text-xs font-semibold text-[#E0E0E0]"> |
| 57 | Aisha Liang |
| 58 | </span> |
| 59 | <span class="block text-[10px] text-[#666] mt-0.5"> |
| 60 | Designer, Figma |
| 61 | </span> |
| 62 | </div> |
| 63 | </div> |
| 64 | </div> |
| 65 | <div class="flex gap-1.5 justify-center absolute bottom-4 left-1/2 -translate-x-1/2" data-dots> |
| 66 | <button aria-label="Go to slide 1" class="w-1.5 h-1.5 rounded-full bg-[#333] transition-all data-[active=true]:bg-[#00FF41] data-[active=true]:w-[18px] data-[active=true]:rounded-[3px]" data-active="true"> |
| 67 | </button> |
| 68 | <button aria-label="Go to slide 2" class="w-1.5 h-1.5 rounded-full bg-[#333] transition-all data-[active=true]:bg-[#00FF41] data-[active=true]:w-[18px] data-[active=true]:rounded-[3px]"> |
| 69 | </button> |
| 70 | <button aria-label="Go to slide 3" class="w-1.5 h-1.5 rounded-full bg-[#333] transition-all data-[active=true]:bg-[#00FF41] data-[active=true]:w-[18px] data-[active=true]:rounded-[3px]"> |
| 71 | </button> |
| 72 | </div> |
| 73 | </div> |
| 1 | <div class="mx-auto position-relative rounded-4 border border-secondary p-4" style="max-width:380px;background:#111;font-family:system-ui,sans-serif;min-height:240px" id="bs-testi"> |
| 2 | <div data-slide class="d-none flex-column gap-3"> |
| 3 | <div style="color:#FBBF24;font-size:14px;letter-spacing:2px"> |
| 4 | ★★★★★ |
| 5 | </div> |
| 6 | <blockquote class="fst-italic ps-3 mb-0" style="font-size:13px;color:#C0C0C0;border-left:2px solid #00FF41"> |
| 7 | "This design system reduced our component development time by 60%. The token architecture is incredibly well thought out." |
| 8 | </blockquote> |
| 9 | <div class="d-flex align-items-center gap-2"> |
| 10 | <div class="rounded-circle d-flex align-items-center justify-content-center fw-bold" style="width:38px;height:38px;background:#1A1A2E;color:#00FF41;font-size:11px"> |
| 11 | SK |
| 12 | </div> |
| 13 | <div> |
| 14 | <span class="d-block fw-semibold text-white" style="font-size:12px"> |
| 15 | Sarah Kim |
| 16 | </span> |
| 17 | <span class="d-block" style="font-size:10px;color:#666"> |
| 18 | Engineering Lead, Vercel |
| 19 | </span> |
| 20 | </div> |
| 21 | </div> |
| 22 | </div> |
| 23 | <div data-slide class="d-none flex-column gap-3"> |
| 24 | <div style="color:#FBBF24;font-size:14px;letter-spacing:2px"> |
| 25 | ★★★★★ |
| 26 | </div> |
| 27 | <blockquote class="fst-italic ps-3 mb-0" style="font-size:13px;color:#C0C0C0;border-left:2px solid #00FF41"> |
| 28 | "We migrated our entire frontend in 3 weeks. The component API is consistent and the documentation is outstanding." |
| 29 | </blockquote> |
| 30 | <div class="d-flex align-items-center gap-2"> |
| 31 | <div class="rounded-circle d-flex align-items-center justify-content-center fw-bold" style="width:38px;height:38px;background:#1A1A2E;color:#00FF41;font-size:11px"> |
| 32 | MR |
| 33 | </div> |
| 34 | <div> |
| 35 | <span class="d-block fw-semibold text-white" style="font-size:12px"> |
| 36 | Marcus Rivera |
| 37 | </span> |
| 38 | <span class="d-block" style="font-size:10px;color:#666"> |
| 39 | CTO, Stripe |
| 40 | </span> |
| 41 | </div> |
| 42 | </div> |
| 43 | </div> |
| 44 | <div data-slide class="d-none flex-column gap-3"> |
| 45 | <div style="color:#FBBF24;font-size:14px;letter-spacing:2px"> |
| 46 | ★★★★★ |
| 47 | </div> |
| 48 | <blockquote class="fst-italic ps-3 mb-0" style="font-size:13px;color:#C0C0C0;border-left:2px solid #00FF41"> |
| 49 | "The accessibility-first approach means we don't have to retrofit a11y later. Every component works with screen readers out of the box." |
| 50 | </blockquote> |
| 51 | <div class="d-flex align-items-center gap-2"> |
| 52 | <div class="rounded-circle d-flex align-items-center justify-content-center fw-bold" style="width:38px;height:38px;background:#1A1A2E;color:#00FF41;font-size:11px"> |
| 53 | AL |
| 54 | </div> |
| 55 | <div> |
| 56 | <span class="d-block fw-semibold text-white" style="font-size:12px"> |
| 57 | Aisha Liang |
| 58 | </span> |
| 59 | <span class="d-block" style="font-size:10px;color:#666"> |
| 60 | Designer, Figma |
| 61 | </span> |
| 62 | </div> |
| 63 | </div> |
| 64 | </div> |
| 65 | <div class="d-flex gap-2 justify-content-center position-absolute start-50 translate-middle-x" id="bs-testi-dots" style="bottom:16px"> |
| 66 | <button aria-label="Go to slide 1" class="rounded-pill border-0" style="width:6px;height:6px;background:#00FF41;transition:all .2s"> |
| 67 | </button> |
| 68 | <button aria-label="Go to slide 2" class="rounded-pill border-0" style="width:6px;height:6px;background:#333;cursor:pointer;transition:all .2s"> |
| 69 | </button> |
| 70 | <button aria-label="Go to slide 3" class="rounded-pill border-0" style="width:6px;height:6px;background:#333;cursor:pointer;transition:all .2s"> |
| 71 | </button> |
| 72 | </div> |
| 73 | </div> |
A main image with a thumbnail strip below. Clicking a thumbnail jumps to that slide and highlights the active thumbnail. The strip stays in sync when the main view is scrolled.
| 1 | <div class="thumb-carousel"> |
| 2 | <div class="thumb-main" id="thumb-main"> |
| 3 | <div class="thumb-big" style="background:linear-gradient(135deg,#0f2027,#203a43)"> |
| 4 | <span> |
| 5 | Tokyo |
| 6 | </span> |
| 7 | </div> |
| 8 | <div class="thumb-big" style="background:linear-gradient(135deg,#1a0533,#2d1b69)"> |
| 9 | <span> |
| 10 | Kyoto |
| 11 | </span> |
| 12 | </div> |
| 13 | <div class="thumb-big" style="background:linear-gradient(135deg,#0c2340,#1e5a8a)"> |
| 14 | <span> |
| 15 | Osaka |
| 16 | </span> |
| 17 | </div> |
| 18 | <div class="thumb-big" style="background:linear-gradient(135deg,#2d1810,#5a3a28)"> |
| 19 | <span> |
| 20 | Hiroshima |
| 21 | </span> |
| 22 | </div> |
| 23 | </div> |
| 24 | <div class="thumb-strip"> |
| 25 | <button class="thumb-btn active" data-i="0" aria-label="Show Tokyo"> |
| 26 | <div class="thumb-mini" style="background:#1a2a2f"> |
| 27 | </div> |
| 28 | <span> |
| 29 | Tokyo |
| 30 | </span> |
| 31 | </button> |
| 32 | <button class="thumb-btn" data-i="1" aria-label="Show Kyoto"> |
| 33 | <div class="thumb-mini" style="background:#1a0f33"> |
| 34 | </div> |
| 35 | <span> |
| 36 | Kyoto |
| 37 | </span> |
| 38 | </button> |
| 39 | <button class="thumb-btn" data-i="2" aria-label="Show Osaka"> |
| 40 | <div class="thumb-mini" style="background:#0f2a4a"> |
| 41 | </div> |
| 42 | <span> |
| 43 | Osaka |
| 44 | </span> |
| 45 | </button> |
| 46 | <button class="thumb-btn" data-i="3" aria-label="Show Hiroshima"> |
| 47 | <div class="thumb-mini" style="background:#3a2218"> |
| 48 | </div> |
| 49 | <span> |
| 50 | Hiroshima |
| 51 | </span> |
| 52 | </button> |
| 53 | </div> |
| 54 | </div> |
| 1 | .thumb-carousel { |
| 2 | max-width:400px; |
| 3 | margin:16px auto; |
| 4 | font-family:system-ui, |
| 5 | sans-serif; |
| 6 | border-radius:12px; |
| 7 | overflow:hidden; |
| 8 | border:1px solid #222; |
| 9 | background:#111 |
| 10 | } |
| 11 | .thumb-main { |
| 12 | display:flex; |
| 13 | overflow:hidden; |
| 14 | scroll-snap-type:x mandatory; |
| 15 | scroll-behavior:smooth |
| 16 | } |
| 17 | .thumb-big { |
| 18 | flex:0 0 100%; |
| 19 | height:160px; |
| 20 | display:flex; |
| 21 | align-items:center; |
| 22 | justify-content:center; |
| 23 | scroll-snap-align:start |
| 24 | } |
| 25 | .thumb-big span { |
| 26 | font-size:24px; |
| 27 | font-weight:700; |
| 28 | color:rgba(255, |
| 29 | 255, |
| 30 | 255, |
| 31 | .25) |
| 32 | } |
| 33 | .thumb-strip { |
| 34 | display:flex; |
| 35 | gap:4px; |
| 36 | padding:8px; |
| 37 | border-top:1px solid #222 |
| 38 | } |
| 39 | .thumb-btn { |
| 40 | flex:1; |
| 41 | display:flex; |
| 42 | flex-direction:column; |
| 43 | align-items:center; |
| 44 | gap:4px; |
| 45 | padding:6px 4px; |
| 46 | border-radius:6px; |
| 47 | border:2px solid transparent; |
| 48 | background:transparent; |
| 49 | cursor:pointer; |
| 50 | transition:all .2s; |
| 51 | font-family:inherit |
| 52 | } |
| 53 | .thumb-btn.active { |
| 54 | border-color:#00FF41; |
| 55 | background:rgba(0, |
| 56 | 255, |
| 57 | 65, |
| 58 | .05) |
| 59 | } |
| 60 | .thumb-btn span { |
| 61 | font-size:9px; |
| 62 | color:#666 |
| 63 | } |
| 64 | .thumb-btn.active span { |
| 65 | color:#00FF41 |
| 66 | } |
| 67 | .thumb-mini { |
| 68 | width:100%; |
| 69 | height:24px; |
| 70 | border-radius:4px |
| 71 | } |
| 1 | const tm=document.getElementById('thumb-main');const tbs=document.querySelectorAll('.thumb-btn');tbs.forEach(t=>t.addEventListener('click',()=>{const i=parseInt(t.dataset.i);tm.scrollTo({left:i*tm.offsetWidth,behavior:'smooth'});tbs.forEach(x=>x.classList.remove('active'));t.classList.add('active')}));tm.addEventListener('scroll',()=>{const i=Math.round(tm.scrollLeft/tm.offsetWidth);tbs.forEach((t,j)=>t.classList.toggle('active',j===i))}); |
| 1 | <div class="max-w-[400px] mx-auto font-sans rounded-xl overflow-hidden border border-[#222] bg-[#111]" id="tw-thumb"> |
| 2 | <div class="flex overflow-hidden snap-x snap-mandatory scroll-smooth" data-main> |
| 3 | <div class="flex-none w-full h-40 flex items-center justify-center snap-start" style="background:linear-gradient(135deg,#0f2027,#203a43)"> |
| 4 | <span class="text-2xl font-bold" style="color:rgba(255,255,255,.25)"> |
| 5 | Tokyo |
| 6 | </span> |
| 7 | </div> |
| 8 | <div class="flex-none w-full h-40 flex items-center justify-center snap-start" style="background:linear-gradient(135deg,#1a0533,#2d1b69)"> |
| 9 | <span class="text-2xl font-bold" style="color:rgba(255,255,255,.25)"> |
| 10 | Kyoto |
| 11 | </span> |
| 12 | </div> |
| 13 | <div class="flex-none w-full h-40 flex items-center justify-center snap-start" style="background:linear-gradient(135deg,#0c2340,#1e5a8a)"> |
| 14 | <span class="text-2xl font-bold" style="color:rgba(255,255,255,.25)"> |
| 15 | Osaka |
| 16 | </span> |
| 17 | </div> |
| 18 | <div class="flex-none w-full h-40 flex items-center justify-center snap-start" style="background:linear-gradient(135deg,#2d1810,#5a3a28)"> |
| 19 | <span class="text-2xl font-bold" style="color:rgba(255,255,255,.25)"> |
| 20 | Hiroshima |
| 21 | </span> |
| 22 | </div> |
| 23 | </div> |
| 24 | <div class="flex gap-1 p-2 border-t border-[#222]"> |
| 25 | <button aria-label="Show Tokyo" data-i="0" class="flex-1 flex flex-col items-center gap-1 p-1.5 rounded-md border-2 border-transparent bg-transparent transition-all data-[active=true]:border-[#00FF41] data-[active=true]:bg-[rgba(0,255,65,.05)]"> |
| 26 | <div class="w-full h-6 rounded" style="background:#1a2a2f"> |
| 27 | </div> |
| 28 | <span class="text-[9px] text-[#666] data-[active=true]:text-[#00FF41]"> |
| 29 | Tokyo |
| 30 | </span> |
| 31 | </button> |
| 32 | <button aria-label="Show Kyoto" data-i="1" class="flex-1 flex flex-col items-center gap-1 p-1.5 rounded-md border-2 border-transparent bg-transparent transition-all data-[active=true]:border-[#00FF41] data-[active=true]:bg-[rgba(0,255,65,.05)]"> |
| 33 | <div class="w-full h-6 rounded" style="background:#1a0f33"> |
| 34 | </div> |
| 35 | <span class="text-[9px] text-[#666] data-[active=true]:text-[#00FF41]"> |
| 36 | Kyoto |
| 37 | </span> |
| 38 | </button> |
| 39 | <button aria-label="Show Osaka" data-i="2" class="flex-1 flex flex-col items-center gap-1 p-1.5 rounded-md border-2 border-transparent bg-transparent transition-all data-[active=true]:border-[#00FF41] data-[active=true]:bg-[rgba(0,255,65,.05)]"> |
| 40 | <div class="w-full h-6 rounded" style="background:#0f2a4a"> |
| 41 | </div> |
| 42 | <span class="text-[9px] text-[#666] data-[active=true]:text-[#00FF41]"> |
| 43 | Osaka |
| 44 | </span> |
| 45 | </button> |
| 46 | <button aria-label="Show Hiroshima" data-i="3" class="flex-1 flex flex-col items-center gap-1 p-1.5 rounded-md border-2 border-transparent bg-transparent transition-all data-[active=true]:border-[#00FF41] data-[active=true]:bg-[rgba(0,255,65,.05)]"> |
| 47 | <div class="w-full h-6 rounded" style="background:#3a2218"> |
| 48 | </div> |
| 49 | <span class="text-[9px] text-[#666] data-[active=true]:text-[#00FF41]"> |
| 50 | Hiroshima |
| 51 | </span> |
| 52 | </button> |
| 53 | </div> |
| 54 | </div> |
| 1 | <div class="mx-auto rounded-4 overflow-hidden border border-secondary" style="max-width:400px;background:#111;font-family:system-ui,sans-serif" id="bs-thumb"> |
| 2 | <div class="d-flex overflow-hidden" id="bs-thumb-main" style="scroll-snap-type:x mandatory;scroll-behavior:smooth"> |
| 3 | <div class="flex-shrink-0 d-flex align-items-center justify-content-center" style="width:100%;height:160px;scroll-snap-align:start;background:linear-gradient(135deg,#0f2027,#203a43)"> |
| 4 | <span class="fw-bold" style="font-size:24px;color:rgba(255,255,255,.25)"> |
| 5 | Tokyo |
| 6 | </span> |
| 7 | </div> |
| 8 | <div class="flex-shrink-0 d-flex align-items-center justify-content-center" style="width:100%;height:160px;scroll-snap-align:start;background:linear-gradient(135deg,#1a0533,#2d1b69)"> |
| 9 | <span class="fw-bold" style="font-size:24px;color:rgba(255,255,255,.25)"> |
| 10 | Kyoto |
| 11 | </span> |
| 12 | </div> |
| 13 | <div class="flex-shrink-0 d-flex align-items-center justify-content-center" style="width:100%;height:160px;scroll-snap-align:start;background:linear-gradient(135deg,#0c2340,#1e5a8a)"> |
| 14 | <span class="fw-bold" style="font-size:24px;color:rgba(255,255,255,.25)"> |
| 15 | Osaka |
| 16 | </span> |
| 17 | </div> |
| 18 | <div class="flex-shrink-0 d-flex align-items-center justify-content-center" style="width:100%;height:160px;scroll-snap-align:start;background:linear-gradient(135deg,#2d1810,#5a3a28)"> |
| 19 | <span class="fw-bold" style="font-size:24px;color:rgba(255,255,255,.25)"> |
| 20 | Hiroshima |
| 21 | </span> |
| 22 | </div> |
| 23 | </div> |
| 24 | <div class="d-flex gap-1 p-2 border-top border-secondary" id="bs-thumb-strip"> |
| 25 | <button aria-label="Show Tokyo" data-i="0" class="btn btn-link text-decoration-none flex-grow-1 d-flex flex-column align-items-center gap-1 p-1" style="border:2px solid transparent"> |
| 26 | <div class="w-100 rounded" style="height:24px;background:#1a2a2f"> |
| 27 | </div> |
| 28 | <span style="font-size:9px;color:#666"> |
| 29 | Tokyo |
| 30 | </span> |
| 31 | </button> |
| 32 | <button aria-label="Show Kyoto" data-i="1" class="btn btn-link text-decoration-none flex-grow-1 d-flex flex-column align-items-center gap-1 p-1" style="border:2px solid transparent"> |
| 33 | <div class="w-100 rounded" style="height:24px;background:#1a0f33"> |
| 34 | </div> |
| 35 | <span style="font-size:9px;color:#666"> |
| 36 | Kyoto |
| 37 | </span> |
| 38 | </button> |
| 39 | <button aria-label="Show Osaka" data-i="2" class="btn btn-link text-decoration-none flex-grow-1 d-flex flex-column align-items-center gap-1 p-1" style="border:2px solid transparent"> |
| 40 | <div class="w-100 rounded" style="height:24px;background:#0f2a4a"> |
| 41 | </div> |
| 42 | <span style="font-size:9px;color:#666"> |
| 43 | Osaka |
| 44 | </span> |
| 45 | </button> |
| 46 | <button aria-label="Show Hiroshima" data-i="3" class="btn btn-link text-decoration-none flex-grow-1 d-flex flex-column align-items-center gap-1 p-1" style="border:2px solid transparent"> |
| 47 | <div class="w-100 rounded" style="height:24px;background:#3a2218"> |
| 48 | </div> |
| 49 | <span style="font-size:9px;color:#666"> |
| 50 | Hiroshima |
| 51 | </span> |
| 52 | </button> |
| 53 | </div> |
| 54 | </div> |
A wide hero-style slider with overlay text, bottom indicators, and full-bleed gradient backgrounds. Great for landing pages and feature highlights.
| 1 | <div class="hero-carousel" id="hero-carousel"> |
| 2 | <div class="hero-track" id="hero-track"> |
| 3 | <div class="hero-slide" style="background:linear-gradient(90deg,#0A0A0A 0%,#151515 60%,#1A1A2E 100%)"> |
| 4 | <div class="hero-content"> |
| 5 | <span class="hero-kicker"> |
| 6 | v2.0 is live |
| 7 | </span> |
| 8 | <h2> |
| 9 | Ship faster with tokens |
| 10 | </h2> |
| 11 | <p> |
| 12 | Design tokens keep colors, spacing, and typography consistent across every platform. |
| 13 | </p> |
| 14 | <button class="hero-cta"> |
| 15 | Read the docs |
| 16 | </button> |
| 17 | </div> |
| 18 | </div> |
| 19 | <div class="hero-slide" style="background:linear-gradient(90deg,#0A0A0A 0%,#151515 60%,#0c2340 100%)"> |
| 20 | <div class="hero-content"> |
| 21 | <span class="hero-kicker"> |
| 22 | Performance |
| 23 | </span> |
| 24 | <h2> |
| 25 | Sub-millisecond edges |
| 26 | </h2> |
| 27 | <p> |
| 28 | Deploy globally and serve dynamic content from 200+ locations. |
| 29 | </p> |
| 30 | <button class="hero-cta"> |
| 31 | View benchmarks |
| 32 | </button> |
| 33 | </div> |
| 34 | </div> |
| 35 | <div class="hero-slide" style="background:linear-gradient(90deg,#0A0A0A 0%,#151515 60%,#1a0533 100%)"> |
| 36 | <div class="hero-content"> |
| 37 | <span class="hero-kicker"> |
| 38 | Security |
| 39 | </span> |
| 40 | <h2> |
| 41 | Zero-trust by default |
| 42 | </h2> |
| 43 | <p> |
| 44 | Authenticate every request with short-lived tokens and mTLS. |
| 45 | </p> |
| 46 | <button class="hero-cta"> |
| 47 | Learn more |
| 48 | </button> |
| 49 | </div> |
| 50 | </div> |
| 51 | </div> |
| 52 | <div class="hero-dots" id="hero-dots"> |
| 53 | <button class="active" aria-label="Slide 1"> |
| 54 | </button> |
| 55 | <button aria-label="Slide 2"> |
| 56 | </button> |
| 57 | <button aria-label="Slide 3"> |
| 58 | </button> |
| 59 | </div> |
| 60 | </div> |
| 1 | .hero-carousel { |
| 2 | position:relative; |
| 3 | width:100%; |
| 4 | overflow:hidden; |
| 5 | border-radius:12px; |
| 6 | font-family:system-ui, |
| 7 | sans-serif; |
| 8 | background:#0A0A0A |
| 9 | } |
| 10 | .hero-track { |
| 11 | display:flex; |
| 12 | transition:transform .6s cubic-bezier(.4, |
| 13 | 0, |
| 14 | .2, |
| 15 | 1) |
| 16 | } |
| 17 | .hero-slide { |
| 18 | flex:0 0 100%; |
| 19 | min-width:100%; |
| 20 | min-height:220px; |
| 21 | padding:32px; |
| 22 | display:flex; |
| 23 | align-items:center |
| 24 | } |
| 25 | .hero-content { |
| 26 | max-width:320px |
| 27 | } |
| 28 | .hero-kicker { |
| 29 | display:inline-block; |
| 30 | padding:3px 8px; |
| 31 | border-radius:4px; |
| 32 | font-size:9px; |
| 33 | font-weight:700; |
| 34 | text-transform:uppercase; |
| 35 | letter-spacing:.5px; |
| 36 | background:rgba(0, |
| 37 | 255, |
| 38 | 65, |
| 39 | .15); |
| 40 | color:#00FF41; |
| 41 | margin-bottom:10px |
| 42 | } |
| 43 | .hero-content h2 { |
| 44 | font-size:22px; |
| 45 | font-weight:700; |
| 46 | color:#E0E0E0; |
| 47 | margin:0 0 8px; |
| 48 | line-height:1.2 |
| 49 | } |
| 50 | .hero-content p { |
| 51 | font-size:12px; |
| 52 | color:#A0A0A0; |
| 53 | margin:0 0 16px; |
| 54 | line-height:1.5 |
| 55 | } |
| 56 | .hero-cta { |
| 57 | padding:8px 16px; |
| 58 | border-radius:6px; |
| 59 | font-size:11px; |
| 60 | font-weight:600; |
| 61 | background:#00FF41; |
| 62 | color:#0A0A0A; |
| 63 | border:none; |
| 64 | cursor:pointer; |
| 65 | transition:all .2s |
| 66 | } |
| 67 | .hero-cta:hover { |
| 68 | transform:translateY(-1px); |
| 69 | box-shadow:0 4px 12px rgba(0, |
| 70 | 255, |
| 71 | 65, |
| 72 | .2) |
| 73 | } |
| 74 | .hero-dots { |
| 75 | position:absolute; |
| 76 | bottom:14px; |
| 77 | left:50%; |
| 78 | transform:translateX(-50%); |
| 79 | display:flex; |
| 80 | gap:6px |
| 81 | } |
| 82 | .hero-dots button { |
| 83 | width:6px; |
| 84 | height:6px; |
| 85 | border-radius:50%; |
| 86 | border:none; |
| 87 | background:#333; |
| 88 | cursor:pointer; |
| 89 | transition:all .2s; |
| 90 | padding:0 |
| 91 | } |
| 92 | .hero-dots button.active { |
| 93 | background:#00FF41; |
| 94 | width:18px; |
| 95 | border-radius:3px |
| 96 | } |
| 1 | const ht=document.getElementById('hero-track');const hd=document.querySelectorAll('#hero-dots button');let hcur=0;const hlen=hd.length;function hgo(i){hcur=(i+hlen)%hlen;ht.style.transform='translateX(-'+hcur*100+'%)';hd.forEach((d,j)=>d.classList.toggle('active',j===hcur))}hd.forEach((d,i)=>d.addEventListener('click',()=>hgo(i)));setInterval(()=>hgo(hcur+1),5000); |
| 1 | <div class="relative w-full overflow-hidden rounded-xl font-sans bg-[#0A0A0A]" id="tw-hero"> |
| 2 | <div class="flex transition-transform duration-[600ms]" data-track style="transition-timing-function:cubic-bezier(.4,0,.2,1)"> |
| 3 | <div class="flex-none w-full min-w-full min-h-[220px] p-8 flex items-center" style="background:linear-gradient(90deg,#0A0A0A 0%,#151515 60%,#1A1A2E 100%)"> |
| 4 | <div class="max-w-[320px]"> |
| 5 | <span class="inline-block px-2 py-0.5 rounded text-[9px] font-bold uppercase tracking-wider mb-2.5 bg-[rgba(0,255,65,.15)] text-[#00FF41]"> |
| 6 | v2.0 is live |
| 7 | </span> |
| 8 | <h2 class="text-[22px] font-bold text-[#E0E0E0] mb-2 leading-tight"> |
| 9 | Ship faster with tokens |
| 10 | </h2> |
| 11 | <p class="text-xs text-[#A0A0A0] mb-4 leading-relaxed"> |
| 12 | Design tokens keep colors, spacing, and typography consistent across every platform. |
| 13 | </p> |
| 14 | <button class="px-4 py-2 rounded-md text-[11px] font-semibold bg-[#00FF41] text-[#0A0A0A] hover:-translate-y-0.5 hover:shadow-[0_4px_12px_rgba(0,255,65,.2)] transition-all"> |
| 15 | Read the docs |
| 16 | </button> |
| 17 | </div> |
| 18 | </div> |
| 19 | <div class="flex-none w-full min-w-full min-h-[220px] p-8 flex items-center" style="background:linear-gradient(90deg,#0A0A0A 0%,#151515 60%,#0c2340 100%)"> |
| 20 | <div class="max-w-[320px]"> |
| 21 | <span class="inline-block px-2 py-0.5 rounded text-[9px] font-bold uppercase tracking-wider mb-2.5 bg-[rgba(0,255,65,.15)] text-[#00FF41]"> |
| 22 | Performance |
| 23 | </span> |
| 24 | <h2 class="text-[22px] font-bold text-[#E0E0E0] mb-2 leading-tight"> |
| 25 | Sub-millisecond edges |
| 26 | </h2> |
| 27 | <p class="text-xs text-[#A0A0A0] mb-4 leading-relaxed"> |
| 28 | Deploy globally and serve dynamic content from 200+ locations. |
| 29 | </p> |
| 30 | <button class="px-4 py-2 rounded-md text-[11px] font-semibold bg-[#00FF41] text-[#0A0A0A] hover:-translate-y-0.5 hover:shadow-[0_4px_12px_rgba(0,255,65,.2)] transition-all"> |
| 31 | View benchmarks |
| 32 | </button> |
| 33 | </div> |
| 34 | </div> |
| 35 | <div class="flex-none w-full min-w-full min-h-[220px] p-8 flex items-center" style="background:linear-gradient(90deg,#0A0A0A 0%,#151515 60%,#1a0533 100%)"> |
| 36 | <div class="max-w-[320px]"> |
| 37 | <span class="inline-block px-2 py-0.5 rounded text-[9px] font-bold uppercase tracking-wider mb-2.5 bg-[rgba(0,255,65,.15)] text-[#00FF41]"> |
| 38 | Security |
| 39 | </span> |
| 40 | <h2 class="text-[22px] font-bold text-[#E0E0E0] mb-2 leading-tight"> |
| 41 | Zero-trust by default |
| 42 | </h2> |
| 43 | <p class="text-xs text-[#A0A0A0] mb-4 leading-relaxed"> |
| 44 | Authenticate every request with short-lived tokens and mTLS. |
| 45 | </p> |
| 46 | <button class="px-4 py-2 rounded-md text-[11px] font-semibold bg-[#00FF41] text-[#0A0A0A] hover:-translate-y-0.5 hover:shadow-[0_4px_12px_rgba(0,255,65,.2)] transition-all"> |
| 47 | Learn more |
| 48 | </button> |
| 49 | </div> |
| 50 | </div> |
| 51 | </div> |
| 52 | <div class="absolute bottom-3.5 left-1/2 -translate-x-1/2 flex gap-1.5" data-dots> |
| 53 | <button aria-label="Slide 1" class="w-1.5 h-1.5 rounded-full border-none bg-[#00FF41] transition-all data-[active=true]:bg-[#00FF41] data-[active=true]:w-[18px] data-[active=true]:rounded-[3px]" data-active="true"> |
| 54 | </button> |
| 55 | <button aria-label="Slide 2" class="w-1.5 h-1.5 rounded-full border-none bg-[#333] cursor-pointer transition-all data-[active=true]:bg-[#00FF41] data-[active=true]:w-[18px] data-[active=true]:rounded-[3px]"> |
| 56 | </button> |
| 57 | <button aria-label="Slide 3" class="w-1.5 h-1.5 rounded-full border-none bg-[#333] cursor-pointer transition-all data-[active=true]:bg-[#00FF41] data-[active=true]:w-[18px] data-[active=true]:rounded-[3px]"> |
| 58 | </button> |
| 59 | </div> |
| 60 | </div> |
| 1 | <div class="position-relative w-100 overflow-hidden rounded-4" style="background:#0A0A0A;font-family:system-ui,sans-serif" id="bs-hero"> |
| 2 | <div class="d-flex" id="bs-hero-track" style="transition:transform .6s cubic-bezier(.4,0,.2,1)"> |
| 3 | <div class="flex-shrink-0 d-flex align-items-center" style="min-width:100%;min-height:220px;padding:32px;background:linear-gradient(90deg,#0A0A0A 0%,#151515 60%,#1A1A2E 100%)"> |
| 4 | <div style="max-width:320px"> |
| 5 | <span class="badge mb-2" style="background:rgba(0,255,65,.15);color:#00FF41;font-size:9px;text-transform:uppercase"> |
| 6 | v2.0 is live |
| 7 | </span> |
| 8 | <h2 class="fw-bold text-white mb-2" style="font-size:22px"> |
| 9 | Ship faster with tokens |
| 10 | </h2> |
| 11 | <p class="small mb-3" style="color:#A0A0A0"> |
| 12 | Design tokens keep colors, spacing, and typography consistent across every platform. |
| 13 | </p> |
| 14 | <button class="btn btn-sm fw-semibold" style="background:#00FF41;color:#0A0A0A"> |
| 15 | Read the docs |
| 16 | </button> |
| 17 | </div> |
| 18 | </div> |
| 19 | <div class="flex-shrink-0 d-flex align-items-center" style="min-width:100%;min-height:220px;padding:32px;background:linear-gradient(90deg,#0A0A0A 0%,#151515 60%,#0c2340 100%)"> |
| 20 | <div style="max-width:320px"> |
| 21 | <span class="badge mb-2" style="background:rgba(0,255,65,.15);color:#00FF41;font-size:9px;text-transform:uppercase"> |
| 22 | Performance |
| 23 | </span> |
| 24 | <h2 class="fw-bold text-white mb-2" style="font-size:22px"> |
| 25 | Sub-millisecond edges |
| 26 | </h2> |
| 27 | <p class="small mb-3" style="color:#A0A0A0"> |
| 28 | Deploy globally and serve dynamic content from 200+ locations. |
| 29 | </p> |
| 30 | <button class="btn btn-sm fw-semibold" style="background:#00FF41;color:#0A0A0A"> |
| 31 | View benchmarks |
| 32 | </button> |
| 33 | </div> |
| 34 | </div> |
| 35 | <div class="flex-shrink-0 d-flex align-items-center" style="min-width:100%;min-height:220px;padding:32px;background:linear-gradient(90deg,#0A0A0A 0%,#151515 60%,#1a0533 100%)"> |
| 36 | <div style="max-width:320px"> |
| 37 | <span class="badge mb-2" style="background:rgba(0,255,65,.15);color:#00FF41;font-size:9px;text-transform:uppercase"> |
| 38 | Security |
| 39 | </span> |
| 40 | <h2 class="fw-bold text-white mb-2" style="font-size:22px"> |
| 41 | Zero-trust by default |
| 42 | </h2> |
| 43 | <p class="small mb-3" style="color:#A0A0A0"> |
| 44 | Authenticate every request with short-lived tokens and mTLS. |
| 45 | </p> |
| 46 | <button class="btn btn-sm fw-semibold" style="background:#00FF41;color:#0A0A0A"> |
| 47 | Learn more |
| 48 | </button> |
| 49 | </div> |
| 50 | </div> |
| 51 | </div> |
| 52 | <div class="d-flex gap-2 justify-content-center position-absolute start-50 translate-middle-x" id="bs-hero-dots" style="bottom:14px"> |
| 53 | <button aria-label="Slide 1" class="rounded-pill border-0" style="width:18px;height:6px;background:#00FF41"> |
| 54 | </button> |
| 55 | <button aria-label="Slide 2" class="rounded-pill border-0" style="width:6px;height:6px;background:#333;cursor:pointer"> |
| 56 | </button> |
| 57 | <button aria-label="Slide 3" class="rounded-pill border-0" style="width:6px;height:6px;background:#333;cursor:pointer"> |
| 58 | </button> |
| 59 | </div> |
| 60 | </div> |
A vertical carousel using scroll-snap-type: y mandatory. Useful for mobile stories, timeline steps, or stacked feature cards.
| 1 | <div class="vert-carousel"> |
| 2 | <div class="vert-track"> |
| 3 | <div class="vert-slide"> |
| 4 | <div class="vert-card"> |
| 5 | <span class="vert-num"> |
| 6 | 01 |
| 7 | </span> |
| 8 | <h4> |
| 9 | Discover |
| 10 | </h4> |
| 11 | <p> |
| 12 | Explore patterns and choose the right component for the job. |
| 13 | </p> |
| 14 | </div> |
| 15 | </div> |
| 16 | <div class="vert-slide"> |
| 17 | <div class="vert-card"> |
| 18 | <span class="vert-num"> |
| 19 | 02 |
| 20 | </span> |
| 21 | <h4> |
| 22 | Build |
| 23 | </h4> |
| 24 | <p> |
| 25 | Implement the markup, styles, and behavior in your framework. |
| 26 | </p> |
| 27 | </div> |
| 28 | </div> |
| 29 | <div class="vert-slide"> |
| 30 | <div class="vert-card"> |
| 31 | <span class="vert-num"> |
| 32 | 03 |
| 33 | </span> |
| 34 | <h4> |
| 35 | Test |
| 36 | </h4> |
| 37 | <p> |
| 38 | Verify keyboard navigation, screen reader output, and reduced motion. |
| 39 | </p> |
| 40 | </div> |
| 41 | </div> |
| 42 | <div class="vert-slide"> |
| 43 | <div class="vert-card"> |
| 44 | <span class="vert-num"> |
| 45 | 04 |
| 46 | </span> |
| 47 | <h4> |
| 48 | Ship |
| 49 | </h4> |
| 50 | <p> |
| 51 | Deploy with confidence and monitor real user interactions. |
| 52 | </p> |
| 53 | </div> |
| 54 | </div> |
| 55 | </div> |
| 56 | </div> |
| 1 | .vert-carousel { |
| 2 | width:100%; |
| 3 | max-width:320px; |
| 4 | margin:16px auto; |
| 5 | height:240px; |
| 6 | overflow:hidden; |
| 7 | border-radius:12px; |
| 8 | border:1px solid #222; |
| 9 | background:#111; |
| 10 | font-family:system-ui, |
| 11 | sans-serif |
| 12 | } |
| 13 | .vert-track { |
| 14 | display:flex; |
| 15 | flex-direction:column; |
| 16 | gap:10px; |
| 17 | height:100%; |
| 18 | overflow-y:auto; |
| 19 | scroll-snap-type:y mandatory; |
| 20 | scroll-behavior:smooth; |
| 21 | padding:10px; |
| 22 | scrollbar-width:none |
| 23 | } |
| 24 | .vert-track::-webkit-scrollbar { |
| 25 | display:none |
| 26 | } |
| 27 | .vert-slide { |
| 28 | flex:0 0 calc(100% - 20px); |
| 29 | scroll-snap-align:start |
| 30 | } |
| 31 | .vert-card { |
| 32 | height:100%; |
| 33 | border-radius:10px; |
| 34 | background:#151515; |
| 35 | border:1px solid #222; |
| 36 | padding:24px; |
| 37 | display:flex; |
| 38 | flex-direction:column; |
| 39 | justify-content:center; |
| 40 | gap:8px |
| 41 | } |
| 42 | .vert-num { |
| 43 | font-size:10px; |
| 44 | font-weight:700; |
| 45 | letter-spacing:1px; |
| 46 | color:#00FF41 |
| 47 | } |
| 48 | .vert-card h4 { |
| 49 | font-size:16px; |
| 50 | font-weight:700; |
| 51 | color:#E0E0E0; |
| 52 | margin:0 |
| 53 | } |
| 54 | .vert-card p { |
| 55 | font-size:12px; |
| 56 | color:#808080; |
| 57 | margin:0; |
| 58 | line-height:1.5 |
| 59 | } |
| 1 | <div class="w-full max-w-[320px] mx-auto h-60 overflow-hidden rounded-xl border border-[#222] bg-[#111] font-sans"> |
| 2 | <div class="flex flex-col gap-2.5 h-full overflow-y-auto snap-y snap-mandatory scroll-smooth p-2.5 scrollbar-hide" style="scrollbar-width:none"> |
| 3 | <div class="flex-none snap-start h-[calc(100%-20px)]"> |
| 4 | <div class="h-full rounded-lg bg-[#151515] border border-[#222] p-6 flex flex-col justify-center gap-2"> |
| 5 | <span class="text-[10px] font-bold tracking-wider text-[#00FF41]"> |
| 6 | 01 |
| 7 | </span> |
| 8 | <h4 class="text-base font-bold text-[#E0E0E0] m-0"> |
| 9 | Discover |
| 10 | </h4> |
| 11 | <p class="text-xs text-[#808080] m-0 leading-relaxed"> |
| 12 | Explore patterns and choose the right component for the job. |
| 13 | </p> |
| 14 | </div> |
| 15 | </div> |
| 16 | <div class="flex-none snap-start h-[calc(100%-20px)]"> |
| 17 | <div class="h-full rounded-lg bg-[#151515] border border-[#222] p-6 flex flex-col justify-center gap-2"> |
| 18 | <span class="text-[10px] font-bold tracking-wider text-[#00FF41]"> |
| 19 | 02 |
| 20 | </span> |
| 21 | <h4 class="text-base font-bold text-[#E0E0E0] m-0"> |
| 22 | Build |
| 23 | </h4> |
| 24 | <p class="text-xs text-[#808080] m-0 leading-relaxed"> |
| 25 | Implement the markup, styles, and behavior in your framework. |
| 26 | </p> |
| 27 | </div> |
| 28 | </div> |
| 29 | <div class="flex-none snap-start h-[calc(100%-20px)]"> |
| 30 | <div class="h-full rounded-lg bg-[#151515] border border-[#222] p-6 flex flex-col justify-center gap-2"> |
| 31 | <span class="text-[10px] font-bold tracking-wider text-[#00FF41]"> |
| 32 | 03 |
| 33 | </span> |
| 34 | <h4 class="text-base font-bold text-[#E0E0E0] m-0"> |
| 35 | Test |
| 36 | </h4> |
| 37 | <p class="text-xs text-[#808080] m-0 leading-relaxed"> |
| 38 | Verify keyboard navigation, screen reader output, and reduced motion. |
| 39 | </p> |
| 40 | </div> |
| 41 | </div> |
| 42 | <div class="flex-none snap-start h-[calc(100%-20px)]"> |
| 43 | <div class="h-full rounded-lg bg-[#151515] border border-[#222] p-6 flex flex-col justify-center gap-2"> |
| 44 | <span class="text-[10px] font-bold tracking-wider text-[#00FF41]"> |
| 45 | 04 |
| 46 | </span> |
| 47 | <h4 class="text-base font-bold text-[#E0E0E0] m-0"> |
| 48 | Ship |
| 49 | </h4> |
| 50 | <p class="text-xs text-[#808080] m-0 leading-relaxed"> |
| 51 | Deploy with confidence and monitor real user interactions. |
| 52 | </p> |
| 53 | </div> |
| 54 | </div> |
| 55 | </div> |
| 56 | </div> |
| 1 | <div class="mx-auto overflow-hidden rounded-4 border border-secondary" style="width:100%;max-width:320px;height:240px;background:#111;font-family:system-ui,sans-serif"> |
| 2 | <div class="d-flex flex-column gap-2 h-100 overflow-auto p-2" style="scroll-snap-type:y mandatory;scroll-behavior:smooth;scrollbar-width:none"> |
| 3 | <div class="flex-shrink-0" style="height:calc(100% - 20px);scroll-snap-align:start"> |
| 4 | <div class="h-100 rounded-3 border border-secondary d-flex flex-column justify-content-center gap-2 p-4" style="background:#151515"> |
| 5 | <span class="fw-bold" style="font-size:10px;letter-spacing:1px;color:#00FF41"> |
| 6 | 01 |
| 7 | </span> |
| 8 | <h4 class="fw-bold text-white mb-0" style="font-size:16px"> |
| 9 | Discover |
| 10 | </h4> |
| 11 | <p class="small mb-0" style="color:#808080"> |
| 12 | Explore patterns and choose the right component for the job. |
| 13 | </p> |
| 14 | </div> |
| 15 | </div> |
| 16 | <div class="flex-shrink-0" style="height:calc(100% - 20px);scroll-snap-align:start"> |
| 17 | <div class="h-100 rounded-3 border border-secondary d-flex flex-column justify-content-center gap-2 p-4" style="background:#151515"> |
| 18 | <span class="fw-bold" style="font-size:10px;letter-spacing:1px;color:#00FF41"> |
| 19 | 02 |
| 20 | </span> |
| 21 | <h4 class="fw-bold text-white mb-0" style="font-size:16px"> |
| 22 | Build |
| 23 | </h4> |
| 24 | <p class="small mb-0" style="color:#808080"> |
| 25 | Implement the markup, styles, and behavior in your framework. |
| 26 | </p> |
| 27 | </div> |
| 28 | </div> |
| 29 | <div class="flex-shrink-0" style="height:calc(100% - 20px);scroll-snap-align:start"> |
| 30 | <div class="h-100 rounded-3 border border-secondary d-flex flex-column justify-content-center gap-2 p-4" style="background:#151515"> |
| 31 | <span class="fw-bold" style="font-size:10px;letter-spacing:1px;color:#00FF41"> |
| 32 | 03 |
| 33 | </span> |
| 34 | <h4 class="fw-bold text-white mb-0" style="font-size:16px"> |
| 35 | Test |
| 36 | </h4> |
| 37 | <p class="small mb-0" style="color:#808080"> |
| 38 | Verify keyboard navigation, screen reader output, and reduced motion. |
| 39 | </p> |
| 40 | </div> |
| 41 | </div> |
| 42 | <div class="flex-shrink-0" style="height:calc(100% - 20px);scroll-snap-align:start"> |
| 43 | <div class="h-100 rounded-3 border border-secondary d-flex flex-column justify-content-center gap-2 p-4" style="background:#151515"> |
| 44 | <span class="fw-bold" style="font-size:10px;letter-spacing:1px;color:#00FF41"> |
| 45 | 04 |
| 46 | </span> |
| 47 | <h4 class="fw-bold text-white mb-0" style="font-size:16px"> |
| 48 | Ship |
| 49 | </h4> |
| 50 | <p class="small mb-0" style="color:#808080"> |
| 51 | Deploy with confidence and monitor real user interactions. |
| 52 | </p> |
| 53 | </div> |
| 54 | </div> |
| 55 | </div> |
| 56 | </div> |
A semantic carousel structure uses a track container with scroll-snap-type, individual slides with scroll-snap-align, and labeled controls outside the track.
| 1 | <section aria-roledescription="carousel" aria-label="Product screenshots"> |
| 2 | <div class="carousel-track" style="scroll-snap-type: x mandatory"> |
| 3 | <div class="carousel-slide" style="scroll-snap-align: start"> |
| 4 | Slide 1 |
| 5 | </div> |
| 6 | <div class="carousel-slide" style="scroll-snap-align: start"> |
| 7 | Slide 2 |
| 8 | </div> |
| 9 | </div> |
| 10 | |
| 11 | <button type="button" class="prev" aria-label="Previous slide"> |
| 12 | <svg aria-hidden="true" width="16" height="16" viewBox="0 0 24 24"> |
| 13 | <polyline points="15 18 9 12 15 6" fill="none" stroke="currentColor" stroke-width="2"/> |
| 14 | </svg> |
| 15 | </button> |
| 16 | <button type="button" class="next" aria-label="Next slide"> |
| 17 | <svg aria-hidden="true" width="16" height="16" viewBox="0 0 24 24"> |
| 18 | <polyline points="9 18 15 12 9 6" fill="none" stroke="currentColor" stroke-width="2"/> |
| 19 | </svg> |
| 20 | </button> |
| 21 | |
| 22 | <div class="indicators" role="tablist" aria-label="Slides"> |
| 23 | <button role="tab" aria-selected="true" aria-label="Slide 1" class="active"></button> |
| 24 | <button role="tab" aria-selected="false" aria-label="Slide 2"></button> |
| 25 | </div> |
| 26 | </section> |
info
warning
best practice
- Hide scrollbars with scrollbar-width: none and ::-webkit-scrollbar for a cleaner cross-browser look.
- Use overflow: hidden on the outer container to clip slides at the boundary.
- For multi-item carousels, calculate item width as calc(100% / visibleCount - gap) to fit exactly N items per viewport.
- Add scroll-behavior: smooth for animated scrolling without JavaScript.
- Support swipe on mobile through native touch scrolling instead of intercepting touch events.
- For auto-play, use a 4–5 second interval and always provide manual controls.
- Preload adjacent images and lazy-load off-screen slides to balance performance and perceived speed.
Carousels are one of the most accessibility-prone components. Follow these practical checks to make them usable for keyboard and screen reader users.
- Wrap the carousel in a section with aria-roledescription="carousel" and a descriptive aria-label.
- Use real <button> elements for controls, not clickable divs or spans.
- Provide visible focus indicators on arrows, dots, and thumbnails.
- Update aria-selected on dot indicators and aria-label on arrow buttons.
- Pause auto-play when the carousel receives keyboard focus or hover, and never auto-advance critical content.
- Respect prefers-reduced-motion by disabling animations and auto-play for users who request reduced motion.
- Ensure all text and controls meet a 4.5:1 contrast ratio against the slide background.
- Avoid keyboard traps — users must be able to tab past the carousel without getting stuck.
Community
Get help on Slack, Discord or VIP
Stuck on a guide? Join the community and ask.