CSS Sprite(CSS 精靈圖)是將多張小圖片合併為一張大圖,再透過 background-position 定位顯示,減少 HTTP 請求數、提升頁面載入速度的經典前端優化技術。
sprite.png)與樣式表(sprite.css)。<?php
/**
* 自動生成水平排列 CSS Sprite
* @param string $srcDir 來源圖片目錄(結尾需含 /)
* @param string $prefix CSS 類別前綴(如 'icon-')
* @param string $dstBase 輸出檔名基礎(不含副檔名),預設 'sprite'
*/
function generateSprite(string $srcDir, string $prefix = 'icon-', string $dstBase = 'sprite'): void {
// 1. 掃描 PNG 檔案
$files = glob($srcDir . '*.png');
if (empty($files)) {
throw new RuntimeException("No PNG files found in $srcDir");
}
sort($files); // 確保順序穩定
// 2. 計算畫布尺寸
$totalWidth = 0;
$maxHeight = 0;
$imgInfos = [];
foreach ($files as $file) {
$info = getimagesize($file);
if (!$info || $info['mime'] !== 'image/png') continue;
$imgInfos[$file] = ['w' => $info[0], 'h' => $info[1]];
$totalWidth += $info[0];
$maxHeight = max($maxHeight, $info[1]);
}
// 3. 建立透明畫布
$canvas = imagecreatetruecolor($totalWidth, $maxHeight);
imagesavealpha($canvas, true);
$transparent = imagecolorallocatealpha($canvas, 0, 0, 0, 127);
imagefill($canvas, 0, 0, $transparent);
// 4. 依序貼圖並生成 CSS
$cssRules = [];
$x = 0;
foreach ($imgInfos as $file => $info) {
$src = imagecreatefrompng($file);
imagecopy($canvas, $src, $x, 0, 0, 0, $info['w'], $info['h']);
imagedestroy($src);
$name = pathinfo($file, PATHINFO_FILENAME);
$class = $prefix . $name;
$cssRules[] = ".$class { width: {$info['w']}px; height: {$info['h']}px; background-position: -{$x}px 0; }";
$x += $info['w'];
}
// 5. 輸出合併圖片
$pngPath = $dstBase . '.png';
imagepng($canvas, $pngPath);
imagedestroy($canvas);
// 6. 生成 CSS 檔案
$cssContent = ".$prefix" . "* { background-image: url('$pngPath'); background-repeat: no-repeat; display: inline-block; }\n";
$cssContent .= implode("\n", $cssRules) . "\n";
file_put_contents($dstBase . '.css', $cssContent);
echo "Generated: $pngPath, {$dstBase}.css (" . count($cssRules) . " icons)\n";
}
// 使用範例
generateSprite(__DIR__ . '/assets/icons/', 'ic-', 'sprite');
?>
.ic-* { background-image: url('sprite.png'); background-repeat: no-repeat; display: inline-block; }
.ic-home { width: 24px; height: 24px; background-position: -0px 0; }
.ic-user { width: 24px; height: 24px; background-position: -24px 0; }
.ic-setting { width: 24px; height: 24px; background-position: -48px 0; }
<link rel="stylesheet" href="sprite.css">
<i class="ic-home"></i>
<i class="ic-user"></i>
<i class="ic-setting"></i>
$x, $y),適合寬度受限容器。mime 呼叫 imagecreatefromjpeg/webp,輸出時可選 imagewebp。@media (-webkit-min-device-pixel-ratio: 2) 區塊指向 sprite@2x.png。sprite*.png/.css,避免殘留。--with-freetype、--with-webp 導致函式不存在。ini_set('memory_limit', '256M') 或分批處理。background-image: url() 路徑。PHP 產生 CSS Sprite 適合舊專案、動態圖示庫、無 Node.js 建構環境的場景。現代前端工程建議納入建構流程(Vite/Webpack/Rollup 插件),實現零執行期成本、自動快取清除、TypeScript 型別安全。理解原理有助於在受限環境快速落地優化。