Целта на днешното занятие е да създадем едно семпло, но много еластично от към функционалност меню. Под семпло имам предвид само външния вид, като естествено вие може да си го промените както пожелаете. За сметка на това обаче менюто ще поддъжа безброй подменюта, което е и големият плюс, а самото добавяне на ново подменю става с копирането на няколко реда код. И за финал, за да е по-мазничко съм добавил малко jquery ефектчета.
Менюто е тествано и работи на всички по-популярни браузъри - Firefox 3.6, Chrome 4, Opera 10, Safari 4, IE 6, IE 7 и IE 8. Освен това може да се ползва за всичко - не е задължително да е главно меню. С малко пипане може да стане хоризонтална навигация, а ако го обърнете на 180 градуса може да се получи помощна лента, забита в дъното на екрана в стил Facebook. Изобщо възможностите са доста и се постарах да покрия колкото се може повече. Ако искате да ровичкате обаче, да предупредя, че трябва да имате поне минимални познания по CSS, HTML и JS, тъй като има някои тънкости. Разбира се винаги може и да попитате, ще се постарая да отговоря. Освен това, ако на някой не му харесва нещо или се сеща за по-културно решение - приемам всякакви идеи и корекции!
| View DemoDownload |
Стъпка 1: HTML
Той представлява един съвсем прост и елементарен списък с няколко поднива, които символизират подменютата. За всеки случай съм копирал и целия работен документ за тези, които не знаят къде да го поставят.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Simple Dropdown Menu w/ CSS & jQuery by RIP</title> <link rel="stylesheet" href="css/style.css" type="text/css" /> <script type="text/javascript" src="js/jquery-1.4.2.min.js"></script> <script type="text/javascript" src="js/simple-dropdown-menu.js"></script> </head> <body> <div id="menu"> <div id="menu_r"> <div id="menu_l"> <ul> <li><a id="home" href="#">Начало</a></li> <li> <a href="#">Новини</a> <ul> <li><a href="#">Свят</a></li> <li> <a href="#">България</a> <ul> <li><a href="#">София</a></li> <li><a href="#">Пловдив</a></li> <li><a href="#">Варна</a></li> <li> <a href="#">Бургас</a> <ul> <li><a href="#">Риби</a></li> <li><a href="#">Жълъди</a></li> <li><a href="#">Кифли</a></li> <li><a href="#">Патладжани</a></li> </ul> </li> </ul> </li> <li> <a href="#">Наука</a> <ul> <li><a href="#">Космос</a></li> <li><a href="#">Клониране</a></li> </ul> </li> <li><a href="#">Спорт</a></li> </ul> </li> <li> <a href="#">Статии</a> <ul> <li><a href="#">Кратки</a></li> <li><a href="#">Дълги</a></li> </ul> </li> <li><a href="#">Каталог</a></li> <li><a href="#">Архив</a></li> <li><a href="#">Форум</a></li> <li><a href="#">Блог</a></li> </ul> </div> </div> </div> </body> </html>
На какво трябва да се обърне внимание тук? Като за начало погледнете си пътищата към javascript, image и css файловете. Ако ги местите и се чудите защо не работят, вероятно това е причината.
Стъпка 2: CSS
Тъй като целта ни е да направим едно безкрайно меню, CSS-а е малко по-дълъг от обикновено. Разбира се ако му накичите още някоя глезотийка редовете ще скочат, но това в крайна сметка няма значение... просто не се заблуждавайте, че е нещо много сложно. За урока съм го стилизирал по-семпличко и без много изображения, за да схванете логиката, а всеки, който иска може да си добави картинки и в подменютата. Между другото за по-голяма оптимизация съм направил sprite от картинките на менюто. Sprite с две думи, освен популярната напитка, представлява една огромна картинка (например хвърлете едно око на YouTube-ската тук), която се зарежда веднъж и впоследствие с помощта на CSS и background-position, ние позиционираме необходимата ни част на необходимото място. Прави се предимно с цел оптимизация, но много трябва да се внимава, защото е малко пипкава работа, особено под по-старите браузъри.
body {
margin: 0;
padding: 0;
font-size: 11px;
font-family: Tahoma, Arial, Verdana, sans-serif;
line-height: 1.3em;
background: #FFF;
color: #666;
}
ul { margin: 0; padding: 0; list-style: none; }
#menu {
background: url(../img/menu.png) repeat-x left -72px;
width: 800px;
margin: 100px auto;
}
#menu_r {
background: url(../img/menu.png) no-repeat right -36px;
}
#menu_l {
background: url(../img/menu.png) no-repeat left 0;
height: 36px;
}
ul.main li {
position: relative;
float: left;
background: url(../img/menu_li.png) no-repeat right top;
padding: 0 3px 0 0;
}
ul.main li a, ul.main li a:link, ul.main li a:visited {
float: left;
padding: 0 25px;
color: #666;
font-size: 12px;
height: 36px;
line-height: 36px;
font-weight: 700;
outline: none;
text-decoration: none;
text-shadow: 1px 1px 0 #fff;
}
ul.main li a:hover {
color: #00b2fc;
background: url(../img/menu.png) repeat-x left -108px;
}
ul.main li a span.arrow {
color: #999;
}
ul.main li a#home:hover {
background: url(../img/home_hover.png) no-repeat left top;
}
ul.main li ul.sub {
display: none;
position: absolute;
top: 36px;
left: -2px;
width: 200px;
border-left: 1px solid #d9d9d9;
border-right: 1px solid #d9d9d9;
}
ul.main li ul.sub li {
position: relative;
padding: 0;
background: none;
}
ul.main li ul.sub li a, ul.main li ul.sub li a:link, ul.main li ul.sub li a:visited {
float: none;
display: block;
width: 180px;
border-bottom: 1px solid #d9d9d9;
height: 30px;
line-height: 30px;
padding: 0 10px;
font-size: 11px;
background: #f8f8f8;
}
ul.main li ul.sub li a:hover {
color: #666;
background: #efefef;
}
ul.main li ul.sub li ul.sub {
position: absolute;
top: -1px;
left: 200px;
border-top: 1px solid #d9d9d9;
}
Тук е трудно, а и безсмислено да се коментира кой ред какво прави, защото нещата са навързани. За това пак - ако има въпроси и предложения, насреща съм.
Стъпка 3: jQuery
Тъй като jQuery е една от най-добрите Javascript библиотеки, аз съм я използвал с актуалната й версия 1.4.2. Приложил съм всички файлове в архива за сваляне, но ако имате желание да го свалите отделно, ето линк за компресираната версия или за отворения файл, по който може да човъркате.
Тук JQ се ползва много малко и буквално, както виждате са 10 реда, но създава приятен ефект.
$(document).ready(function ()
{
$('.main li:has(ul) > a').addClass('more');
$('a.more').append('<span> »</span>');
$('.main li').hover(function () {
$(this).find('ul:first').stop(true, true).animate({opacity: 'toggle', height: 'toggle'}, 200).addClass('active_list');
}, function () {
$(this).children('ul.active_list').stop(true, true).animate({opacity: 'toggle', height: 'toggle'}, 200).removeClass('active_list');
});
});
Идеята тук е да търсим всяко LI, което е родителски елемент на A и съдържа в себе си UL. Така ако е изпълнено условието на линка се добавя клас "more", на колко клас на следващия ред добавяме стрелкички до името на бутона. Това го правим с цел да се разбере, че този бутон съдържа в себе си информация и подтиква юзъра да провери каква е тя.
След това създаваме плавния ефект на Slide Up & Down. Търсим всеки първи списък и му пускаме анимация, която го слайдва надолу и му добавя клас "active_list". След това търсим списък с вече добавения клас "active_list" и поставяме условие, ако мишока не е върху него да се изпълни анимацията за затваряне или иначе казано прибиране нагоре. След това просто изтриваме класа "active_list" и всичко е готово.
Накратко е това. В javascript файла, който се намира в архива съм закоментирал ред по ред кое какво прави мааалко по-разширено. Нещата не са никак сложни, стига да имате малко понятие.
Плюсовете на менюто са, че може лесно да се интегрира, а с готовата структура бързо се преправя, така, че да пасне за нуждите на всеки.
collapse="true"





[...] Как лесно да си направим падащо меню, чрез CSS & jQuery – Simple Drop Down Menu w/ CSS & jQuery [...]
Поздравления за свършената работа. Менюто е много хубаво. Работи перфектно.
Браво на производителя му. {:
Здравейте,
Имам въпрос относно менюто.
След като го обогатя с повечко подменюта някои от последните(най-долните по ред) се отварят извън видимата част на страницата и трябва да се скролвам надолу, но тъй като при отместване на мишката върху празно поле менюто се прибира обратно, има опасност от това, желаното кликване да не се получи от първия път.
Как да настроя някои от подменютата да се разгръщат нагоре, а не надолу?
За по-ясна представа, ето един скрийншот - http://kachi-snimka.info/images/cqs1272055023a.jpg
Благодаря предварително!
Както писах и в блога ми:
"Това, което искаш може да се направи, но си иска доста работа, за да стане като хората. При него логиката е малко по-различна и трябва да се пипне цялото меню, което направо си става за отделен урок :). В този си вид, преди да го пусна го тествах точно в твоята ситуация и честно казано не виждам проблем, защото повечето хора ползват скрола на мишката за предвижване, така че не е нужно да напускат менюто.
Иначе толкова дълги менюта по принцип не се препоръчват, защото закриват половината сайт, а и точно поради факта, че можеш неволно да преместиш мишката и да се затвори. Така че първо помисли си дали това е правилния начин да представиш нещата."
Здравейте, менюто много ми хареса и поздравявам създателя, но бих искал да вмъкна две забележки:
1. Не е ли по-добре да се добави z-index на hover
2. Как би изглеждало менюто ако не е сложено на страница с бял фон (това ме спира да го ползвам).
За 2 след като редактирах изображенията дадени в архива отново не се получи, много бих искал съвет ако не ви отнема много от времето. Благодаря.
Здравей Nikola,
благодарим за забележките които имаш :)
За първата от тях бих казал, че в зависимост от нуждите които имаш може да използваш z-index, position:absolute; или друг метод който е подходящ за теб в дадена ситуация, но това е урок ориентиран по-скоро за jQuery от колкото за HTML и CSS и за това авторът е обяснил начинът по който да създадем въпросното меню без да навлиза в подробности за имплементацията му.
За втората забележка : Има много решения за проблема (прозрачни изображения, използване на CSS3 за заоблените ъгли на менюто и други). С удоволствие бихме ти помогнали в имплементацията на менюто, но се нуждаем от малко повечко информация за проблемите с които се сблъскваш.
Никола, за z-indexa помисли защо би ти бил необходим при hover? :) Аз не намирам смисъл, тъй като няма застъпващи се елементи. Естествено, ако решиш да промениш крайния му вид може да изпаднеш в ситуация, в която имаш нужда от него.
Колкото до картинките, там наистина трябва да се пипнат нещата. От самото начало не съм предполагал, че това меню ще може просто да се сложи някъде и пасне на 100%. Както е казал колегата горе - има доста решения на твоя проблем. Или си правиш отново картинки, подходящи за твоя дизайн, прозрачни изображения, CSS3 или изобщо не ползваш заоблени ъгли.
Малко късно се включвам, но имам една-две забележки, които искам да споделя.
Започвам със стиловете -- могат да се оптимизират селекторите. Примерно, когато си в UL, единственото място където ще е поместен дъщерен UL елемент е в LI т.е. не е нужно изрично да се указва, че стои UL LI UL, а може и само UL UL. Допълнително, в контекста на меню е малко вероятно да имаш UL с друго предназначение и може да се играе само с тагове.
Друго интересно е, че ползваш text-shadow за сянката на текста, но не и (-moz-|-webkit-)border-radius за закръгленията.
Но това са "козметични неща", така че ги оставям.
Относно скрипта: не съм jQuery-ист и не харесвам навързване на методи като свински черва, но ми се струва, че можеш да слееш 3 и 4 ред т.е. така и така метода върща обект с колекция от тези линкове, можеш директно да вкараш SPAN-овете.
Също, не видях стилове за fallback без пуснат скрипт. Ще попита някой "Ама то кой ще е без пуснат скрипт?" и отговора е принципен -- "Защото скрипта трябва да разширява функциите на CSS, където ги няма, но не и да ги изземва". Т.е. според мен на hover на LI, трябва да се добави клас за IE 6, понеже само този браузър не подържа hover на LI; респективно да се махне на leave. От там анимираш прозрачност от 0 към 1 и обратно, както и сетваш display в началото и края на анимацията.
Така ми се струва ще е най-правилно.
Въпроса за z-index е основателен. На няколко пъти съм забравял да добавям и в комбинация с последващи елменти с релативна позиция се получават интересни ефекти. Как точно, не съм сигурен, но се получава.
Няма значение кога се включваш, важното е, че наистина си вникнал в урока и имаш забележки, на които ще се опитам да отговоря :).
Първо, стиловете са написани по този начин, защото това е урок и искам читателите с по-скромни знания да успяват да проследяват последователността в действията.
Ползвам само text-shadow, защото дори без него менюто се възпроизвежда ОК. Ако сложа обаче border-radius, тогава автоматично елиминираме няколко браузъра и всички знаем кои са те :P. Освен това заоблени с border-radius ъгли заедно с бекграунд не е перфектната комбинация под всички браузъри.
За сливането на 3 и 4 ред си прав. Няма проблем когато са заедно, просто в случая ми се е сторило, че това са два отделни низа на веригата и съм ги разбил за по-голяма яснота.
За fallback-a ти написах един роман, но се усетих, че ще звучи прекалено обяснително и защитно, така че с две думи - такъв няма, защото това меню ще има версия 2. От самото начало беше предвидена, но искахме да направим експеримент. Просто има прекалено много хора, които взимат съдържанието на даден урок и го пляскат някъде, и то работи. Няма нищо лошо в това, дори се радваме, че творбите ни се ползват. Но нека не забравяме, че пишем уроци и искаме хората да размърдат малко мозъчетата си :). Радвам се, че ти си забелязал този "пропуск", но бъди сигурен, че във версия 2, 3 и т.н., менютата ще изглеждат в пъти по-завършени, по-оптимизирани и пр. Това ще бъде така, защото вече имаме база за сравнение.
За z-index се обосновах в коментара над твоя - просто в случая не виждам смисъл от него, а колкото по-малко пропъртита, толкова по-малък шанс да се счупи нещо.
Благодаря за критиката! Надявам се да има повече и да е градивна, като твоята, защото това ни кара да се замислим къде са ни грешките не само в кода, но и в начина на представяне на информацията :).