Show timeline items with fade-in effect
by der_robert
HTML
<div class="timeline">
<div class="timeline-item">
<div class="timeline-content">
<span class="timeline-icon">📝</span>
<div class="log-header">
<div class="log-date">05.08.2025 09:43</div>
<div class="log-user">von <i>admin</i></div>
<div class="log-description">Benutzerdaten aktualisiert</div>
</div>
<table class="log-changes">
<thead>
<tr>
<th>Feld</th>
<th>Vorher</th>
<th>Nachher</th>
</tr>
</thead>
<tbody>
<tr>
<td>Name</td>
<td>Max</td>
<td>Maximilian</td>
</tr>
<tr>
<td>PLZ</td>
<td>12345</td>
<td>54321</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="timeline-item">
<div class="timeline-content">
<span class="timeline-icon">đź”’</span>
<div class="log-header">
<div class="log-date">05.08.2025 10:15</div>
<div class="log-user">von <i>hannah</i></div>
<div class="log-description">Passwort zurĂĽckgesetzt</div>
</div>
<table class="log-changes">
<thead>
<tr>
<th>Feld</th>
<th>Vorher</th>
<th>Nachher</th>
</tr>
</thead>
<tbody>
<tr>
<td>Passwort</td>
<td>••••••</td>
<td>••••••</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
SCSS
.timeline {
position: relative;
max-width: 900px;
margin: 60px auto;
padding: 0 20px;
&::before {
content: '';
position: absolute;
top: 0;
bottom: 0;
left: 40px;
width: 4px;
background: #ccc;
}
.timeline-item {
position: relative;
margin-bottom: 50px;
padding-left: 80px;
.timeline-content {
background: #fff;
border-left: 4px solid #2196f3;
padding: 20px 25px;
border-radius: 10px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
position: relative;
.timeline-icon {
position: absolute;
left: -50px;
top: 20px;
width: 32px;
height: 32px;
background: #2196f3;
color: white;
border-radius: 50%;
font-size: 18px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 0 0 4px #e3f2fd;
}
.log-header {
margin-bottom: 10px;
.log-date {
font-weight: bold;
color: #333;
}
.log-user {
font-style: italic;
color: #666;
}
.log-description {
margin-top: 5px;
color: #444;
}
}
.log-changes {
width: 100%;
border-collapse: collapse;
margin-top: 15px;
th, td {
padding: 8px 10px;
border: 1px solid #ddd;
}
th {
background: #f3f3f3;
color: #222;
text-align: left;
}
td {
background: #fcfcfc;
word-break: break-word;
}
}
}
}
@media screen and (max-width: 600px) {
&::before {
left: 20px;
}
.timeline-item {
padding-left: 60px;
.timeline-content {
.timeline-icon {
left: -40px;
}
}
}
}
}
JavaScript
document.addEventListener('DOMContentLoaded', () => {
const items = document.querySelectorAll('.timeline-item');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
}
});
}, { threshold: 0.2 });
items.forEach(item => observer.observe(item));
});