Overflow-y auto 使overflow-x 剪辑不可见

问题描述 投票:0回答:1

我正在尝试为卡片创建一个滚动容器,其中滚动仅在卡片内容中执行,而不是在页眉或页脚中执行。我想容器应该隐藏水平溢出,并且卡片应该有

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>

我找不到任何可以正常工作的溢出设置组合。

css reactjs scroll overflow
1个回答
0
投票

解决方案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
    ,而不是 卡容器。这将只允许垂直滚动每个 卡的内部内容而不影响主卡容器的 布局。
  • 在主容器 (cardsContainerRef) 上设置
    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>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.