Grundlagen zur Gestaltung einer Navigation per CSS

Die Funktion printNavigation() ist in ConPresso4 die Basis fuer die Ausgabe der Navigationselemente. Sie gibt abhaengig von den uebergebenen Parametern eine "unsortierte Liste" (<ul>) aus, die mit geeigneten CSS-Definitionen auf nahezu beliebige Weise formatiert werden kann.

Die Idee hinter der Verwendung einer Liste ist die, dass HTML-Elemente heutzutage nicht mehr fuer Layout zweckentfremdet werden sollten. Leider haben sich in den letzten Jahren aufgrund von Browser-Einschraenkungen und -Inkompatibilitaeten viele Unsitten eingebuergert. Das bekannteste Beispiel hierfuer ist die Verwendung von Tabellen fuer die Erstellung des Basis-Layouts einer Seite.

Bei der Programmierung von modernem (x)HTML wird jedoch wieder mehr auf die Trennung von Layout und Inhalt geachtet. Webseiten werden durch <div>-Elemente in Bloecke wie Header, Navigation, Inhalt und Footer geteilt. Inhalte werden durch die Verwendung von Ueberschriften h1, h2, usw. gegliedert. Und HTML-Elemente werden fuer den Zweck benutzt, fuer den sie gedacht waren: Tabellen fuer tabellarische Daten, usw.. Und da eine Navigation nun mal eher einer verschachtelten Liste entspricht als einer Tabelle, wird sie in ConPresso auch als Liste ausgegeben.

Das Ziel ist die Schaffung von Websites, deren Inhalt getrennt vom Aussehen gehandhabt wird. Hierdurch kann durch einfache Aenderung der CSS-Definitionen das gesamte Aussehen der Website geaendert werden. (Ein sehr beeindruckendes Beispiel hierfuer ist der CSS-Zengarden. Die Seite basiert auf immer demselben Code, der nur durch unterschiedliche Stylesheets anders formatiert wird.)

Ein - natuerlich nicht ganz unerwuenschter - Nebeneffekt ist, dass die Seite so auch gaenzlich ohne CSS dargestellt werden kann. Das ist dann zwar nicht mehr "huebsch", bringt aber einen enormen Schub im Bezug auf die Barrierefreiheit.

Soviel zu der Frage "Wieso Listen?", die mir des oefteren gestellt wurde. Kommen wir zu den Beispielen, wie man Navigationen in ConPresso aufbauen kann.

Aus Gruenden der Einfachheit kann hier nur die Basis der Formatierungsmoeglichkeiten gezeigt werden. Vielleicht gibt es CSS-Profis, die Ihre Beispiele mit einer kurzen Erklaerung hier beschreiben koennen, um anderen ein wenig Inspiration zu geben, welche Moeglichkeiten es gibt. Das waere dann natuerlich auch eine Hilfe fuer die Anwender, die keine Experten in HTML und CSS sind.

Basis aller folgenden Beispiele ist eine in ConPresso angelegte Navigation mit dem folgenden Aufbau:

Beispiel 1:

Das einfachste Beispiel gibt nur die verschachtelte UL-Liste aus, die dann in den folgenden Beispielen mit CSS formatiert wird:

 <div id="navigation1">
     <?php printNavigation(); ?>
 </div>

Beispiel 2: einfache Formatierung

Die Ausgabe unterscheidet sich nur ein wenig von der in Beispiel 1: Die Listen-Punkte wurden entfernt und die Einrueckung ein wenig kleiner gesetzt. Ausserdem wird das aktive Element blau dargestellt.

 <div id="navigation2">
     <?php printNavigation(); ?>
 </div>

Nur der neu eingesetzte CSS-Code sorgt hier dafuer, dass das ein bischen weniger wie eine Liste aussieht.

Aktive Elemente werden durch printNavigation() als '<li class="active">' ausgegeben und koennen so gesondert formatiert werden.

 <style>
    #navigation2 {border: 1px solid #000; padding: 1em;}

    #navigation2 ul {margin: 0; padding: 0; list-style-type: none;}
    #navigation2 li {margin: 0; padding: 0;}

    #navigation2 li a {margin: 0; padding: 0; color: #000;}

    #navigation2 li li {padding-left: 1.5em;} /* erst die zweite Ebene einruecken */

    #navigation2 li.active a {color: #00c;} /* jede aktive Ebene einfaerben */
    #navigation2 li.active li.active a {color: #00c;}
    #navigation2 li.active li.active li.active a {color: #00c;}

    #navigation2 li.active li a {color: #000;} /* eine nicht aktive Unterebene wird in der
                                                  urspruenglichen Farbe dargestellt */
 </style>

Beispiel 3: Anzeige nur einer Ebene - horizontal

Soll nur eine Ebene anzeigt werden, ist dieses durch den dritten Parameter von printNavigation() moeglich. Dieser Parameter schraenkt die Anzahl der auszugebenden Ebenen ein.

In diesem Beispiel wird nur die "Haupt"-Navigation ausgegeben und per CSS horizontal formatiert:

 <div id="navigation3">
     <div id="haupt">
         <?php printNavigation('', 0, 1); ?>

         <!-- noetig, damit es unterhalb der mit "float" formatierten LI-Elemente weitergeht -->
         <div style="clear: both;"> </div>
     </div>
 </div>

Das dazugehoerige CSS:

 <style>
    #navigation3 {border: 1px solid #000; padding: 1em;}

    /* Ebene 1 */
    #navigation3 ul {margin: 0; padding: 0; list-style-type: none;}
    #navigation3 #haupt li {margin: 0; padding: 0; float: left; display: inline; margin-right: 1em;}
 </style>

Beispiel 4: Nur eine Unternavigation

Natuerlich sollte man nicht vergessen, auch eine Unternavigation auszugeben :-).

Die Funktion printNavigation() erlaubt das Setzen eines vierten Parameters. Dieser Parameter entspricht der ID der uebergeordneten Navigationselementes. Es werden dann nur die Unterpunkte dieses Elementes ausgegeben.

Ueblicherweise moechte man dieses abhaengig vom gewaehlten Haupt-Navigationspunkt ausgeben. Hierzu ist die Benutzung einer neuen Funktion von ConPresso noetig: getActiveElements(). Diese Funktion liefert ein Array der aktiven Ebenen zurueck.

Allerdings hat diese Funktion eine Einschraenkung: Die gerade aktive Ebene kann nur anhand der Rubrik-ID herausgefunden werden. Wird eine Rubrik in der Navigation mehrfach verwendet, wird nur das erste Auftreten dieser Rubrik gefunden. Sollte eine Navigation also dieses Feature nutzen wollen, ist darauf zu achten, dass jede Rubrik nur ein mal in der Navigation verwendet wird. Ein moeglicher Workaround hierfuer ist die Nutzung einer "externen URL" in der Navigation, die als einfacher Link auf die Rubrik zeigt.

 <div id="navigation4">
     <div id="unter">
         <?php
         $ae = getActiveElements();
         if (isset($ae[1])) {                   // nur ausgeben, wenn es eine aktive erste Ebene gibt
             printNavigation('', 0, 1, $ae[1]); // es wird wieder nur eine Ebene ausgegeben (die zweite)
         }
         ?>
     </div>
 </div>

Der dazugehoerige CSS-Code:

 <style>
    #navigation4 {border: 1px solid #000; padding: 1em;}

    #navigation4 ul {margin: 0; padding: 0; list-style-type: none;}
 </style>

Beispiel 5: Kombination horizontale Haupt- + vertikale Unternavigation

Dieses Beispiel ist eine einfache Kombination von Beispiel 3 und 4:

 <div id="navigation5">
     <div id="haupt">
         <?php printNavigation('', 0, 1); ?>

         <!-- noetig, damit es unterhalb der mit "float" formatierten LI-Elemente weitergeht -->
         <div style="clear: both;"> </div>
     </div>

     <div id="unter">
         <?php
         /* Hier wird getActiveElements() benutzt, um bei der Unternavigation
          * nur die Unterpunkte der aktiven "erste Ebene" ($ae[1]) auszugeben.
          *
          * Verantwortlich hierfuer ist der vierte Parameter von printNavigation()
          */
         $ae = getActiveElements();
         if (isset($ae[1])) { // nur ausgeben, wenn es eine aktive erste Ebene gibt
             printNavigation('', 0, 1, $ae[1]); // es wird wieder nur eine Ebene ausgegeben (die zweite)
         }
         ?>
     </div>
 </div>

Der dazugehoerige CSS-Code:

 <style>
    #navigation5 {border: 1px solid #000; padding: 1em;}

    #navigation5 ul {margin: 0; padding: 0; list-style-type: none;}

    /* Ebene 1 */
    #navigation5 #haupt li {margin: 0; padding: 0; float: left; display: inline; margin-right: 1em;}

    /* Ebene 2 - fast ohne Formatierung */
    #navigation5 #unter {margin-top: 1em;}
 </style>

Beispiel 6: Ein Kessel buntes + Hover-Effekt

Ein wenig "buntes" gefaellig, das nebenbei auch noch mit einem kleinen Hover-Effekt ausgestattet ist - ohne jegliches Javascript?

Code:

 <div id="navigation5">
     <?php printNavigation('', 0, 1); ?>
 </div>

CSS:

 <style>
    #navigation6 {border: 1px solid #000; padding: 1em;}

    #navigation6 ul {margin: 0; padding: 0; list-style-type: none;}

    #navigation6 a {
        padding: 0.5em;
        margin: 0.5em 0;
        display: block;
        width: 200px;
        background: #00c;
        color: #fff;
        border-left: 1em #ee0 solid;
        text-decoration: none;
    }
    #navigation6 a:hover {
        border-left: 1em #0ee solid;
    }
 </style>