Thanh tiến trình dạng sọc (striped progress bar) là một biến thể trực quan và hiện đại của thành phần UI cơ bản, thường được sử dụng để phản ánh trạng thái xử lý không đồng bộ — như tải tệp, gọi API hoặc render dữ liệu. Khác với thanh tiến trình trơn, phiên bản có họa tiết sọc chéo tạo cảm giác năng động và chuyên nghiệp hơn, đặc biệt khi kết hợp hiệu ứng chuyển động nền.
Để xây dựng thành phần này, ta kết hợp ba yếu tố chính: nền gradient tuyến tính mô phỏng sọc, lớp phủ động bằng @keyframes, và logic cập nhật trạng thái bằng JavaScript.
Cách triển khai cơ bản
Dưới đây là đoạn mã HTML/CSS/JS tối ưu hóa, sử dụng tên lớp rõ ràng, đơn vị linh hoạt và logic tăng dần mượt mà:
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Thanh Tiến Trình Sọc</title>
<style>
.loader-wrapper {
width: 25vw;
height: 1.875rem;
background: #e0e0e0;
border-radius: 0.3125rem;
overflow: hidden;
margin: 1.5rem auto;
}
.loader-fill {
height: 100%;
width: 0%;
background-color: #2e7d32;
background-image:
linear-gradient(
45deg,
rgba(255, 255, 255, 0.2) 25%,
transparent 25%,
transparent 50%,
rgba(255, 255, 255, 0.2) 50%,
rgba(255, 255, 255, 0.2) 75%,
transparent 75%,
transparent
);
background-size: 0.875rem 0.875rem;
color: white;
font-size: 0.875rem;
text-align: right;
line-height: 1.875rem;
transition: width 0.2s ease;
position: relative;
}
.loader-fill::after {
content: attr(data-percent) '%';
position: absolute;
right: 0.5rem;
top: 50%;
transform: translateY(-50%);
}
</style>
</head>
<body>
<div class="loader-wrapper">
<div class="loader-fill" id="loader" data-percent="0"></div>
</div>
<script>
const loader = document.getElementById('loader');
let current = 0;
const startLoading = () => {
if (current < 100) {
current += Math.floor(Math.random() * 3) + 1; // Tăng ngẫu nhiên từ 1–3%
current = Math.min(current, 100);
loader.style.width = `${current}%`;
loader.dataset.percent = current;
} else {
clearInterval(loadInterval);
}
};
const loadInterval = setInterval(startLoading, 120);
</script>
</body>
</html>
Thêm hiệu ứng sọc di chuyển
Để làm nổi bật cảm giác "đang xử lý", ta áp dụng animation cho thuộc tính background-position. Thay vì dịch chuyển theo chiều ngang thuần túy, hiệu ứng được thiết lập để tạo luồng sọc chạy chéo từ phải sang trái liên tục:
<style>
.loader-fill {
/* ... các thuộc tính trước đó ... */
animation: stripeFlow 1.2s linear infinite;
}
@keyframes stripeFlow {
0% {
background-position: 0.875rem 0;
}
100% {
background-position: -0.875rem 0;
}
}
</style>
Chú ý rằng giá trị background-size và khoảng dịch chuyển trong @keyframes cần đồng bộ để đảm bảo chuyển động liền mạch — ở đây cả hai đều dùng 0.875rem (tương đương 14px), giúp sọc lặp lại mượt mà mà không bị đứt quãng.
Mã trên sử dụng data-percent thay vì nội dung trực tiếp để tách biệt dữ liệu trạng thái và giao diện, hỗ trợ dễ dàng tích hợp với framework hoặc hệ thống quản lý trạng thái sau này.