From 4c1931fd6429eafbe3bd84425eb8e0dccbf9d934 Mon Sep 17 00:00:00 2001 From: neodk2004 Date: Sat, 15 Aug 2026 09:02:36 +0200 Subject: [PATCH] fix(post-detail): fix carousel image centering at the actual root cause MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two prior attempts today (aabb7d3, a070b37) both failed in production despite each being verified in isolation — confirmed via DevTools that the deployed DOM/CSS exactly matched what had tested correctly, yet the real page still rendered short images pinned to the top. The real, unfixable-from-outside root cause: CarouselContent's own ref div (src/components/ui/carousel.tsx) is hardcoded to className= "overflow-hidden" with no way to reach it via props, so it never gets an explicit height — every centering attempt built on top of it (grid, flex, items-center at various levels) still bottomed out on that div having only an indefinite, percentage-against-an-auto-parent height, which is a genuinely ambiguous CSS case browsers can resolve inconsistently. Fix: give CarouselContent a new optional viewportClassName prop that reaches that specific div, and pass h-full through it from PostDetailDialog. Carousel's own root div already has a definite height (traced up through the dialog's fixed dvh values), so h-full on the ref div now resolves to a real pixel value instead of falling back to auto — eliminating the ambiguity instead of working around it. Carousel/ CarouselItem revert to plain h-full + flex items-center/justify-center, no grid trick needed anymore. Re-verified via an isolated static HTML/CSS repro (embla-free, no auth needed) before deploying this time. --- src/components/feed/PostDetailDialog.tsx | 25 ++++++++++++------------ src/components/ui/carousel.tsx | 8 ++++++-- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/components/feed/PostDetailDialog.tsx b/src/components/feed/PostDetailDialog.tsx index 47f4164..1a6c4ea 100644 --- a/src/components/feed/PostDetailDialog.tsx +++ b/src/components/feed/PostDetailDialog.tsx @@ -264,18 +264,19 @@ export function PostDetailDialog({ post, open, onClose, onDeleted }: PostDetailD isCarousel ? (
- {/* grid items-center (not flex) on purpose: CarouselContent's own - ref div (src/components/ui/carousel.tsx) is hardcoded to - "overflow-hidden" with no height/flex class reaching it, so it - never fills this element's height — shorter images in a - mixed-aspect-ratio carousel rendered pinned to the top instead - of centered. This is the deepest point we can attach centering - to from outside. Grid over flex specifically because grid's - default justify-items:stretch keeps the ref div's width at - 100% (required for embla's horizontal scroll math); flex's - shrink-to-content main-axis default would have broken that. */} - - + {/* CarouselContent's own ref div (src/components/ui/carousel.tsx) + was hardcoded to "overflow-hidden" with no way to give it a + height — every className/grid/flex trick attached to its + ancestors or CarouselItem still had nothing but an indefinite + (percentage-against-auto-parent) height to work with at that + div specifically, so shorter images in a mixed-aspect-ratio + carousel rendered pinned to the top instead of centered no + matter what. Fixed at the source via CarouselContent's new + viewportClassName prop, which reaches that div directly — + h-full there now resolves against Carousel's own (genuinely + definite) height instead of falling back to auto. */} + + {images.map((img) => ( ) { +function CarouselContent({ + className, + viewportClassName, + ...props +}: React.ComponentProps<"div"> & { viewportClassName?: string }) { const { carouselRef, orientation } = useCarousel() return (