Разработка мегаменю с иконками категорий 1С-Битрикс
Иконки категорий в мегаменю решают навигационную задачу быстрее текста: глаз распознаёт пиктограмму ноутбука быстрее, чем читает слово «Ноутбуки». Для магазинов с большим количеством категорий — электроника, товары для дома, DIY — это стандарт. Реализация в Битрикс требует поля для иконки в разделах инфоблока и корректного вывода в шаблоне.
Хранение иконок разделов
Два подхода:
1. SVG-спрайт + код иконки. Пользовательское поле UF_ICON_CODE (тип строка) в разделе инфоблока хранит идентификатор иконки: icon-laptop, icon-phone, icon-furniture. SVG-спрайт подключается один раз в шаблоне, иконки выводятся через <use href="#icon-laptop">. Размер страницы минимален.
2. Файл SVG/PNG. Пользовательское поле UF_MENU_ICON (тип файл) — загружаем SVG напрямую через административную часть. Менеджер видит, что загружает. Недостаток: несколько HTTP-запросов на страницу (или инлайн через base64).
Для больших магазинов рекомендуем SVG-спрайт: все иконки в одном файле, нет дополнительных запросов.
Добавление пользовательского поля к разделам
// /local/lib/Install/InstallMenuIcons.php
\CUserTypeEntity::Add([
'ENTITY_ID' => 'IBLOCK_' . CATALOG_IBLOCK_ID . '_SECTION',
'FIELD_NAME' => 'UF_ICON_CODE',
'USER_TYPE_ID' => 'string',
'SORT' => 100,
'MULTIPLE' => 'N',
'MANDATORY' => 'N',
'EDIT_FORM_LABEL' => ['ru' => 'Код иконки (для мегаменю)', 'en' => 'Icon code'],
]);
SVG-спрайт
Спрайт собирается из дизайн-системы или загружается из iconify/heroicons. Подключается в </body> шаблона как скрытый блок:
<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
<symbol id="icon-laptop" viewBox="0 0 24 24">
<path d="M4 6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v7H4V6Z"/>
<path d="M2 17h20v1a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1v-1Z"/>
</symbol>
<symbol id="icon-smartphone" viewBox="0 0 24 24">
<rect x="5" y="2" width="14" height="20" rx="2"/>
<path d="M12 18h.01"/>
</symbol>
<!-- ... остальные иконки ... -->
</svg>
Получение иконки в шаблоне
// В result_modifier.php или непосредственно в шаблоне
function renderMenuIcon(string $iconCode): string
{
if (empty($iconCode)) return '';
// Санитизация: только допустимые символы
$safe = preg_replace('/[^a-z0-9\-]/', '', strtolower($iconCode));
if (!$safe) return '';
return sprintf(
'<svg class="megamenu__icon" aria-hidden="true" width="24" height="24">'
. '<use href="#%s"></use></svg>',
htmlspecialchars('icon-' . $safe)
);
}
Шаблон мегаменю с иконками
// Загрузка разделов с пользовательским полем UF_ICON_CODE
$res = \CIBlockSection::GetList(
['LEFT_MARGIN' => 'ASC'],
['IBLOCK_ID' => CATALOG_IBLOCK_ID, 'ACTIVE' => 'Y', 'DEPTH_LEVEL' => [1, 2]],
false,
['ID', 'NAME', 'CODE', 'SECTION_PAGE_URL', 'DEPTH_LEVEL',
'IBLOCK_SECTION_ID', 'UF_ICON_CODE', 'UF_MENU_ICON']
);
<!-- В шаблоне: категория первого уровня -->
<a href="<?= htmlspecialchars($category['SECTION_PAGE_URL']) ?>"
class="megamenu__link">
<?php if ($category['UF_ICON_CODE']): ?>
<?= renderMenuIcon($category['UF_ICON_CODE']) ?>
<?php elseif ($category['UF_MENU_ICON']): ?>
<img src="<?= \CFile::GetPath($category['UF_MENU_ICON']) ?>"
alt="" class="megamenu__icon" width="24" height="24" loading="lazy">
<?php endif ?>
<span class="megamenu__link-text"><?= htmlspecialchars($category['NAME']) ?></span>
</a>
CSS для иконок в мегаменю
.megamenu__link {
display: flex;
align-items: center;
gap: 0.625rem;
padding: 0.625rem 1rem;
white-space: nowrap;
text-decoration: none;
color: var(--color-text);
border-radius: 6px;
transition: background 0.15s, color 0.15s;
}
.megamenu__link:hover,
.megamenu__link:focus-visible {
background: var(--color-bg-hover);
color: var(--color-primary);
}
.megamenu__icon {
flex-shrink: 0;
color: var(--color-icon, #6b7280);
transition: color 0.15s;
}
.megamenu__link:hover .megamenu__icon {
color: var(--color-primary);
}
/* Крупные иконки для горизонтального меню (планшет) */
@media (min-width: 768px) and (max-width: 1023px) {
.megamenu__link--top-level {
flex-direction: column;
gap: 0.375rem;
padding: 0.75rem 0.625rem;
font-size: 0.8125rem;
text-align: center;
}
.megamenu__link--top-level .megamenu__icon {
width: 32px;
height: 32px;
}
}
Иконки через CSS content (альтернатива для emoji)
Для быстрого старта без дизайн-системы — emoji как иконки через CSS:
/* В UF_ICON_CODE хранится emoji: 💻, 📱, 🪑 */
.megamenu__emoji-icon {
font-size: 1.25rem;
line-height: 1;
flex-shrink: 0;
}
// В шаблоне
if (mb_strlen($category['UF_ICON_CODE']) <= 2) {
// Скорее всего emoji
echo '<span class="megamenu__emoji-icon" aria-hidden="true">'
. htmlspecialchars($category['UF_ICON_CODE'])
. '</span>';
}
Административный интерфейс для редакторов
Редакторам сложно вводить код иконки вручную. Добавляем в административную часть подсказку — справочник доступных иконок с превью. Реализуется через кастомный тип пользовательского поля (UserTypeEntity) с виджетом выбора или через документацию со скриншотами спрайта.
Сроки реализации
| Конфигурация | Срок |
|---|---|
SVG-спрайт + поле UF_ICON_CODE + вывод |
2–3 дня |
+ файловые иконки через UF_MENU_ICON |
+1 день |
| + виджет выбора иконки в административной части | +2–3 дня |
| + анимация иконок при hover | +0.5 дня |







