[CSS] 瀑布流排版

2024-02-01  本文已影响0人  JellyL

需求

多个卡片,宽度一样,按瀑布流排列,每个元素依次加入到最短的那一列

实现方案

interface WaterfallsProps {
  heights: number[];
  columns: number;
}

interface AutoGridRowSpecialUnitProps {
  height: number;
  index: number;
}

const AutoGridRowSpecialUnit: React.FC<AutoGridRowSpecialUnitProps> = ({
 height,
 index,
}) => {
  const containerRef = useRef<HTMLDivElement | null>(null);

  useEffect(() => {
    const container = containerRef.current;
    if (container) {
      container.style.gridRow = `span ${Math.ceil(container.offsetHeight)}`;
    }
  }, []);

  return (
    <div id={index} ref={containerRef} className="border-aux-1 border-2 mb-1 mx-1">
        <div
          style={{ height }}
          className="bg-pri-1 text-white-1 flex justify-center items-center"
        >
          {index}
        </div>
    </div>
  );
}

export const GridWaterfalls: React.FC<WaterfallsProps> = ({
  heights,
  columns,
}) => {

  return (
      <div className={`w-[320px] grid`} style={{ gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`}}>
        {
          heights.map((height, index) => (
            <AutoGridRowSpecialUnit key={index} height={height} index={index} />
          ))
        }
      </div>
  );
};

export const Component = () => {
  const heights = [
    100,
    160,
    400,
    30,
    83,
    45,
    200
  ].sort((a, b) => Math.random() > 0.5 ? 1 : -1);

  return (
    <div className="w-full h-[100vh] flex items-center justify-center">   
      <GridWaterfalls heights={heights} columns={2} />
      <GridWaterfalls heights={heights} columns={3} />
    </div>
  );
};

实现效果:


瀑布流

竖向排版(适合用于论文或新闻排版的方式):

interface WaterfallsProps {
  heights: number[];
  columns: number;
}

export const Waterfalls: React.FC<WaterfallsProps> = ({ heights, columns }) => {

  return (
      <div
        className="w-[320px]"
        style={{
          columnCount: columns,
          columnGap: 10,
          columnFill: "revert-layer"
        }}
      >
        {
          heights.map((height, index) => (
            <div id={index} key={index} className="border-aux-1 border-2">
              <div
                style={{ height }}
                className="bg-pri-1 text-white-1 flex justify-center items-center"
              >
                {index}
              </div>
            </div>
          ))
        }
      </div>
  );
};

export const Component = () => {
  const heights = [
    100,
    160,
    400,
    30,
    83,
    45,
    200
  ].sort((a, b) => Math.random() > 0.5 ? 1 : -1);

  return (
    <div className="w-full h-[100vh] flex items-center justify-center">   
        <Waterfalls heights={heights} columns={2} />
        <Waterfalls heights={heights} columns={3} />  
    </div>
  );
};

实现效果:


竖向排版
上一篇下一篇

猜你喜欢

热点阅读