Annons:
Etikett05-css
Läst 10018 ggr
johan-ahlback
2010-10-22 17:29

Css drop-down med bonus

Bild 1. Klicka för att öppna i full storlek.

Jag ska visa hur man kan göra en drop-down meny med enbart html och css. När den är klar kommer jag visa hur man kan göra den bättre med lite jquery magi. I den här här artikeln antar jag att du kan lite grundläggande css och html. Om du inte hänger med ordentligt kan du kopiera all kod i slutet av artikeln så har du en fungerande meny. Men vill du lära dig så rekommenderar jag att du läser.

Varför skapar jag menyn i css innan jag börjar med jquery?

När man skapar en hemsida ska man inte lägga till javascript fören man vet att allt fungerar utan javascript. För det finns personer som inte har javascript aktiverat. Så om man skapar en fungerande meny i html och css först vet man att den kommer att fungera för alla.

Nackdelar med drop-down med css

Den största nackdelen är att de som använder internet explorer 6 inte kommer att se undermenyerna på grund av att internet explorer 6 bara kan ha :hover på länkar. Men de kommer att kunna använda menyn när man lagt till javascript.

Grunden för menyn.

För att kunna bygga en drop-down behöver vi en lista i html. För att skapa en undermeny behöver vi bara lägga en ul tagg i en li tagg. Till exempel:

Så här ser min html kod ut:

Jag har även två div element som du också kommer att behöva. Du ser dem högst upp och de är #access och .menu. Jag använder dem för att kunna bestämma bredd och annat i css.

Just nu ser det inte mycket ut för världen. Det är en vanlig lista bara. Så skapa ett css dokument så kan vi börja skriva css som gör att menyn ser ut och fungerar som den ska.

Först bestämmer vi bredd och bakgrundsfärg. Vi bestämmer även tecken storleken.

#access {
background: #000;
display: block;
float: left;
margin: 0 auto;
width: 940px;
}
#access,
div.menu {
font-size: 13px;
width: 928px;
}

Sen bestämmer vi att listorna inte ska någon list stil och att de inte ska någon margin.

#access ul{
list-style: none;
margin: 0;
}

Efter det säger vi att att list element ska flyta till vänster, vara relativt positionerade och ha en bredd på 100 pixlar. Anledningen till att vi vill att de ska flyta till vänster är att de hamnar på rad.

#access li {
float: left;
position: relative;
width:100px;
}

Om du kollar på menyn nu kan du se att vi är en bit på vägen:

Css drop-down med bonus 1

Nu bestämmer vi hur länkarna ska se ut. Line-height används för att få större yta på länken. Man kan använda padding men line-height har en tendens att bli lite bättre.

#access a {
color: #aaa;
display: block;
line-height: 38px;
padding: 0 10px;
text-decoration: none;
}

Nu ska vi fixa till alla listor som är nästlade. Vi anger skuggor för att få en snyggare effekt. Vi döljer dem och positionerar dem. Z-index gör så att de hamnar högst upp.

#access ul ul {
box-shadow: 0px 3px 3px rgba(0,0,0,0.2);
-moz-box-shadow: 0px 3px 3px rgba(0,0,0,0.2);
-webkit-box-shadow: 0px 3px 3px rgba(0,0,0,0.2);
display: none;
position: absolute;
top: 38px;
left: 0;
float: left;
width: 180px;
z-index: 99999;
padding:0;
}

nu ser vi till att de listor som är nästlade hamnar rätt. #access ul ul ul är den tredje nivån. Left gör så att de hamnar vid sidan av och inte under den listan som är förälder.

#access ul ul li {
min-width: 180px;
}
#access ul ul ul {
left: 100%;
top: 0;
}

Sen fixar vi länkarna i andra nivån-

#access ul ul a {
background: #333;
line-height: 1em;
padding: 10px;
width: 160px;
height: auto;
}

Nu kommer vi till det som internet explorer får problem med, vi ska använda hover på li element. Vi väljer alla a element som finns under ett li element som man hovrar över.

#access li:hover > a,
#access ul ul :hover > a {
background: #999;
color: #fff;
}

Nu till den sista biten som bestämmer att när man hovrar över ett li element som har en child som är en annan lista så ska den visas:

#access ul li:hover > ul {
display: block;
}

Nu är menyn klar.

Css drop-down med bonus 2

Kan man lägga till fler steg?

Ja det kan man men jag råder till att inte göra det. En tre stegs meny är användarvänligt men inte en fyra stegs. Det är bättre att organisera länkarna bättre.

Förbättra menyn med jquery.

Nu har vi en helt fungerande meny men den kan göras bättre med lite jquery magi. Så ladda ner jquery om du inte redan gjort det: http://jquery.com/. Länka in det genom att skriva det här i head taggen:

sen skapar du ett nytt js dokument och länkar in det på samma sätt.Det är i det dokumentet vi ska skriva all jquery.

Nya css klasser och bilder.

Vi ska lägga till lite klasser i css dokumentet som vi kommer att använda med jquery. Vi behöver en som stoppar att andra nivån öppnas vid hover och sen fyra klasser som vi kommer att använda till bilder:

/* klassen menuitem läggst till av jquery */
#access ul li.menuitem:hover > ul {
display: none;
}

span.opendown{
width:12px;
height:9px;
background: url(images/opendown.png) center center no-repeat;
display:inline-block;
margin-left:10px;
}
span.closeup{
width:12px;
height:9px;
background: url(images/closeup.png) center center no-repeat;
display:inline-block;
margin-left:10px;
}
span.openright{
width:9px;
height:12px;
background: url(images/openright.png) center center no-repeat;
display:inline-block;
margin-left:10px;
}
span.closeleft{
width:9px;
height:12px;
background: url(images/closeleft.png) center center no-repeat;
display:inline-block;
margin-left:10px;
}

bilden jag använder ser ut såhär:

Css drop-down med bonus 3

Sen har jag roterat den så att den ligger i alla fyra vinklar.

Ladda scriptet när sidan när DOM är redo.

Som vanligt när man ska manipulera DOM måste man vänta på att hela dokumentet laddat klart. Därför anväder vi document ready function. All jquery vi skriver ska skrivas innan den funktionen:

$(function(){
//koden här
});

Nu vet vi att scriptet inte körs fören DOM är klart. Nu ska vi ge alla top länkar klassen menuitem så att submenyerna öppnas vid hover:

$(".menu > ul > li").addClass("menuitem");

Där väljer vi alla li som ligger direkt under ul som i sin tur ligger direkt under menu.

Nu ska vi lägga till bilden som visas när en submeny är stängd. Vi vill att bilderna bara ska visas om det finns en submeny. Därför använder vi "has()" som kollar om elementet har en child. Sen letar vi efter det första a elementet och lägger till en span med ett klass namn som vi lagt till i css.

$(".menu > ul > li.menuitem").has("ul").find("a:first").append('');

Css drop-down med bonus 4

Nu ska vi fixa så att submenyn öppnas när man klickar på bilden. Jag använder toggle för att göra det så enkelt som möjligt. Om jag inte hade använt toggle hade jag fått använda två olika click event och kollat vilken klass span hade för att sedan andra klassen. Toggle gör det enkelt genom att man kan använda flera funktioner i toggle som körs varannan gång till exempel:

$("#knapp").toggle(function(){
gör något
},function(){
gör nått annat
});

Om man klickar på #knapp en gång kommer det första hända, den andra gången kommer nått annat hända. Klickar man igen kommer det första hända igen. Så här ser toggle ut för menyn:
Först väljer vi vad som man ska klicka på. I den första funktionen så har jag en hover funktion som ändrar css värde för ul. Om vi utelämnar den biten kommer det inte fungera på grund av #access ul li.menuitem:hover > ul {display: none;}. Listan skulle döljas igen på en gång. Sen letar vi på den ul som ska visas genom att använda this som är det element vi klickat på. Till sist ändrar vi klassen för span så att bilden ändras när man klickar på den. I andra funktionen döljer vi listan och andrar klassnamnet igen

//toggle funktion
$(".menu > ul > li > a span").toggle(function(){
//css fix
$(".menu > ul > li > ul").hover(function(){
$(this).css("display", "block")
})
//visar submenyn
$(this).parent().parent().find("ul:first").slideDown("fast");
//ändrar klass
$(this).removeClass("opendown").addClass("closeup");
},function(){
//döljer
$(this).parent().parent().find("ul:first").slideUp("fast");
//ändrar klass
$(this).removeClass("closeup").addClass("opendown");
});

Css drop-down med bonus 5

Nu ska vi lägga till bilder för de element som har submenyer i andra nivån:

$(".menu > ul > li > ul > li").has("ul").find("a:first").append('');

Nu ska vi använda hover för att ändra bild. Förman ska inte behöva klicka för att få upp tredje nivån. Hover kan ha två funktioner, en som är nar man hovrar in över elementet det andra när man hovrar ut:

$(".menu > ul > li > ul > li").has("ul").hover(function(){
$(this).find("a:first span").removeClass("openright").addClass("closeleft");
},function(){
$(this).find("a:first span").removeClass("closeleft").addClass("openright");
});

Css drop-down med bonus 6

Css drop-down med bonus 7

Nu är menyn helt klar. Den funger med och utan javascript aktiverat. Om man dock har ie6 och javascript avaktiverat fungerar den inte.

Exprimentera med det här och visa upp dem här under.

Alla koder:

html:
Css:

#access {
background: #000;
display: block;
float: left;
margin: 0 auto;
width: 940px;
}
#access,
div.menu {
font-size: 13px;
width: 928px;
}
#access ul{
list-style: none;
margin: 0;
}
#access li {
float: left;
position: relative;
width:100px;
}
#access a {
color: #aaa;
display: block;
line-height: 38px;
padding: 0 10px;
text-decoration: none;
}
#access ul ul {
box-shadow: 0px 3px 3px rgba(0,0,0,0.2);
-moz-box-shadow: 0px 3px 3px rgba(0,0,0,0.2);
-webkit-box-shadow: 0px 3px 3px rgba(0,0,0,0.2);
display: none;
position: absolute;
top: 38px;
left: 0;
float: left;
width: 180px;
z-index: 99999;
padding:0;
}
#access ul ul li {
min-width: 180px;
}
#access ul ul ul {
left: 100%;
top: 0;
}
#access ul ul a {
background: #333;
line-height: 1em;
padding: 10px;
width: 160px;
height: auto;
}
#access li:hover > a,
#access ul ul :hover > a {
background: #999;
color: #fff;
}
#access ul li:hover > ul {
display: block;
}

#access ul li.menuitem:hover > ul {
display: none;
}

span.opendown{
width:12px;
height:9px;
background: url(images/opendown.png) center center no-repeat;
display:inline-block;
margin-left:10px;
}
span.closeup{
width:12px;
height:9px;
background: url(images/closeup.png) center center no-repeat;
display:inline-block;
margin-left:10px;
}
span.openright{
width:9px;
height:12px;
background: url(images/openright.png) center center no-repeat;
display:inline-block;
margin-left:10px;
}
span.closeleft{
width:9px;
height:12px;
background: url(images/closeleft.png) center center no-repeat;
display:inline-block;
margin-left:10px;
}

Jquery:

$(function(){
$(".menu > ul > li").addClass("menuitem");

$(".menu > ul > li.menuitem").has("ul").find("a:first").append('');

$(".menu > ul > li > a span").toggle(function(){
$(".menu > ul > li > ul").hover(function(){
$(this).css("display", "block")
})
$(this).parent().parent().find("ul:first").slideDown("fast");
$(this).removeClass("opendown").addClass("closeup");
},function(){
$(this).parent().parent().find("ul:first").slideUp("fast");
$(this).removeClass("closeup").addClass("opendown");
});
$(".menu > ul > li > ul > li").has("ul").find("a:first").append('');
$(".menu > ul > li > ul > li").has("ul").hover(function(){
$(this).find("a:first span").removeClass("openright").addClass("closeleft");
},function(){
$(this).find("a:first span").removeClass("closeleft").addClass("openright");
});
});

Ålder föder inte visdom. Eftertanke gör det.

Värd för Trackmania iFokus och medarbetare på Hemsidor iFokus

MadeByJohan.se

Annons:
[Beavis]
2010-10-22 20:47
#1

hej johan

Tack för denna tutorial. Jag funderar bara på om du kunde lägga till någon liten text som klargör Vart koden skall läggas?

I eller ?

Bara några funderingar (jag e nog kvalificerad för html for dummies?)

johan-ahlback
2010-10-22 23:36
#3

script och style ska vara åtskilda. Dela hellst upp det i olika dokument och länka in dem istället.

screenshots finns den med ren css är under "Nu är menyn klar." och den med jquery finns innan all kod på slutet.

Ålder föder inte visdom. Eftertanke gör det.

Värd för Trackmania iFokus och medarbetare på Hemsidor iFokus

MadeByJohan.se

[Beavis]
2010-10-23 02:56
#4

ok jag har kört med stylesheets i dokumentet i head som du såg ovan. det är så jag gjort med css tidigare då jag  aldrig lyckats med separata stylesheets.

MichaelE
2010-10-23 18:01
#5

Ser att det finns css3 med i koden. Tyvärr är det ju bara två webbläsare hittills som stödjer både CSS3/html 5 fullt ut och det är ju opera och firefox 4. Påpekar bara, annars är det en intressant artikel. Kommer nog själv få användning av det någon gång.

johan-ahlback
2010-10-23 20:06
#6

box-shadow: 0px 3px 3px rgba(0,0,0,0.2);
-moz-box-shadow: 0px 3px 3px rgba(0,0,0,0.2);
-webkit-box-shadow: 0px 3px 3px rgba(0,0,0,0.2);

De här stödj av chrome, firefox 3.6, safari, opera(?) och internet explorer 9 beta. mycket av css3 fungerar i många webbläsare om man använder prefix.

Ålder föder inte visdom. Eftertanke gör det.

Värd för Trackmania iFokus och medarbetare på Hemsidor iFokus

MadeByJohan.se

Annons:
[Beavis]
2010-10-23 20:39
#7

Jag lyckas inte ladda ner jquery på sajten du loggade till??

När jag klickar på "Download" kommer det bara upp en massa kod i rutan…. skumt jag kör firefoxver. 3.6.11  IE 8,0.6001.18702 och har xp som OS. jag testar även i chrome ibland.

MichaelE
2010-10-23 20:57
#8

#6 jag syftade även html5. Visst stödjer de senaste webbläsarna css3 men IE9 kommer enbart, såvitt jag vet, till W7. Dåligt drag av MS men det gör fortfarande att tusentals personer blir tvungna att installera en annan webläsare än IE8 pga css3. Ska man bygga en hemsida som passar även de som använder XP (de är fler än vista) så borde man göra en sida uppbyggd med css2 ifall de inte vill installera någon annan webbläsare.

johan-ahlback
2010-10-23 22:37
#9

ingenting i css3 används för att skapa en sida. css3 används till olika effekter och den innehåller nya selektorer. Html5 är i princip samma sak. Jag bygger sidor i css nivå 2.1 för att sedan lägga till css3 nivå. Och det finns saker som gör att gamla webbläsare får stöd för de nya selektorerna, effekterna och html5. Så att man ska sluta göra sidor snyggare med css3 bara för att det finns vissa webbläsare som inte stödjer det låter inte så roligt.

Dessutom vill jag säga att css3 inte är en ny version av css utan bara en påbyggnad. css3 är tredje nivån. Gå in på min sida och kolla med ie6. Jag använder css3 där och det är inga problem

Ålder föder inte visdom. Eftertanke gör det.

Värd för Trackmania iFokus och medarbetare på Hemsidor iFokus

MadeByJohan.se

MichaelE
2010-10-24 00:18
#10

Okej. HTML5 vet jag är svårare med för jag har testat en och samma sida i olika webbläsare och IE9 kuggar ganska ordentligt på dem såhär långt.

Jag är medveten om att css3 är en påbyggnad, samma sak som html är en nyare version av html 4.01.

Men om de ändå fungerar så pass med gamla webbläsare så har jag inget mer att säga.

[Beavis]
2010-10-26 01:17
#11

jag lyckades ladda ner och installera jquery med IE(gick inte med ff) men det öppnades ändå en fil med js i dreamweaver?

Jag kör vidare iaf så får jag se hur det går?

Men måste fråga en grej om ni kan svara på det? Skall det vara en bild eller ett block över "menyraden" när jag öppnar filen i ff och chrom får jag ett tomrum ovanför menyn med några prickar i?

johan-ahlback
2010-10-26 02:57
#12

installera jquery? vad menar du med det?

Ta ett screenshot på menyn så kan jag lista ut vad som är fel.

Ålder föder inte visdom. Eftertanke gör det.

Värd för Trackmania iFokus och medarbetare på Hemsidor iFokus

MadeByJohan.se

[Beavis]
2010-10-26 14:10
#13

#12 ok ska försöka se vad jag kan göra med screenshots

Alltså som jag förstod det av din artikel behöver jag jquery installerad på min dator för att effekterna av koden skall synas?

Så jag gick in på adressen du refererar till och försökte ladda ner jquery. Det gick inte bra i firefox men däremot gick det i IE.

Den textmassa som dök upp på skärmen direkt när jag fösökte i Firefox dök upp när jag instalerat jquery på datorn istället men jag tror att det fungerar som det ska?

(Jag kan inte javascript så jag gör som det står i instruktionerna)

Annons:
MichaelE
2010-10-26 14:28
#14

jquery är en fil som ska ligga i målmappen för din hemsida, den länkas från html filen via

[Beavis]
2010-10-26 15:04
#15

Okej nu har jag en screenshot på min dropdown meny som den ser ut just nu med mitt js.

MichaelE
2010-10-26 15:19
#16

Det visar att det är fel i din css kodning, publicera gärna hela din kod så vi kan se var felet ligger.

johan-ahlback
2010-10-26 16:31
#17

du råkar inte ha en tom lista i html koden? det är det enda jag kan komma på. För om du har lagt till all css så ska det inte finnas list-style kvar.

Ålder föder inte visdom. Eftertanke gör det.

Värd för Trackmania iFokus och medarbetare på Hemsidor iFokus

MadeByJohan.se

[Beavis]
2010-10-26 21:18
#18

Jag håller på och pillar med det sista men har svårt att lokalisera vart visa av koderna skall ligga som ni kanske förstått av ,mina tidigare inlägg??

Nu undrar jag var denna raden skall ligga?                                   $(".menu > ul > li").addClass("menuitem");

i scriptet eller i html dokumentet? om det är i js scriptet är det alldeles först i det eller i slutet?

Sen har du delat upp jquery delen i två i "Alla koder". ska det var två separata jquery med de koderna?

Jag försöker följa instruktionena men e osäker och antagligen lite pantad? så jag behöver lite nogrannare förklaring.

jag är konfunderad


strecket i min skärmdump har jag lagt till på eget bevåg

Det är så här långt jag kommit btw

johan-ahlback
2010-10-27 01:41
#19

scriptet. Alla koder som är i slutet är javascript.

Om du har svårt att se skillnad på css och javascript ska du tänka såhär:
Utför koden en handling? då är det javascript.
Bestämmer koden hur något ska se ut? då är det css.

Ålder föder inte visdom. Eftertanke gör det.

Värd för Trackmania iFokus och medarbetare på Hemsidor iFokus

MadeByJohan.se

[Beavis]
2010-10-29 00:28
Bild 1. Klicka för att öppna i full storlek.
#20

#19 Jag har aldrig kört javascript och har altid lagt min css i