使用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/200![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/7d6842b409144c9f99fd8aa5bdc24d89.png#pic_center)
0/svg" width="12" height="12"><circle cx="6" cy="6" r="6"></circle></svg><div class="content"><time>1989</time><div class="text"><p>I was born in the north of Sweden</p></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实现
<!DOCTYPE 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>1989</time><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>2005</time><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>2010</time><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>2015</time><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>2020</time><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
<!DOCTYPE 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>1989</time><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>2005</time><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>2010</time><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>2015</time><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>2020</time><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