SnippetUI

Card Thống Kê

Đây là thành phần thẻ thống kê lý tưởng cho trang tổng quan và trang đích, vì các con số hoạt hình và đếm từ 0 khi cuộn trang.

HTMLCSSJavaScript

Xem trước

Bốn thẻ thống kê được sắp xếp theo dạng lưới và khi bạn cuộn, các số sẽ đếm từ 0.

🚀
0
Active Users
0%
Satisfaction
🌍
0+
Countries
0%
Uptime

Trường hợp sử dụng và tính năng

  • Phần hiệu suất trang đích: Truyền đạt một cách hiệu quả các số liệu như lượt xem, mức độ hài lòng của khách hàng, số lượng quốc gia, v.v.
  • Sử dụng Trình quan sát giao lộ: Hoạt ảnh kích hoạt khi cuộn và hiển thị lần đầu tiên.
  • Hỗ trợ dấu thập phân: Hỗ trợ cả bộ đếm số nguyên và số thập phân với thuộc tính data-decimals.
  • Quản lý màu bằng các biến CSS: Bạn có thể sử dụng biến --accent để phân tách các màu nhấn cho mỗi thẻ.

Điểm thiết kế và UX

  1. Hoạt hình dễ dàng: Thay vì cubic-bezier, một cách dễ dàng độc đáo sử dụng hàm ẩn khối là một chuyển động tự nhiên trong đó giá trị số ngừng tăng tốc.
  2. Văn bản chuyển màu: Với -webkit-background-clip: text, bản thân con số sẽ chuyển màu, tạo cảm giác cao cấp.
  3. Định dạng số bằng toLocaleString(): Hiển thị số theo ngôn ngữ, chẳng hạn như 12847 → 12,847.

Cách tùy chỉnh

Thay đổi tốc độ đếm (mili giây):

// Rút ngắn thời gian hoạt ảnh
// animateCounter(el, target, suffix, decimals, 1000);

// Kéo dài thời gian hoạt ảnh
// animateCounter(el, target, suffix, decimals, 3000);

Thay đổi số chữ số thập phân:

<!-- 3 chữ số thập phân -->
<span class="stat-number" data-target="99.999" data-suffix="%" data-decimals="3">0%</span>

Mã triển khai

<div class="stats-grid">
<div class="stat-card stat-card-1">
  <div class="stat-icon">🚀</div>
  <span class="stat-number" data-target="12847" data-suffix="" data-decimals="0">0</span>
  <div class="stat-label">Active Users</div>
</div>
<!-- Cấu trúc tương tự cho các thẻ khác -->
</div>

<style>
`
.stat-number {
background: linear-gradient(135deg, var(--accent), var(--accent-light));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.stat-card-1 { --accent: #6366f1; --accent-light: #8b5cf6; }
`
</style>

<script>
(function() {
function animateCounter(el, target, suffix, decimals, duration) {
  var start = null;
  function step(ts) {
    if (!start) start = ts;
    var p = Math.min((ts-start)/duration,1);
    var v = (1-Math.pow(1-p,3))*target;
    el.textContent=(decimals>0?v.toFixed(decimals):Math.floor(v).toLocaleString())+suffix;
    if(p<1) requestAnimationFrame(step);
  }
  requestAnimationFrame(step);
}
var observer = new IntersectionObserver(function(entries) {
  entries.forEach(function(e) {
    if (e.isIntersecting) {
      var el = e.target;
      if (!el.classList.contains('animated')) {
        el.classList.add('animated');
        animateCounter(el, parseFloat(el.dataset.target), el.dataset.suffix || '', parseInt(el.dataset.decimals || '0'), 2000);
      }
    }
  });
}, { threshold: 0.5 });

document.querySelectorAll('.stat-number').forEach(function(el) {
  observer.observe(el);
});
})();
</script>

Trạng thái tương thích với trình duyệt

Trình duyệtTrạng thái tương thích
Chrome 51+✅ Hoàn toàn tương thích
Firefox 55+✅ Hoàn toàn tương thích
Safari 12.1+✅ Tương thích
Cạnh 79+✅ Hoàn toàn tương thích

API Intersection Observer chỉ hỗ trợ Nenewa trong các trình duyệt hiện đại. Cần có một polyfill nếu bạn muố