• 作者:老汪软件技巧
  • 发表时间:2024-10-16 00:03
  • 浏览量:

使用CSS Flexbox创建简洁时间轴

在网页设计中,时间轴是一种常见且有效的方式来展示事件的顺序和进程。本文将介绍如何使用CSS Flexbox创建一个简洁优雅的时间轴,无需复杂的JavaScript代码。

基本HTML结构

首先,我们需要创建基本的HTML结构:

html复制<div class="timeline">
  <div class="events">
    <div class="event life">
      <svg class="marker" xmlns="http://www.w3.org/2000/svg" width="12" height="12">
        <circle cx="6" cy="6" r="6">circle>
      svg>
      <div class="content">
        <time>1989time>
        <div class="text">
          <p>I was born in the north of Swedenp>
        div>
      div>
    div>
    
  div>
div>

CSS样式1. 创建时间线

使用::before伪元素创建时间线:

css复制.events {
  position: relative;
}
.events::before {
  content: "";
  position: absolute;
  top: 0;
  height: 100%;
  width: 1px;
  background: white;
}

2. 事件对齐

使用Flexbox对齐事件:

css复制.event {
  display: flex;
  align-items: baseline;
}
.event .marker {
  position: relative;
  left: -6px;
}

3. 垂直间距

使用Flexbox控制事件间的垂直间距:

css复制.events {
  display: flex;
  flex-direction: column;
  row-gap: 1em;
}

4. 响应式设计

使用CSS Flexbox创建简洁时间轴__使用CSS Flexbox创建简洁时间轴

使用媒体查询实现响应式设计:

css复制@media (min-width: 700px) {
  .events::before {
    left: 50%;
  }
  
  .event .marker {
    order: 1;
  }
  
  .event .content {
    width: 50%;
    text-align: right;
    padding-inline: 1em;
  }
  
  .event:nth-child(even) {
    flex-direction: row-reverse;
  }
  
  .event:nth-child(even) .content {
    text-align: left;
  }
  
  .event:nth-child(even) .marker {
    left: 6px;
  }
}

完整CSS代码

以下是完整的CSS代码:

css复制.events::before {
  content: "";
  position: absolute;
  top: 0;
  height: 100%;
  width: 1px;
  background: var(--color-hr);
}
.events {
  position: relative;
  display: flex;
  margin-block: 0.5em;
  flex-direction: column;
  row-gap: 1em;
}
.event {
  display: flex;
  align-items: baseline;
}
.event .marker {
  position: relative;
  left: -6px;
}
.event.life .marker {
  fill: var(--melange_b_yellow);
}
.event.programming .marker {
  fill: var(--melange_b_magenta);
}
.event.family .marker {
  fill: var(--melange_b_red);
}
.content time {
  font-family: concourse_4, Helvetica, sans-serif;
  font-weight: bold;
}
@media (min-width: 700px) {
  .events::before {
    left: 50%;
  }
  
  .event .marker {
    order: 1;
  }
  
  .event .content {
    width: 50%;
    text-align: right;
    padding-inline: 1em;
  }
  
  .event:is(.programming, .work, .projects) {
    flex-direction: row-reverse;
  }
  
  .event:is(.programming, .work, .projects) .content {
    text-align: left;
  }
  
  .event:is(.programming, .work, .projects) .marker {
    left: 6px;
  }
}

通过这些CSS样式,我们创建了一个简洁、响应式的时间轴。在小屏幕上,事件垂直排列;在大屏幕上,事件分布在时间线的两侧。这种设计既美观又实用,能够有效地展示事件的顺序和重要性。

使用Flexbox使得创建这样的时间轴变得相对简单,它简化了许多曾经复杂的布局任务。通过调整颜色、字体和间距,你可以进一步自定义时间轴以适应你的网站设计。

demos实现HTML实现

html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>交互式时间轴演示title>
  <style>
    /* CSS 样式将在这里 */
  style>
head>
<body>
  <h1>交互式时间轴演示h1>
  
  <div class="controls">
    <label>
      时间轴颜色:
      <input type="color" id="lineColor" value="#ffffff">
    label>
    <label>
      事件间距:
      <input type="range" id="eventSpacing" min="0.5" max="3" step="0.1" value="1">
    label>
    <label>
      响应式布局宽度:
      <input type="number" id="responsiveWidth" min="300" max="1200" step="50" value="700">px
    label>
  div>
  <div class="timeline">
    <div class="events">
      <div class="event life">
        <svg class="marker" xmlns="http://www.w3.org/2000/svg" width="12" height="12">
          <circle cx="6" cy="6" r="6">circle>
        svg>
        <div class="content">
          <time>1989time>
          <div class="text">
            <p>我出生在瑞典北部p>
          div>
        div>
      div>
      <div class="event programming">
        <svg class="marker" xmlns="http://www.w3.org/2000/svg" width="12" height="12">
          <circle cx="6" cy="6" r="6">circle>
        svg>
        <div class="content">
          <time>2005time>
          <div class="text">
            <p>开始学习编程p>
          div>
        div>
      div>
      <div class="event life">
        <svg class="marker" xmlns="http://www.w3.org/2000/svg" width="12" height="12">
          <circle cx="6" cy="6" r="6">circle>
        svg>
        <div class="content">
          <time>2010time>
          <div class="text">
            <p>搬到瑞典南部p>
          div>
        div>
      div>
      <div class="event programming">
        <svg class="marker" xmlns="http://www.w3.org/2000/svg" width="12" height="12">
          <circle cx="6" cy="6" r="6">circle>
        svg>
        <div class="content">
          <time>2015time>
          <div class="text">
            <p>开始职业编程生涯p>
          div>
        div>
      div>
      <div class="event family">
        <svg class="marker" xmlns="http://www.w3.org/2000/svg" width="12" height="12">
          <circle cx="6" cy="6" r="6">circle>
        svg>
        <div class="content">
          <time>2020time>
          <div class="text">
            <p>组建家庭p>
          div>
        div>
      div>
    div>
  div>
  <script>
    // JavaScript 代码将在这里
  script>
body>
html>

CSS实现

body {
  font-family: Arial, sans-serif;
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
  background-color: #f0f0f0;
  color: #333;
}
h1 {
  text-align: center;
}
.controls {
  background-color: #e0e0e0;
  padding: 10px;
  margin-bottom: 20px;
  border-radius: 5px;
}
.controls label {
  display: block;
  margin-bottom: 10px;
}
.timeline {
  background-color: #fff;
  padding: 20px;
  border-radius: 5px;
  box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.events::before {
  content: "";
  position: absolute;
  top: 0;
  height: 100%;
  width: 2px;
  background: var(--line-color, #fff);
}
.events {
  position: relative;
  display: flex;
  margin-block: 0.5em;
  flex-direction: column;
  row-gap: var(--event-spacing, 1em);
}
.event {
  display: flex;
  align-items: baseline;
}
.event .marker {
  position: relative;
  left: -6px;
}
.event.life .marker { fill: #ffd700; }
.event.programming .marker { fill: #ff00ff; }
.event.family .marker { fill: #ff0000; }
.content time {
  font-weight: bold;
}
@media (min-width: 700px) {
  .events::before {
    left: 50%;
  }
  .event .marker {
    order: 1;
  }
  .event .content {
    width: 50%;
    text-align: right;
    padding-inline: 1em;
  }
  .event:nth-child(even) {
    flex-direction: row-reverse;
  }
  .event:nth-child(even) .content {
    text-align: left;
  }
  .event:nth-child(even) .marker {
    left: 6px;
  }
}

js实现

document.addEventListener('DOMContentLoaded', function() {
  const lineColor = document.getElementById('lineColor');
  const eventSpacing = document.getElementById('eventSpacing');
  const responsiveWidth = document.getElementById('responsiveWidth');
  const timeline = document.querySelector('.timeline');
  const events = document.querySelector('.events');
  function updateTimeline() {
    timeline.style.setProperty('--line-color', lineColor.value);
    events.style.setProperty('--event-spacing', `${eventSpacing.value}em`);
    document.body.style.setProperty('--responsive-width', `${responsiveWidth.value}px`);
  }
  lineColor.addEventListener('input', updateTimeline);
  eventSpacing.addEventListener('input', updateTimeline);
  responsiveWidth.addEventListener('input', updateTimeline);
  updateTimeline();
});

完整demo

html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>交互式时间轴演示title>
  <style>
    body {
      font-family: Arial, sans-serif;
      max-width: 800px;
      margin: 0 auto;
      padding: 20px;
      background-color: #f0f0f0;
      color: #333;
    }
    h1 {
      text-align: center;
    }
    .controls {
      background-color: #e0e0e0;
      padding: 10px;
      margin-bottom: 20px;
      border-radius: 5px;
    }
    .controls label {
      display: block;
      margin-bottom: 10px;
    }
    .timeline {
      background-color: #fff;
      padding: 20px;
      border-radius: 5px;
      box-shadow: 0 2px 5px rgba(0,0,0,0.1);
    }
    .events::before {
      content: "";
      position: absolute;
      top: 0;
      height: 100%;
      width: 2px;
      background: var(--line-color, #fff);
    }
    .events {
      position: relative;
      display: flex;
      margin-block: 0.5em;
      flex-direction: column;
      row-gap: var(--event-spacing, 1em);
    }
    .event {
      display: flex;
      align-items: baseline;
    }
    .event .marker {
      position: relative;
      left: -6px;
    }
    .event.life .marker { fill: #ffd700; }
    .event.programming .marker { fill: #ff00ff; }
    .event.family .marker { fill: #ff0000; }
    .content time {
      font-weight: bold;
    }
    @media (min-width: var(--responsive-width, 700px)) {
      .events::before {
        left: 50%;
      }
      .event .marker {
        order: 1;
      }
      .event .content {
        width: 50%;
        text-align: right;
        padding-inline: 1em;
      }
      .event:nth-child(even) {
        flex-direction: row-reverse;
      }
      .event:nth-child(even) .content {
        text-align: left;
      }
      .event:nth-child(even) .marker {
        left: 6px;
      }
    }
  style>
head>
<body>
  <h1>交互式时间轴演示h1>
  
  <div class="controls">
    <label>
      时间轴颜色:
      <input type="color" id="lineColor" value="#ffffff">
    label>
    <label>
      事件间距:
      <input type="range" id="eventSpacing" min="0.5" max="3" step="0.1" value="1">
    label>
    <label>
      响应式布局宽度:
      <input type="number" id="responsiveWidth" min="300" max="1200" step="50" value="700">px
    label>
  div>
  <div class="timeline">
    <div class="events">
      <div class="event life">
        <svg class="marker" xmlns="http://www.w3.org/2000/svg" width="12" height="12">
          <circle cx="6" cy="6" r="6">circle>
        svg>
        <div class="content">
          <time>1989time>
          <div class="text">
            <p>我出生在瑞典北部p>
          div>
        div>
      div>
      <div class="event programming">
        <svg class="marker" xmlns="http://www.w3.org/2000/svg" width="12" height="12">
          <circle cx="6" cy="6" r="6">circle>
        svg>
        <div class="content">
          <time>2005time>
          <div class="text">
            <p>开始学习编程p>
          div>
        div>
      div>
      <div class="event life">
        <svg class="marker" xmlns="http://www.w3.org/2000/svg" width="12" height="12">
          <circle cx="6" cy="6" r="6">circle>
        svg>
        <div class="content">
          <time>2010time>
          <div class="text">
            <p>搬到瑞典南部p>
          div>
        div>
      div>
      <div class="event programming">
        <svg class="marker" xmlns="http://www.w3.org/2000/svg" width="12" height="12">
          <circle cx="6" cy="6" r="6">circle>
        svg>
        <div class="content">
          <time>2015time>
          <div class="text">
            <p>开始职业编程生涯p>
          div>
        div>
      div>
      <div class="event family">
        <svg class="marker" xmlns="http://www.w3.org/2000/svg" width="12" height="12">
          <circle cx="6" cy="6" r="6">circle>
        svg>
        <div class="content">
          <time>2020time>
          <div class="text">
            <p>组建家庭p>
          div>
        div>
      div>
    div>
  div>
  <script>
    document.addEventListener('DOMContentLoaded', function() {
      const lineColor = document.getElementById('lineColor');
      const eventSpacing = document.getElementById('eventSpacing');
      const responsiveWidth = document.getElementById('responsiveWidth');
      const timeline = document.querySelector('.timeline');
      const events = document.querySelector('.events');
      function updateTimeline() {
        timeline.style.setProperty('--line-color', lineColor.value);
        events.style.setProperty('--event-spacing', `${eventSpacing.value}em`);
        document.body.style.setProperty('--responsive-width', `${responsiveWidth.value}px`);
      }
      lineColor.addEventListener('input', updateTimeline);
      eventSpacing.addEventListener('input', updateTimeline);
      responsiveWidth.addEventListener('input', updateTimeline);
      updateTimeline();
    });
  script>
body>
html>

==参考文章:== Jonas Hietala: A simple timeline using CSS flexbox