Verticaal uitklapbaar menu (zonder java)

Status
Niet open voor verdere reacties.

damnsharp

Terugkerende gebruiker
Lid geworden
6 jan 2012
Berichten
1.414
Kan je een uitklapbaar menu zonder java maken met visibility en display tags en misschien nog wat meer?
Plaatje: website_submenu.PNG
Ik ben op weg, heb express menu wat naar rechts gezet anders nauwelijks zichtbaar maar het gaat nog niet goed want menu items onder menu moeten ook omlaag gaan natuurlijk.
linkje testwebsite
 
Hoi damnsharp,
  • Een uitklapmenu maken met de visibility-eigenschap is in dit geval geen goed idee: bij een {visibility: hidden;} blijft altijd de door het element ingenomen ruimte bestaan, en is alleen leeg ("Invisible boxes still affect layout", zie de css-specs). Dat zou dus gaten in het menu veroorzaken op de punten waar sub-menu's bij de hover moeten komen.
  • Een uitklapmenu maken met de display-eigenschap is ook geen goed idee: bij een {display: none;} kan dat ontoegankelijkheid veroorzaken en/of kan de link niet opgemerkt worden door Google. Interpretatie display:none = "ik besta niet". Maar pure text-browsers of voorlees-browsers en de Google-bot kunnen niet hoveren om een {display: block;} op te roepen en daar verder mee te komen.

Dat is wat niet de aangewezen weg is. ;)
Wat dan wel?
De buitenboord-motor met positionering!
  • Je kan de sub-<ul>'s voor de ongehoverde toestand een {position: absolute; left: 0; margin-left: -9999px;} meegeven, dan staan ze buiten beeld en nemen ook geen plek in. Voor pure text-browsers en voor de Google-bot zijn ze dan nog steeds zichtbaar (die trekken zich van deze css niets aan).
  • Voor de hover-toestand moeten ze dan in dit geval wel weer een {position: relative;} krijgen, dan komen ze onder de <li> waar ze deel van uitmaken, en niet ernaast of over de andere items heen. En de margin-left wordt weer op 0 of naar smaak iets naar rechts gezet.
  • Verder speelt in jouw test-opmaak, dat de alle list-items <li> een vaste hoogte hebben gekregen: #subnav li {height: 30px;}. Dus ook de list-items die een submenu moeten herbergen met een <ul> en daar weer <li>'s in. Die passen dus nooit in die 30px hoogte, want elke <li> uit zo'n submenu is ook al 30px hoog! > De #subnav li {height: 30px;} moet geschrapt worden, dan kunnen ze er wel in.
  • Vervolgens zouden ze met jQuery of een minder zwaar zelfbouw-javascriptje accordeon-uitrolbaar gemaakt kunnen worden, zoals je stelde in je andere vraag.

Met vriendelijke groet,
CSShunter
 
Kijk mooi CSShunter, :thumb:, het begint er met het menu steeds meer op te lijken. Wat stom dat ik niet heb gedacht aan position absolute/relative. Daarmee is meer mogelijk dan ik gebruik. Ik kon me eerst al bijna niet voorstellen hoe ik met CSS wat in een menu zou kunnen omlaag kunnen schuiven zonder dat daar javascript of jquery aan te pas komt. Die laatste werkt misschien mooier maar hoeft niet persé denk ik. Als ik dit met CSS kan oplossen ook goed. Kan ik die WordPress plugin vraag laten vervallen, aan de andere kant om te weten hoe het met jquery kan vind ik ook wel leuk.
Mijn vorderingen: kijk hier
Ik heb ul li:hover ul een postitie relative gegeven en een left -20px; Dat margin-left: -9999px; gebeuren er wat gekke dingen. Snap dat -9999px ook niet.

De navigatie li met line-height: 30px; zorgt al voor de hoogte dus, is inderdaad die height niet meer nodig, goed opgemerkt.

Verder nog paar dingen aangepast zoals je zei maar het loopt nog niet helemaal gesmeerd. Bijv. submenu 3 is nu niet aanklikbaar.
En... site geeft bij IE problemen menu boven en menu links problemen. Heb gechecked op http://validator.w3.org/ = ok en http://jigsaw.w3.org/css-validator/ = ok
Kan je daar een tip voor geven?

(stom trouwens dat bliksekaters.nl is gehackt, staan leuke tips op)
 
Hoi damnsharp,
In je huidige testpagina lijkt het wel alsof de subsub's er niet zijn als je niet hovert, maar in werkelijkheid zijn ze er wel! :rolleyes:
  • Ze worden alleen (omdat ze een absolute positie hebben) bedekt door de volgende <li>'s die in de normal flow zitten: de "submenu 3" en "submenu 4".

Dat kan je zien als je deze "submenu 3" en "submenu 4" weghaalt: dan staat de subsub-<ul> met zijn twee grijze <li>'s ook zonder een hover op dezelfde plaats.

submenu-sub-sub.png

Om deze reden verschijnen ook de subsub's als je helemaal niet over de bijbehorende "nog een submenu" hovert, maar als je van onder het blokje af naar boven muist: dan komen de twee subsub's al tevoorschijn als je over de "submenu 3" hovert! :eek:

======
Hier komt de margin-left van -9999px om de hoek kijken. Deze zorgt ervoor (tezamen met de absolute positie) dat de subsub-<ul> 9999px links van de linkerkant van het blok komt te staan (en verticaal geen ruimte inneemt voor de rest van het blokje).
Maar op -9999px is er geen beeldscherm! :D (er staat misschien een kopje koffie)

Dan is de subsub-<ul> dus ook niet los te behoveren, en kan pas een rol gaan spelen als de absolute positie en de -9999px worden weggehaald.


  • Absolute positie weg = grijze items komen verticaal onder hun parent-element "nog een submenu" te staan, en schuiven daarmee naar onderen wat er onder staat (de "submenu 3" en "submenu 4").

  • De -9999px weg = het grijze blokje komt weer achter het kopje koffie vandaan en staat weer op het scherm op de goede horizontale L/R-positie.

Maak er maar eens dit van:
Code:
#subnav ul ul {
    position: absolute;
    left: 0;
    margin-left: -9999px;
    } 
#subnav ul li:hover ul {
    position: relative;
    margin-left: 0; 
    }

Verder zou ik aan de #subnav li a een {display: block;} toevoegen, en de L/R-paddings van de <li>'s overhevelen naar deze <a>'s. Dan is steeds de hele knop behoverbaar met verandering van de tekstkleur en/of background-kleur (en niet alleen over de lengte van de link-tekst).

Tegen het verticaal komen te staan van de items van het horizontale topmenu in IE7 zou ik eens proberen alle eigenschappen van de #nav {...} tot eigenschappen van de #nav ul {...} te maken; de absolute positie van de #nav zal IE7 waarschijnlijk de das om doen. Met een beetje geluk komen dan ook tegelijk het submenu-blokje en de content op hun goede plaats in IE7.

Met vriendelijke groet,
CSShunter
 
Bedankt CSShunter. Een gedeelte snap ik :) maar een ander gedeelte niet :confused:. Ik ga het zo bekijken en dingen uitproberen en kom er dan op terug. Met jouw uitleg :thumb: uitgeprint en nalopend kom ik er vast uit. Bericht je straks terug.
 
Phoei, was een heel gepuzzel om het te snappen maar... het is wel nu duidelijker geworden. Heb erg moeten lachen om dat kopje koffie :)
Ik ben begonnen in de html die submenu 3 en 4 weg te halen en toen viel er wat kwartjes op zijn plaats. Ik heb het menu iets helderder in tekst gemaakt en aanpassingen gedaan zoals je voorstelde.
Ik zie weinig verschil als display block erbij zit maar wel dat het directer werkt. Ook waarom ik de L/R paddings van de li's moet overhevelen naar de a's zie ik niet maar werkt wel. :cool:

Vreemd, het verticaal gaan van menu gaat nog niet goed met dat #nav of ik snap niet wat je precies bedoelt. Ik heb #nav aangepast aan #nav ul maar geen verschil dus maar terug gezet.

Nou, we zijn er bijna en een menu in CSS valt nog niet altijd mee merk ik wel :o
 
Links: inline en block

Hoi damnsharp,
Hier de nadere verklaring.

Ik zie weinig verschil als display block erbij zit.
Zie het tekeningetje:
menu-link-inline-en-block.png

Standaard heeft een link binnen een ander element een "inline"-karakter, dwz de link heeft een oppervlak dat L/R niet verder gaat dan de lengte van de tekst + de eventuele paddings L/R van de link.

Dit is het bovenste item: geel is de 20px brede padding aan weerszijden, het groene kadertje is het link-oppervlak.
Naast het groen (het rood gearceerde gedeelte is dan geen link, dwz als je er overheen hovert reageert de link niet: geen reactie op klikken, en geen verandering van de link-kleur.
  • NB: Het handje dat wel verschijnt als je zonder de {display:block;} over het rood gearceerde deel hovert is schijn die bedriegt: de <li> om de <a> heen heeft in je css een {cursor: pointer;} die daarvoor zorgt, maar daarmee is het nog geen hoverbare&klikbare link geworden! Het handje van de <li> in het rood gearceerde deel doet dan helemaal niets!

Geeft je nu een {display: block;} aan de links, dan krijgen ze een "block"-karakter, dwz de link heeft het oppervlak zo breed als het omringende element toestaat (met daarbinnen de paddings L/R van de link).
Dat is het tweede item in de tekening: de link is nu over de hele breedte aanklikbaar en van kleur verschietend. :)
  • NB: De {cursor: pointer;} kan dan ook met een gerust geweten uit de <li> geschrapt worden: de <a>'s hebben dezelfde breedte, en die hebben uit zichzelf al de pointer.

=======

Waarom ik de L/R paddings van de li's moet overhevelen naar de a's zie ik niet.
Een padding hoort bij het element zelf, en als je de paddings op de <li>'s hebt staan, begint de <a> erbinnen pas nadat de linker-padding van de <li> is opgehouden, en eindigt al voordat de rechter-padding van de <li> begint.
Betekent: in de padding-gebiedjes van de <li> zit géén link: de link is dus daar niet aanklikbaar.

Dat is het onderste item van de tekening: de gele padding van de <li> staat buiten de link, en op de uiteinden van het item kan de link dus niet reageren.
Verplaats je de padding naar binnen de link zelf, dan telt deze wel mee voor het aanklikbare oppervlak, maar evengoed begint en eindigt de tekst waar de L-padding ophoudt en de R-padding begint.
Zo wordt het weer item 2 van de tekening. :)

=======

Het verticaal gaan van menu gaat nog niet goed met dat #nav
Zal ik nog even naar kijken, want niet uitgetest in IE7.

=======

een menu in CSS valt nog niet altijd mee merk ik wel
Klopt, want in een css-uitklapmenu spelen zowel alle kenmerken van het css-boxmodel *) als die van de relatieve en absolute positionering. En vaak zijn er ook nog floats bij.
Dan heb je alle knooppunten van css wel zo ongeveer te pakken!

Wordt vervolgd!
CSShunter
____________
*) Daarom is een Doctype zo belangrijk: zonder Doctype schiet Internet Explorer in de quirksmode:
de fratsen-toestand van IE5 die er een andere boxmodel op na hield. :confused:
 
Jeetje, je moet het allemaal maar weten ;) Maar fantastische tekening, met de tekst erbij verklaart dat een heleboel. Ik ga beginnen met dat cursor pointer weg te halen want snap dat het niet meer nodig is en die paddings naar de li's vind ik nu ook logisch.
Ik ga het css-boxmodel uitpluizen.
 
Hoi damnsharp,
Dan hier de IE7-toestand. Bij mij is je testpagina in IE7 nog steeds niet in orde (en volgens browsershots.org ook niet; zie hier). :confused:

bolletjes-ie7.png

Ik heb dit alternatief gebakken: dubbelmenu.htm
Op het oog identiek aan je testpagina (op de groene tekst in de bolletjes na), maar niets is minder waar. ;)

Hoe aangepakt
Kritiek voor IE7 is de {display:block;} van de links, als die in een list-item staan dat inline is.
Verder probeer ik altijd (als het maar enigszins mogelijk is) om {position: absolute;} voor elementen te vermijden.
En dat kan hier. :)


  • Eigenlijk kan de hele #header-div gemist worden.
  • Het linkerlogo kan er direct links-floatend in.
  • Het rechterlogo hoeft niet te floaten, en kan met een margin-left aan de rechterkant gezet worden.
  • Dan komt de #nav.
  • Die hoeft niet in een <div id="nav"> verpakt te worden: een <ul id="nav"> is genoeg.
  • Deze #nav krijgt een {clear: left;} om onder het linkerlogo te komen, wordt ook links gefloat, en krijgt een negatieve magin-top om 'm hoger te trekken dan de onderkant van het rechterlogo.
  • Om het meest rechtse bolletje bovenop te krijgen op het overlap-punt met het rechterlogo, wordt een {z-index: 1;} aan de #nav toegevoegd (en een {position: relative;} die nodig is om een z-index van kracht te laten worden).
  • De list-items van de #nav krijgen een {float: left;}, waarmee IE7 gered is.
  • Daarmee worden bovendien de spleetjes gedicht die optreden als ze inline staan, en die bij langzaam L-R hoveren even een flits van twee witte bolletjes veroorzaken ipv om te klappen naar het groen van de volgende:

li-spleetje.png


  • De class="menu-button" voor de <li>'s is niet nodig: deze kunnen gewoon via #nav li {...} bereikt worden, en de links erin via #nav li a {...}.
  • Om de bolletjes en het klik-oppervlak precies symmetrisch te krijgen (de tekst staat al op {text-align: center;}), wordt het background-image op een horizontale positie van 50% gezet, en de asymmetrische L-padding en R-padding uit de links gehaald.
  • Nu is de switch tussen het hoveren over het ene en het andere bolletje steeds precies in het midden tussen twee bollekes:

bolletjes-symmetrie.png


  • De #wrapper krijgt nu een {clear: both; padding-top: 25px;} om de linkerkolom en de content op de goede hoogte er onder te krijgen (een aparte clearing-div is niet nodig).
  • Tenslotte heb ik de link-tekst in de normale toestand groen ipv wit gemaakt, want het wit op het grijze bolletje heeft veel te weinig contrast om voor alle bezoekers zichtbaar en toegankelijk te zijn. Zie in ander topic: Voldoende contrastverschil !

Nog wat aanvullende toelichtinkjes staan verder in de css van de broncode.

Met vriendelijke groet,
CSShunter
 
Laatst bewerkt:
Beste CSShunter, reactie op jouw uitleg. Met paar vragen maar vooral dank! :)
Ik loop het ook even punt voor punt door.

  • #header: kan gemist worden. Dat is dan denk ik nu omdat ik ook een #middenkolom div heb die alles al in bedwang houdt?
  • rechterlogo: is een float niet handiger dan een margin-left van 775px?
  • div id=nav: kijk, met een ul id=nav werkt het dus ook, weer wat bijgeleerd ;)
  • Goh, die inline-spleetjes bij #nav li was me nog niet opgevallen maar is inderdaad beter hiermee! :)
  • {z-index: 1;} begrijp ik niet, in commentaar zet jij: om bovenste helft v/h bolletje boven de link van het rechterlogo te laten komen -> heeft dat weer met IE te maken?
  • Perfect, contrastverschil is nu beter met kleur groen. Moet de ontwerpster ook nog aan wennen zo te zien.
  • Die aparte class bij de nav li is nog een erfenis van een ander bolletjes menu met verscillende kleuren. Inderdaad kan nu weg.
  • Ah mooi, de buttons zijn nu inderdaad netjes niet meer asymetrish aan te klikken maar "gewoon". Er was wel een reden waarom ik die 10px had toegevoegd maar weet die nu zelf ook niet meer.
  • Die #wrapper toevoegingen moeten nu natuurlijk omdat de header is weggevallen lijkt mij toch?

---

Nog een vraag over het menu, is het mogelijk om het sub-submenu uitklapbaar te laten als erop geklikt wordt?
 
Hoi damnsharp,
En de reactie op de reactie:
  • Misbare #header: inderdaad vanwege de middenkolom-div.
  • Rechterlogo-float: zou ook kunnen.
  • De z-index: is voor alle browsers, niet alleen IE. Dit is het rechterlogo-gebied:

rechterlogo-gebied.png


  • De bolletjes-strook komt weliswaar later in de html, maar door het floaten ervan zit die toch eronder in de stapeling van de laagjes. Met de z-index wordt dat weer opgeheven. - Als ook het rechterlogo wordt gefloat, heb je de z-index waarschijnlijk niet nodig.
  • Toevoegingen #wrapper: helemaal juist, wegens de weggevallen #header (met z'n hoogte).

=======

Uitgeklapt subsubmenu na de klik
Ja, dat kan. Het zal steeds op de verse pagina geregeld moeten worden.
Ik vemoed zo dat de vervolgvraag zal zijn: hoe dan? ;)

Bv. de pagina van submenu-sub1a krijgt in z'n html van het menu een class="current":
HTML:
<!-- start subnav -->
    <div id="subnav">
        <ul>
            <li><a href="#">submenu 1</a> </li>
            <li><a href="#">nog een submenu2</a>
                 <ul class="current">
                     <li><a href="#">submenu sub1a</a></li>
                     <li><a href="#">submenu sub1b</a></li>
                 </ul>
            </li>
            <li><a href="#">submenu 3</a></li>
... enz.
  • NB: de class="current" komt op de <ul> boven de pagina-van-dienst, want z'n parallel-subsub pagina's moeten ook zichtbaar blijven!
  • Vervolgens laat je die current-class hetzelfde doen als wat bij de hover gebeurt:
Code:
#subnav ul.current {
    position: relative;
    margin-left: 0px; 
    }

Met vriendelijke groet.
CSShunter
__________
PS: Er zit nu twee keer een class="current" op zo'n pagina: eentje voor het goede groene bolletje, en eentje voor het uitklapmenu. Maar omdat de ene geregeld wordt met #nav li.current (enz.) en de andere met #subnav ul.current kunnen die elkaar niet bijten.
 
Laatst bewerkt:
Het is bijna helemaal helder CSShunter! Ik heb de status op opgelost gezet. Dat z-index zoek ik nog op internet op want is me nog niet helemaal duidelijk.
Nogmaals kei bedankt :thumb:
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan