Startseite  •  Tutorials  •  CSS-Menü 01

Horizontales CSS–Menü mit horizontalem Submenü

Zu jeder Webseite gehört ein Menü, in der Regel jedenfalls. CSS bietet die Möglichkeit zahlreiche Menüs verschiedenster Arten zu erstellen. Dabei kann für einen Mouseover-Effekt auch auf JavaScript verzichtet werden. Ein elegantes horizontales Menü soll in diesem Tutorial vorgestellt werden. Das fertige Beispiel ist hier zu sehen.

Buttongrafiken in GIMP erstellen

Für den Bildwechsel benötigen wir zwei kleine Buttongrafiken, die wir in GIMP herstellen.

Zunächst erstellt ihr in GIMP ein neues Dokument mit der Größe von 104 Pixel Breite und 28 Pixel Höhe. Über der Hintergrundebene fügt ihr eine neue Ebene mit dem Namen verlauf ein. Anschließend wählt das Auswahl-Werkzeug aus, stellt eine Größe von 100 x 28 Pixel ein und zieht vom Nullpunkt eine Auswahl auf.

feste Auswahl

Ihr wechselt bei laufender Auswahl zur Anzeige für Vorder –und Hintergrundfarbe. Dort stellt ihr eine beliebige Vordergrundfarbe, hier ein Grau-Blau, ein und als Hintergrundfarbe wird Weiß ausgewählt. Mit dem Verlaufs-Werkzeug zieht ihr von oben nach unten den Verlauf und hebt danach die Auswahl wieder auf.

Verlauf ziehen

Erstellt eine neue Ebene mit dem Namen licht. Mit dem Auswahlwerkzeug zieht ihr, wieder vom Nullpunkt aus, eine Auswahl von 100 x 20 Pixel auf. Tauscht die Vorder- mit der Hintergrundfarbe, so dass Weiß die Vordergrundfarbe ist. Im Verlaufwerkzeug wird als Verlauf  VG nach Transparent eingestellt und zieht anschließend etwas unterhalb der oberen Kante bis zum unteren Ende der Auswahl einen Verlauf. Danach kann die Auswahl wieder aufgehoben werden.

Transparenzverlauf

Buttonlicht

Nun kommt noch eine neue Ebene, die wir rand nennen. Dort wird der Rand des Buttons gezeichnet. Dies werden wir mit dem Bleistift-Werkzeug machen. Sucht euch dunkles Grau als Vordergrundfarbe aus und stellt die Werkzeugspitze des Bleistifts auf 1 Pixel mit harter Kontur. Nun ist ein ruhiges Händchen gefragt. Zieht einen Rahmen, wie auf dem Bild zu sehen ist, um den Button herum. Stellt die Vordergrundfarbe wieder auf Weiß und zieht noch mal zwei Linien, eine links neben und eine oben unterhalb der dunklen Linie.

Rahmenlinie

Soweit sieht das schon ganz gut aus. Wir werden den nur noch ein wenig verfeinern. Wechselt in die Ebene verlauf und wählt das Radier-Werkzeug aus. In den Eigenschaften wird die Größe auf Circle (1) gestellt. Radiert die drei Pixel in den oberen Ecken weg. Dasselbe wird auch in der Ebene licht gemacht. Nun stellt die Ebenentransparenz der Ebene licht auf 80%. Zum Schluss fügen wir noch einen Schlagschatten ein. Den findet ihr unter Script-Fu -> Schlagschatten. Dieser wird auf die Ebene verlauf angewendet und erstellt automatisch eine Ebene unterhalb des Verlaufs. Wählt die Einstellungen des Beispiels und deaktiviert die Option Größenänderung zulassen.

Schattenoptionen

Nun kann das Dokument gespeichert werden, beispielsweise als button_out.xcf. Damit haben wir einen Button im Normalzustand. Wir brauchen aber noch eine Variante für Hoverzustand, also wenn die Maus über den Button fährt. Also wird die Datei noch mal mittels Speichern unter … als button_in.xcf gespeichert. Aktiviert die Ebene verlauf, stellt das Auswahl-Werkzeug erneut auf 100 x 28 Pixel ein.

Button_in

Die Vorder- und Hintergrundfarben des Verlaufs müssen nun vertauscht werden.

Farbtausch

Zieht bei laufender Auswahl den neuen Verlauf von oben nach unten und hebt die Auswahl wieder auf. Mit dem Radierer müssen noch mal die paar Pixel oben entfernt werden. Die Ebene licht wird auf 60% gestellt und das Dokument gespeichert. Soweit unsere Vorlagen. Vielleicht solltet ihr euch sicherheitshalber eine Sicherungskopie der beiden Dateien erstellen, denn für den Export werden die Ebenen zu einer Ebene zusammengefügt.

Für das Zusammenfügen der Ebenen wählt ihr die oberste Ebene aus und ruft über die rechte Maustaste das Ebenenkontextmenü auf. Mit der Option sichtbare Ebenen vereinen werden die Ebenen auf eine Ebene zusammengefasst.

Für den Export des Bildes wählt ihr wieder das Auswahlwerkzeug mit den Einstellungen 100 x 28 Pixel aus und zieht eine Auswahl vom Nullpunkt ausgehend auf. Die Auswahl wird mit Strg+C kopiert und ein neues Dokument mit Strg+N erstellt. Die Auswahl wird mit Strg+V in das neue Dokument eingefügt. Es wird eine schwebende Auswahl angezeigt, die ihr über das Kontextmenü (rechte Maustaste -> Ebene verankern) mit der Hintergrundebene vereint. Nun kann dieses neue Dokument gespeichert werden. Da wir einen Farbverlauf in unserem Bild haben, ist eine jpg-Datei das Format unserer Wahl. Im Speicherdialog sucht ihr unter Dateityp: Nach Endung die entsprechende Datei-Endung heraus und vergebt einen sinnvollen Namen an die Datei. In dem anschließend folgenden Komprimierungsdialog stellt ihr eine Komprimierung von 100% ein.

Für den Export des Mouseover-Zustands gilt die gleiche Vorgehensweise. Nun werdet ihr festgestellt haben, dass der Schlagschatten nicht mit exportiert wurde. Dies hat seinen Grund darin, dass wir später im Menü die Menüpunkte zentriert einfügen möchten. Durch die 4 Pixel Schlagschatten würde dieses Vorhaben aber erschwert werden. Deshalb wird der Schlagschatten separat als eigene Datei exportiert. Macht es genauso, wie bereits mit den Buttons, nur dass die Auswahl logischerweise nur 4 x 28 Pixel beträgt. Jetzt solltet ihr drei Dateien vorliegen haben. Für dieses Tutorial habe ich sie normal.jpg, hover.jpg und shadow.jpg genannt.

Das CSS-Menü

Nachdem wir nun unsere Grafiken haben, können wir uns an das Menü begeben. Am einfachsten sind diese Menüs mit Listen zu machen. Aber zunächst erstellen wir uns ein Grundgerüst in XHTML. Dazu gehören eine XHTML-Datei und eine CSS-Datei, die alle grundsätzlichen Angaben enthält. Erstellt euch drei Unterordner mit den Namen styles, scripts und images. In den Ordner images kopiert ihr euere Grafiken, die ihr aus GIMP exportiert habt. Beginnen wir nun mit der XHTML-Datei:

<!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">
<head>
<link rel="stylesheet" type="text/css" href="styles/main.css">
<title>CSS Menüs - Horizontales Menü</title>
</head>
<body>
</body>
</html>

Hier haben wir einen gültigen Doctype, der dem Browser mitteilt, dass dieses Dokument ein XHTML-Dokument ist und gerne so interpretiert werden möchte. Im HEAD-Bereich habe ich schon mal unsere CSS-Datei eingebunden. Dieser Link besagt, dass eine CSS-Datei namens main.css in dem Ordner styles abgelegt ist und mittels link in das XHTML-Dokument eingebunden wird. Die Datei wird gespeichert als .html- oder .htm-Datei. Des Weiteren ist natürlich die CSS-Datei nötig, auf die im Kopf verwiesen wird. In dem Ordner styles erstellt ihr eine neue Textdatei und benennt sie in main.css um.

Wir formatieren nun den BODY und definieren drei Container: einen Hauptcontainer content, für das Menü menu und für den Inhalt inhalt.

body{
    padding: 0;
    margin: 0;
    background-color: #fdfcfb;
    font-family: Verdana, Arial, Helvetica, sans-serif;
    font-size: 12px;
    color: #333;
    text-align: center;
}
/* Die Hauptbox */
#content{
    top: 20px;
    left: 40px;
    width: 808px;
    height: 600px;
    position: absolute;
}
/* Das obere Menue */
#menu{
    padding: 0;
    margin: 0;
    height: 28px;
    width: 800px;
    margin: 0px 4px;
    top: 4px;
    left: 0px;
    position: absolute;
}
/* Der Inhalt */
#inhalt{
    top: 120px;
    left: 0px;
    width: 520px;
    position: absolute;
    margin: 0px 4px;
    text-align: left;
}

In die XHTML-Datei werden die Container im BODY hinzugefügt:

<!-- Hauptcontainer -->
<div id="content">
   <!-- Menü oben -->
     <div id="menu"></div>
   <!-- Ende Menü oben -->
   <!-- Inhalte -->
     <div id="inhalt"></div>
   <!-- Ende Inhalte -->
</div>
<!-- Ende Hauptcontainer -->

Nun sind wir soweit, dass wir ein wenig Fleisch an die Knochen bringen können. Erstellt in dem Ordner styles noch mal ein neues Textdokument und benennt es in navi.css um. Diese CSS-Datei wird wie die main.css in HEAD eingebunden. In der navi.css werden jetzt alle Definitionen für die Navigation festgehalten. Wie schon erwähnt besteht dieses Menü aus einer Liste, genauer gesagt aus einer ungeordneten Liste ul. Dieser Liste werden wir eine id zuordnen, die es uns ermöglicht auf Kindelement und Ereignisse zuzugreifen. Sinnigerweise nennen wir diese id mal #navoben. Dort definieren wir die Größe, entfernen die Listenstile und bei einem Anker die Auszeichnungen:

#navoben{
    height: 28px;
    padding: 0;
    margin: 0;
}
#navoben ul{ list-style-type: none;}
#navoben a{
    text-decoration: none;
}

Nun wenden wir uns den einzelnen Listenelementen zu und veranlassen, dass diese mit display: block in einer horizontalen Reihe erscheinen:

#navoben li{
    margin: 0;
    padding: 0;
    float: left;
    text-align: center;
    display: block;
}

und definieren anschließend den Bildertausch:

#navoben li a{
    background: url(../images/hover.jpg) left top no-repeat;
    font-family: Arial, Verdana, Helvetica, sans-serif;
    color: #112c5d;
    font-size: 11px;
    font-weight: bold;
    display: block;
    height: 28px;
    width: 100px;
    padding: 8px 0px 0px 0px;
}
#navoben li a:hover{
    background: url(../images/normal.jpg) left top no-repeat;
    color: #666;
}

Damit wäre das Grundgerüst für das Menü eigentlich erledigt. Wer keine Unterpunkte mehr braucht, ist hier schon fertig. Natürlich muss die Liste nun auch in die XHTML-Datei geschrieben werden um im Browser auch was zu sehen:

<div id="menu">
  <ul id="navoben">
    <li><a href="#">HOME</a></li>
    <li><img src="images/shadow.jpg" alt="" width="4"
    height="28"/></li>
    <li><a href="#">PUNKT 1</a></li>
    <li><img src="images/shadow.jpg" alt="" width="4"
    height="28"/></li>
    <li><a href="#">PUNKT 2</a></li>
    <li><img src="images/shadow.jpg" alt="" width="4"
    height="28"/></li>
    <li><a href="#">PUNKT 3</a></li>
    <li><img src="images/shadow.jpg" alt="" width="4"
    height="28"/></li>
    <li><a href="#">PUNKT 4</a></li>
    <li><img src="images/shadow.jpg" alt="" width="4"
    height="28"/></li>
  </ul>
</div>

Aufmerksame Leser werden hier gesehen haben, dass jedes zweite Listenelement ein Bild enthält. Dies ist der Schlagschatten, den wir unabhängig von den Buttons aus GIMP exportiert haben. Nun ist der Text mittig auf den Buttons positioniert und der Schlagschatteneffekt ist wieder vorhanden.

Die Unterpunkte werden auch in einer ungeordneten Liste dargestellt und in dem jeweiligen Listenelement verschachtelt eingefügt. Nehmen wir erstmal den ersten Menüpunkt:

<li><a href="#">HOME</a></li>
<li><img src="images/shadow.jpg" alt="" width="4"
height="28" /></li>
<li><a href="#">PUNKT 1</a>
  <ul>
     <li><a href="#">PUNKT 1.1</a></li>
     <li>|</li>
     <li><a href="#">PUNKT 1.2</a></li>
     <li>|</li>
     <li><a href="#">PUNKT 1.3</a></li>
     <li>|</li>
     <li><a href="#">PUNKT 1.4</a></li>
   </ul>
</li>

Das Ergebnis sieht im Browser ein wenig kurios aus. Zunächst müssen wir die Untermenüpunkte „verstecken“, bis mit der Maus über den Hauptmenüpunkt gefahren wird.

#navoben li ul{
   display: none;
   position: absolute;
   top: 28px;
   left: 0px;
   height: 28px;
   padding: 0;
   margin: 0;
   background-color: #fdfcfb;
}

Die Untermenüpunkte werden auch in Position zum Hauptmenü gebracht. Da die Browser unterschiedliche Interpretationen von Schriftober- und Unterlängen haben kann man sich das Positionieren erleichtern, indem die Hintergrundfarbe zunächst in einer gut sichtbaren Farbe gesetzt wird. Ist die Position zufrieden stellend wird die Farbe wieder zurückgesetzt.

Die lästige Wiederholung der Buttongrafiken muss natürlich auch unterbunden werden, insofern ist die Vererbung aus der übergeordneten Liste zu überschreiben. Beim Mouseover des Hauptmenüpunktes als auch eines der Untermenüpunkte sollen diese wieder sichtbar werden und in einer Reihe stehen. Deshalb muss die Angabe display: block; für #navoben li ul a und für #navoben li:hover ul gemacht werden:

#navoben li ul a{
   display: block;
   background-image: none;
   float: left;
   width: auto;
   font-size: 10px;
   font-weight: bold;
   color: #666;
   padding-right: 12px;
}
#navoben li ul a:hover{
   background-image: none;
   color: #999;
}
#navoben li:hover ul{
   display: block;
}

Wer über einen modernen Browser verfügt, kann bereits ein recht anständiges Ergebnis sehen. Diejenigen, die mit IE-Versionen kleiner als 7 arbeiten sehen … NICHTS! Glücklicherweise gibt es auch dafür Lösungen, allerdings kommen wir da nicht um JavaScript herum. Wir verwenden hier ein kleines Script von Stu Nicholls, der sich besonders diesen Problemen verschrieben hat. Dafür muss in der navi.css noch eine kleine Ergänzung vorgenommen werden:

#navoben li.over ul{ /* für den IE*/
   display: block;
   z-index: 6000;
}

Nun kommt auch der Ordner scripts zum Einsatz; kopiert folgendes Script in eine Textdatei und nennt sie ieHover.js:

startList = function() {
if (document.all&&document.getElementById) {
     navRoot = document.getElementById("navoben");
     for (i=0; i<navRoot.childNodes.length; i++) {
      node = navRoot.childNodes[i];
      if (node.nodeName=="LI") {
        node.onmouseover=function() {
          this.className+=" over";
          }
        node.onmouseout=function() {
        this.className=this.className.replace(" over", "");
      }
    }
  }
}
window.onload=startList;

Dieses JavaScript muss selbstverständlich in die XHTML-Datei eingebunden werden. Fügt im HEAD-Bereich noch diese Zeile ein:

<script language="JavaScript" src="scripts/ieHover.js"></script>

Die grundsätzliche Funktionalität ist nun vorhanden. Jetzt müssen wir noch ein wenig am Äußeren schrauben. Zum Beispiel sieht der „|“ zwischen den Untermenüpunkten ein wenig deplaziert aus. Mit einer eigenen Klasse holen wir diesen Strich wieder in die Reihe zurück:

#navoben li ul li.ohne{
   float: left;
   width: auto;
   font-weight: normal;
   color: #666;
   padding-top: 6px;
   padding-right: 12px;
}

Die Untermenüpunkte sind noch alle am linken Rand ausgerichtet. Um dies zu ändern muss in den verschachtelten Listen die Position angegeben werden.

<li><a href="#">PUNKT 1</a>
  <ul style="margin-left:131px;">
    <li><a href="#">PUNKT 1.1</a></li>
    <li class="ohne">|</li>
    <li><a href="#">PUNKT 1.2</a></li>
    <li class="ohne">|</li>
    <li><a href="#">PUNKT 1.3</a></li>
    <li class="ohne">|</li>
    <li><a href="#">PUNKT 1.4</a></li>
  </ul>
</li>
<li><img src="images/shadow.jpg" alt="" width="4"
height="28" /></li>
<li><a href="#">PUNKT 2</a>
  <ul style="margin-left:235px;">
    <li><a href="#">PUNKT 2.1</a></li>
    <li class="ohne">|</li>
    <li><a href="#">PUNKT 2.2</a></li>
    <li class="ohne">|</li>
    <li><a href="#">PUNKT 2.3</a></li>
    <li class="ohne">|</li>
    <li><a href="#">PUNKT 2.4</a></li>
    <li class="ohne">|</li>
    <li><a href="#">PUNKT 2.4</a></li>
  </ul>
</li>

Da die Position des Untermenüs abhängig von der Textmenge und, durch die Zentrierung, von der Länge des Textes des Hauptmenüpunktes ist, muss die style-Angabe in der Liste individuell vorgenommen werden.

Fürs Auge habe ich dem Hauptcontainer content noch eine schicke Hintergrundgrafik verpasst:

#content{
   background: #fdfcfb url(../images/bg.jpg) left top repeat-x;
   top: 20px;
   left: 40px;
   width: 808px;
   height: 600px;
   position: absolute;
}

Und der Container menu hat einen unteren Rand erhalten:

#menu{
   padding: 0;
   margin: 0;
   height: 64px;
   width: 800px;
   border-bottom: #56575c 1px solid;
   margin: 0px 4px;
   top: 4px;
   left: 0px;
   position: absolute;
}

Dieses Menü ist in Haupt- und Untermenüpunkten erweiterbar, es müssen lediglich die Breiten der Container angepasst werden. Dies ist, durch den Bildertausch, eine etwas schickere Variante des horizontalen Menüs. Natürlich lässt sich diese Form des Menüs auch mit unterschiedlichen Hintergrundfarben und Rändern erstellen. Hier mal ein Beispiel:

#navoben li a{
   background-color: #d6d9de;
   border: #58575d 1px solid;

   font-family: Arial, Verdana, Helvetica, sans-serif;
   color: #112c5d;
   font-size: 11px;
   font-weight: bold;
   display: block;
   height: 21px;
   width: 100px;
   padding: 7px 0 0 0;
   margin-right: 4px;
}

Durch das fehlende Bild ist hier die Höhe mit dem padding verrechnet worden. So erhalten wir die gleiche Größe wie mit Bild. Der Schlagschatten ist durch ein entsprechendes margin ersetzt worden.

#navoben li a:hover{
   background-color: #f0f1f3;
   border: #58575d 1px solid;

   color: #666;
}
#navoben li ul{
   display: none;
   position: absolute;
   top: 30px;
   left: 0px;
   height: 28px;
   padding: 0;
   margin: 0;
   background-color: #fdfcfb;
}

Der obere Abstand des Submenüs wurde ein wenig erhöht. So überlagert dieses nicht mehr die Hauptmenüpunkte.

#navoben li ul a{
   display: block;
   border: none;
   background-color: #fdfcfb;

   float: left;
   width: auto;
   font-size: 10px;
   font-weight: bold;
   color: #666;
   padding-right: 12px;
}

Der Rand muss explizit abgestellt und die gewünschte Hintergrundfarbe angegeben werden.

#navoben li ul li.ohne{
   float: left;
   width: auto;
   font-weight: normal;
   color: #666;
   padding-top: 6px;
   padding-right: 12px;
}
#navoben li ul a:hover{
   border: none;
   background-color: #fdfcfb;

   color: #999;
}

Der XHTML-Code für den menu-Container ist dann folgender:

<div id="menu">
  <ul id="navoben">
    <li><a href="#">HOME</a></li>
    <li><a href="#">PUNKT 1</a>
      <ul style="margin-left:133px;">
        <li><a href="#">PUNKT 1.1</a></li>
        <li class="ohne">|</li>
        <li><a href="#">PUNKT 1.2</a></li>
        <li class="ohne">|</li>
        <li><a href="#">PUNKT 1.3</a></li>
        <li class="ohne">|</li>
        <li><a href="#">PUNKT 1.4</a></li>
      </ul>
    </li>
    <li><a href="#">PUNKT 2</a>
      <ul style="margin-left:239px;">
        <li><a href="#">PUNKT 2.1</a></li>
        <li class="ohne">|</li>
        <li><a href="#">PUNKT 2.2</a></li>
        <li class="ohne">|</li>
        <li><a href="#">PUNKT 2.3</a></li>
        <li class="ohne">|</li>
        <li><a href="#">PUNKT 2.4</a></li>
        <li class="ohne">|</li>
        <li><a href="#">PUNKT 2.4</a></li>
      </ul>
    </li>
    <li><a href="#">PUNKT 3</a>
      <ul style="margin-left:345px;">
        <li><a href="#">PUNKT 3.1</a></li>
        <li class="ohne">|</li>
        <li><a href="#">PUNKT 3.2</a></li>
        <li class="ohne">|</li>
        <li><a href="#">PUNKT 3.3</a></li>
      </ul>
    </li>
    <li><a href="#">PUNKT 4</a>
      <ul style="margin-left:451px;">
        <li><a href="#">PUNKT 4.1</a></li>
        <li class="ohne">|</li>
        <li><a href="#">PUNKT 4.2</a></li>
        <li class="ohne">|</li>
        <li><a href="#">PUNKT 4.3</a></li>
      </ul>
    </li>
  </ul>
</div>

Ihr seht, die Möglichkeiten sind vielfältig. Ich wünsche viel Spaß beim Experimentieren!