fix(ecommerce): overflow horizontal en mobile hacía ver todo "a tamaño real"
Root cause real del bug reportado por el usuario (imagen de producto viéndose gigante/cortada en Chrome y Edge Android) -- no era la imagen: al mover "También te puede gustar" DENTRO del grid de la página (para el layout de 2 filas del commit anterior), su carrusel horizontal (overflow-x-auto interno, sin flex-wrap) empezó a contar como item de ese grid. Sin min-w-0, el ancho mínimo intrínseco de TODAS las cards del carrusel sin wrappear se usa para dimensionar la columna compartida del grid -- en mobile (grid de una sola columna), eso empujaba TODO (imagen, título, specs) a ~800px de ancho en un viewport real de ~380px. El navegador termina "zoomeando" el layout para que entre, dando la sensación de que todo se ve a tamaño real / cortado. Confirmado en vivo con bisección real: sin el fix, el grid medía 783px en un viewport de 380px; agregando min-w-0 al contenedor del carrusel vuelve a 380px. Se agrega min-w-0 también a los otros 3 contenedores del grid (galería, info, buy-box) y a la tira de miniaturas dentro de ProductGallery (mismo patrón de overflow-x-auto) como defensa preventiva -- práctica estándar para items de grid/flex con scroll horizontal interno. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_012Y4df3Z7odr9Cg8F2nw6uV
This commit is contained in:
1 parent
f92e8e6b36
commit
1c9693e573
2 files changed
+19
-4
No files matched your search
@@ -52,7 +52,7 @@ export default async function ProductPage({ params }: ProductPageProps) {
|
|||||||
esperar a que termine la columna más alta antes de aparecer. */}
|
esperar a que termine la columna más alta antes de aparecer. */}
|
||||||
<section className="mx-auto grid max-w-[1600px] gap-x-10 gap-y-12 px-4 py-10 lg:grid-cols-[1.08fr_.92fr] lg:py-16 xl:grid-cols-[1.1fr_.75fr_360px] xl:grid-rows-[auto_auto]">
|
<section className="mx-auto grid max-w-[1600px] gap-x-10 gap-y-12 px-4 py-10 lg:grid-cols-[1.08fr_.92fr] lg:py-16 xl:grid-cols-[1.1fr_.75fr_360px] xl:grid-rows-[auto_auto]">
|
||||||
<ProductGallery images={product.images} name={product.name} />
|
<ProductGallery images={product.images} name={product.name} />
|
||||||
<div>
|
<div className="min-w-0">
|
||||||
<span className="text-xs font-black uppercase tracking-[.18em] text-ari-coral">{product.category} · {product.collection}</span>
|
<span className="text-xs font-black uppercase tracking-[.18em] text-ari-coral">{product.category} · {product.collection}</span>
|
||||||
<h1 className="mt-3 text-4xl font-black tracking-tight sm:text-6xl">{product.name}</h1>
|
<h1 className="mt-3 text-4xl font-black tracking-tight sm:text-6xl">{product.name}</h1>
|
||||||
<p className="mt-5 text-lg leading-8 text-slate-600">{product.description}</p>
|
<p className="mt-5 text-lg leading-8 text-slate-600">{product.description}</p>
|
||||||
@@ -79,7 +79,7 @@ export default async function ProductPage({ params }: ProductPageProps) {
|
|||||||
scrollea. Los sugeridos (hasta 2) usan el mismo cálculo de
|
scrollea. Los sugeridos (hasta 2) usan el mismo cálculo de
|
||||||
"recommended" que ya alimenta el carrusel de abajo -- mismo
|
"recommended" que ya alimenta el carrusel de abajo -- mismo
|
||||||
criterio real (categoría/colección), no un dato inventado. */}
|
criterio real (categoría/colección), no un dato inventado. */}
|
||||||
<div className="xl:sticky xl:top-24 xl:row-span-2 xl:self-start">
|
<div className="min-w-0 xl:sticky xl:top-24 xl:row-span-2 xl:self-start">
|
||||||
<div className="rounded-2xl border border-slate-200 p-6 shadow-sm">
|
<div className="rounded-2xl border border-slate-200 p-6 shadow-sm">
|
||||||
<ProductPurchase product={product} />
|
<ProductPurchase product={product} />
|
||||||
</div>
|
</div>
|
||||||
@@ -92,8 +92,16 @@ export default async function ProductPage({ params }: ProductPageProps) {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
{/* min-w-0 es necesario: sin esto, el carrusel horizontal
|
||||||
|
(overflow-x-auto interno) contaba como item de este grid, y su
|
||||||
|
ancho minimo intrinseco (la suma de TODAS las cards sin
|
||||||
|
wrappear, ya que el scroller no tiene flex-wrap) empujaba todo
|
||||||
|
el grid completo a ~800px en mobile -- afectaba a TODA la
|
||||||
|
columna compartida (imagen, titulo, specs), no solo al
|
||||||
|
carrusel. Confirmado en vivo: sin min-w-0 el grid medía 783px
|
||||||
|
en un viewport real de 380px; con min-w-0 vuelve a 380px. */}
|
||||||
{recommended.length > 0 && (
|
{recommended.length > 0 && (
|
||||||
<div className="pb-16 lg:col-span-2">
|
<div className="min-w-0 pb-16 lg:col-span-2">
|
||||||
<h2 className="mb-7 text-3xl font-black">También te puede gustar</h2>
|
<h2 className="mb-7 text-3xl font-black">También te puede gustar</h2>
|
||||||
<ProductCarousel products={recommended} />
|
<ProductCarousel products={recommended} />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -109,7 +109,14 @@ export function ProductGallery({ images, name }: { images: string[]; name: strin
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="grid gap-4 lg:grid-cols-[86px_1fr]">
|
<div className="min-w-0 grid gap-4 lg:grid-cols-[86px_1fr]">
|
||||||
|
{/* min-w-0: esta tira de miniaturas es un overflow-x-auto (scroll
|
||||||
|
horizontal) igual que el carrusel de "También te puede gustar"
|
||||||
|
en app/product/[slug]/page.tsx -- mismo bug si este componente
|
||||||
|
termina como item de un grid externo sin min-w-0: para productos
|
||||||
|
con muchas fotos, el ancho minimo intrinseco de TODAS las
|
||||||
|
miniaturas sin wrappear puede forzar overflow horizontal en toda
|
||||||
|
la pagina en mobile. */}
|
||||||
<div className="order-2 flex gap-3 overflow-x-auto lg:order-1 lg:flex-col">
|
<div className="order-2 flex gap-3 overflow-x-auto lg:order-1 lg:flex-col">
|
||||||
{images.map((image) => <button type="button" key={image} onClick={() => { setSelected(image); reset(); }} onMouseEnter={() => { setSelected(image); reset(); }} className={`relative aspect-square w-20 shrink-0 overflow-hidden rounded-2xl border-2 ${selected === image ? "border-fuchsia-500" : "border-transparent"}`}><Image src={image} alt="" fill sizes="80px" className="object-cover" /></button>)}
|
{images.map((image) => <button type="button" key={image} onClick={() => { setSelected(image); reset(); }} onMouseEnter={() => { setSelected(image); reset(); }} className={`relative aspect-square w-20 shrink-0 overflow-hidden rounded-2xl border-2 ${selected === image ? "border-fuchsia-500" : "border-transparent"}`}><Image src={image} alt="" fill sizes="80px" className="object-cover" /></button>)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in new issue
Block a user