我正在尝试为卡片创建一个滚动容器,其中滚动仅在卡片内容中执行,而不是在页眉或页脚中执行。我想容器应该隐藏水平溢出,并且卡片应该有
overflow-y: auto
。但是,这样做会导致以下卡片不可见。
function MainComponent() {
const [activeCardIndex, setActiveCardIndex] = React.useState(0);
const cardsContainerRef = React.useRef(null);
const cardsRefs = React.useRef([]);
const updateLayoutOffset = React.useCallback(() => {
if (!cardsContainerRef.current || !cardsRefs.current[activeCardIndex]) {
return 0;
}
const storyWidth = cardsRefs.current[activeCardIndex].offsetWidth;
const containerWidth = cardsContainerRef.current.offsetWidth;
let offset = containerWidth / 2 - storyWidth / 2 - activeCardIndex * storyWidth - activeCardIndex * 8;
cardsContainerRef.current.style.transform = `translateX(${offset}px)`;
}, [activeCardIndex]);
React.useLayoutEffect(() => {
updateLayoutOffset();
}, [updateLayoutOffset]);
React.useEffect(() => {
updateLayoutOffset();
}, [activeCardIndex, updateLayoutOffset]);
const goToNextCard = React.useCallback(() => {
if (activeCardIndex === cardsRefs.current.length - 1) {
return;
}
setActiveCardIndex(activeCardIndex + 1);
}, [activeCardIndex]);
const goToPreviousCard = React.useCallback(() => {
if (activeCardIndex === 0) {
return;
}
setActiveCardIndex(activeCardIndex - 1);
}, [activeCardIndex]);
let cards = ["Card 1", "Card 2", "Card 3"];
return (
<div className="flex h-dvh max-h-dvh w-full max-w-full flex-col justify-center overflow-hidden bg-black px-2 py-1 sm:bg-[#1a1a1a] sm:py-3">
<div className="flex h-full max-h-full flex-row transition-transform duration-500">
<div className="flex h-full max-w-full flex-row items-center sm:gap-4">
<button className="rounded-md bg-blue-500 p-2 text-white" onClick={goToPreviousCard}>
Previous
</button>
<div className="flex aspect-[9/16] h-full max-h-full max-w-full flex-col rounded-md bg-black">
<div className="flex flex-col gap-2 p-2">
<h1 className="h-fit flex-1 text-left leading-none text-white">Header </h1>
</div>
<div ref={cardsContainerRef} className="flex grow flex-row items-center gap-2 overflow-y-auto overflow-x-clip transition-transform duration-500">
{cards.map((card, index) => (
<div
ref={(el) => {
if (el) {
cardsRefs.current[index] = el;
}
}}
key={index}
className="relative flex h-full min-w-full max-w-full flex-col gap-2 overflow-y-auto text-pretty rounded-md bg-white p-2 dark:bg-[#343434]"
>
{Array(40)
.fill(0)
.map((_, i) => (
<p key={i} className="text-center">
{card}
</p>
))}
</div>
))}
</div>
<div className="flex w-full flex-row items-center p-2">
<input className="min-w-0 flex-1 rounded-full border-[1px] bg-transparent px-4 py-2 text-left" />
</div>
</div>
<button className="rounded-md bg-blue-500 p-2 text-white" onClick={goToNextCard}>
Next
</button>
</div>
</div>
</div>
);
}
ReactDOM.createRoot(document.getElementById("root")).render(<MainComponent />);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>
我找不到任何可以正常工作的溢出设置组合。
解决方案1:
overflow-x: clip
并将其替换
使用 overflow-visible
确保其他卡片可见<div className="h-full overflow-y-auto">
{/* Card content */}
</div>
overflow-y-auto
从卡片本身移至此内部容器import React from 'react';
const MainComponent = () => {
const [activeCardIndex, setActiveCardIndex] = React.useState(0);
const cardsContainerRef = React.useRef(null);
const cardsRefs = React.useRef([]);
const updateLayoutOffset = React.useCallback(() => {
if (!cardsContainerRef.current || !cardsRefs.current[activeCardIndex]) {
return 0;
}
const storyWidth = cardsRefs.current[activeCardIndex].offsetWidth;
const containerWidth = cardsContainerRef.current.offsetWidth;
let offset = containerWidth / 2 - storyWidth / 2 - activeCardIndex * storyWidth - activeCardIndex * 8;
cardsContainerRef.current.style.transform = `translateX(${offset}px)`;
}, [activeCardIndex]);
React.useLayoutEffect(() => {
updateLayoutOffset();
}, [updateLayoutOffset]);
React.useEffect(() => {
updateLayoutOffset();
}, [activeCardIndex, updateLayoutOffset]);
const goToNextCard = React.useCallback(() => {
if (activeCardIndex === cardsRefs.current.length - 1) return;
setActiveCardIndex(activeCardIndex + 1);
}, [activeCardIndex]);
const goToPreviousCard = React.useCallback(() => {
if (activeCardIndex === 0) return;
setActiveCardIndex(activeCardIndex - 1);
}, [activeCardIndex]);
const cards = ["Card 1", "Card 2", "Card 3"];
return (
<div className="flex h-dvh max-h-dvh w-full max-w-full flex-col justify-center overflow-hidden bg-black px-2 py-1 sm:bg-[#1a1a1a] sm:py-3">
<div className="flex h-full max-h-full flex-row transition-transform duration-500">
<div className="flex h-full max-w-full flex-row items-center sm:gap-4">
<button
className="rounded-md bg-blue-500 p-2 text-white hover:bg-blue-600 transition-colors"
onClick={goToPreviousCard}
>
Previous
</button>
<div className="flex aspect-[9/16] h-full max-h-full max-w-full flex-col rounded-md bg-black">
{/* Fixed Header */}
<div className="flex flex-col gap-2 p-2 bg-black">
<h1 className="h-fit flex-1 text-left leading-none text-white">Header</h1>
</div>
{/* Scrollable Cards Container */}
<div
ref={cardsContainerRef}
className="flex grow flex-row items-start gap-2 overflow-visible transition-transform duration-500"
>
{cards.map((card, index) => (
<div
ref={(el) => {
if (el) cardsRefs.current[index] = el;
}}
key={index}
className="relative flex h-full min-w-full max-w-full flex-col gap-2 rounded-md bg-white p-2 dark:bg-[#343434]"
>
{/* Scrollable Content Container */}
<div className="h-full overflow-y-auto">
{Array(40).fill(0).map((_, i) => (
<p key={i} className="text-center py-1">
{card}
</p>
))}
</div>
</div>
))}
</div>
{/* Fixed Footer */}
<div className="flex w-full flex-row items-center p-2 bg-black">
<input
className="min-w-0 flex-1 rounded-full border-[1px] border-gray-600 bg-transparent px-4 py-2 text-left text-white focus:outline-none focus:border-blue-500"
placeholder="Type here..."
/>
</div>
</div>
<button
className="rounded-md bg-blue-500 p-2 text-white hover:bg-blue-600 transition-colors"
onClick={goToNextCard}
>
Next
</button>
</div>
</div>
</div>
);
};
export default MainComponent;
解决方案2:
overflow-y-auto
,而不是
卡容器。这将只允许垂直滚动每个
卡的内部内容而不影响主卡容器的
布局。overflow-x-hidden
。这
将确保任何水平溢出的内容不会影响
其余布局。function MainComponent() {
const [activeCardIndex, setActiveCardIndex] = React.useState(0);
const cardsContainerRef = React.useRef(null);
const cardsRefs = React.useRef([]);
const updateLayoutOffset = React.useCallback(() => {
if (!cardsContainerRef.current || !cardsRefs.current[activeCardIndex]) {
return;
}
const cardWidth = cardsRefs.current[activeCardIndex].offsetWidth;
const containerWidth = cardsContainerRef.current.offsetWidth;
const offset = containerWidth / 2 - cardWidth / 2 - activeCardIndex * cardWidth - activeCardIndex * 8;
cardsContainerRef.current.style.transform = `translateX(${offset}px)`;
}, [activeCardIndex]);
React.useLayoutEffect(() => {
updateLayoutOffset();
}, [updateLayoutOffset]);
React.useEffect(() => {
updateLayoutOffset();
}, [activeCardIndex, updateLayoutOffset]);
const goToNextCard = React.useCallback(() => {
if (activeCardIndex === cardsRefs.current.length - 1) return;
setActiveCardIndex(activeCardIndex + 1);
}, [activeCardIndex]);
const goToPreviousCard = React.useCallback(() => {
if (activeCardIndex === 0) return;
setActiveCardIndex(activeCardIndex - 1);
}, [activeCardIndex]);
const cards = ["Card 1", "Card 2", "Card 3"];
return (
<div className="flex h-screen max-h-screen w-full max-w-full flex-col justify-center overflow-hidden bg-black px-2 py-1 sm:bg-[#1a1a1a] sm:py-3">
<div className="flex h-full max-h-full flex-row transition-transform duration-500">
<div className="flex h-full max-w-full flex-row items-center sm:gap-4">
<button className="rounded-md bg-blue-500 p-2 text-white" onClick={goToPreviousCard}>
Previous
</button>
<div className="flex aspect-[9/16] h-full max-h-full max-w-full flex-col rounded-md bg-black">
<div className="flex flex-col gap-2 p-2">
<h1 className="h-fit flex-1 text-left leading-none text-white">Header</h1>
</div>
<div
ref={cardsContainerRef}
className="flex grow flex-row items-center gap-2 overflow-hidden transition-transform duration-500"
>
{cards.map((card, index) => (
<div
ref={(el) => {
if (el) cardsRefs.current[index] = el;
}}
key={index}
className="relative flex h-full min-w-full max-w-full flex-col gap-2 text-pretty rounded-md bg-white p-2 dark:bg-[#343434]"
>
<div className="overflow-y-auto max-h-full">
{Array(40)
.fill(0)
.map((_, i) => (
<p key={i} className="text-center">
{card}
</p>
))}
</div>
</div>
))}
</div>
<div className="flex w-full flex-row items-center p-2">
<input className="min-w-0 flex-1 rounded-full border-[1px] bg-transparent px-4 py-2 text-left" />
</div>
</div>
<button className="rounded-md bg-blue-500 p-2 text-white" onClick={goToNextCard}>
Next
</button>
</div>
</div>
</div>
);
}