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

如何用React SCSS为选中项的上下及后续列表元素设置差异化样式

问题解决:为选中项上方元素设置差异化样式

我已经实现选中项下方紧邻元素及后续元素的差异化样式,但无法给选中项上方的元素设置不同样式。

期望效果

选中项样式突出,其上方所有元素使用一套统一样式,下方所有元素使用另一套统一样式。

当前问题

仅能修改选中项下方元素的样式,上方元素与选中项样式一致,达不到预期。

现有代码

React 组件代码

import React, { useState } from 'react'
import './App.scss'

function App() {
 
   const [list] = useState([{
      time:'10:00',
      selected:false,
   },{
      time:'10:30',
      selected:false,
   },{
      time:'11:00',
      selected:false,
   },{
      time:'11:30',
      selected:true,
   },{
      time:'12:00',
      selected:false,
   },{
      time:'12:30',
      selected:false,
   },{
      time:'01:00',
      selected:false,
   }]);

  return (
   <div className='container'>
<ul className='list'>
   {list.map((item) => (
     <li
       key={item.id}
       className={`item ${item.selected === true ? "selected" : ""}`}
     >
       {item.time}
     </li>
   ))}
 </ul>
   </div>
   
  );
}


export default App

SCSS 代码

.list{
    display: flex;
    list-style: none;
    margin: 0;
    flex-direction: column;
}
.item{
    display: flex;
    margin: 5px;
    font-weight: 500;
    font-size: 19px;
    line-height: 28px;
    letter-spacing: 0.35px;
    background-color: black;
    color: white;
    &.selected{
        font-weight: 500;
        font-size: 22px;
        line-height: 28px;
        letter-spacing: 0.35px;
        background-color: black;
        color: white;
        &.selected + .item:nth-child(n + 1) {
            font-weight: 400;
            font-weight: 500;
    font-size: 19px;
    line-height: 28px;
    letter-spacing: 0.35px;
    background-color: yellow;
          }
          &.selected ~ .item {
            font-weight: 500;
    font-size: 15px;
    line-height: 28px;
    letter-spacing: 0.35px;
    background-color: red;
          }
    }
}

解决方案

由于CSS原生不支持向前选择兄弟元素(即无法通过选中项反向选择它之前的元素),我们可以通过React预先计算每个元素与选中项的位置关系,给对应元素添加专属类名,再通过SCSS设置样式。

修改后的React组件代码

import React, { useState } from 'react'
import './App.scss'

function App() {
  const [list] = useState([
    { time: '10:00', selected: false },
    { time: '10:30', selected: false },
    { time: '11:00', selected: false },
    { time: '11:30', selected: true },
    { time: '12:00', selected: false },
    { time: '12:30', selected: false },
    { time: '01:00', selected: false }
  ]);

  // 找到选中项的索引位置
  const selectedIndex = list.findIndex(item => item.selected);

  return (
    <div className='container'>
      <ul className='list'>
        {list.map((item, index) => (
          <li
            key={item.time} // 修正key值(原代码无id字段,用time作为唯一标识)
            className={`item 
              ${item.selected ? 'selected' : ''}
              ${index < selectedIndex ? 'above-selected' : ''}
              ${index > selectedIndex ? 'below-selected' : ''}
            `}
          >
            {item.time}
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App

修改后的SCSS代码

.list{
  display: flex;
  list-style: none;
  margin: 0;
  flex-direction: column;
}

.item{
  margin: 5px;
  font-weight: 500;
  font-size: 19px;
  line-height: 28px;
  letter-spacing: 0.35px;
  background-color: black;
  color: white;

  // 选中项样式
  &.selected{
    font-size: 22px;
    // 可根据需求添加其他突出样式
  }

  // 选中项上方元素样式
  &.above-selected{
    background-color: #333; // 示例样式,可自行修改
    font-size: 17px;
  }

  // 选中项下方元素样式
  &.below-selected{
    background-color: red; // 示例样式,可自行修改
    font-size: 15px;
  }
}

说明

通过React计算每个元素的索引与选中项索引的关系,给上方元素添加above-selected类,下方元素添加below-selected类,就能轻松实现三类元素的样式区分,避开CSS选择器的局限性,实现逻辑直观且易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 04:30:42