Разработка фильтрации по цвету с визуальным отображением 1С-Битрикс
Фильтр по цвету — один из наиболее заметных UI-элементов в fashion и home-каталогах. Разница между «галочкой с текстом Красный» и «кружком цвета #E53935» — это разница в конверсии для товаров, где внешний вид критичен. Реализация требует хранения HEX-значений цветов, кастомного UI и корректной работы с торговыми предложениями.
Хранение цветов
Два подхода:
Свойство типа «Список» с XML_ID = HEX: значение свойства — читаемое название («Красный»), XML_ID — HEX-код (#E53935). Простой подход, удобный для небольшого набора цветов.
Свойство с дополнительными полями через инфоблок цветов: отдельный инфоблок, каждый цвет — элемент с полем PREVIEW_PICTURE (свотч) и UF-полем UF_HEX_CODE. Подходит когда цветов 50+ или нужны свотчи с текстурой/паттерном.
Настройка свойства для первого подхода
В административной панели, свойство типа «Список»:
- Код:
COLOR - Значения: «Красный» → XML_ID:
#E53935, «Синий» → XML_ID:#1565C0, «Белый» → XML_ID:#FFFFFF
При отображении в фильтре используем XML_ID как цвет и VALUE как alt-текст.
Получение цветов для UI фильтра
// Получение цветов с HEX-кодами из XML_ID
$colors = [];
$res = CIBlockPropertyEnum::GetList(
['SORT' => 'ASC'],
['IBLOCK_ID' => $iblockId, 'CODE' => 'COLOR']
);
while ($color = $res->Fetch()) {
$colors[] = [
'id' => $color['ID'],
'name' => $color['VALUE'],
'hex' => $color['XML_ID'], // #RRGGBB
'xmlId' => $color['XML_ID'],
];
}
// Подсчёт товаров по цвету (через торговые предложения)
$colorCounts = getColorCountsFromOffers($iblockId, OFFERS_IBLOCK_ID);
UI: свотчи цветов
$selectedColors = array_map('htmlspecialchars', (array)($_GET['COLOR'] ?? []));
?>
<div class="filter-block filter-block--color">
<h3 class="filter-block__title">Цвет</h3>
<div class="color-swatches">
<?php foreach ($colors as $color): ?>
<?php $isSelected = in_array($color['xmlId'], $selectedColors); ?>
<label class="color-swatch <?= $isSelected ? 'is-active' : '' ?>"
title="<?= htmlspecialchars($color['name']) ?>">
<input type="checkbox"
name="COLOR[]"
value="<?= htmlspecialchars($color['xmlId']) ?>"
<?= $isSelected ? 'checked' : '' ?>>
<span class="swatch-circle"
style="background-color: <?= htmlspecialchars($color['hex']) ?>;"
aria-label="<?= htmlspecialchars($color['name']) ?>">
</span>
<?php if ($color['hex'] === '#FFFFFF' || $color['hex'] === '#ffffff'): ?>
<span class="swatch-circle swatch-circle--bordered"
style="background-color: <?= htmlspecialchars($color['hex']) ?>;"></span>
<?php endif; ?>
</label>
<?php endforeach; ?>
</div>
</div>
<?php
CSS свотчей
.color-swatch {
display: inline-flex;
flex-direction: column;
align-items: center;
cursor: pointer;
margin: 4px;
}
.color-swatch input[type="checkbox"] {
display: none;
}
.swatch-circle {
width: 28px;
height: 28px;
border-radius: 50%;
border: 2px solid transparent;
box-shadow: 0 0 0 1px rgba(0,0,0,0.15);
transition: box-shadow 0.15s, transform 0.15s;
}
.swatch-circle--bordered {
box-shadow: 0 0 0 1px #ccc;
}
.color-swatch.is-active .swatch-circle {
box-shadow: 0 0 0 2px var(--accent-color, #2196f3);
transform: scale(1.1);
}
.color-swatch:hover .swatch-circle {
transform: scale(1.05);
}
Фильтрация по цвету через торговые предложения
Цвет обычно — свойство торгового предложения, не родительского товара:
function getProductIdsByColors(int $offersIblockId, array $colorXmlIds): array
{
if (empty($colorXmlIds)) return [];
// Получение ID значений свойства по XML_ID
$enumIds = [];
$res = CIBlockPropertyEnum::GetList(
[],
['IBLOCK_ID' => $offersIblockId, 'CODE' => 'COLOR', 'XML_ID' => $colorXmlIds]
);
while ($row = $res->Fetch()) {
$enumIds[] = $row['ID'];
}
if (empty($enumIds)) return [];
$productIds = [];
$res = CIBlockElement::GetList(
[],
[
'IBLOCK_ID' => $offersIblockId,
'ACTIVE' => 'Y',
'>CATALOG_QUANTITY' => 0,
'PROPERTY_COLOR' => $enumIds,
],
false,
false,
['PROPERTY_CML2_LINK']
);
while ($row = $res->GetNext()) {
if ($row['PROPERTY_CML2_LINK_VALUE']) {
$productIds[] = intval($row['PROPERTY_CML2_LINK_VALUE']);
}
}
return array_unique($productIds);
}
// Применение фильтра
$selectedColors = array_map('htmlspecialchars', (array)($_GET['COLOR'] ?? []));
if (!empty($selectedColors)) {
$colorProductIds = getProductIdsByColors(OFFERS_IBLOCK_ID, $selectedColors);
$arFilter['ID'] = !empty($colorProductIds) ? $colorProductIds : [0];
}
Отображение цветов в карточке товара
Для согласованности с фильтром — те же свотчи в миниатюрах каталога:
// Получение доступных цветов для товара
$availableColors = [];
$res = CIBlockElement::GetList(
[],
[
'IBLOCK_ID' => OFFERS_IBLOCK_ID,
'ACTIVE' => 'Y',
'>CATALOG_QUANTITY' => 0,
'PROPERTY_CML2_LINK' => $productId,
],
false,
false,
['PROPERTY_COLOR']
);
while ($offer = $res->GetNext()) {
$colorXmlId = $offer['PROPERTY_COLOR_ENUM_XML_ID'];
if ($colorXmlId && !isset($availableColors[$colorXmlId])) {
$availableColors[$colorXmlId] = $offer['PROPERTY_COLOR_VALUE'];
}
}
Сроки выполнения
Цветовой фильтр через свойство «Список» с HEX в XML_ID — 1 рабочий день. Полная реализация с торговыми предложениями, свотчами в карточках, кешированием счётчиков — 2–3 рабочих дня.







