You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中基于CSS Grid位置实现元素平移的方案咨询

最优实现方案:ResizeObserver + 行奇偶性判断

不需要监听整个窗口宽度,而是用ResizeObserver监听Grid容器的尺寸变化,动态计算列数后判断每个box所在行的奇偶性,再应用平移样式。这种方式更精准、性能更优,还能处理容器非全屏的场景。

React组件代码

import { useEffect, useRef, useState } from 'react';
import './App.css';

function App() {
  const containerRef = useRef(null);
  const [columns, setColumns] = useState(0);
  // 生成8个box示例
  const boxes = Array.from({ length: 8 }, (_, idx) => idx + 1);

  useEffect(() => {
    const container = containerRef.current;
    if (!container) return;

    // 计算当前列数(每个box宽100px)
    const updateColumns = () => {
      const colCount = Math.floor(container.offsetWidth / 100);
      setColumns(colCount || 1);
    };

    // 初始化列数
    updateColumns();

    // 监听容器尺寸变化
    const observer = new ResizeObserver(updateColumns);
    observer.observe(container);

    return () => observer.unobserve(container);
  }, []);

  return (
    <div ref={containerRef} className="grid-container">
      {boxes.map((num, idx) => {
        // 计算当前box所在行(从1开始计数)
        const row = Math.floor(idx / columns) + 1;
        const isOddRow = row % 2 === 1;
        return (
          <div
            key={num}
            className={`box ${isOddRow ? 'shift-left' : 'shift-right'}`}
          >
            {num}
          </div>
        );
      })}
    </div>
  );
}

export default App;

CSS样式代码

.grid-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, 100px);
  gap: 10px;
  justify-content: center;
  padding: 20px;
}

.box {
  width: 100px;
  height: 100px;
  background-color: #e0e0e0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.2rem;
  transition: transform 0.3s ease;
}

.shift-left {
  transform: translateX(-200px);
}

.shift-right {
  transform: translateX(200px);
}

方案优势

  1. 精准监听:只关注Grid容器的尺寸变化,而非整个窗口,避免窗口变化但容器宽度不变时的无效计算,性能更优。
  2. 逻辑匹配:完全贴合你给出的示例需求:
    • 窄窗口2列时,第1、3行(奇数行)的box左移,第2、4行(偶数行)的box右移;
    • 窗口变宽为3列时,第1、3行的box左移,第2行的box右移,完美匹配你描述的效果。
  3. 关注点分离:用CSS类控制平移样式,便于维护,还能添加过渡动画提升交互体验。

纯CSS替代方案(局限性明显)

如果不需要处理动态容器宽度,仅针对全屏窗口的固定列数场景,可以用媒体查询+:nth-child选择器实现,但需要预设所有可能的列数:

/* 2列场景(窄窗口) */
@media (max-width: 600px) {
  .grid-container .box:nth-child(4n-3),
  .grid-container .box:nth-child(4n-2) {
    transform: translateX(-200px);
  }
  .grid-container .box:nth-child(4n-1),
  .grid-container .box:nth-child(4n) {
    transform: translateX(200px);
  }
}

/* 3列场景(中等宽度) */
@media (min-width: 601px) and (max-width: 900px) {
  .grid-container .box:nth-child(6n-5),
  .grid-container .box:nth-child(6n-4),
  .grid-container .box:nth-child(6n-3) {
    transform: translateX(-200px);
  }
  .grid-container .box:nth-child(6n-2),
  .grid-container .box:nth-child(6n-1),
  .grid-container .box:nth-child(6n) {
    transform: translateX(200px);
  }
}

/* 4列场景(宽窗口) */
@media (min-width: 901px) {
  .grid-container .box:nth-child(8n-7),
  .grid-container .box:nth-child(8n-6),
  .grid-container .box:nth-child(8n-5),
  .grid-container .box:nth-child(8n-4) {
    transform: translateX(-200px);
  }
  .grid-container .box:nth-child(8n-3),
  .grid-container .box:nth-child(8n-2),
  .grid-container .box:nth-child(8n-1),
  .grid-container .box:nth-child(8n) {
    transform: translateX(200px);
  }
}

这种方式的局限性:无法覆盖容器宽度动态变化的场景(比如容器是百分比宽度),只能处理预设的窗口宽度区间。

内容的提问来源于stack exchange,提问作者user25987386

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 02:57:35