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

React火车行程组件:用CSS Flex/Grid实现节点垂直线连接

嘿,我帮你梳理下实现火车行程节点连线的思路,完全用Flex布局就能搞定,而且代码结构清晰!

实现思路与代码示例

1. 整体布局结构

首先,整个行程列表是垂直的Flex容器,每个单段行程项又是横向的Flex容器,拆成三个核心区域:时间区、节点连线区、站点信息区。这种布局能保证三个部分自动对齐,还能适配不同屏幕宽度。

2. 核心:节点与垂直线的实现

节点连线的视觉效果是关键,我推荐用「主垂直线+圆形节点覆盖」的方案,简单又可靠:

  • 给节点容器设置position: relative,内部加一条绝对定位的垂直线,贯穿整个容器高度;
  • 每个圆形节点用和页面背景一致的底色,边框颜色和垂直线统一,这样圆形会覆盖住下方的线,自然形成“节点间有连线”的效果;
  • 给当前行程的节点加特殊样式(比如填充色),能快速突出显示。

3. 子组件拆分与整合

把时间、节点、站点信息拆成独立的React组件,方便后续复用和维护,父组件只负责组合布局逻辑。

React组件示例

import React from 'react';
import './TripItinerary.css';

// 时间子组件
const TimeComponent = ({ time }) => (
  <div className="trip-time">
    <span>{time}</span>
  </div>
);

// 节点子组件
const NodesComponent = ({ nodes, currentIndex }) => (
  <div className="trip-nodes">
    {/* 贯穿整个节点区的垂直线 */}
    <div className="nodes-vertical-line"></div>
    {nodes.map((node, index) => (
      <div 
        key={index} 
        className={`node ${index === currentIndex ? 'node-active' : ''}`}
      >
        <div className="node-circle"></div>
      </div>
    ))}
  </div>
);

// 站点信息子组件
const InfoComponent = ({ station, status }) => (
  <div className="trip-info">
    <h3>{station}</h3>
    <p className="status">{status}</p>
  </div>
);

// 父组件:组合所有子组件
const TripItinerary = ({ trips }) => (
  <div className="trip-container">
    {trips.map((trip, index) => (
      <div key={index} className="trip-item">
        <TimeComponent time={trip.time} />
        <NodesComponent nodes={trip.nodes} currentIndex={trip.currentIndex} />
        <InfoComponent station={trip.station} status={trip.status} />
      </div>
    ))}
  </div>
);

export default TripItinerary;

CSS样式(TripItinerary.css)

/* 整体行程容器:垂直排列所有行程项 */
.trip-container {
  display: flex;
  flex-direction: column;
  gap: 2rem;
  padding: 1rem;
  max-width: 800px;
  margin: 0 auto;
}

/* 单个行程项:横向排列三个区域 */
.trip-item {
  display: flex;
  align-items: flex-start;
  gap: 1.5rem;
}

/* 时间区:固定宽度,避免挤压 */
.trip-time {
  flex-shrink: 0;
  width: 60px;
  text-align: center;
  font-weight: bold;
  color: #333;
}

/* 节点连线区:垂直排列所有节点 */
.trip-nodes {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  align-items: center;
}

/* 贯穿的垂直线:绝对定位在节点区中间 */
.nodes-vertical-line {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 12px; /* 对应圆形直径24px,保证线在圆心位置 */
  width: 2px;
  background-color: #ccc;
}

/* 单个节点:设置层级确保圆形在垂直线上方 */
.node {
  position: relative;
  z-index: 1;
}

.node-circle {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 2px solid #ccc;
  background-color: white; /* 用底色覆盖垂直线 */
}

/* 活跃节点样式:突出当前行程 */
.node-active .node-circle {
  background-color: #007bff;
  border-color: #007bff;
}

/* 站点信息区:占据剩余空间 */
.trip-info {
  flex: 1;
}

.trip-info h3 {
  margin: 0 0 0.5rem 0;
  color: #333;
}

.status {
  margin: 0;
  color: #666;
  font-size: 0.9rem;
}

额外优化提示

  • 响应式适配:可以给.trip-item加媒体查询,小屏幕下改成垂直布局,提升移动端体验;
  • 自定义样式:根据需求调整节点大小、连线颜色、活跃节点样式,轻松匹配产品设计;
  • 扩展功能:节点里可以添加图标(比如火车、换乘标识),信息区可以增加延误时间、站台号等实时数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:02:06