Рубрика: Верстка / Front-end

Как отцентровать элемент div с помощью css

Сегодня рассмотрим задачу, которая встречается у всех и каждого очень часто: горизонтальное выравнивание элемента/блока по центру с помощью CSS.

В CSS есть несколько способов центрирования div, в зависимости от ситуации. Вот основные:

1. Центрирование по горизонтали (inline-block)

Если div имеет display: inline-block;, можно использовать text-align: center; у родителя:

.parent {
  text-align: center;
}

.child {
  display: inline-block;
}

2. Центрирование по горизонтали (margin auto)

Если div имеет фиксированную ширину, можно использовать margin: auto:

.child {
  width: 200px;
  margin: 0 auto;
}

Вместо строгого width: 200px; можно указывать width: fit-content;

3. Полное центрирование (flexbox)

Самый удобный способ – использовать display: flex; у родителя:

.parent {
  display: flex;
  justify-content: center; /* По горизонтали */
  align-items: center; /* По вертикали */
  height: 100vh; /* Чтобы занять всю высоту экрана */
}

4. Центрирование через Grid

Grid-контейнер позволяет легко центрировать элемент:

.parent {
  display: grid;
  place-items: center;
  height: 100vh;
}

5. Абсолютное центрирование (position absolute)

Если div внутри другого блока, можно использовать position: absolute;:

.parent {
  position: relative;
  height: 100vh;
}

.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

Это те способы, которые довольно просты и тривиальны. Я думаю, что каждый найдет тот, который подходит ему в данном конкретном случае.

Всем удачи и до встречи!

Что такое брейкпоинты для медиа-запросов в CSS?

Брейкпоинты в CSS используются для создания адаптивного дизайна, чтобы стили менялись под определённые размеры экрана или другие условия. В HTML5 конкретных брейкпоинтов нет, но CSS позволяет настроить их под любые нужды проекта.

Популярные брейкпоинты

Это стандартные размеры экранов, которые чаще всего используют веб-разработчики. Их можно модифицировать под свой проект:

/* Очень маленькие устройства (вертикальные смартфоны, меньше 576px) */
@media (max-width: 575.98px) {
  /* Стили для очень маленьких экранов */
}

/* Маленькие устройства (горизонтальные смартфоны, от 576px и выше) */
@media (min-width: 576px) and (max-width: 767.98px) {
  /* Стили для маленьких экранов */
}

/* Средние устройства (планшеты, от 768px и выше) */
@media (min-width: 768px) and (max-width: 991.98px) {
  /* Стили для планшетов */
}

/* Большие устройства (десктопы, от 992px и выше) */
@media (min-width: 992px) and (max-width: 1199.98px) {
  /* Стили для больших экранов */
}

/* Очень большие устройства (широкие мониторы, от 1200px и выше) */
@media (min-width: 1200px) {
  /* Стили для очень больших экранов */
}

Кастомные брейкпоинты

Если проект требует более точных настроек, например, под какие-то специфичные устройства, вот пример кастомного брейкпоинта:

/* Для маленьких экранов шириной до 400px */
@media (max-width: 400px) {
  /* Стили для супер-компактных экранов */
}

Медиа-запросы по ориентации экрана

Иногда важно знать, держит пользователь устройство вертикально или горизонтально:

/* Вертикальная ориентация экрана */
@media (orientation: portrait) {
  /* Стили для портретного режима */
}

/* Горизонтальная ориентация экрана */
@media (orientation: landscape) {
  /* Стили для альбомного режима */
}

Медиа-запросы по соотношению сторон

Если проект требует дизайна, завязанного на пропорции экрана:

@media (aspect-ratio: 16/9) {
  /* Стили для экранов с соотношением 16:9 */
}

Лайфхаки для использования брейкпоинтов

  1. Mobile-First подход: Пиши стили сначала для маленьких экранов, а потом используй min-width для более крупных.
  2. Относительные единицы: Вместо пикселей используй em или rem — так дизайн будет адаптироваться под настройки пользователя.
  3. Тестируй на реальных устройствах: Разработчики девтулзы — топ, но ничего не заменит тестов на настоящих девайсах.

Вывод комментариев в WordPress с ответами

Для того, чтобы вывести все комментарии сайта (а не только для текущей страницы), мы разработали такой код:

<?php $comments = get_comments([
			'status' => 'approve', // Только одобренные комментарии
			'orderby' => 'comment_date_gmt', // Сортировка по дате
			'order' => 'DESC', // Порядок вывода: старые сначала
		]);?>
		<?php 
		// Группируем комментарии по их родителям
		$grouped_comments = group_comments_by_parent($comments);
		
		// Выводим комментарии
		if (!empty($comments)) {
			render_all_comments($comments, $grouped_comments);
		} else {
			echo '<p>' . __('No comments found.') . '</p>';
		}
		?>

// Функция для группировки комментариев по родителю
function group_comments_by_parent($comments) {
	$grouped = array();

	foreach ($comments as $comment) {
		$parent_id = $comment->comment_parent;
		if (!isset($grouped[$parent_id])) {
			$grouped[$parent_id] = array();
		}
		$grouped[$parent_id][] = $comment;
	}

	return $grouped;
}

// Функция для рекурсивного отображения комментариев
function render_all_comments($comments, $grouped, $parent_id = 0, $depth = 0) {
	if (isset($grouped[$parent_id])) {

		foreach ($grouped[$parent_id] as $comment):?>
		<article class="comment <?php if($comment->comment_parent):?>reply<?php endif;?>" id="<?php echo $comment->comment_ID;?>">
			<header class="author-data">
				<?php $date = new DateTime($comment->comment_date);?>
				<address class="author" rel="author"><?php echo $comment->comment_author;?></address>
				<time pubdate datetime="<?php echo $date->format('Y-m-d');?>" title="<?php echo $date->format('F d Y');?>"><?php echo $date->format('h:m:s');?> <span><?php echo $date->format('d.m.Y');?></span></time>
			</header>
			<div class="comment-content"><?php echo $comment->comment_content;?></div>
		</article>
		<?php
			// Рекурсивно отображаем ответы на текущий комментарий
			render_all_comments($comments, $grouped, $comment->comment_ID, $depth + 1);
		?>
		<?php endforeach;?>
	<?php }
}

Получение комментариев

<?php $comments = get_comments([
    'status' => 'approve', 
    'orderby' => 'comment_date_gmt',
    'order' => 'DESC',
]);?>

Функция get_comments получает комментарии:

  • status: только одобренные.
  • orderby: сортируются по дате.
  • order: выводятся в обратном порядке (сначала новые).

Группировка комментариев

$grouped_comments = group_comments_by_parent($comments);

Функция group_comments_by_parent распределяет комментарии по родителям. Это нужно для отображения иерархии (комментарий-ответ).

function group_comments_by_parent($comments) {
    $grouped = array();

    foreach ($comments as $comment) {
        $parent_id = $comment->comment_parent; // ID родительского комментария
        if (!isset($grouped[$parent_id])) {
            $grouped[$parent_id] = array(); // Создаем массив для родителя, если его еще нет
        }
        $grouped[$parent_id][] = $comment; // Добавляем комментарий в группу
    }

    return $grouped;
}

Отображение комментариев

if (!empty($comments)) {
    render_all_comments($comments, $grouped_comments);
} else {
    echo '<p>' . __('No comments found.') . '</p>';
}

Если есть комментарии, вызывается функция render_all_comments для их отображения.

Функция render_all_comments

function render_all_comments($comments, $grouped, $parent_id = 0, $depth = 0) {
    if (isset($grouped[$parent_id])) {
        foreach ($grouped[$parent_id] as $comment):?>
        <article class="comment <?php if($comment->comment_parent):?>reply<?php endif;?>" id="<?php echo $comment->comment_ID;?>">
            <header class="author-data">
                <?php $date = new DateTime($comment->comment_date);?>
                <address class="author" rel="author"><?php echo $comment->comment_author;?></address>
                <time pubdate datetime="<?php echo $date->format('Y-m-d');?>" title="<?php echo $date->format('F d Y');?>"><?php echo $date->format('h:m:s');?> <span><?php echo $date->format('d.m.Y');?></span></time>
            </header>
            <div class="comment-content"><?php echo $comment->comment_content;?></div>
        </article>
        <?php
            render_all_comments($comments, $grouped, $comment->comment_ID, $depth + 1);
        ?>
        <?php endforeach;?>
    <?php }
}

Эта функция:

  1. Рекурсивно отображает комментарии: сначала выводит корневые, затем вложенные.
  2. Выводит данные комментария:
    • Автор: <?php echo $comment->comment_author;?>.
    • Дата и время: <?php $date->format(); ?>.
    • Текст комментария: <?php echo $comment->comment_content;?>.
  3. Рекурсивно вызывает себя для вложенных комментариев, передавая ID текущего комментария как parent_id.

Резюме

  1. Модулярность: Код хорошо структурирован с использованием функций (group_comments_by_parent и render_all_comments).
  2. Поддержка вложенности: Рекурсия позволяет отображать вложенные комментарии.
  3. Адаптируемость: Можно легко изменить структуру и оформление вывода, редактируя render_all_comments.

Этот шаблон подходит для страниц, где нужно отображать отзывы или комментарии с возможностью ответа.

Валидация ввода украинских и русских символов в jQuery

Иногда требуется ограничить ввод символов в текстовое поле так, чтобы пользователь мог вводить только буквы украинского и русского алфавитов. Это может быть полезно, например, для форм с именами и фамилиями, где нежелательны цифры, латинские символы или специальные знаки. Давайте рассмотрим, как с помощью jQuery можно легко реализовать такую валидацию.

Основная идея

С помощью метода .keyup() мы можем отслеживать события, происходящие при каждом нажатии клавиши в целевом поле ввода. Это позволит контролировать и корректировать содержимое поля в реальном времени. Для удаления недопустимых символов мы будем использовать регулярное выражение, которое оставит в поле только буквы кириллицы, включая специфические для украинского и русского алфавитов.

Код валидации

Для реализации валидации создайте следующий скрипт на JavaScript с использованием jQuery:

$("input#billing-first_name, input#billing-last_name").keyup(function() {
    $(this).val($(this).val().replace(/[^а-яА-ЯїЇєЄіІёЁ ]/g, ""));
});

Объяснение работы кода

  1. Выбор полей: В данном примере мы выбираем два поля с идентификаторами billing-first_name и billing-last_name. Это могут быть, например, поля для ввода имени и фамилии в форме.
  2. Отслеживание ввода: Используя метод .keyup(), мы подключаем функцию, которая будет выполняться каждый раз, когда пользователь отпускает клавишу. Это позволяет применять валидацию по мере ввода текста.
  3. Замена символов: Метод .replace() используется для замены всех неподходящих символов на пустую строку. Регулярное выражение /[^а-яА-ЯїЇєЄіІёЁ ]/g определяет:
    • ^ — отрицание, т.е. все символы, не соответствующие выражению;
    • а-яА-Я — русские буквы (и в нижнем, и в верхнем регистре);
    • їЇєЄіІ — буквы, уникальные для украинского языка;
    • ёЁ — буква «ё» в русском алфавите;
    • — пробел (для удобства, если нужно вводить фамилию, состоящую из двух частей).
    Всё, что не попадает под эти символы, будет заменено на пустую строку, т.е. удалено из поля.

Применение и возможные изменения

Такой код можно легко адаптировать для других полей или расширить список символов, если необходимо. Например, если вы хотите, чтобы поля принимали и латинские буквы, можно добавить их в регулярное выражение. Вот пример для кириллицы и латиницы:

$("input#billing-first_name, input#billing-last_name").keyup(function() {
    $(this).val($(this).val().replace(/[^а-яА-ЯїЇєЄіІёЁa-zA-Z ]/g, ""));
});

Преимущества и ограничения метода

Преимущества:

  • Простота и лёгкость внедрения. Несколько строк кода обеспечивают базовую валидацию.
  • Валидация происходит на стороне клиента, что улучшает UX (пользовательский опыт), так как пользователь сразу видит результат.

Ограничения:

  • Клиентская валидация уязвима, так как её можно обойти при отключённом JavaScript. Поэтому, если важна надёжность, следует продублировать валидацию и на сервере.
  • Скрипт работает только при наличии jQuery, поэтому нужно убедиться, что он подключен к проекту.

Заключение

Использование jQuery для валидации полей ввода на основе символов кириллицы — это простой и эффективный способ ограничить ввод только нужными символами. Благодаря регулярным выражениям и событиям jQuery вы можете гибко адаптировать проверку для самых разных форм и языков.

Как написать идеальный запрос (промпт) для ChatGPT

Сегодня в интернете можно найти множество рекомендаций по тому, как составить идеальный запрос (промпт) для ChatGPT. С развитием нейросетей такие инструменты стали важной частью как профессиональной, так и повседневной жизни. Ключевой навык — это умение правильно формулировать запросы, так как от этого зависит качество полученного ответа. Это актуально не только для ChatGPT, но и для других моделей, таких как ЯндексGPT или Google Bard. Чем точнее сформулирован запрос, тем более релевантный и точный ответ можно ожидать.

Что такое ChatGPT

ChatGPT — это чат-бот, разработанный компанией OpenAI, который обладает возможностью вести диалог, создавать шутки, стихи, статьи, резюме научных работ, а также писать программный код. Некоторые даже считают, что такие системы могут заменить людей в ряде профессий.

Почему ChatGPT популярен

Популярность ChatGPT обусловлена несколькими важными факторами:

  1. Обширная база данных: Модель обучена на большом объёме данных, что позволяет ей охватывать множество тем и давать разнообразные ответы.
  2. Доступность на разных платформах: ChatGPT легко интегрируется в различные приложения и интерфейсы, что делает его доступным для использования в различных сценариях.
  3. Точность ответов: Модель спроектирована с акцентом на предоставление корректных и полезных ответов, избегая сложных или спорных тем.
  4. Постоянные улучшения: OpenAI активно развивает модель, добавляя новые функции и улучшая её точность, что позволяет ChatGPT оставаться лидером на рынке.
  5. Широкий спектр задач: Модель может решать различные задачи, такие как генерация текста, перевод, программирование, анализ данных и многое другое.
  6. Активное сообщество пользователей: Благодаря большому количеству пользователей и разработчиков, которые активно используют ChatGPT, модель продолжает совершенствоваться.

Как составить идеальный запрос для ChatGPT

Чтобы получить качественный результат, при формулировании запроса стоит учесть несколько моментов:

  1. Роль: Определите, кем является ChatGPT в вашем запросе: журналистом, кулинаром, программистом и т. д. Это позволит модели адаптировать ответ, исходя из специфики выбранной роли.
  2. Задача: Сформулируйте задачу чётко и конкретно. Например: «Составь план питания для мужчины 25 лет с весом 70 кг, работающего в офисе».
  3. Цель: Определите, для кого предназначен ответ, например: «Напиши короткий пост для предпринимателей в VK». Это поможет получить ответ, соответствующий вашей целевой аудитории.
  4. Формат ответа: Укажите, в каком формате нужен ответ — рассказ, стихотворение, обзор или таблица. Можно также уточнить длину ответа, например, 300–500 слов.
  5. Контекст: Уточните детали, если требуется. ChatGPT сохраняет историю диалога, поэтому можно добавлять дополнительные условия без необходимости переписывать запрос целиком.

Полезные советы для работы с ChatGPT

  1. Дробите запросы: Для сложных задач, таких как решение математических уравнений, лучше разделить запрос на несколько этапов. Например, запросите вывод каждого шага по отдельности.
  2. Проверка ответа: Чтобы убедиться в точности ответа, можно попросить модель уточнить свою уверенность. Если ответ сомнительный, попробуйте изменить или уточнить запрос.
  3. Используйте примеры: Для более точного результата можно предоставить ChatGPT примеры текста или изображений, чтобы он мог на их основе создать собственный контент.

Заключение

Научиться правильно формулировать запросы для ChatGPT можно с помощью практики. Экспериментируйте, уточняйте и проверяйте результаты, чтобы добиться наилучшего качества ответов.

Полезные запросы к ChatGPT для программистов

Среди них: объяснение сложных алгоритмов, оптимизация кода, рефакторинг, генерация кода для задач и регулярных выражений, помощь в проектировании базы данных, архитектуре приложений, создании документации и CI/CD pipeline. ChatGPT также может предложить примеры использования библиотек и языков, помочь автоматизировать рутинные задачи и улучшить продуктивность программиста.

Многие опасаются, что нейросети, такие как ChatGPT, смогут заменить программистов. ChatGPT действительно умеет генерировать код, решать задачи и помогать в различных областях, однако в ближайшее время полностью заменить разработчиков она вряд ли сможет. Вместо этого нейросеть значительно ускоряет и облегчает их работу. Ключевую роль здесь играет правильный промтинг — умение формулировать запросы к ИИ так, чтобы получить нужный результат. Это отличается от привычных поисковых запросов, поскольку требует другого подхода к взаимодействию с ИИ.

Запросы для кода и алгоритмов

Эффективность и качество кода — ключевые аспекты работы программистов. Чтобы достичь высокого уровня, разработчики могут использовать нейросети для быстрого поиска решений. Промты в этом разделе помогут генерировать чистый и оптимизированный код, улучшать алгоритмы и повышать качество программного обеспечения.

Важно учитывать, что для разных задач запросы должны быть уникальными, будь то поиск ошибки или написание email. Конкретизация и контекст играют ключевую роль в получении качественного результата.

Пример промтов:

1. Объяснение сложного алгоритма

Пример запроса: «Объясни алгоритм Дейкстры пошагово».

ChatGPT не только объяснит, как работает алгоритм Дейкстры для поиска кратчайшего пути на графе, но и приведет конкретный пример с вершинами. Это поможет лучше понять, как алгоритм применяется на практике, и визуализировать его работу в контексте реальных данных.

2. Оптимизация кода

Пример запроса: «Оптимизируй этот Python-код для повышения производительности».

Допустим, у нас есть код, вычисляющий сумму квадратов чисел от 1 до nnn:

def sum_of_squares(n):
result = 0
for i in range(1, n + 1):
result += i * i
return result

n = 1000000
print(sum_of_squares(n))

ChatGPT может предложить улучшение, используя встроенную функцию sum и генератор:

def sum_of_squares(n):
    return sum(i * i for i in range(1, n + 1))

n = 1000000
print(sum_of_squares(n))

Этот подход повышает читаемость и производительность.

Промт 3: Генерация кода для конкретной задачи

Пример запроса: «Создай функцию на JavaScript для сортировки массива объектов по ключу».

ChatGPT может предложить такую функцию:

function sortByKey(array, key) {
    return array.sort((a, b) => {
        if (a[key] < b[key]) return -1;
        if (a[key] > b[key]) return 1;
        return 0;
    });
}

Эта функция сортирует объекты по указанному ключу. Вы также получите пример использования кода для практической задачи, что делает его удобным для немедленного применения.

Маркер на карте гугл с произвольной ссылкой

Для одного из проектов у нас потребовалось сделать на нашей карте клик по маркеру, чтобы открывалась необходимая ссылка. В нашем случае ссылка вела на открытие самих Google Maps и прокладывание маршрута от текущего места до офиса клиента.

var myLatlng = new google.maps.LatLng(50.5342832,30.2296718);
	var myOptions = {
		zoom:15,
		mapTypeId: google.maps.MapTypeId.ROADMAP,
		center: myLatlng,
		panControl: false,
		zoomControl: true,
		mapTypeControl: false,
		scaleControl: true,
		streetViewControl: false,
		overviewMapControl: false,
		disableDoubleClickZoom:true,
		suppressInfoWindows:true,
		scrollwheel: true
	};
	map = new google.maps.Map(document.getElementById("map"), myOptions);
	map.setOptions({styles: styles});
	
	var markerLatlng = new google.maps.LatLng(50.53248143295204, 30.229685611563006);
	const image = "/assets/images/pin.png";
	var marker = new google.maps.Marker({
		url: 'https://www.google.com/maps/dir//адрес клиента',
		position: markerLatlng,
		icon: image
	});

	marker.setMap(map);
	google.maps.event.addListener(marker, 'click', function() {
		window.open(marker.url, '_blank');
	});

В этом коде мы формируем карту с заданным центром и на ней размещаем необходимый нам маркер, который выглядит как пин (наше изображение, которое мы хотим разместить на карте). После этого мы для маркера указываем необходимую нам ссылку в параметре url.

var markerLatlng = new google.maps.LatLng(50.53248143295204, 30.229685611563006);
	const image = "/assets/images/pin.png";
	var marker = new google.maps.Marker({
		url: 'https://www.google.com/maps/dir//адрес клиента',
		position: markerLatlng,
		icon: image
	});

Далее вешаем обработчик клика по маркеру и открываем нашу ссылку. Мы захотели ее открыть в новом окне, используя параметр _blank.

google.maps.event.addListener(marker, 'click', function() {
		window.open(marker.url, '_blank');
	});

Какие CMS популярны? Как выбрать CMS при разработке сайта?

Выбор системы управления содержанием (CMS) для разработки сайта зависит от множества факторов, включая тип сайта, его функциональные требования, уровень сложности, потребности в масштабировании, удобство использования для администраторов, доступность расширений и т. д. Вот некоторые основные критерии, которые стоит учитывать при выборе CMS:

  1. Тип сайта: Важно определить, для чего будет использоваться сайт. Это может быть блог, интернет-магазин, корпоративный сайт, портфолио и т. д.
  2. Удобство использования: CMS должна быть интуитивно понятной для администраторов, чтобы они могли легко добавлять, редактировать и удалять контент.
  3. Безопасность: CMS должна обеспечивать надежную защиту от хакерских атак и иметь регулярные обновления безопасности.
  4. Экосистема плагинов и тем: Важно, чтобы CMS имела богатую экосистему дополнений, которые могут добавить необходимый функционал без необходимости в разработке с нуля.
  5. Сообщество и поддержка: Чем больше сообщество вокруг CMS, тем больше вероятность получения помощи и решения проблем.
  6. Скорость и производительность: CMS должна обеспечивать хорошую производительность сайта даже при высоких нагрузках.
  7. Расширяемость и масштабируемость: CMS должна позволять легко масштабировать сайт с ростом бизнеса.
  8. Стоимость: Некоторые CMS бесплатны, в то время как другие могут требовать лицензионные платежи или плату за дополнительный функционал.

Популярные CMS в мире:

  1. WordPress: Одна из самых популярных и распространённых CMS. Имеет большое сообщество пользователей и разработчиков, богатую библиотеку плагинов и тем.
  2. Joomla: Еще одна из популярных CMS, более подходящая для создания корпоративных сайтов и онлайн-журналов.
  3. Drupal: Мощная CMS, которая обладает расширенными возможностями по управлению контентом и поддерживает создание сложных сайтов.
  4. Magento: Специализированная CMS для интернет-магазинов, обладает широкими возможностями по управлению товарами, заказами и платежами.
  5. Shopify: Еще одна CMS, специализированная на интернет-магазинах, но отличается от Magento тем, что предлагает готовые решения в облаке, что облегчает настройку и управление.

В СНГ популярность могут иметь те же системы, но также стоит обратить внимание на локальные CMS, которые могут быть более адаптированы к специфике регионального рынка.

Замена вариаций продукта с Select на Radio buttons для WooCommerce (вариант 2)

В одном из статей был описан метод, как можно заменить стандарный вывод выбора вариаций с помощью select на radio. Эта статья находится тут.

Сегодня же будет показан еще один, альтернативный, вариант решения данной проблемы.

Открываем файл /ваша_тема/woocommerce/single-product/add-to-cart/variable.php (если такого файла нет, то нужно создать его.

В папке /ваша_тема/woocommerce/ находятся шаблоны woocommerce, которые изменяются для темы. Исходники их находятся в папке с плагином woocommerce в папке /templates.

В этом файле мы перед функцией вывода select выбора вариаций товара добавляем

<?foreach($options as $index => $item):?>
<label for="<?=sanitize_title( $attribute_name );?>_<?=$item;?>" <?if($index===0):?>class="active"<?endif;?>><?=$item;?></label>
<?endforeach;?>

и оборачиваем все это (вместе с выводом select) в обертку

<div class="radio-input-container"></div>

В итоге у нас получится следующая конструкция:

<div class="radio-input-container">
<?foreach($options as $index => $item):?>
<label for="<?=sanitize_title( $attribute_name );?>_<?=$item;?>" <?if($index===0):?>class="active"<?endif;?>><?=$item;?></label>
<?endforeach;?>
<?php
wc_dropdown_variation_attribute_options(
array(
'options'   => $options,
'attribute' => $attribute_name,
'product'   => $product,
)
);
?>
</div>

в js файл со скриптами добавляем:

$('.radio-input-container label').on('click', function(){
var Value = $(this).text();
var Label = $(this);
$('.radio-input-container label').removeClass('active');
Label.addClass('active');
Label.parent().find('select').val(Value).change();
});

Я также добавил очистку наших «лейблов» по клику на ссылку «Очистить»:

$('.reset_variations').on('click', function(){
$('.radio-input-container label').removeClass('active');
});

и следующие стили получились:

.radio-input-container {
display: flex;
gap: 10px;
flex-wrap: wrap;
margin-bottom: 15px;
label {
width: 20%;
text-align: center;
border: 1px solid @colorGrey;
border-radius: 5px;
padding: 6px 15px 5px 15px;
cursor: pointer;
font-weight: 500;
&:hover, &.active {
border-color: @colorRed;
background: @colorWhite;
}
}
select {
display: none;
}
}

Select я спрятал намеренно, что не портило дизайн и не путало пользователя.

В итоге получилась такая вот красота: