måndag 21 april 2008

CSS-nöt: Dynamisk "talande" webbplatsnavigering

Jag håller nu på med att utveckla en webbplats där jag vill ha en "talande" meny (se till exempel denna artikel i Smashing Magazine). Det innebär i princip att varje menyelement ska bestå av själva länknamnet plus en kortfattad beskrivning. Menyn ska vara horisontell och består bara av en nivå. Vidare vill jag att den presentationsmässigt ska vara helt dynamisk, så att jag kan generera den utifrån någon datakälla utan att jag manuellt behöver göra några inställningar för de olika menyelementen.

Det luriga är elementens bredd. Jag vill att varje menyelement (länk) ska vara precis så brett att länknamnet ryms på en rad - varken mer eller mindre. Beskrivningstexten ska anpassa sig till detta. Se exempel nedan:

Exempel på "talande" meny

Så vad är problemet? Strukturmässigt rör det sig om en länk som innehåller dels en rubrik och dels en beskrivning. Hur får man då länkens bredd att styras av rubriken, men inte av beskrivningstexten? Det har jag klurat lite på, men ännu inte hittat någon bra lösning. Dags för alla stylesheet-ninjor där ute att vakna ur slummern!

Några förslag? Jag kommer att uppdatera det här inlägget med den bästa lösningen som dyker upp.

11 kommentarer:

  1. Jag suger på CSS, och jag har ingen lösning. Däremot så hade det varit intressant att se hur du tänker tackla radbrytningar i fallet om något ord i beskrivningen har en bredd som är större än bredden på rubriken... :)

    (Fullösningen är givetvis att aldrig ha så långa ord).

    SvaraRadera
  2. En snabb lösning som använder javascript var det enklaste (och första) sättet jag kom på att lösa problemet. Nackdelen är förstås att det inte är ren CSS. Ytterligare en nackdel är att man kan hinna se att menyns styles förändras efter att sidan laddas (det kan förstås lösas genom att dölja menyn tills scriptet körts).

    La upp ett POC här: http://samuelsjoberg.com/samples/menu.html

    SvaraRadera
  3. Om vi ignorerar Internet Explorer så är det här en lösning:

    http://samuelsjoberg.com/samples/menu2.html

    SvaraRadera
  4. Gillar ditt andra förslag, Samme – det är även identiskt (mer eller mindre) med ett experiment jag gjorde tidigare ikväll. Tyvärr blir det svårt att ignorera IE.

    Javascriptlösningen är visserligen smidig, men jag hade helst använt en ren CSS-lösning. Frågan är om jag hellre tar en serversidelösning än Javascript? Typ definiera bredden på elementen i termer av antal tecken i "rubriken" eller något. Inte heller optimalt direkt.

    SvaraRadera
  5. Jag har ignorerat IE i flera år, det är jättelätt...

    SvaraRadera
  6. Sammes första POC fungerar förresten inte heller i IE7. Höjden blir helt galen på de olika delarna och bredden blir inte heller rätt.

    SvaraRadera
  7. Är det inte roligare att göra det så krångligt och ineffektivt som möjligt? Typ att generera menyelementen som bilder med världens längsta php-kod =). Svårt att ändra font då iofs. Men det går nog också.

    SvaraRadera
  8. För den nyfikne kan jag meddela att problemet med Sammes andra förslag i IE6 är att element "med layout" (exempelvis då width-styleattributet är något annat än auto) förlorar sin shrink-wrap-egenskap, och istället får den maximala bredden som finns tillgängligt i det första förälderelementet som har layout.

    Läste en del om det där i denna artikel.

    SvaraRadera
  9. Kul nöt!

    Sammes andra lösning är det jag instinktivt tänkte på, han löste det som jag tänkte, fast förmodligen mycket snyggare.

    Men kan du inte göra som man brukar göra om man vill ha t ex genomskinliga png:er? Om IE, javascripta. I övrigt, kör så det ryker med standard.

    SvaraRadera
  10. Irriterande det där. Försökte med någon slags first-child-grej och med att det ger olika absolute/relative-grejer, men... Det är svårt att lösa på andra sätt om man inte kan få tag på bredden.

    SvaraRadera
  11. Hmm, det slår mig nu att man kanske kan använda CSS embeddat javascript för att sätta bredden i MSIE. Att mitt första inlägg inte fungerar i IE7 låter troligt. Jag har antagligen använt fel metod att plocka ut width på elementet för just den obskyra webbläsaren.

    SvaraRadera