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

在Next.js/React搭配styled-components中如何修改grid每行最后一项的样式?

适配auto-fill grid动态选中每行最后一个元素的方案

针对你在Next.js + styled-components环境下的需求,提供3种不同适用场景的解决方案:


方案1:纯间距调整场景(无JS、全兼容)

如果你的需求只是消除每行最后一个元素的右间距,不需要修改其他样式(如边框、背景色等),可以用容器负边距的技巧实现,无需选中元素:

import styled from 'styled-components'

const GridContainer = styled.div`
  display: grid;
  grid-template-columns: repeat(auto-fill, 25rem);
  /* 抵消元素右间距,配合padding保证容器左右对齐 */
  margin-right: -1.5rem;
  padding-right: 1.5rem;
`

const GridItem = styled.div`
  margin-right: 1.5rem;
  /* 其他基础样式 */
  padding: 1rem;
  border: 1px solid #e5e7eb;
`

方案2:JS动态标记(兼容性最好,支持所有样式修改)

如果需要修改任意样式(如特殊背景、边框等),推荐用JS在组件挂载和窗口resize时自动标记每行最后一个元素,适配所有浏览器:

// Next.js 13+ App Router需要加该行,Pages Router可省略
'use client'
import { useEffect, useRef } from 'react'
import styled from 'styled-components'

const GridContainer = styled.div`
  display: grid;
  grid-template-columns: repeat(auto-fill, 25rem);
  gap: 1rem;
`

const GridItem = styled.div`
  padding: 1rem;
  border: 1px solid #e5e7eb;
  /* 行尾元素自定义样式 */
  &.last-in-row {
    border-right-color: #ef4444;
    background: #f9fafb;
  }
`

export default function GridComponent() {
  const containerRef = useRef(null)

  useEffect(() => {
    const markLastItems = () => {
      const container = containerRef.current
      if (!container) return
      const items = container.querySelectorAll('.grid-item')
      if (items.length < 2) return

      let lastRowOffset = -1
      // 先清除原有标记
      items.forEach(item => item.classList.remove('last-in-row'))
      // 倒序遍历标记每行最后一个元素
      for (let i = items.length - 1; i >= 0; i--) {
        const currentOffset = items[i].offsetTop
        if (currentOffset !== lastRowOffset) {
          items[i].classList.add('last-in-row')
          lastRowOffset = currentOffset
        }
      }
    }

    markLastItems()
    window.addEventListener('resize', markLastItems)
    return () => window.removeEventListener('resize', markLastItems)
  }, [])

  return (
    <GridContainer ref={containerRef}>
      <div className="grid-item">First row item</div>
      <div className="grid-item">First row item</div>
      <div className="grid-item">Last item in first row item</div>
      <div className="grid-item">Second row item</div>
      <div className="grid-item">Second row item</div>
      <div className="grid-item">Last item in Second row item</div>
    </GridContainer>
  )
}

方案3:纯CSS实现(现代浏览器兼容)

如果你的业务不需要兼容2023年之前的旧版浏览器,可以用CSS :has() 选择器实现,无需JS代码:

import styled from 'styled-components'

const GridContainer = styled.div`
  display: grid;
  grid-template-columns: repeat(auto-fill, 25rem);
  gap: 1rem;

  /* 匹配非最后一行的行尾元素 */
  .grid-item:not(:last-child):has(+ .grid-item[style*="grid-row-start"]) {
    border-right-color: #ef4444;
    background: #f9fafb;
  }
  /* 匹配最后一行的行尾元素 */
  .grid-item:last-child {
    border-right-color: #ef4444;
    background: #f9fafb;
  }
`

该方案兼容Chrome 105+、Safari 15.4+、Firefox 121+版本浏览器。


内容的提问来源于stack exchange,提问作者Rafael do Carmo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 05:27:03