Thema: Design

Button-Mania

06. Juni 2010

Button-Mania
Die Gestaltung von Schaltflächen kann aufwendiger sein, als man es auf den ersten Blick vermuten könnte. Reine Bildlösungen sind zu unflexiblel, und die Standard-System Schaltflächen will keiner mehr sehen. Es gibt viele Tutorials zu diesem Thema – soviele, dass es Seiten gibt, die eben diese Tutorials wieder zusammenfassen. Ein reichlich bestelltes Feld, warum also noch ein Artikel zu diesem Thema? Weil mir in den meisten Lösungen etwas fehlt, frei nach dem Motto: Je mehr Layout, desto weniger Funktionalität.

Der “klassische” Button kann oft mehr, als die “design” Variante. Eine Standard-Schaltfläche kennt die Zustände: Aktiv, Fokussiert, Gedrückt, Deaktiviert. Nimmt man die CSS Eigenschaft :hover dazu, kann eine Schaltfläche auch noch auf das Überfahren mit der Maus reagieren. Die meisten der im Netz verfügbaren Gestaltungslösungen nehmen einer Schaltfläche viele dieser Fähigkeiten – in den schlimmsten Fällen bleibt noch nicht einmal der “passende” HTML-Tag übrig.

Die Basis: der HTML Code

Solange man einen Button innerhalb von Formularen nutzt, sollte dieser auch vom Typ eine Schaltfläche (INPUT oder BUTTON) sein, kein DIV- oder A- Tag. Nur so kann gewährleistet werden, dass eine Übertragung von Formulardaten auch ohne den Einsatz von Javascript möglich ist.
Um eine Schaltfläche umzugestalten eignet sich der BUTTON-Tag sicher besser, als der INPUT-Tag, denn der BUTTON-Tag kann eine HTML Struktur enthalten, die Input Variante hingegen nur Text. Laut W3C Spezifikation gilt:

Buttons created with the BUTTON element function just like buttons created with the INPUT element, but they offer richer rendering possibilities: the BUTTON element may have content. For example, a BUTTON element that contains an image functions like and may resemble an INPUT element whose type is set to “image”, but the BUTTON element type allows content.

Nachteil: Der BUTTON-Tag “sendet” keine einheitliche Information an den Server (besser gesagt, die Browser reagieren unterschiedlich). Während der Internet Explorer den Inhalt eines benannten Buttons sendet, liefern Firefox, Safari, Opera & co. das value Attribut. Zudem sendet der Internet Explorer gleich alle Schaltflächen-Werte, und nicht nur den Wert der gedrückten Schaltfläche. Eine serverseitige “Fallunterscheidung” auf Basis der genutzten Schaltfläche ist damit browserübergreifend nicht möglich. Allerdings ist dieses in den meisten Fällen auch gar nicht nötig. Als Basis für die nachfolgende Ausgestaltung ein geradezu “klassisches” Button Pärchen:

Beispiel
Screenshot ohne CSS, nichts weiter als zwei Standard Schaltflächen (FF 3.6, WinXP)
<!-- Der Typ muss genannt werden, auch hier gibt es
browserspezifische Unterschiede:
im IE ist der default Type: button, im FireFox submit.
Für eine höhere Gestaltungsvielfalt werden die Inhalte
beider Schaltflächen noch einmal geschachtelt, so
dass sie sich auch ohne CSS voneinander abgrenzen:
 -->
<button type="submit"><strong>Absenden</strong></button>
<button type="reset"><em>Abbrechen</em></button>

Grundlegende Gestaltung, das Zurücksetzen (reset)

Ein Standard-System Button unterscheidet sich massiv von Browser zu Browser (und Betriebssystem). Farbe, Form, Highlight – alles ist verschieden. Bevor es mit der eigentlichen Gestaltung losgehen kann, ist ein Zurücksetzen, ein “Gleichschalten” also unumgänglich:

button {
 background: none;
 border: none;
 margin: 0;
 padding: 0;
 /* Fix für die unterschiedliche Ausgangshöhe von Schaltflächen */
 line-height: 0;
}
 
button * {
  /* Stattdessen wird die Höhe auf die Kinderelement(e) gesetzt */
  line-height:16px;
 /*und die Darstellung der verwendeten Inline-Tags vereinheitlicht */
 font-style:normal;
 font-weight:normal;
}

Im Internet Explorer “wächst” die Schaltfläche (egal ob INPUT oder BUTTON) proportional zu den Inhalten, je länger der Text, desto größer wird der Innenabstand. Allerdings nützt das Zurücksetzen von Padding hier nichts, stattdessen braucht der IE Angaben zur Eigenschaft overflow. Da diese Eigenschaft nur für den Internet Explorer gilt (und greift), sollte sie über einen conditional comment eingebunden werden.

<!--[if IE]>
button {
/*IE - Unterdrückung des wachsenden Innenabstands */
 overflow:visible;
 width:auto;
}
<![endif]-->

In einigen Browsern wird die Schaltfläche beim Fokussieren mit einer gepunkteten Linie umrandet. Beim A-Tag reicht es, die Eigenschaft outline auf none zu setzen, für einen Button braucht es noch ein wenig mehr:

button, button:focus {
  outline: none;
}
 
/* fix for Firefox */
button::-moz-focus-inner {
  border:0;
  /* es gibt in einigen Versionen einen Extra-Innenabstand */
  padding:0;
}

Älteren IE-Versionen kann man notfalls noch mit einer CSS-Expression auf die Sprünge helfen:

<!--[if lt IE 8]>
button {
  noFocusLine: expression(this.onFocus=this.blur());
}
<![endif]-->

Es sei an dieser Stelle erwähnt, dass dieses Unterdrücken aus Usability / Accessability Sicht nicht gewünscht ist, bei manchen Gestaltungsvorgaben ist es anders aber nicht zu bewerkstelligen.

Beispiel
Screenshot nach dem “Reset”, nichts ist mehr übrig geblieben

Die Ausgestaltung des Buttons

Nach dem reset CSS bleibt von der Schaltfläche nicht mehr viel übrig. Ab diesem Zeitpunkt liessen sich viele bekannte Techniken zur Gestaltung von Buttons auf die erstellten Schaltflächen anwenden. Janko Jovanovic nutzt in seiner Version die Technik sliding-doors, ein geteiltes Bild, dass in diesem Fall auf den BUTTON und den STRONG bzw. EM-Tag übertragen werden könnte. Aber warum mit Grafiken arbeiten, wenn die meisten Browser es bereits ganz ohne können? Die zur Zeit so beliebten “glossy” Buttons lassen sich Dank browserspezifischer CSS Eigenschaften auch ohne Grafik erstellen. Als Vorlage für diesen Versuch soll eine Variante aus dem genannten Tutorial von Janko Jovanovic dienen:

Beispiel
Beispiel Grafik, übernommen aus: “Make fancy buttons using CSS sliding doors technique”
button {
  padding:6px 16px;
  font: 600 12px/1 Helvetica, Arial, sans-serif;
  border:1px solid #667a93;
  /* Fallback für ältere Browser */
  background:#35ccda;
  /* Zweifarbiger Hintergrund für Google Chrome + Safari */
  background:-webkit-gradient(
    linear, 0% 0%, 0% 90%,
    from(#8be2ea),
    to(#21b7c9),
    /* Harter Bruch bei halber Höhe */
    color-stop(0.5, #8be2ea)
  );
  /* Gleiches Hintergrund Verhalten für den FireFox */
  background:-moz-linear-gradient(#8be2ea 50%, #21b7c9 100%);
 /* Abgerundete Ecken */
  -webkit-border-radius:6px;
  -moz-border-radius:6px;
  border-radius:6px;
  /* Drei Schattenangaben: Aussen, leichtes Grau,
      nach innen oben weiss, unten extra Abdunklung */
  -moz-box-shadow:
    0px 0px 3px rgba(0,0,0,0.4),
    inset 0px 0px 5px rgba(255,255,255,0.5),
    inset 0 -13px 2px -10px #13aabc;
  /* Gleiches Verhalten für Chrome + Safari */
  -webkit-box-shadow:
    0px 0px 3px rgba(0,0,0,0.4),
    inset 0px 0px 5px rgba(255,255,255,0.5),
    inset 0 -13px 2px -10px #13aabc;
  /* Damit man auch das Gefühl hat, dass man Klicken kann */
  cursor:pointer;
  /* "Emboss" für den Text */
  text-shadow:0 1px 1px #ffffff;
}
Beispiel
Das Ergebnis: Screenshot (FF 3.6, WinXP), im Vergleich zur Grafik basierten Variante (rechts)

Die Verwendung von box-shadow

Das Beispiel (wie die anderen in der Demo auch) nutzt die CSS Eigenschaft box-shadow. Laut Spezifikation lässt das Element auch den Einsatz multibler Schattenangaben zu, damit ist der Gestaltungsfreiraum enorm. Deshalb an dieser Stelle eine kurze Erläuterung zur Zusammensetzung der CSS Notation:

/* Die ersten beiden Werte beschreiben den
    horizontalen und vertikalen Versatz des Schattens */
/* Schatten nach rechts unten*/
#test {
  box-shadow:8px 8px;
}
 
/* Negative Werte verschieben den Schatten
    dabei nach links, bzw. oben */
#test {
  box-shadow:-8px 8px;
}
 
/* Der dritte, optionale Wert bestimmt die
    Weichzeichnung des Schattens */
#test {
  box-shadow:-8px 8px 4px;
}
 
/* Der vierte, optionale Wert bestimmt den maximalen Radius, den der
    Schatten einnehmen kann, je geringer der Wert, desto kleiner wird
    der Schatten  */
#test {
  box-shadow:-8px 8px 4px 2px;
}
 
/* Nun braucht der Schatten noch eine Farbangabe, dabei lassen sich
    hexadezimale Farbangaben oder die neue rgba Syntax verwenden,
    der vierte Wert bei rgba bestimmt dabei die Alphatransparenz  */
#test {
  box-shadow:-8px 8px 4px 2px rgba(0,0,0,0.5);
}
 
/* Um den Schatten von außen nach innen zu legen, gibt es
    zusätzlich noch das Schlüsselwort inset, das an beliebiger
    Stelle in die Definition eingefügt werden kann  */
#test {
  box-shadow:-8px 8px 4px 2px rgba(0,0,0,0.5) inset;
}
 
/* Um mehrere Schatten zu kombinieren werden die einzelnen
    Definitionen mit Komma separiert notiert, bei Schatten, die
    sich überlagern, "gewinnt" die erst genannte Angabe.  */
 
#test {
  box-shadow:-8px 8px 4px 2px rgba(0,0,0,0.5) inset,
  8px 8px 4px 4px rgba(190,190,190,0.4) inset;
}

In Kombination mit den CSS Eigenschaft gradient lassen sich zahlreiche Effekte realisieren, allerdings unterstützen noch lange nicht alle Browser box-shadow. Safari, Chrome und Firefox ab 3.5 (jeweils mit -webkit bzw. -moz-Präfix), und einige Opera Versionen über das -o-Präfix können mit der Syntax umgehen. Für eine optimale Browserunterstützung sind also vier verschiedene box-shadow Angaben notwendig, und ein Fallback sollte ebenfalls bedacht werden. Die Vorteile einer solchen “reinen” CSS basierten dieser Lösung: Diese Buttons lassen sich wirklich endlos skalieren, auch mehrzeilige Schaltflächen sind kein Problem und der Einsatz von Grafiken wird deutlich reduziert. Dem IE kann man übrigens auch noch etwas auf die Sprünge helfen. Verläufe und Schatten lassen sich auch im Internet Explorer über CSS realisieren:

<!--[if IE]>
button {
  filter:progid:DXImageTransform.Microsoft.gradient(
    startColorstr=#a8e9ef,
    endColorstr=#35ccda
  )
  /* Hier als eine Art Schattenersatz, da die Abdunklung
    an allen Kanten erfolgt*/
  progid:DXImageTransform.Microsoft.Glow(
    color=#CDCDCD,
    strength=1
  );
}
 
button strong,
button em {
  display:inline-block;
  filter:progid:dxImageTransform.Microsoft.dropShadow(
   color=#ffffff,
   offX=1,
   offY=0
  );
}
<![endif]-->

Und die abgerundeten Ecken im Internet Explorer? Mit reinen CSS Mitteln nicht möglich, hier ist der Einsatz von Hintergrundgrafiken zwangsweise erforderlich. Je nach der notwendigen Flexibilität lässt sich für den IE die “sliding-doors” Technik (zwei Grafiken) oder eine Variante mit insgesamt vier Grafiken (alle vier Ecken) einsetzen. Auf dieser kleinen Demo-Seite habe ich ein entsprechendes Beispiel eingefügt. Da die vier Ecken Version mehr Tags innerhalb des Buttons braucht, wurde der Quellcode der Schaltfläche für den Internet Explorer mit Hilfe der conditional comments angepasst:

<button type="submit"><strong>
<!--[if IE]><span><span><span><span><![endif]-->
Absenden
<!--[if IE]></span></span></span></span><![endif]-->
</strong></button>

Feintuning, Wiederbelebung der verschiedenen Zustände

Wie einleitend erwähnt fehlen mir bei vielen Lösungen die Abbildung der verschiedenen Zustände, die so eine Schaltfläche einnehmen kann: Aktiv (Beim Klick), Fokus (per Tab), Hover (Überfahren mit der Maus), und Deaktiviert (Attribut disabled). Wie man die Schaltfläche bei diesen Zuständen verändert ist vom Layout abhängig, aber sichtbar sollten diese Änderungen schon sein, ein Beispiel Szenario:

/* per Tab oder Maus */
button:focus, button:hover {
  -moz-box-shadow:
    0 0 5px 2px #fdda39, 0px 0px 3px rgba(0,0,0,0.4),
    inset 0px 0px 5px rgba(255,255,255,0.5),
    inset 0 -13px 2px -10px #13aabc;
-webkit-box-shadow:
    0 0 5px 2px #fdda39, 0px 0px 3px rgba(0,0,0,0.4),
    inset 0px 0px 5px rgba(255,255,255,0.5),
    inset 0 -13px 2px -10px #13aabc;
}
 
/* Beim Überfahren mit der Maus */
button:hover * {
  text-decoration:underline;
}
 
/* Beim Klick */
button:active {
  -webkit-transform:translateY(1px);
  -moz-transform:translateY(1px)
}
 
/* Deaktivierte Schaltflächen */
button[disabled]:active, button[disabled] {
  background:#d9d9d9;
  border-color:#777;
  color:#666666;
  -webkit-transform:none !important;
  -moz-transform:none !important;
  background:-webkit-gradient(
    linear, 0% 0%, 0% 90%,
    from(#d9d9d9),
    to(#b9b9b9),
    color-stop(0.5, #d9d9d9)
  );
  background:-moz-linear-gradient(#d9d9d9 50%, #b9b9b9 100%);
  -moz-box-shadow:
    0px 0px 3px rgba(0,0,0,0.4),
    inset 0px 0px 5px rgba(255,255,255,0.5),
    inset 0 -13px 2px -10px #a5a5a5;
  -webkit-box-shadow:
     0px 0px 3px rgba(0,0,0,0.4),
     inset 0px 0px 5px rgba(255,255,255,0.5),
    inset 0 -13px 2px -10px #a5a5a5;
  cursor:default;
}
 
button[disabled]:active * , ButtonGroup1 button[disabled] * {
  text-decoration:none;
}

Eine kleine Demonstration zeigt den hier beschriebenen CSS und HTML Code noch einmal im konkreten Einsatz. Man kann mit dem Einsatz der neueren CSS Möglichkeiten zwar schon einiges aus einer Schaltfläche herausholen. Aber auf die Verwendung von Grafiken wirklich verzichten geht nur, wenn man sich von dem Gedanken verabschiedet, dass eine Seite in jedem Browser gleich aussehen soll (und das entscheidet letztlich der Kunde). Ob es wirklich lohnt auf Bitmap Grafiken zu verzichten und komplett auf CSS zu setzen ist und bleibt auch für die nächste Zeit eine Fallentscheidung. Dem gestalteten Button aber gleich alle Funktionalitäten zu nehmen ist weder notwendig noch sinnvoll, hier bietet CSS mit seinen Pseudoklassen alles was man braucht.

Mehr zum Thema:

Seite 2 von 212