Выпадающее меню для WordPress на CSS
В этой статье я расскажу, как создать выпадающее меню для WordPress на CSS. Сначала опишу все этапы создания меню с настройкой через CSS, а затем выведу его через файл темы.
Примечание: я буду использовать WordPress 3.9 и тему Twenty Thirteen, но все действия аналогичны для любого сайта на WordPress 3.
Демо-версия
Ниже приведена ссылка на скачивание ZIP-архива, который содержит все необходимые для этой статьи коды.
Демо-версия: Выпадающее меню для WordPress - Версия 1.0 (3 кБ ZIP)
Создаем меню в WordPress
WordPress 3 имеет простой в использовании drag-and-drop интерфейс для создания структуры меню. Если вы еще не работали с меню, чтобы создать и сохранить пользовательское меню, перейдите Внешний вид > Меню. Задайте для меню название и сохраните его:

Добавление пользовательского Walker-класса в functions.php
Прежде, чем мы сможем вывести меню в файле темы WordPress, нам нужно добавить Walker-класс WordPress в файл functions.php.
Этот код «очистит» выводимую HTML-разметку нашего меню, чтобы мы могли легко создавать CSS. Скопируйте и вставьте код класса Walker в файл functions.php, который располагается в папке темы. Если файл functions.php не существует, создайте его, а затем вставьте в него код класса:
class CSS_Menu_Walker extends Walker {
var $db_fields = array('parent' => 'menu_item_parent', 'id' => 'db_id');
function start_lvl(&$output, $depth = 0, $args = array()) {
$indent = str_repeat("t", $depth);
$output .= "n$indent<ul>n";
}
function end_lvl(&$output, $depth = 0, $args = array()) {
$indent = str_repeat("t", $depth);
$output .= "$indent</ul>n";
}
function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) {
global $wp_query;
$indent = ($depth) ? str_repeat("t", $depth) : '';
$class_names = $value = '';
$classes = empty($item->classes) ? array() : (array) $item->classes;
/* Добавление активного класса */
if (in_array('current-menu-item', $classes)) {
$classes[] = 'active';
unset($classes['current-menu-item']);
}
/* Проверка наличия дочерних элементов */
$children = get_posts(array('post_type' => 'nav_menu_item', 'nopaging' => true, 'numberposts' => 1, 'meta_key' => '_menu_item_menu_item_parent', 'meta_value' => $item->ID));
if (!empty($children)) {
$classes[] = 'has-sub';
}
$class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item, $args));
$class_names = $class_names ? ' class="' . esc_attr($class_names) . '"' : '';
$id = apply_filters('nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args);
$id = $id ? ' id="' . esc_attr($id) . '"' : '';
$output .= $indent . '<li' . $id . $value . $class_names .'>';
$attributes = ! empty($item->attr_title) ? ' title="' . esc_attr($item->attr_title) .'"' : '';
$attributes .= ! empty($item->target) ? ' target="' . esc_attr($item->target ) .'"' : '';
$attributes .= ! empty($item->xfn) ? ' rel="' . esc_attr($item->xfn ) .'"' : '';
$attributes .= ! empty($item->url) ? ' href="' . esc_attr($item->url ) .'"' : '';
$item_output = $args->before;
$item_output .= '<a'. $attributes .'><span>';
$item_output .= $args->link_before . apply_filters('the_title', $item->title, $item->ID) . $args->link_after;
$item_output .= '</span></a>';
$item_output .= $args->after;
$output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
}
function end_el(&$output, $item, $depth = 0, $args = array()) {
$output .= "</li>n";
}
}
Вывод меню через файл темы
Теперь у нас есть созданное меню и размещенный класс Walker. Пришло время вывести наше меню через файл темы. Для этого мы используем функцию wp_nav_menu(). С помощью PHP мы вызовем эту функцию и передадим ей параметры нашего меню для вывода структуры HTML.
Параметр menu - это название меню, созданного нами в шаге 1. container_id добавляет в HTML-код меню идентификатор CSS, который мы будем использовать позже в стилях CSS. Параметр Walker указывает функции wp_nav_menu() использовать для вывода HTML-разметки наш пользовательский Walker-класс WordPress:
<?php wp_nav_menu(array(
'menu' => 'Main Menu',
'container_id' => 'cssmenu',
'walker' => new CSS_Menu_Walker()
)); ?>
Добавьте этот PHP-код в один из файлов темы. Где бы вы его не поместили, меню будет выводиться в этом месте. Я использую тему WordPress по умолчанию Twenty Thirteen. Она содержит файл header.php, в него я и вставлю этот код.
Если вы сделали все правильно, то сейчас должны увидеть, что в вашей теме отображается HTML-список без заданных стилей:

Добавление CSS
Откройте файл CSS вашей темы styles.css (в папке CSS или в корневом каталоге темы). Вы можете сразу скопировать и вставить весь приведенный ниже код в файл CSS вашей темы. Я буду разбивать CSS-код на части, чтобы пояснять каждый его фрагмент.
Обратите внимание, что мы используем тот же идентификатор, который мы указали в функции wp_nav_menu() - #cssmenu.
Первый фрагмент CSS-кода - это всего лишь несколько строк, чтобы быть уверенными, что все браузеры начинают обработку с той же точки:
#cssmenu,
#cssmenu ul,
#cssmenu li,
#cssmenu a {
border: none;
margin: 0;
padding: 0;
line-height: 1;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
Следующий фрагмент CSS-кода - это стили первого уровня выпадающего меню. Если браузер пользователя не поддерживает градиенты, то заполните фон цветом #3c3c3c.
Псевдокласс :after позволяет добавить тонкую цветную рамку вокруг каждого пункта меню:
#cssmenu {
height: 37px;
display: block;
padding: 0;
margin: 0;
border: 1px solid;
border-radius: 5px;
width: auto;
border-color: #080808;
}
#cssmenu,
#cssmenu > ul > li > ul > li a:hover {
background: #3c3c3c;
background: -moz-linear-gradient(top, #3c3c3c 0%, #222222 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #3c3c3c), color-stop(100%, #222222));
background: -webkit-linear-gradient(top, #3c3c3c 0%, #222222 100%);
background: -o-linear-gradient(top, #3c3c3c 0%, #222222 100%);
background: -ms-linear-gradient(top, #3c3c3c 0%, #222222 100%);
background: linear-gradient(top, #3c3c3c 0%, #222222 100%);
}
#cssmenu > ul {
list-style: inside none;
padding: 0;
margin: 0;
}
#cssmenu > ul > li {
list-style: inside none;
padding: 0;
margin: 0;
float: left;
display: block;
position: relative;
}
#cssmenu > ul > li > a {
outline: none;
display: block;
position: relative;
padding: 12px 20px;
text-align: center;
text-decoration: none;
text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.4);
font-weight: bold;
font-size: 13px;
font-family: Arial, Helvetica, sans-serif;
border-right: 1px solid #080808;
color: #ffffff;
}
#cssmenu > ul > li > a:hover {
background: #080808;
color: #ffffff;
}
#cssmenu > ul > li:first-child > a {
border-radius: 5px 0 0 5px;
}
#cssmenu > ul > li > a:after {
content: '';
position: absolute;
border-right: 1px solid;
top: -1px;
bottom: -1px;
right: -2px;
z-index: 99;
border-color: #3c3c3c;
}
На данный момент ваше меню должно выглядеть так, как показано на рисунке ниже:

Далее нам нужно задать стили для подменю. Нужно, чтобы они по умолчанию были скрыты, а затем выводились, когда пользователь наводит курсор мыши на родительский элемент.
Сначала нам нужно установить для всех пунктов подменю display: none. После этого мы используем псевдокласс :hover, чтобы установить для подменю состояние:hover. Это создаст эффект скрытия и вывода подменю при наведении указателя мыши на родительский элемент:
#cssmenu ul li.has-sub:hover > a:after {
top: 0;
bottom: 0;
}
#cssmenu > ul > li.has-sub > a:before {
content: '';
position: absolute;
top: 18px;
right: 6px;
border: 5px solid transparent;
border-top: 5px solid #ffffff;
}
#cssmenu > ul > li.has-sub:hover > a:before {
top: 19px;
}
#cssmenu ul li.has-sub:hover > a {
background: #3f3f3f;
border-color: #3f3f3f;
padding-bottom: 13px;
padding-top: 13px;
top: -1px;
z-index: 999;
}
#cssmenu ul li.has-sub:hover > ul,
#cssmenu ul li.has-sub:hover > div {
display: block;
}
#cssmenu ul li.has-sub > a:hover {
background: #3f3f3f;
border-color: #3f3f3f;
}
#cssmenu ul li > ul,
#cssmenu ul li > div {
display: none;
width: auto;
position: absolute;
top: 38px;
padding: 10px 0;
background: #3f3f3f;
border-radius: 0 0 5px 5px;
z-index: 999;
}
#cssmenu ul li > ul {
width: 200px;
}
#cssmenu ul li > ul li {
display: block;
list-style: inside none;
padding: 0;
margin: 0;
position: relative;
}
#cssmenu ul li > ul li a {
outline: none;
display: block;
position: relative;
margin: 0;
padding: 8px 20px;
font: 10pt Arial, Helvetica, sans-serif;
color: #ffffff;
text-decoration: none;
text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.5);
}
#cssmenu ul ul a:hover {
color: #ffffff;
}
#cssmenu > ul > li.has-sub > a:hover:before {
border-top: 5px solid #ffffff;
}
Если вы все сделали правильно, то должны получить новое выпадающее меню WordPress. Если, вам кажется, что в этом меню что-то не так, прочитайте раздел, посвященный устранению неполадок.
Исходные файлы
По этой ссылке вы можете скачать исходные файлы. ZIP-архив содержит functions.php и styles.css:
Демо-версия: Выпадающее меню для WordPress - Версия 1.0 (3 кБ ZIP)
Устранение неполадок
Если вам кажется, что меню функционирует неправильно или выглядит не так, как нужно, возможно проблема заключается в стилях, оставшихся от вашей темы WordPress. То есть, ваша тема содержит другие стили CSS, которые конфликтуют со стилями нашего меню.
Единственный способ решить эту проблему - определить эти стили CSS и удалить их. Лучше всего использовать для этого расширение Firebug для Firefox и проинспектировать стили CSS вручную. Как только вы найдете конфликтующие стили, удалите их.