← Назад к вопросам
Как работал с SVG иконками?
2.0 Middle🔥 192 комментариев
#Soft Skills и рабочие процессы
Комментарии (2)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Работа с SVG иконками
Это важная часть фронтенда. SVG иконки масштабируемы, оптимальны и гибки в стилизации.
1. Встроенный SVG (inline)
<!-- Копируем SVG код прямо в HTML -->
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path d="M5 12h14M12 5v14" stroke-width="2" stroke-linecap="round"/>
</svg>
Особенности:
- Полный контроль над SVG
- Можно стилизовать CSS
- Нет дополнительного запроса
- Большой HTML если много иконок
- Можно анимировать
Когда использовать:
- Динамические иконки с анимацией
- Иконки которые нужно менять по состоянию
2. SVG файл как img
<img src="/icons/menu.svg" alt="Меню" width="24" height="24" />
Особенности:
- Простой способ
- Кэшируется браузером
- Отдельный запрос
- Нельзя стилизовать CSS
- Нельзя анимировать
- Может быть медленнее
Когда использовать:
- Статические иконки
- Разные иконки на разных страницах
3. SVG как background
.icon {
width: 24px;
height: 24px;
background-image: url('/icons/menu.svg');
background-size: contain;
background-repeat: no-repeat;
}
Особенности:
- Кэшируется браузером
- Нельзя стилизовать содержимое SVG
- Можно менять размер через background-size
- Нельзя анимировать содержимое
Когда использовать:
- Фоновые декоративные элементы
- Простые иконки без анимации
4. SVG спрайт (РЕКОМЕНДУЕТСЯ)
<!-- sprite.svg -->
<svg style="display: none;">
<defs>
<symbol id="icon-menu" viewBox="0 0 24 24">
<path d="M5 12h14M2 6h20M2 18h20" stroke="currentColor" stroke-width="2"/>
</symbol>
<symbol id="icon-close" viewBox="0 0 24 24">
<path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2"/>
</symbol>
<symbol id="icon-search" viewBox="0 0 24 24">
<circle cx="11" cy="11" r="8" stroke="currentColor" stroke-width="2"/>
<path d="m21 21-4.35-4.35" stroke="currentColor" stroke-width="2"/>
</symbol>
</defs>
</svg>
<!-- Использование спрайта -->
<svg class="icon icon-menu" width="24" height="24">
<use xlink:href="#icon-menu"></use>
</svg>
<svg class="icon icon-close" width="24" height="24">
<use xlink:href="#icon-close"></use>
</svg>
<svg class="icon icon-search" width="24" height="24">
<use xlink:href="#icon-search"></use>
</svg>
<style>
.icon {
width: 24px;
height: 24px;
stroke: currentColor; /* наследует цвет текста */
}
.icon-menu {
stroke: blue;
}
.icon-close {
stroke: red;
}
.icon:hover {
stroke: green;
}
</style>
Особенности:
- Одна загрузка спрайта
- Можно стилизовать CSS
- Экономит трафик
- Стандартный подход
- Хорошая производительность
5. Font Icon (не рекомендуется)
<!-- Был популярен (Font Awesome, Bootstrap Icons) -->
<i class="fas fa-heart"></i>
Проблемы:
- Требует загрузку шрифта
- Может быть медленнее SVG
- Сложнее кастомизировать
- Проблемы с выравниванием
SVG лучше чем шрифты!
6. React компонент Icon
// Icon.jsx
export function Icon({ id, width = 24, height = 24, stroke = 'currentColor', ...props }) {
return (
<svg width={width} height={height} {...props}>
<use xlinkHref={`#${id}`} stroke={stroke} />
</svg>
);
}
// Использование
import { Icon } from './Icon';
function Header() {
return (
<header>
<Icon id="icon-menu" />
<Icon id="icon-search" stroke="blue" />
<Icon id="icon-user" width={32} height={32} />
</header>
);
}
7. Icon Component с инлайн SVG
// MenuIcon.jsx
export function MenuIcon({ size = 24, color = 'currentColor' }) {
return (
<svg width={size} height={size} viewBox="0 0 24 24" fill="none">
<path
d="M5 12h14M2 6h20M2 18h20"
stroke={color}
strokeWidth="2"
/>
</svg>
);
}
// Использование
import { MenuIcon } from './MenuIcon';
function Button() {
return <button><MenuIcon size={20} color="blue" /></button>;
}
8. Лучший подход: Icon библиотека
// lib/icons.jsx
const icons = {
menu: (props) => (
<svg {...props} viewBox="0 0 24 24">
<path d="M5 12h14M2 6h20M2 18h20" stroke="currentColor" strokeWidth="2" />
</svg>
),
close: (props) => (
<svg {...props} viewBox="0 0 24 24">
<path d="M18 6L6 18M6 6l12 12" stroke="currentColor" strokeWidth="2" />
</svg>
),
search: (props) => (
<svg {...props} viewBox="0 0 24 24">
<circle cx="11" cy="11" r="8" stroke="currentColor" strokeWidth="2" />
<path d="m21 21-4.35-4.35" stroke="currentColor" strokeWidth="2" />
</svg>
)
};
export function Icon({ name, size = 24, color = 'currentColor', className = '' }) {
const IconComponent = icons[name];
if (!IconComponent) {
console.warn(`Icon "${name}" not found`);
return null;
}
return (
<IconComponent
width={size}
height={size}
color={color}
className={className}
fill="none"
/>
);
}
// Использование
<Icon name="menu" size={24} />
<Icon name="close" size={20} color="red" />
9. Оптимизация SVG файлов
# Используй SVGO для оптимизации
npm install -g svgo
svgo input.svg -o output.svg
# Или оптимизируй все файлы
svgo *.svg -o optimized/
Что оптимизирует:
- Удаляет лишние атрибуты
- Минифицирует пути
- Удаляет комментарии
- Сокращает размер на 30-50%
10. Примеры из практики
Иконка с анимацией
function LoadingIcon() {
return (
<svg width="24" height="24" viewBox="0 0 24 24">
<circle
cx="12" cy="12" r="10"
stroke="currentColor"
strokeWidth="2"
fill="none"
style={{
animation: 'spin 1s linear infinite',
transformOrigin: '50% 50%'
}}
/>
<style>{`
@keyframes spin {
to { transform: rotate(360deg); }
}
`}</style>
</svg>
);
}
Иконка с hover эффектом
function FavoriteIcon({ isFavorite, onToggle }) {
return (
<button onClick={onToggle} className="favorite-btn">
<svg
width="24" height="24"
viewBox="0 0 24 24"
className={isFavorite ? 'favorite-active' : ''}
>
<path
d="M20 4.6l-5.5 5.5L12 2 6.5 10.1 1 4.6v14.8c0 2 1.6 3.6 3.6 3.6h12.8c2 0 3.6-1.6 3.6-3.6V4.6z"
stroke="currentColor"
strokeWidth="2"
fill="none"
/>
</svg>
</button>
);
}
<style>
.favorite-btn svg {
stroke: gray;
transition: all 0.3s ease;
}
.favorite-btn svg.favorite-active {
stroke: red;
fill: red;
}
.favorite-btn:hover svg {
transform: scale(1.2);
}
</style>
Адаптивные иконки
function ResponsiveIcon() {
return (
<svg
width="100%"
height="100%"
viewBox="0 0 24 24"
style={{ maxWidth: '24px', maxHeight: '24px' }}
>
<path d="M5 12h14" stroke="currentColor" strokeWidth="2" />
</svg>
);
}
/* Адаптируется к контейнеру благодаря viewBox */
11. Инструменты для создания иконок
- Figma (проектирование)
- Adobe Illustrator (профессиональное)
- Inkscape (бесплатное)
- IconMoon (генератор спрайтов)
- Icomoon (готовые иконки)
- Feather Icons (минималистичные)
- Heroicons (красивые иконки)
- Material Design Icons (много иконок)
12. Чеклист при работе с SVG
[ ] SVG оптимизирован (SVGO)
[ ] viewBox установлен (для масштабирования)
[ ] stroke/fill явно указаны
[ ] currentColor для наследования цвета
[ ] width/height для фиксированного размера
[ ] alt текст для img тега
[ ] aria-label для доступности
[ ] Не забыл закрыть пути (</path>)
[ ] Проверил на разных браузерах
[ ] Испытал на производительность
Итого
Мой подход к SVG иконкам:
- Для простого случая: встроенный SVG в HTML
- Для множества иконок: SVG спрайт
- Для React приложения: Icon компонент с библиотекой
- Для анимации: инлайн SVG с CSS/JS анимацией
СВГ лучше чем:
- Font Icons (быстрее, гибче)
- PNG иконки (масштабируемые)
- DataURI (отдельный запрос лучше)
Советы:
- Используй currentColor для наследования цвета
- Оптимизируй файлы SVGO
- Устанавливай viewBox для масштабируемости
- React компоненты для переиспользования
- Спрайты для производительности