Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> CSS

Lợi ích của CSS Image Sprite (Ghép ảnh) và cách triển khai

Giới thiệu

CSS Image Sprite là kỹ thuật gộp nhiều ảnh nhỏ (icon, button state) thành một file ảnh lớn. Giảm số lượng HTTP request → tải trang nhanh hơn, chuyển trạng thái mượt mà (không chờ load ảnh hover).

Ví dụ hoàn chỉnh - Sprite Icon Twitter/Facebook

<!DOCTYPE html>
<html lang="vi">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSS Image Sprite</title>
  <style>
    * { box-sizing: border-box; }
    body { font-family: 'Segoe UI', system-ui, sans-serif; padding: 40px 20px; background: #f5f5f5; text-align: center; }
    h1 { margin-bottom: 30px; }
    /* Sprite sheet: 64x64 per icon, arranged vertically */
    .sprite-icon {
      display: inline-block;
      width: 64px;
      height: 64px;
      background: url('https://cdn.jsdelivr.net/gh/simple-icons/simple-icons/icons/twitter.svg') no-repeat center/contain, 
                  url('https://cdn.jsdelivr.net/gh/simple-icons/simple-icons/icons/facebook.svg') no-repeat center/contain;
      /* Thực tế dùng 1 file PNG/PNG sprite. Đây là demo concept. */
      margin: 0 16px;
      transition: transform 0.2s, opacity 0.2s;
    }
    .sprite-icon:hover { transform: scale(1.1); opacity: 0.8; }
    /* Cách dùng background-position với 1 file sprite thật */
    .sprite-real {
      display: inline-block;
      width: 64px;
      height: 64px;
      background: url('sprites_64.png') no-repeat; /* 1 file chứa nhiều icon */
      margin: 0 16px;
    }
    .sprite-real.twitter { background-position: 0 0; }
    .sprite-real.facebook { background-position: 0 -64px; }    /* Icon 2 ở dòng 2 */
    .sprite-real.instagram { background-position: 0 -128px; } /* Icon 3 ở dòng 3 */
    .sprite-real:hover { opacity: 0.7; }
    .code-block { background: #1e1e1e; color: #d4d4d4; padding: 20px; border-radius: 8px; text-align: left; font-family: monospace; font-size: 14px; line-height: 1.6; overflow-x: auto; margin: 20px 0; }
  </style>
</head>
<body>
  <h1>CSS Image Sprite Demo</h1>
  <p style="max-width:600px; margin:0 auto 30px; color:#666">Sprite gộp nhiều icon vào 1 file. Dùng background-position để chọn icon. Giảm HTTP requests, load nhanh, hover mượt.</p>
  <div>
    <a href="#" class="sprite-real twitter" aria-label="Twitter"></a>
    <a href="#" class="sprite-real facebook" aria-label="Facebook"></a>
    <a href="#" class="sprite-real instagram" aria-label="Instagram"></a>
  </div>
  <div class="code-block">
.sprite-real { display:inline-block; width:64px; height:64px; background:url(sprites_64.png) no-repeat; }
.sprite-real.twitter { background-position: 0 0; }
.sprite-real.facebook { background-position: 0 -64px; }
.sprite-real.instagram { background-position: 0 -128px; }
  </div>
  <h2 style="margin-top:40px">Lợi ích chính</h2>
  <ul style="max-width:600px; margin:0 auto; text-align:left; color:#444; line-height:1.8">
    <li>Giảm HTTP requests: 10 icon = 1 request thay vì 10. Quan trọng cho HTTP/1.1, vẫn có ích cho HTTP/2 (header overhead).</li>
    <li>Tải nhanh hơn: Browser cache 1 file, không cần handshake nhiều lần.</li>
    <li>Hover instant: Trạng thái hover đã có sẵn trong sprite, không delay load ảnh mới.</li>
    <li>Dễ maintain: Chỉ cập nhật 1 file ảnh thay vì 수십 file.</li>
  </ul>
  <h2 style="margin-top:40px">Best Practices</h2>
  <ul style="max-width:600px; margin:0 auto; text-align:left; color:#444; line-height:1.8">
    <li>Sắp xếp icon theo lưới (grid) đều đặn để dễ tính background-position.</li>
    <li>Để khoảng trống (padding) giữa các icon trong sprite tránh chảy màu (bleeding) khi zoom.</li>
    <li>Dùng công cụ tự động: spritezero, gulp-spritesmith, webpack-spritesmith, Sprite Cow (web).</li>
    <li>Cho Retina: Tạo sprite @2x, dùng background-size hoặc media query min-resolution: 2dppx.</li>
    <li>Accessibility: Thêm aria-label hoặc text ẩn cho screen reader.</li>
  </ul>
  <h2 style="margin-top:40px">Sprite cho Retina (High DPI)</h2>
  
.sprite-retina {
  width: 32px; height: 32px; /* Kích thước hiển thị */
  background: url('sprite@2x.png') no-repeat;
  background-size: 200px 100px; /* Kích thước THỰC của file sprite @2x */
}
.sprite-retina.icon1 { background-position: 0 0; }
.sprite-retina.icon2 { background-position: -32px 0; } /* 64px thực tế / 2 = 32px CSS */