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

如何解决TailwindCSS移动端网格列重叠并实现横向吸附滚动?

解决移动端天气预报卡片重叠问题

问题出在哪

你原来的移动端代码用了grid-cols-7 grid-flow-col,这会把14个卡片(7天×日/夜)硬塞成7列2行的网格,再加上卡片固定了w-[325px],小屏幕根本装不下,直接就重叠了。而且overflow-x-clip会把溢出的内容截断,连滚动都做不了。

怎么改

我们把移动端布局拆成上下两行,每行单独做横向滚动(分别放日间、夜间的卡片),桌面端保留原来的两列网格就行:

  1. 先把预报数据按白天、晚上分开
  2. 外层容器在移动端用两行Grid,桌面端还是原来的两列7行
  3. 给每行的滚动容器加上正确的滚动和吸附属性

修正后的代码

// 先把预报数据分成日间和夜间两组
const daytimePeriods = forecast.filter(period => period.isDaytime);
const nighttimePeriods = forecast.filter(period => !period.isDaytime);

return (
  {/* 外层容器:移动端两行布局,桌面端两列7行 */}
  <div className="w-full gap-4 md:grid md:grid-cols-2 md:grid-rows-7">
    {/* 移动端:日间卡片横向滚动容器 */}
    <div className="flex overflow-x-auto snap-x pb-4 md:hidden">
      {daytimePeriods.map(period => (
        <div className="border w-[325px] h-[200px] flex-shrink-0 rounded-2xl p-2 snap-center mx-auto" key={`day-${period.number}`}>
          <div>{period.name}</div>
          <div className="flex w-full max-h-[100px]">
            <div>
              <Image 
                className="max-h-[100px] max-w-[100px]" 
                src={period.icon} 
                width={100} 
                height={100} 
                alt="Forecast Icon" 
              />
            </div>
            <div className="w-full px-2">
              <ul>
                <li>Temp: {period.temperature}°{period.temperatureUnit}</li>
                <li>Dewpoint: {period.dewpoint.value?.toFixed(2)}°{period.dewpoint.unitCode.replace('wmoUnit:deg', '')}</li>
                <li>Humidity: {period.relativeHumidity.value}%</li>
                <li>Wind: {period.windSpeed} {period.windDirection}</li>
              </ul>
            </div>
          </div>
          <p className="weather">{period.detailedForecast}</p>
        </div>
      ))}
    </div>

    {/* 移动端:夜间卡片横向滚动容器 */}
    <div className="flex overflow-x-auto snap-x pb-4 md:hidden">
      {nighttimePeriods.map(period => (
        <div className="border w-[325px] h-[200px] flex-shrink-0 rounded-2xl p-2 snap-center mx-auto" key={`night-${period.number}`}>
          <div>{period.name}</div>
          <div className="flex w-full max-h-[100px]">
            <div>
              <Image 
                className="max-h-[100px] max-w-[100px]" 
                src={period.icon} 
                width={100} 
                height={100} 
                alt="Forecast Icon" 
              />
            </div>
            <div className="w-full px-2">
              <ul>
                <li>Temp: {period.temperature}°{period.temperatureUnit}</li>
                <li>Dewpoint: {period.dewpoint.value?.toFixed(2)}°{period.dewpoint.unitCode.replace('wmoUnit:deg', '')}</li>
                <li>Humidity: {period.relativeHumidity.value}%</li>
                <li>Wind: {period.windSpeed} {period.windDirection}</li>
              </ul>
            </div>
          </div>
          <p className="weather">{period.detailedForecast}</p>
        </div>
      ))}
    </div>

    {/* 桌面端:两列网格布局(日间/夜间各一列,对应7天) */}
    <div className="hidden md:contents">
      {daytimePeriods.map(period => (
        <div className="border w-full h-[200px] rounded-2xl p-2" key={`desktop-day-${period.number}`}>
          <div>{period.name}</div>
          <div className="flex w-full max-h-[100px]">
            <div>
              <Image 
                className="max-h-[100px] max-w-[100px]" 
                src={period.icon} 
                width={100} 
                height={100} 
                alt="Forecast Icon" 
              />
            </div>
            <div className="w-full px-2">
              <ul>
                <li>Temp: {period.temperature}°{period.temperatureUnit}</li>
                <li>Dewpoint: {period.dewpoint.value?.toFixed(2)}°{period.dewpoint.unitCode.replace('wmoUnit:deg', '')}</li>
                <li>Humidity: {period.relativeHumidity.value}%</li>
                <li>Wind: {period.windSpeed} {period.windDirection}</li>
              </ul>
            </div>
          </div>
          <p className="weather">{period.detailedForecast}</p>
        </div>
      ))}
    </div>

    <div className="hidden md:contents">
      {nighttimePeriods.map(period => (
        <div className="border w-full h-[200px] rounded-2xl p-2" key={`desktop-night-${period.number}`}>
          <div>{period.name}</div>
          <div className="flex w-full max-h-[100px]">
            <div>
              <Image 
                className="max-h-[100px] max-w-[100px]" 
                src={period.icon} 
                width={100} 
                height={100} 
                alt="Forecast Icon" 
              />
            </div>
            <div className="w-full px-2">
              <ul>
                <li>Temp: {period.temperature}°{period.temperatureUnit}</li>
                <li>Dewpoint: {period.dewpoint.value?.toFixed(2)}°{period.dewpoint.unitCode.replace('wmoUnit:deg', '')}</li>
                <li>Humidity: {period.relativeHumidity.value}%</li>
                <li>Wind: {period.windSpeed} {period.windDirection}</li>
              </ul>
            </div>
          </div>
          <p className="weather">{period.detailedForecast}</p>
        </div>
      ))}
    </div>
  </div>
);

关键调整点

  • 数据拆分:用filter把白天和晚上的预报分开,方便分别渲染到对应的滚动容器里
  • 移动端滚动:用flex overflow-x-auto snap-x实现横向滚动,flex-shrink-0保证卡片不会被挤变形,snap-center让滚动时卡片自动吸附到屏幕中间,mx-auto让初始状态下卡片居中显示
  • 桌面端兼容:用md:contents让分组的卡片直接融入外层的Grid布局,保留原来的两列7行结构
  • 移除冲突属性:删掉原来移动端的grid-cols-7 grid-flow-col overflow-x-clip,避免布局冲突

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 05:02:01