Простое выпадающее меню на css (CSS Drop Down Menu)

Поставил себе задачу сделать простейшее горизонтальное выпадающее меню исключительно с помощью css стилей, связываться с плагинами равно как и с jQuery не хотелось, чтобы не усложнять себе задачу и облегчить максимально мою тему Golden ratio.
Сразу как-то не заладилось у меня с css, разработчики WordPress добавили все мыслимые классы в меню, но самое главное естественно забыли: во первых отметить элемент li, который имеет потомков добавив ему класс parent, во вторых просто прописать уровень вложенности меню depth0, depth1, depth2 …
Но не тут то было. Нам оставили возможность подключить фильтр strong>nav_menu_css_class и добавить для каждого элемента свой нужный нам класс, но и тут полный облом – в этот фильтр передаются массив уже присвоенных классов и сам элемент однако толку от этого элемента = 0 . В отрыве от общей структуры меню ничего неизвестно ни о его потомках ни об уровне элемента. Рассчитывать все эти данные самостоятельно имея в наличии только id элемента – себе дороже будет. Кстати просматривая коды всех эти Walker_Nav_Menu, Walke создается впечатление что разработчики ну просто забыли добавить столь нужные классы ведь вот, вот они эти данные прямо тут, рукой достать можно и не надо ничего вычислять лишнего – глубина постоянно передается из одной функции в другую, но почему-то только не в фильтр nav_menu_css_class, примерно тоже самое и с массивом потомков. Эх ладно, быть может я вижу вообще все в неправильном CSS?

Далее описываю свой способ извращения.

Задача:

добавить для каждого элемента li из горизонтального меню классы –
parent – для тех ли у которых есть подменю
depthX – глубина, где X уровень вложения

Решение:

В function.php вашей темы добавляем:

class DD_Walker_Menu extends Walker_Nav_Menu { function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ){ $GLOBALS[‘dd_children’] = ( isset($children_elements[$element->ID]) )? 1:0; $GLOBALS[‘dd_depth’] = (int) $depth; parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output ); } } class DD_Walker_Page extends Walker_Nav_Menu { var $db_fields = array (‘parent’ => ‘post_parent’, ‘id’ => ‘ID’); function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ){ $GLOBALS[‘dd_children’] = ( isset($children_elements[$element->ID]) )? 1:0; $GLOBALS[‘dd_depth’] = (int) $depth; $element->attr_title = $element->title = $element->post_title; $element->url = get_page_link($element->ID); parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output ); } } add_filter(‘nav_menu_css_class’,’add_parent_css’,10,2); function add_parent_css($classes, $item){ global $dd_depth, $dd_children; $classes[] = ‘depth’.$dd_depth; if($dd_children) $classes[] = ‘parent’; return $classes; }

123456789101112131415161718192021222324252627 class DD_Walker_Menu extends Walker_Nav_Menu { function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ){     $GLOBALS[‘dd_children’] = ( isset($children_elements[$element->ID]) )? 1:0;        $GLOBALS[‘dd_depth’] = (int) $depth;        parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );    }}  class DD_Walker_Page extends Walker_Nav_Menu {   var $db_fields = array (‘parent’ => ‘post_parent’, ‘id’ => ‘ID’);   function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ){     $GLOBALS[‘dd_children’] = ( isset($children_elements[$element->ID]) )? 1:0;        $GLOBALS[‘dd_depth’] = (int) $depth;        $element->attr_title = $element->title =  $element->post_title;        $element->url =  get_page_link($element->ID);        parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );    }}add_filter(‘nav_menu_css_class’,‘add_parent_css’,10,2);function  add_parent_css($classes, $item){     global  $dd_depth, $dd_children;     $classes[] = ‘depth’.$dd_depth;     if($dd_children)         $classes[] = ‘parent’;    return $classes;}

Теперь печатем меню в header.php

<ul id=»headermenu»> <?php if(has_nav_menu( ‘header-menu’ )){ wp_nav_menu( array( ‘container_class’ => », ‘items_wrap’ => ‘%3$s’ , ‘container’ => », ‘menu’ => ‘header-menu’, ‘walker’=> new DD_Walker_Menu ) ); } else{ wp_list_pages(array(‘title_li’=>», ‘walker’=> new DD_Walker_Page )); } ?> </ul>

1234567891011 <ul id=«headermenu»>  <?php    if(has_nav_menu( ‘header-menu’ )){        wp_nav_menu( array( ‘container_class’ => », ‘items_wrap’ => ‘%3$s’ , ‘container’ => »,  ‘menu’ => ‘header-menu’, ‘walker’=> new DD_Walker_Menu ) );    }    else{        wp_list_pages(array(‘title_li’=>», ‘walker’=> new DD_Walker_Page ));    }     ?></ul>

Проверяем если меню задано пользователем выводим его если нет выводим список страниц.
Обратите внимание подставляется новый обработчик Walker !

Примерный css код может быть такой

#headermenu{ /*background-color: #EEEEEE; */ text-align: right; padding:0 1.618em 0 0.618em; font-family: Tahoma; background-color: #F7F7F7; margin: 0 1.38em 0; padding: 0; } #headermenu> li{ display: inline; margin-left: 1.618em; } #headermenu li{ list-style: none; } #headermenu li a{ text-decoration: none; font-size: 1em; font-family: ‘Lato’,Helvetica,Arial,sans-serif ; letter-spacing: normal; white-space:nowrap; } #headermenu li.parent::after{ content:’»’; } #headermenu .sub-menu{ display: none; position: absolute; margin: 1.2em 0 0 -4em; padding: 0.6em; background-color: #fff; text-align: left; font-size: 0.9em; } #headermenu li.parent:hover::after{ content:’«’; } #headermenu li:hover>.sub-menu{ display: inline; border: solid 1px #BBBBBB; z-index: +1; }

12345678910111213141516171819202122232425262728293031323334353637383940414243444546 #headermenu{    /*background-color: #EEEEEE; */    text-align: right;    padding:0 1.618em 0 0.618em;    font-family: Tahoma;    background-color: #F7F7F7;    margin:  0 1.38em 0;    padding: 0;}#headermenu> li{    display: inline;    margin-left: 1.618em;}#headermenu li{    list-style: none;}#headermenu  li a{    text-decoration: none;    font-size: 1em;    font-family: ‘Lato’,Helvetica,Arial,sans-serif ;    letter-spacing: normal;    white-space:nowrap;} #headermenu li.parent::after{    content:‘»’;} #headermenu  .sub-menu{   display: none;   position: absolute;   margin: 1.2em 0 0 -4em;   padding: 0.6em;   background-color: #fff;   text-align: left;   font-size: 0.9em;}#headermenu  li.parent:hover::after{   content:‘«’;} #headermenu  li:hover>.sub-menu{    display: inline;    border: solid 1px #BBBBBB;    z-index: +1;}

#menu-header-menu – корневой элемент ul вашего меню если что помень его на свой
Гребаный IE! есесено все покажет по своему – псевдо класс after эта гадина игнорирует и придется родительские пункты обозначить просто жирным шрифтом:

#headermenu li.parent>a{ font-weight: bold; }

123 #headermenu li.parent>a{    font-weight: bold;}