Перейти к содержимому

Реферальная программа Мегаплана

Партнерская программа Kredov

Урок (Viewport)#2 - создание выпадающих меню

#1 c0ns0l3

c0ns0l3
  • Пользователь
  • 264 сообщений
  • Репутация: 49
3

Отправлено 05 Октябрь 2013 - 16:30

Доброго времени суток уважаемые.
Это тема является продолжением - Урок (Viewport)#1 - основная разметка, спрайты, общие принципы
Напоминаю общий вид нашего шаблона:
Изображение

Исходники первого урока:
Изображение lesson00.rar 61,38К 4


Поэтому сегодня, мы рассмотрим выпадающие менюшки. Которые мы будем реализовывать только на CSS.
Верхнее меню ( nav_bar ):
Изображение

Меню в шапке ( header_nav ):
Изображение


Вступление:
Как всегда начинать нужно с HTML каркаса. По скольку я планирую этот шаблон в будущем "натянуть" на Wordpress, то и будем использовать каркас, который нам предоставлять WP:wp_nav_menu
Предоставляет данная функция нам каркас в виде списков (UL) с элементами меню (LI), ссылкой в них (A) и если есть вложенное меню то с вложенным в родительский LI еще одного списка UL с такой же иерархией.

Примерно имеющий таков вид:
<ul>
	<li><a href="{post_link}">{post_title}</a></li>
	<li>
		<a href="{post_link}">{post_title}</a>
		<ul class="sub-menu">
			<li><a href="{sub-post_link}">{sub-post_title}</a></li>
			...
		</ul>
	</li>
	...
</ul>

Для верстки, мы набросаем основываясь на приведенном примере наш каркас, соответствующий нашему дизайну, за исключением того, что добавим класс "dropdown" к родительскому элементу LI в котором есть вложенное меню (эту функцию мы реализуем на WP, хотя можно реализовать и на JS т.к. нам понадобится добавлять визуальный элемент "стрелка" для меню, в которых есть выпадающих список):

<ul class="bar_menu">
						<li><a href="#">Sample Page</a></li>
						<li class="dropdown">
							<a href="#">Page Layouts</a>
							<ul class="sub-menu">
								<li><a href="#">One Column Column</a></li>
								<li><a href="#">Two Column</a></li>
							</ul>
						</li>
						<li class="dropdown">
							<a href="#">Page Templates</a>
							<ul class="sub-menu">
								<li><a href="#">Blog Page</a></li>
								<li><a href="#">Archive Page</a></li>
								<li><a href="#">Full Width Page</a></li>
								<li><a href="#">Contact Page</a></li>
							</ul>
						</li>
						<li><a href="#">Theme Colors</a></li>
						<li><a href="#">Contact</a></li>
					</ul>

Т.к. я уже набросал каркас для меню в nav_bar, то и начнем мы сразу с него.


Меню в верхнем навигационном блоке.

Начнем с простого, добавим стили оформления ко всему #nav_bar для текста и ссылок, т.к. у нас в нем находится не только наше навигационное меню, а еще и "Дата" (не знаю зачем) и "RSS/E-Mail подписка" (на стилях которых мы и будем изначально прыгать):

/*общая стилизация*/
  #nav_bar {
   text-shadow: 0px -1px 3px rgba(0, 0, 0, 1);
   font-style: italic;
   color: #787878;
   font-size: 11px;
   line-height: 35px;
  }
  #nav_bar a {color: #bbbbbb;}
  #nav_bar a:hover {color: #dddddd;text-decoration: none;}

Добавляем нашу дату в каркас:
<div id="nav_bar_data">03 Oct 2013<span>•</span></div>

И блок подписок:
<div id="rss_holder">{rss_holder}</div>
Оборачиваем наше будущее меню (UL) в #nav_menu

Полученный код:
Спойлер


Проставляем им позиционирование:

/*позиционирование вложенных элементов*/
  #nav_bar_data, #nav_menu {float:left;}
  #rss_holder {float: right;}

Принцип работы выпадающего меню на CSS:
При неактивном состоянии наведения мышки на родительский элемент LI - вложенное меню (UL) будет находиться вне экрана. А при наведении (:hover) будет возвращаться на свое законное место.

Сейчас постараюсь показать на практике эту идею и пока будем верстать без эффекта выпадания:

Так как менюшка у нас горизонтальная, то и обтекание ставим "слева". Добавляем отступы в ссылках. Высоту и т.д.
/*Меню первого уровня*/
  .bar_menu > li {float: left;position: relative; height: 35px;}
  .bar_menu > li > a {padding: 0 10px;}

Теперь нужно добавить "разделитель" (seperator) между элементами. Мы будем добавлять справа от li соответственно. Так как в дизайне, в последнем элементе разделитель отсутствует, а при помощи CSS есть возможность выбрать только последний элемент при помощи псевдо-класса :last-child (:first-child работает полноценно только в "Модных Браузерах"), то в последнем будем убирать разделитель. Реализуем это как и в предыдущем уроке средствами виртуальных блок after/before. И используем наш спрайт с первого урока, в котором уже есть нужное нам изображение.
/*Разделитель*/
			.bar_menu > li:after {
				content: '';
				position: absolute;
				width: 3px;height: 10px;
				top:13px; right:-4px;
				background: transparent url(img/sprites.png) -40px 0 no-repeat;
			}
			/*убираем сеператор в последнем элемента*/
			.bar_menu > li:last-child:after {background: none;}

И так как у нас наш разделитель выходит на 4 пикселя вправо за LI, то и делаем ему внешний отступ на эти же 4 пикселя ;)
.bar_menu > li {margin-right: 4px}

Теперь нам понадобится прикрутить стрелку, которая демонстрирует нам наличие выпадающего меню. Здесь мы действуем тем же способом, только "прикручиваем" ее теперь к ссылке, в которой мы сможем регулировать отдельно отступом справа для предоставления места нашей стрелочке.
/*стрелка выпад меню*/
	  .bar_menu > li.dropdown a {
		  padding-right: 20px;
		  position: relative;
	  }
	  .bar_menu > li.dropdown > a:after {
		  content: '';
		  width: 10px; height: 10px;
		  top:13px;right:4px;
		  position: absolute;
		  background: transparent url(img/sprites.png) -20px 0 no-repeat
	  }

Но и не забываем добавить ей эффект наведения мышки при помощи опять же смещения нашего спрайта.
/*:hover*/
	  .bar_menu > li.dropdown:hover > a:after {background-position: -30px 0;}

Вроде первый уровень менюшки - готов B)


Перейдем ко второму уровню.

Теперь мы будем настраивать наше выпадающее меню (UL). Как видим, ему в первую очередь понадобится добавить фон, такой же как у самой навигационной полоски и закруглить снизу...
/* МЕНЮ ВТОРОГО УРОВНЯ */
	   .bar_menu ul {
				 /*фон*/
				 background-image: url(img/noise.png);
				 background-repeat: repeat;
				 background-color: #232323;
				/*закругление*/
				 -webkit-border-bottom-right-radius: 5px;
				 -webkit-border-bottom-left-radius: 5px;
				 -moz-border-radius-bottomright: 5px;
				 -moz-border-radius-bottomleft: 5px;
				 border-bottom-right-radius: 5px;
				 border-bottom-left-radius: 5px;
				 /*отступ снизу*/
				 padding-bottom: 5px;
				 /*типа тень*/
				 border-bottom: solid 1px rgba(25,25,25,0.5);
				 border-right: solid 1px rgba(25,25,25,0.2);
			 }

Добавим так же внутренние отступы LI справа и слева, таким образом отодвинув А от краев, а уже самой А добавим подчеркивание и ставим отображение как блок, что бы она тянулась на всю ширину родительского элемента (LI)
/*отступы и подчеркивание*/
			  .bar_menu ul > li {padding: 0 10px;}
			  .bar_menu ul > li a {border-bottom: solid 1px rgba(255,255,255,.05);display: block;}

И опять же, у последнего элемента убираем подчеркивание:
.bar_menu ul > li:last-child a {border-bottom: none}

Вау вау вау, все работает! Но, что ЭТО?! :) :o :)
Изображение

Мало того, что наша менюшка залезла ПОД блок шапки, так еще и ссылки не отрабатываются на ней?!


Объясняю, это z-index противная штука в таких вещах.. иногда в нем легко потеряться....

У каждого элемента на странице (блока) есть свой z-index, то на каком уровне он находится... как слои в Фотожопе :)! И этот самый z-index генерируется автоматом, в зависимости от того, когда какой элемент был создан, и так как наша шапка, описывается после описание навигационной полоски нашей, то и создана она позже, то и z-index у нее выше!

Заметка: z-index работает внутри одного элемента (родителя).
Замечание: этот же эффект мы будем наблюдать и в меню шапки, оно будет находится под блоком "слайдер". Мы сейчас махом уберем всю эту "не красоту".


/** Z - Index по менюшкам*/
#nav_bar, #header, #index_slider, #content {position: relative; z-index: 10;}
#nav_bar {z-index: 20;}
#header {z-index: 15;}

Обратите внимание, что я зацепил и блок "контент". А все потому, что как уже говорилось в первом уроке, наш слайдер будет находиться только на главной странице, а на остальных его не будет. Следовательно под менюшкой в шапке будет находиться уже не слайдер, а блок с контентом.
Расставил z-index для навигационной полоски самый высокий, т.к. он должен перекрывать шапку. Для шапки "средний", т.к. он должен перекрывать все то, чему мы установили минимальный z-index

Нам осталось поправить немножко цвета ссылок в нашей менюшке:
.bar_menu a {color: #787878 !important;}
  .bar_menu a:hover {color: #bbbbbb !important;}

Добавит эффект родительского элемента когда наведена мышка на подменю:
  .bar_menu > li:hover > a {color: #bbbbbb !important;}

И теперь самое главное реализовать "скрытое подменю" и появление его по наведению мышки.
/*Делаем эффект выпадания*/
			.bar_menu >li ul {position: relative;top:-999em;}
			.bar_menu >li:hover ul {top:0;}

Ура, вся наша менюшка теперь похожа на то, что нарисовано в соседнем окне фотошопа!

Полный исходный код менюшки:
Спойлер



Менюшка в шапке
Изображение
Здесь ничего нового по отношению к менюшке, которую мы делали только-что нету, кроме нескольких нюансов:
  • В первом уровне появилось "описание элемента"
  • При наведении на первый уровень - эффект буд-то менюшка вылезла за свои приделы.
  • Черная горизонтальная линия разделяет первый и второй уровни меню. - проблема заключается в том, что если будет расстояние вложенного UL (второй уровень) между LI которая является его родителем, то получается так, что именно эта LI потеряет триггер hover когда мы проведем по этому "пространству" курсором мышки.
Решать эти проблемы мы будем примерно таким образом.
  • Изменится каркас нашего HTML - добавится элемент <span> {link_description} </span> - реализовывать будем средствами WordPress.
  • Будем использовать отрицательное позиционирование нашей менюшки первого уровня.
  • Понадобится использовать контур (бордер) снизу элемента первого уровня, или сверху элемента второго уровня.

Начнем...

Я набросал сразу каркас, который примерно будет похож на от, что у нас в фотошопе:

HTML:
Спойлер



Добавим общие стили:
/** общая стилизация*/
  .header_menu {
   font-style: italic;
   height: 56px;
   width: 100%;
	  border-bottom: solid 10px #1e1e1e;
	 }
  .header_menu a {font-size:11px;color: #787878;text-shadow: 0px 0px 2px rgba(0, 0, 0, 1);}
  .header_menu a:hover {color:#bbbbbb; text-decoration: none;}

И начнем работать с первым уровнем.
Что лично я думаю сделать, я думаю сделать всетаки примерно следующее:
  • Вытянуть LI за ее пределы на -5 пикселей.
/*первый уровень*/
   .header_menu >li {
	float: left;
	position: relative;
	top:-5px;
	height:61px;
   }
   /* наведение на элемент */
   .header_menu >li:hover {
	 /*фон*/
				 background-image: url(img/noise.png);
				 background-repeat: repeat;
				 background-color: #232323;
				/*закругление*/
				 -webkit-border-top-right-radius: 5px;
				 -webkit-border-top-left-radius: 5px;
				 -moz-border-radius-topright: 5px;
				 -moz-border-radius-topleft: 5px;
				 border-top-right-radius: 5px;
				 border-top-left-radius: 5px;
   }
  • Я хочу растянуть ссылку на всю выосоту и ширину, и под нее поместить спан с описанием (не забудем про z-index, иначе описание получится ПОВЕРХ ссылки)
/*ссылки*/
    .header_menu >li > a:hover {color:#fff;}
    .header_menu >li > a {
	 line-height: 43px;
	 font-size: 13px;
	 color: #fff;
	 display: block;
	 height: 56px;
	 margin-top:5px;
	 position: relative;
	 z-index:2;
    }
    /*описание*/
    .header_menu >li > span {
	 position: relative;
	 height: 20px;
	 top:-20px;
	 margin-bottom: -20px;
	 display: block;
	 z-index: 1;
    }

Таким образом, у меня все получается на своих местах, и на данный момент выпадающее меню находится четко под ссылкой.
Теперь добавим оформление выпадающего меню с добавлением сверху бордера в 10 пикселей прозрачности ;)
.header_menu ul {
	 border-top: solid 10px #1e1e1e;
	 /*фон*/
				 background-image: url(img/noise.png);
				 background-repeat: repeat;
				 background-color: #232323;
				 /*закругление*/
				 -webkit-border-bottom-right-radius: 5px;
				 -webkit-border-bottom-left-radius: 5px;
				 -moz-border-radius-bottomright: 5px;
				 -moz-border-radius-bottomleft: 5px;
				 border-bottom-right-radius: 5px;
				 border-bottom-left-radius: 5px;
				 /*отступ снизу*/
				 padding-bottom: 5px;
				 /*типа тень*/
				 border-bottom: solid 1px rgba(25,25,25,0.5);
				 border-right: solid 1px rgba(25,25,25,0.2);
    }

И добавляем стили к ссылкам:
/*стили ссылок*/
	 .header_menu ul a {
	  line-height: 35px;
	  display: block;
	  border-bottom: solid 1px rgba(255,255,255,.05);
	 }
	 .header_menu ul li:last-child a {border-bottom: none;}


Код целиком:
Спойлер



Собственно весь исходный код того, что у меня получилось:
Прикрепленный файл  lesson01.rar   62,29К   Количество загрузок: 145

 

 

  • 1

#2 TimurR

TimurR
  • Пользователь PRO
  • 831 сообщений
  • Репутация: 180

Отправлено 08 Февраль 2015 - 20:29

Некоторые изображения не открываются. 


  • 0

Рекомендую хостинг: www.ihc.ru

Разработка сайтов / Дизайн / Верстка - писать в л.с.



#3 hnerd

hnerd
  • Пользователь
  • 284 сообщений
  • Репутация: 18

Отправлено 14 Февраль 2015 - 17:35

Спасибо! Полезная статья, пригодилась!


  • 0


Оформление форума – IPBSkins.ru