Product Gallery <mv-product-gallery>

상품 페이지 갤러리입니다. 네이티브 scroll-snap 기반 메인 이미지(터치 스와이프), 열 또는 행으로 동기화된 썸네일(선택적 호버 전환), 포인터를 따라가는 호버 줌, 화살표와 카운터, 작은 컨테이너에서의 분할 막대, 클릭 확대와 패닝이 가능한 <dialog> 전체 화면을 제공합니다.

카테고리미디어
유형Web Component (<mv-product-gallery>)
상태안정
Keywordsgallery, galerie, product, pdp, thumbnails, zoom, lightbox, fullscreen, swipe, e-commerce

When to use

  • A product detail page needs a main image with synce일 thumbnails, swipe on touc시간 and hover zoo분
  • Shoppers must open product images fullscreen, click to zoom and pan
  • Thumbnails should sit in a column or row, collapsing into a segmented bar in small containers

Avoid when

  • The slides are marketing content or cards rather than views of one product → use Carousel instead
  • An editorial photo showcase should rearrange itself around the selected image → use Mosaic Gallery instead

설치

node scripts/add.mjs product-gallery --out ./src/marvelous

Marvelous UI MCP 서버를 사용하는 AI 에이전트: install_components({ slugs: ["product-gallery"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).

복사되는 파일(의존성 포함): tokens/tokens.css, core/base.css, core/dom.js, core/element.js, core/focus.js, core/motion.js, components/product-gallery/product-gallery.js, components/product-gallery/product-gallery.css.

사용법

기본 마크업입니다. 여기서 시작해 속성, data-*, CSS 변수로 커스터마이즈하세요:

<div id="pg-demo" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,22rem),1fr));gap:2.5rem;width:min(100%,62rem);margin-inline:auto;align-items:start">
  <div style="display:grid;gap:.75rem">
    <mv-product-gallery id="pg-demo-main" label="Merino crewneck sweater" thumbs="start" zoom="2.2">
      <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.97 0.012 80)'/%3E%3Cstop offset='1' stop-color='oklch(0.91 0.025 75)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cdefs%3E%3Cpattern id='k' width='12' height='10' patternUnits='userSpaceOnUse'%3E%3Cpath d='M0 0l6 8 6-8' fill='none' stroke='black' stroke-opacity='.09' stroke-width='1.6'/%3E%3C/pattern%3E%3C/defs%3E%3Cellipse cx='200' cy='420' rx='150' ry='18' fill='url(%23fl)' opacity='1'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='oklch(0.8 0.05 75)'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='url(%23k)'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='url(%23sh)'/%3E%3Cpath d='M160 118 Q200 152 240 118 Q200 136 160 118Z' fill='black' fill-opacity='.22'/%3E%3Cpath d='M154 116 Q200 160 246 116' fill='none' stroke='black' stroke-opacity='.12' stroke-width='5'/%3E%3Cpath d='M133 370 Q200 379 267 370 L267 388 Q200 397 133 388 Z' fill='black' fill-opacity='.1'/%3E%3Cpath d='M64 318 L100 331 L103 316 L68 303 Z' fill='black' fill-opacity='.1'/%3E%3Cpath d='M336 318 L300 331 L297 316 L332 303 Z' fill='black' fill-opacity='.1'/%3E%3Cpath d='M132 222 L133 380 M268 222 L267 380' stroke='black' stroke-opacity='.08' stroke-width='3'/%3E%3C/svg%3E" alt="Merino crewneck sweater in sand, front view">
      <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.97 0.012 80)'/%3E%3Cstop offset='1' stop-color='oklch(0.91 0.025 75)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cdefs%3E%3Cpattern id='k' width='12' height='10' patternUnits='userSpaceOnUse'%3E%3Cpath d='M0 0l6 8 6-8' fill='none' stroke='black' stroke-opacity='.09' stroke-width='1.6'/%3E%3C/pattern%3E%3C/defs%3E%3Crect x='0' y='0' width='400' height='500' fill='white' fill-opacity='.18'/%3E%3Cpath d='M200 58 q0-16 12-16 q12 0 12 12 q0 10-12 14 L200 78' fill='none' stroke='oklch(0.55 0.02 60)' stroke-width='5' stroke-linecap='round'/%3E%3Cpath d='M200 78 L96 124 L304 124 Z' fill='none' stroke='oklch(0.6 0.08 60)' stroke-width='8' stroke-linejoin='round'/%3E%3Cg transform='translate(40 30) scale(.8)'%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='oklch(0.8 0.05 75)'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='url(%23k)'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='url(%23sh)'/%3E%3Cpath d='M160 118 Q200 152 240 118 Q200 136 160 118Z' fill='black' fill-opacity='.2'/%3E%3Cpath d='M133 372 Q200 380 267 372 L267 388 Q200 397 133 388 Z' fill='black' fill-opacity='.1'/%3E%3C/g%3E%3Cpath d='M300 470 c-4-60 6-110 30-150 c-2 50-10 100-12 150z' fill='oklch(0.55 0.08 150)' opacity='.55'/%3E%3Cpath d='M318 470 c8-52 30-86 58-104 c-14 38-30 72-40 104z' fill='oklch(0.5 0.08 150)' opacity='.5'/%3E%3Crect x='292' y='452' width='64' height='48' rx='6' fill='oklch(0.72 0.06 55)' opacity='.9'/%3E%3C/svg%3E" alt="The sweater on a wooden hanger">
      <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.97 0.012 80)'/%3E%3Cstop offset='1' stop-color='oklch(0.91 0.025 75)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cdefs%3E%3Cpattern id='k' width='44' height='36' patternUnits='userSpaceOnUse'%3E%3Cpath d='M2 2l20 30 20-30' fill='none' stroke='black' stroke-opacity='.14' stroke-width='7' stroke-linecap='round'/%3E%3Cpath d='M2 2l20 30 20-30' fill='none' stroke='white' stroke-opacity='.12' stroke-width='2' transform='translate(0 -3)'/%3E%3C/pattern%3E%3C/defs%3E%3Crect width='400' height='500' fill='oklch(0.8 0.05 75)'/%3E%3Crect width='400' height='500' fill='url(%23k)'/%3E%3Crect width='400' height='500' fill='url(%23sh)'/%3E%3Cg transform='rotate(-6 250 330)'%3E%3Crect x='190' y='300' width='150' height='74' rx='6' fill='oklch(0.97 0.01 90)'/%3E%3Crect x='190' y='300' width='150' height='74' rx='6' fill='none' stroke='black' stroke-opacity='.12'/%3E%3Ctext x='265' y='333' text-anchor='middle' font-family='Georgia,serif' font-size='20' letter-spacing='3' fill='oklch(0.3 0.02 60)'%3EMERINO%3C/text%3E%3Ctext x='265' y='356' text-anchor='middle' font-family='Arial,sans-serif' font-size='9' letter-spacing='1.2' fill='oklch(0.45 0.02 60)'%3E100 % LAINE %C2%B7 18,5 %C2%B5m%3C/text%3E%3C/g%3E%3C/svg%3E" alt="Close-up of the knit and the merino label">
      <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.96 0.015 145)'/%3E%3Cstop offset='1' stop-color='oklch(0.89 0.03 150)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cdefs%3E%3Cpattern id='k' width='12' height='10' patternUnits='userSpaceOnUse'%3E%3Cpath d='M0 0l6 8 6-8' fill='none' stroke='black' stroke-opacity='.09' stroke-width='1.6'/%3E%3C/pattern%3E%3C/defs%3E%3Cellipse cx='200' cy='392' rx='150' ry='16' fill='url(%23fl)' opacity='1'/%3E%3Crect x='96' y='292' width='208' height='96' rx='16' fill='oklch(0.7 0.06 150)' style='filter:brightness(.9)'/%3E%3Crect x='96' y='292' width='208' height='96' rx='16' fill='url(%23k)'/%3E%3Crect x='96' y='292' width='208' height='96' rx='16' fill='url(%23sh)'/%3E%3Cpath d='M104 356h192' stroke='black' stroke-opacity='.12' stroke-width='3'/%3E%3Crect x='110' y='190' width='180' height='112' rx='16' fill='oklch(0.7 0.06 150)'/%3E%3Crect x='110' y='190' width='180' height='112' rx='16' fill='url(%23k)'/%3E%3Crect x='110' y='190' width='180' height='112' rx='16' fill='url(%23sh)'/%3E%3Cpath d='M160 190 Q200 232 240 190' fill='black' fill-opacity='.14'/%3E%3Cpath d='M166 190 Q200 222 234 190' fill='none' stroke='black' stroke-opacity='.18' stroke-width='5'/%3E%3Cpath d='M118 268h164' stroke='black' stroke-opacity='.1' stroke-width='3'/%3E%3C/svg%3E" alt="Two folded sweaters in sage">
      <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.95 0.012 250)'/%3E%3Cstop offset='1' stop-color='oklch(0.87 0.025 255)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cdefs%3E%3Cpattern id='k' width='12' height='10' patternUnits='userSpaceOnUse'%3E%3Cpath d='M0 0l6 8 6-8' fill='none' stroke='black' stroke-opacity='.09' stroke-width='1.6'/%3E%3C/pattern%3E%3C/defs%3E%3Cellipse cx='200' cy='420' rx='150' ry='18' fill='url(%23fl)' opacity='1'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='oklch(0.34 0.05 262)'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='url(%23k)'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='url(%23sh)'/%3E%3Cpath d='M160 118 Q200 152 240 118 Q200 136 160 118Z' fill='black' fill-opacity='.22'/%3E%3Cpath d='M154 116 Q200 160 246 116' fill='none' stroke='black' stroke-opacity='.12' stroke-width='5'/%3E%3Cpath d='M133 370 Q200 379 267 370 L267 388 Q200 397 133 388 Z' fill='black' fill-opacity='.1'/%3E%3Cpath d='M64 318 L100 331 L103 316 L68 303 Z' fill='black' fill-opacity='.1'/%3E%3Cpath d='M336 318 L300 331 L297 316 L332 303 Z' fill='black' fill-opacity='.1'/%3E%3Cpath d='M132 222 L133 380 M268 222 L267 380' stroke='black' stroke-opacity='.08' stroke-width='3'/%3E%3C/svg%3E" alt="Midnight blue, front view">
    </mv-product-gallery>
    <p style="margin:0;font-size:.75rem;color:var(--mv-fg-muted)">Hover to zoom · click for fullscreen · arrow keys · swipe on touch.</p>
  </div>
  <div style="display:grid;gap:.75rem">
    <mv-product-gallery label="Aurora sneaker" thumbs="bottom" hover-thumbs style="--mv-product-gallery-ratio:1;--mv-product-gallery-thumb:4rem">
      <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.96 0.015 230)'/%3E%3Cstop offset='1' stop-color='oklch(0.88 0.035 235)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cellipse cx='200' cy='322' rx='170' ry='14' fill='url(%23fl)' opacity='1'/%3E%3Cg transform='translate(-10 10)'%3E%3Cpath d='M62 300 L358 300 C362 320 350 336 328 336 L86 336 C68 336 58 320 62 300 Z' fill='oklch(0.97 0.005 90)'/%3E%3Cpath d='M62 318 L360 318' stroke='black' stroke-opacity='.08' stroke-width='3'/%3E%3Cpath d='M68 300 C66 252 106 236 150 232 L206 198 C226 186 252 188 264 204 L292 240 C324 250 348 262 352 286 L354 300 Z' fill='oklch(0.78 0.07 235)'/%3E%3Cpath d='M68 300 C66 252 106 236 150 232 L206 198 C226 186 252 188 264 204 L292 240 C324 250 348 262 352 286 L354 300 Z' fill='url(%23sh)'/%3E%3Cpath d='M292 240 C324 250 348 262 352 286 L354 300 L318 300 C318 278 306 256 292 240Z' fill='black' fill-opacity='.08'/%3E%3Cpath d='M140 292 C184 258 236 250 306 264' fill='none' stroke='white' stroke-opacity='.85' stroke-width='9' stroke-linecap='round'/%3E%3Cpath d='M214 206 l26 36 M226 200 l26 36 M200 214 l28 34' stroke='oklch(0.97 0.005 90)' stroke-width='5' stroke-linecap='round'/%3E%3Cpath d='M206 198 C226 186 252 188 264 204' fill='none' stroke='black' stroke-opacity='.18' stroke-width='5'/%3E%3Ccircle cx='96' cy='262' r='5' fill='white' fill-opacity='.8'/%3E%3C/g%3E%3C/svg%3E" alt="Aurora sneaker in sky, side view">
      <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.96 0.015 230)'/%3E%3Cstop offset='1' stop-color='oklch(0.88 0.035 235)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cellipse cx='210' cy='372' rx='170' ry='16' fill='url(%23fl)' opacity='1'/%3E%3Cg transform='translate(40 70) scale(.85)'%3E%3Cpath d='M62 300 L358 300 C362 320 350 336 328 336 L86 336 C68 336 58 320 62 300 Z' fill='oklch(0.97 0.005 90)'/%3E%3Cpath d='M62 318 L360 318' stroke='black' stroke-opacity='.08' stroke-width='3'/%3E%3Cpath d='M68 300 C66 252 106 236 150 232 L206 198 C226 186 252 188 264 204 L292 240 C324 250 348 262 352 286 L354 300 Z' fill='oklch(0.78 0.07 235)'/%3E%3Cpath d='M68 300 C66 252 106 236 150 232 L206 198 C226 186 252 188 264 204 L292 240 C324 250 348 262 352 286 L354 300 Z' fill='url(%23sh)'/%3E%3Cpath d='M292 240 C324 250 348 262 352 286 L354 300 L318 300 C318 278 306 256 292 240Z' fill='black' fill-opacity='.08'/%3E%3Cpath d='M140 292 C184 258 236 250 306 264' fill='none' stroke='white' stroke-opacity='.85' stroke-width='9' stroke-linecap='round'/%3E%3Cpath d='M214 206 l26 36 M226 200 l26 36 M200 214 l28 34' stroke='oklch(0.97 0.005 90)' stroke-width='5' stroke-linecap='round'/%3E%3Cpath d='M206 198 C226 186 252 188 264 204' fill='none' stroke='black' stroke-opacity='.18' stroke-width='5'/%3E%3Ccircle cx='96' cy='262' r='5' fill='white' fill-opacity='.8'/%3E%3C/g%3E%3Cg transform='translate(-10 30) scale(.85)' opacity='1'%3E%3Cpath d='M62 300 L358 300 C362 320 350 336 328 336 L86 336 C68 336 58 320 62 300 Z' fill='oklch(0.97 0.005 90)'/%3E%3Cpath d='M62 318 L360 318' stroke='black' stroke-opacity='.08' stroke-width='3'/%3E%3Cpath d='M68 300 C66 252 106 236 150 232 L206 198 C226 186 252 188 264 204 L292 240 C324 250 348 262 352 286 L354 300 Z' fill='oklch(0.78 0.07 235)'/%3E%3Cpath d='M68 300 C66 252 106 236 150 232 L206 198 C226 186 252 188 264 204 L292 240 C324 250 348 262 352 286 L354 300 Z' fill='url(%23sh)'/%3E%3Cpath d='M292 240 C324 250 348 262 352 286 L354 300 L318 300 C318 278 306 256 292 240Z' fill='black' fill-opacity='.08'/%3E%3Cpath d='M140 292 C184 258 236 250 306 264' fill='none' stroke='white' stroke-opacity='.85' stroke-width='9' stroke-linecap='round'/%3E%3Cpath d='M214 206 l26 36 M226 200 l26 36 M200 214 l28 34' stroke='oklch(0.97 0.005 90)' stroke-width='5' stroke-linecap='round'/%3E%3Cpath d='M206 198 C226 186 252 188 264 204' fill='none' stroke='black' stroke-opacity='.18' stroke-width='5'/%3E%3Ccircle cx='96' cy='262' r='5' fill='white' fill-opacity='.8'/%3E%3C/g%3E%3C/svg%3E" alt="The pair, three-quarter view">
      <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.96 0.015 45)'/%3E%3Cstop offset='1' stop-color='oklch(0.89 0.035 40)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cellipse cx='200' cy='322' rx='170' ry='14' fill='url(%23fl)' opacity='1'/%3E%3Cg transform='translate(-10 10)'%3E%3Cpath d='M62 300 L358 300 C362 320 350 336 328 336 L86 336 C68 336 58 320 62 300 Z' fill='oklch(0.97 0.005 90)'/%3E%3Cpath d='M62 318 L360 318' stroke='black' stroke-opacity='.08' stroke-width='3'/%3E%3Cpath d='M68 300 C66 252 106 236 150 232 L206 198 C226 186 252 188 264 204 L292 240 C324 250 348 262 352 286 L354 300 Z' fill='oklch(0.58 0.13 38)'/%3E%3Cpath d='M68 300 C66 252 106 236 150 232 L206 198 C226 186 252 188 264 204 L292 240 C324 250 348 262 352 286 L354 300 Z' fill='url(%23sh)'/%3E%3Cpath d='M292 240 C324 250 348 262 352 286 L354 300 L318 300 C318 278 306 256 292 240Z' fill='black' fill-opacity='.08'/%3E%3Cpath d='M140 292 C184 258 236 250 306 264' fill='none' stroke='white' stroke-opacity='.85' stroke-width='9' stroke-linecap='round'/%3E%3Cpath d='M214 206 l26 36 M226 200 l26 36 M200 214 l28 34' stroke='oklch(0.97 0.005 90)' stroke-width='5' stroke-linecap='round'/%3E%3Cpath d='M206 198 C226 186 252 188 264 204' fill='none' stroke='black' stroke-opacity='.18' stroke-width='5'/%3E%3Ccircle cx='96' cy='262' r='5' fill='white' fill-opacity='.8'/%3E%3C/g%3E%3C/svg%3E" alt="Brick, side view">
      <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.96 0.015 45)'/%3E%3Cstop offset='1' stop-color='oklch(0.89 0.035 40)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cellipse cx='210' cy='372' rx='170' ry='16' fill='url(%23fl)' opacity='1'/%3E%3Cg transform='translate(40 70) scale(.85)'%3E%3Cpath d='M62 300 L358 300 C362 320 350 336 328 336 L86 336 C68 336 58 320 62 300 Z' fill='oklch(0.97 0.005 90)'/%3E%3Cpath d='M62 318 L360 318' stroke='black' stroke-opacity='.08' stroke-width='3'/%3E%3Cpath d='M68 300 C66 252 106 236 150 232 L206 198 C226 186 252 188 264 204 L292 240 C324 250 348 262 352 286 L354 300 Z' fill='oklch(0.58 0.13 38)'/%3E%3Cpath d='M68 300 C66 252 106 236 150 232 L206 198 C226 186 252 188 264 204 L292 240 C324 250 348 262 352 286 L354 300 Z' fill='url(%23sh)'/%3E%3Cpath d='M292 240 C324 250 348 262 352 286 L354 300 L318 300 C318 278 306 256 292 240Z' fill='black' fill-opacity='.08'/%3E%3Cpath d='M140 292 C184 258 236 250 306 264' fill='none' stroke='white' stroke-opacity='.85' stroke-width='9' stroke-linecap='round'/%3E%3Cpath d='M214 206 l26 36 M226 200 l26 36 M200 214 l28 34' stroke='oklch(0.97 0.005 90)' stroke-width='5' stroke-linecap='round'/%3E%3Cpath d='M206 198 C226 186 252 188 264 204' fill='none' stroke='black' stroke-opacity='.18' stroke-width='5'/%3E%3Ccircle cx='96' cy='262' r='5' fill='white' fill-opacity='.8'/%3E%3C/g%3E%3Cg transform='translate(-10 30) scale(.85)' opacity='1'%3E%3Cpath d='M62 300 L358 300 C362 320 350 336 328 336 L86 336 C68 336 58 320 62 300 Z' fill='oklch(0.97 0.005 90)'/%3E%3Cpath d='M62 318 L360 318' stroke='black' stroke-opacity='.08' stroke-width='3'/%3E%3Cpath d='M68 300 C66 252 106 236 150 232 L206 198 C226 186 252 188 264 204 L292 240 C324 250 348 262 352 286 L354 300 Z' fill='oklch(0.58 0.13 38)'/%3E%3Cpath d='M68 300 C66 252 106 236 150 232 L206 198 C226 186 252 188 264 204 L292 240 C324 250 348 262 352 286 L354 300 Z' fill='url(%23sh)'/%3E%3Cpath d='M292 240 C324 250 348 262 352 286 L354 300 L318 300 C318 278 306 256 292 240Z' fill='black' fill-opacity='.08'/%3E%3Cpath d='M140 292 C184 258 236 250 306 264' fill='none' stroke='white' stroke-opacity='.85' stroke-width='9' stroke-linecap='round'/%3E%3Cpath d='M214 206 l26 36 M226 200 l26 36 M200 214 l28 34' stroke='oklch(0.97 0.005 90)' stroke-width='5' stroke-linecap='round'/%3E%3Cpath d='M206 198 C226 186 252 188 264 204' fill='none' stroke='black' stroke-opacity='.18' stroke-width='5'/%3E%3Ccircle cx='96' cy='262' r='5' fill='white' fill-opacity='.8'/%3E%3C/g%3E%3C/svg%3E" alt="Brick, the pair">
    </mv-product-gallery>
    <output id="pg-demo-out" aria-live="polite" style="font-size:.75rem;color:var(--mv-fg-muted)">Thumbnails below, swap on hover.</output>
  </div>
</div>
<script type="module">
  const out = document.getElementById("pg-demo-out");
  document.getElementById("pg-demo").addEventListener("mv-change", (e) => {
    if (e.target.localName === "mv-product-gallery") out.textContent = `mv-change · image ${e.detail.index + 1}`;
  });
</script>

API

Attributes

Name유형DefaultDescription
indexnumber0Displayed image (0-based), reflected on every change.
thumbsstart | bottom | nonestartThumbnails in a left column, a row below, or none. Under 26rem wide: a segmented bar instead.
hover-thumbsbooleanHovering a thumbnail with the mouse switches the image.
zoomnumber2Hover zoom factor (mouse); 1 disables it.
labelstringProduct imagesAccessible name of the carousel and the fullscreen view.
no-fullscreenbooleanDisables fullscreen.

Properties

Name유형Description
countnumberNumber of images (read-only).

Methods

NameDescription
goTo(index, { smooth }) / next() / prev()Navigation.
openFullscreen(index?)Opens fullscreen.

Events

NameDescription
mv-changedetail: { index, image }.
mv-fullscreendetail: { open, index }.

Content structure

NameDescription
<img> / <picture>Direct children are the images; data-thumb for a different thumbnail.

CSS classes

NameDescription
mv-product-gallery-thumbs / -thumb / -main / -viewport / -track / -slide / -image / -arrow / -fullscreen / -counter / -bar / -lightboxGenerated parts; data-active, data-zoomed.

CSS variables

NameDefaultDescription
--mv-product-gallery-ratio4 / 5Image aspect ratio.
--mv-product-gallery-thumb4.5remThumbnail width.
--mv-product-gallery-radiusvar(--mv-radius-xl)Main image radius.

Accessibility

APG carousel pattern: focusable aria-roledescription=“carousel” region (←/→, Home/End, Enter/Space = fullscreen), role=group slides “2 of 5”, hidden images are inert. Thumbnails are “Image 2 of 5: …” buttons with aria-current, navigable with arrow keys (roving tabindex). Changes are announced (aria-live polite). Named arrows, disabled at the ends. Fullscreen: native modal <dialog> (focus trap, Esc, focus returned to the gallery). Reduced motion: instant scrolling, no hover zoom.

이 페이지는 AI로 번역되었습니다. 번역 문제 신고