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 */