Ну тут от настройки шаблона cms зависит, а не от фронтенда. Если сайт без cms, то ручками просто прописывать класс активного пункта для нужных пунктов меню на каждой странице. Типа:
- Первый пункт
- Первый пункт
- Второй пункт
- Второй пункт
Источник
Инструмент для подсветки активного пункта простого HTML меню
Чуть ли не каждое меню, прорисованное дизайнером в макете, имеет чуть иное отображения для текущего пункта меню, на котором в данный момент находится пользователь. Это элементарные приемы для повышения юзабилити. Чаще всего такие активные пункты меню стараются как то выделить цветом.
Меню обычно принято реализовывать на ненумерованном списке , а для того чтобы сделать текущий пункт меню активным — к нему добавляют классы current active :
- Текущая ссылка (current) — пункт меню, на котором сейчас находится пользователь
- Активные ссылки (active) — пункты меню, которые являются родительскими относительно текущего пункта меню, на котором сейчас находится пользователь
Конечно если вы используете Symfony — у вас есть возможность использовать KNPMenuBundle , где есть возможность настроить подсветку активного пункта, хотя если вы делаете это в первый раз — может показаться сложновато. Но елси у вас простенькое HTML меню всего с несколькими уровнями вложенности и вам лень переносить его в ООП меню типа KNPMenuBundle , предлагаю библиотеку ActiveMenuItemBundle, которая вам поможет в подсветке текущего пункта меню.
Установка
Проще всего установить последнюю на сегодня версию ActiveMenuItemBundle к проекту на Symfony с помощью Composer:
а после — зарегистрировать бандл в app/AppKernel.php :
public function registerBundles() < $bundles = array( // other bundles. new BW\ActiveMenuItemBundle\BWActiveMenuItemBundle(), );
Использование
Теперь у вас в Twig-шаблонах доступно несколько новых фильтров и функций, которые помогут определить активный пункт меню.
Для того чтобы проверить совпал ли роут пункта меню с текущим роутом, используйте is_active фильтр.
Пример 1:
Если роут совпал — фильтр вернет строку current active .
Для родительского пункта многоуровнего меню, чтобы проверить, совпал ли текущий роут с дочерними его подпунтами — используйте is_active функцию, передав в нее массив дочерних роутов первым аргументом, и роут данного пункта меню вторым аргументом.
Пример 2:
Если совпал роут child_route_2 для ссылки Current link , то ей присвоитяся классы current active , а ее родителю с роутом parent_route будет присвоен только класс active .
Если вам нужно вместо роутов работать с request URI — используйте is_active_uri фильтр и is_active_uri функцию, которые работают точно также, ео передавать в них нужно request URI, который можно сгенерировать функцией path , поставляемой из коробки Symfony.
Пример 3:
Demo
Для просмотра демо примера — нужно импортировать роутинг в файле app/config/routing_dev.yml для dev режима:
bw_active_menu_item: resource: "@BWActiveMenuItemBundle/Resources/config/routing.yml" prefix: /bw/demo/active-menu-item
Потом запустить встроенный сервер php app/console server:run в dev режиме и перейти по адресу localhost:8000/bw/demo/active-menu-item/index . Вот демо код Twig-шаблона.
Вывод
Буду рад если мой бандл кому то пригодится, думаю инструмент получился полезный, простой и имеет отличную производительность для небольших HTML меню. На больших и сложных меню не тестировал, но исходя из простоты и быстроты выполнения кода — должен справляться хорошо, главное принять правильное решение где использовать роуты, а где request URI (тут нужно будет немного подумать).
Кому интересно — вот код, который отвечает за работу фильтров и функций, чтобы долго не искали.
Всем спасибо за внимание и приятной работы!
P.S. Я понимаю, стрелочки легко нажимать, но если уж минусите — то, пожалуйста, потрудитесь в комментариях описать почему.
Источник
Создаем анимированный индикатор активного элемента меню с помощью CSS
В этой статье я расскажу, как создать меню с индикатором активного элемента на чистом CSS .
Вот то, что мы будем создавать:
Мы разобьем весь процесс на три этапа:
В данном примере мы также будем использовать SCSS , чтобы воспользоваться всеми преимуществами, которые дают нам переменные и функции Sass , в долгосрочной перспективе это позволяет намного проще поддерживать такой код.
Шаг 1: Базовая структура и стили
Во-первых, давайте зададим HTML-разметку для меню с использованием маркированного списка. Мы также можем разметить имена базового класса:
с именем класса PrimaryNav , который работает как контейнер для элементов списка внутри него, каждый с классом Nav-item .
Определение переменных
Одной из ключевых особенностей этого меню навигации является максимальная ширина. В зависимости от количества пунктов оно растягивается на всю ширину контейнера. Поэтому нам нужно задать в коде SCSS переменную $menu-items , которая затем будет использоваться для расчета значения $width каждого элемента .Nav-item .
Мы также добавили переменную $indicator-color , чтобы определить цвет, используемый для индикации активного пункта меню:
// Переменные элементов меню // Количество элементов в меню $menu-items: 5; // Мы умножаем их на 1%, чтобы получить корректное значение в % $width: (100/$menu-items) * 1%; // Цвета $background-color: #121212; $indicator-color: #e82d00;
Стили элементов
Теперь мы можем задать основные стили для элементов меню:
// Родительский контейнер .PrimaryNav < // Удаляем разделители по умолчанию list-style: none; // Центрируем все по горизонтали! margin: 50px auto; // Ширина меню не будет никогда превышать это значение, и с ним связаны вычисления ширины элементов в процентах max-width: 720px; padding: 0; width: 100%; >// Элементы меню .Nav-item < background: #fff; display: block; float: left; margin: 0; padding: 0; text-align: center; // Текущие вычисления ширины для 5 элементов дают нам 20% width: $width; // Первый элемент меню &:first-child < border-radius: 3px 0 0 3px; >// Последний элемент меню &:last-child < border-radius: 0 3px 3px 0; >// Если элемент меню является активным, мы устанавливаем ему тот же цвет, что и для индикатора &.is-active a < color: $indicator-color; >a < color: $background-color; display: block; padding-top: 20px; padding-bottom: 20px; text-decoration: none; &:hover < color: $indicator-color; >> >
Шаг 2: Создание индикатора
Мы зададим для индикатора разметку способом, который предполагает использование нескольких классов. То же самое можно сделать, используя только класс .PrimaryNav , но дополнительные имена класса обеспечат большую гибкость, которая пригодится нам позже.
У нас уже есть класс .PrimaryNav , который содержит основные стили меню навигации. Теперь давайте создадим для индикатора класс .with-indicator :
Здесь мы будем использовать CSS , хотя обычно для этого используется JavaScript . Но давайте посмотрим, как это можно сделать только с помощью CSS .
Хитрость заключается в том, чтобы пункты меню взаимодействовали друг с другом. В маркированном списке первый пункт списка ( :first-child ) может взаимодействовать со вторым дочерним элементом либо с помощью селектора следующего элемента + , либо через ~ , но второй дочерний элемент списка не может взаимодействовать с первым ( не может идти в обратном направлении в DOM, наподобие нашего ).
Последний элемент списка :last-child отслеживает состояние всех элементов списка, расположенных на одном уровне с ним. Последний дочерний элемент может отслеживать и состояние :hover , и состояние :active для всех элементов того же уровня. Это делает его идеальным кандидатом на то, чтобы установить на нем индикатор.
Мы создаем индикатор, используя элементы :before и :after для последнего дочернего элемента. Элемент :before будет использовать Треугольник CSS и отрицательный отступ для центрирования:
// Индикатор элемента, на который наведен курсор .with-indicator < // Меню "привязано" к абсолютному значению позиции псевдоэлемента last-child. position: relative; .Nav-item:last-child < &:before, &:after < content: ''; display: block; position: absolute; >// Треугольник CSS &:before < width: 0; height: 0; border: 6px solid transparent; border-top-color: $color-indicator; top: 0; left: 12.5%; // Исправляем смещение - оно может изменяться margin-left: -3px; >// Блок, который располагается позади текста &:after < width: $width; background: $indicator-color; top: -6px; bottom: -6px; left: 0; z-index: -1; >> >
Шаг 3: Перемещение индикатора
Теперь, когда мы задали индикатор, нам нужно сделать так, чтобы он перемещался к пункту меню, на который наведен курсор мыши. В этом нам поможет селектор ~ , который мы используем для сравнения элементов между первым и последним дочерними элементами.
, то есть индикатор указывает на первый элемент. Мы можем перемещать индикатор от одного пункта меню к другому, изменяя для него позицию left . Все элементы меню равны по ширине.
Чтобы переместить индикатор на одну позицию, селекторы элемента :last-child для :before и :after должны иметь смещение, равное ширине .Nav-item . Помните созданную нами переменную $width ? Мы используем ее для атрибута left .
Вот как это все можно задать в CSS :
.with-indicator .Nav-item:nth-child(1).is-active ~ .Nav-item:last-child:after < left: 0; >.with-indicator .Nav-item:nth-child(2).is-active ~ .Nav-item:last-child:after < left: 20%; >.with-indicator .Nav-item:nth-child(3).is-active ~ .Nav-item:last-child:after < left: 40%; >.with-indicator .Nav-item:nth-child(4).is-active:after < left: 60%; >.with-indicator .Nav-item:nth-child(5).is-active:after < left: 80%; >Давайте приведем все это в динамику с помощью Sass: // Переменные пунктов меню // Количество элементов в меню, плюс один для смещения $menu-items: 5; // Текущее количество элементов в меню $menu-items-loop-offset: $menu-items - 1; // Мы умножаем его на 1%, чтобы получить корректное значение в % $width: (100/$menu-items) * 1%; .with-indicator < @for $i from 1 through $menu-items-loop-offset < // Когда .Nav-item активен, перемещаем на него индикатор. .Nav-item:nth-child(#).is-active ~ .Nav-item:last-child:after < left:($width*$i)-$width; >.Nav-item:nth-child(#).is-active ~ .Nav-item:last-child:before < left:($width*$i)+($width/2)-$width; /* этот код обеспечивает перемещение треугольника на пункт меню. */ >> // end @for loop
Треугольник :before имеет дополнительное смещение сверху на половину ширины от смещения left.
Теперь добавим анимацию и еще один цикл Sass for для отслеживания положения индикатора относительно того, куда сейчас наведен курсор. Когда мы наводим курсор мыши на пункт меню, он приобретает статус :hover , и индикатор перемещается. Но как только мы отводим курсор, индикатор возвращается к пункту с состоянием is-active :
// Нам нужно использовать !important, чтобы переназначить состояние, когда на элемент :last-child наведен курсор или он является активным @for $i from 1 through $menu-items-loop-offset < // Когда пункт меню имеет состояние :hover, перемещаем на него индикатор. .Nav-item:nth-child(#):hover ~ .Nav-item:last-child:after < left:($width*$i)-$width !important; >.Nav-item:nth-child(#):hover ~ .Nav-item:last-child:before < left:($width*$i)+($width/2)-$width !important; >> // конец цикла @for // обеспечиваем, чтобы last-child взаимодействовал с самим собой .Nav-item < &:last-child < &:hover, &.is-active < &:before < left: (100%-$width)+($width/2) !important; >&:after < left: 100%-$width !important; >> > >
Окончательный результат
И вот мы получили анимированное меню с индикатором активного элемента без использования JavaScript .
Вадим Дворников автор-переводчик статьи « Creating an Animated Menu Indicator with CSS Selectors »
Источник