Меню с прозрачным ховером

Попалась на работе интересная задача. Решил поделиться.

screen

Проблема была в том, что над ховером и активным классом меню должна была бы быть прозрачная полоса. А т.к. header и весь content абсолютно разные блоки, сделать это только с помощью css не представлялось возможным.
Ну собственно на помощь пришел jquery.

За основу взят пример.
Можно было бы сделать на его основе. Линию сделать прозрачной, псевдоблоками создать белые блоки, сдвинуть их вправо и влево относительно родительского блока. Только с шириной в данном случае была бы загвоздка. Тут 100% от родителя не укажешь. Можно конечно указать 10000px, но в данном случае может появится горизонтальный скролл. От этого так же можно избавиться с помощью overflow: hidden на какойнибудь совсем совсем родительский блок, но так я делать не захотел.

Решил что логичнее сделать 2 линии – слева и справа от активного/ховера. Ширина и отступы расчитываются при загрузке и при ховере.

Главное тут – код jquery. По большей части я отредактировал код источника, не особо придумывая чтото свое. Но тут основной момент – левая и правая полоса не должна превышать размеры окна. Соответственно расстояние расчитывается путем не сложной математики и манипуляциями с левым отступом от окна, ширины окна и ширины активного/ховер блока.

jQuery(document).ready(function() {
 var el, leftPos, newWidth,
 mainNav = jQuery("#menu-primary-items"),
 activeMenu = mainNav.find('.current');
mainNav.append("<li id='magic-line-left'></li>");
mainNav.append("<li id='magic-line-right'></li>");
var magicLineLeft = jQuery("#magic-line-left");
var magicLineRight = jQuery("#magic-line-right");
var windowWidth = jQuery(window).width(),
 activeMenuWidth = activeMenu.innerWidth(),
 activeMenuPosistion = Math.round(activeMenu.position().left),
 leftLineWidth = Math.round(activeMenu.offset().left),
 leftLineOffset = leftLineWidth - activeMenuPosistion;
 rightLineWidth = Math.round(windowWidth - leftLineWidth - activeMenuWidth),
 rightLineOffset = activeMenuPosistion + activeMenuWidth;
 ;
magicLineLeft
 .css({
 'width': leftLineWidth,
 'left': '-' + leftLineOffset + 'px'
 })
 .data("origWidthL", leftLineWidth)
 .data("origLeftL", '-' + leftLineOffset + 'px');
magicLineRight
 .css({
 'width': rightLineWidth,
 'left': rightLineOffset
 })
 .data("origWidthR", rightLineWidth)
 .data("origLeftR", rightLineOffset);
jQuery("#menu-primary-items > li > a").hover(function() {
 el = jQuery(this);
var hoverMenuWidth = el.innerWidth(),
 hoverMenuPosistion = Math.round(el.position().left),
 hoverLeftLineWidth = Math.round(el.offset().left),
 hoverLeftLineOffset = hoverLeftLineWidth - hoverMenuPosistion;
 hoverRightLineWidth = Math.round(windowWidth - hoverLeftLineWidth - hoverMenuWidth),
 hoverRightLineOffset = hoverMenuPosistion + hoverMenuWidth
 ;
var newWidthL = hoverLeftLineWidth,
 leftPosL = '-'+ (hoverLeftLineOffset) +'px';
 var newWidthR = hoverRightLineWidth,
 leftPosR = hoverRightLineOffset;
magicLineLeft.stop().animate({
 width: newWidthL,
 left: leftPosL
 });
magicLineRight.stop().animate({
 width: newWidthR,
 left: leftPosR
 });
if(el.parent().not('.current')) {
 mainNav.find('.current').addClass('hovered');
 }
}, function() {
 magicLineLeft.stop().animate({
 width: magicLineLeft.data("origWidthL"),
 left: magicLineLeft.data("origLeftL")
 });
magicLineRight.stop().animate({
 width: magicLineRight.data("origWidthR"),
 left: magicLineRight.data("origLeftR")
 });
if(el.parent().not('.current')) {
 mainNav.find('.current').removeClass('hovered');
 }
 });
 });

В общем, вот функциональный результат.

Поделиться с друзьями:

Блог веб-разработчика

Приветствую вас в своем блоге. Здесь вы найдете информацию о различных около-веб темах; об особенностях CMS Wordpress, о верстке CSS, программировании HTML, Javascript и так далее. Подписывайтесь на мой канал, будьте в курсе последних тенденций из мира веб.