- 作者:老汪软件技巧
- 发表时间: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复制@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