Flexible Formulare für responsive Webdesign

Mit der steigenden Zahl an mobilen Endgeräten unterschiedlicher Hersteller, stehen Webdesigner mittlerweile vor demselben Problem wie damals, als die Bildschirmauflösungen unberechenbar wurden. Je nach Auflösung und Pixeldichte des Endgeräts werden Webseiten unterschiedlich dargestellt. Diesem Problem widmet das responsive Webdesign. Mittels sogenannten Media Queries können Elemente für unterschiedliche Breiten und Höhen des Browsers angepasst werden. Ein Problem was dabei oft auftritt sind Formulare. In diesem Artikel wird eine einfache Lösung zur Gestaltung von responsiven Formularen präsentiert.

Update: 22.07.2016

Die meisten Formulare werden im klassischen Sinne so gestaltet, dass es einen Label (z. B. Vorname, Telefon, E-Mail) gibt, welcher links neben einem Input-Feld steht. Seit HTML5 gibt es auch die Möglichkeit einen Platzhalter (Placeholder) in Eingabefeld selbst zu definieren, so dass der Label oft weggelassen werden kann. Zuvor wurden hauptsächlich Lösungen implementiert, die den Platzhalter per JavaScript simulierten. In unserem Formular-Beispiel bleibt der Label erhalten, da Platzhalter in ausgefüllten Formularen nicht mehr sichtbar sind.

Um komplexe Formulare übersichtlich zu gestalten werden Eingabefelder meistens gruppiert nebeneinander dargestellt. Oft wird dazu eine feste Breite für das Element definiert, sowie mit der „float“-Eigenschaft versehen. Wenn ausreichend Platz zur Verfügung steht, ist dies kein Problem. Mit den zuvor erwähnten Media Queries definiert man dann für bestimmte Punkte (Breakpoints) neue Werte, so dass das Formular in verschiedenen Browsergrößen entsprechend angepasst wird. Sofern man die Breakpoints kennt ist dies auch kein Problem. Jedoch gibt es zwischen den etablierten: 320 x 480, 768 x 1024, 1280 x 800 und 1920 x 1200, mittlerweile eine Vielzahl von Zwischenauflösungen. Gerade bei mobilen Geräten nimmt die Fülle an Zwischenauflösungen kontinuierlich zu. Daher verfolgen viele Webdesigner den Trend unterhalb von 1024 px auf ein flexibles Design zu setzen.

Um Eingabefelder ebenfalls flexibel zu gestalten ist es notwendig die Breite in relativen Einheiten (z. B. rem, em, %,  vw oder vh) zu definieren. Da man im Designprozess die Media-Queries nicht für die Eingabeelement  wie input, select, label und button immer wieder neu anpassen will, definiert man diese initial mit 100%. Damit diese dann nicht 100% der Seitenbreite einnehmen, benötigt man ein Element welches drumherum fließt und die Breite entsprechend begrenzt. Wer schon mit Bootstrap oder einem anderen CSS Framework gearbeitet hat, wird diese Art von Grid-System etwas sagen. Genau dies ist auch bei Formularen die Lösung.

Es muss aber nicht immer gleich ein komplettes Framework im Projekt eingebunden werden, wenn man "nur" responsive Formulare benötigt. Dies kann schneller ungesetzt werden als die meisten denken.

Einfaches Grid-System für Formulare

Um zu zeigen wie universell und einfach dieses Konzept ist, greife ich nicht auf ein bestimmtes Framework zurück, sondern implementiere ein eigenes um das Prinzip verständlich zu machen. Mit Hilfe der Schieberegler (sofern Du einen Browser verwendest, der dies "schon" unterstützt), kann die Breite der nachfolgenden Container angepasst werden. So wird der Effekt besser sichtbar.

Breite: 960px

Breite: 960px

CSS Klassen und HTML Code

Das Prinzip ist sehr einfach und anhand der Namensgebung der CSS Klassen leicht ersichtlich. Lediglich um Breakpoints besser steuern zu können habe ich zusätzlich die gleichen Klassennamen noch einmal mit einem "s" vergegen. Dies wird dir im unteren Teil bei den Media-Queries näher erläutert. Du kannst natürlich noch mehr Klassen für Deine Breakpoints hinzufügen.

Basic Grid

Man definiert alle benötigten Klassen und vergibt diesen die Grundeigenschaften wie "float" und "padding". Anschließend legt man für jeden Teil des Grid eine bestimmte relative Breite fest. Die Angaben zur Breite errechnen sich anhand der Unterteilung. So habe ich im Beispiel ein 12 Spalten Grid-System gewählt. Somit ergibt sich für die Klasse .grid-1 eine Breite von 8.33%, was sich aus 1/12 errechnet. Für .grid-12 ergibt sich analog 100% aus 12/12. Um eine möglichst hohe Genauigkeit unter allen Browsern zu erzielen sollte man 10 Dezimalstellen wählen. Sonst kann es mitunter zu leichten Verschiebungen in unterschiedlichen Browsern kommen.

Um jede Gruppe von Grid-Element herum benötigt man ein Element, was die Zeile (row) abgrenzt und die "floats" wieder auflöst. Hierfür wird die Klassen ".row" verwendet. Im unteren HTML Beispiel wird die Anwendung verdeutlicht. Wichtig ist außerdem die verwendung des Box-Models "border-box". Erst dadurch kann die "padding" Eigenschaft zusammen mit einer relativen Breite von 100% korrekt in einem Container verwendet werden.

/* Setting box model */
html {
  box-sizing: border-box;
}

*, *:before, *:after {
  box-sizing: inherit;
}

/* Grid classes from 1 to 12 for a 12 column grid layout */
.grid-s-1, .grid-s-2, .grid-s-3, .grid-s-4, .grid-s-5, .grid-s-6, .grid-s-7,
.grid-s-8, .grid-s-9, .grid-s-10, .grid-s-11, .grid-s-12,
.grid-1, .grid-2, .grid-3, .grid-4, .grid-5, .grid-6, .grid-7, .grid-8, .grid-9,
.grid-10, .grid-11, .grid-12 {
  float: left;
  padding-left: 5px;
  padding-right: 5px;
  padding-bottom: 10px;
}

.row {
  clear: both;
  width: auto;
  min-height: 20px;
  float: none;
  margin-left: -5px;
  margin-right:-5px;
}

.row:after {
  content: ".";
  clear: both;
  display: block;
  visibility: hidden;
  height: 0px;
}

/* Default values */
.grid-1 {
  width: 8.3333333333%;
}
.grid-2 {
  width: 16.6666666666%;
}
.grid-3 {
  width: 25%;
}
.grid-4 {
  width: 33.3333333333%;
}
.grid-5 {
  width: 41.6666666666%;
}
.grid-6 {
  width: 50%;
}
.grid-7 {
  width: 58.3333333333%;
}
.grid-8 {
  width: 66.6666666666%;
}
.grid-9 {
  width: 75%;
}
.grid-10 {
  width: 83.3333333333%;
}
.grid-11 {
  width: 91.6666666666%;
}
.grid-12 {
  width: 100%;
}

Grid Klassen im HTML verwenden

Die einzelnen Klassen können so verwendet werden, dass innerhalb eines Elements mit der Klasse "row" immer Grid-Elemente sind welche in Summe maximal 12 ergeben. Das bedeutet z. B. 3 x grid-4 oder 1 x grid-2 und 2 x grid-5, etc. Jede weitere Reihe wird wieder durch ein Element mit der Klasse ".row" getrennt.

<!-- Example for grid with select box -->
<div class="row">
<div class="grid-4 label">
<label>Anrede:</label>
</div>
<div class="grid-12">
<select name="salutation">
<option value="1">Herr</option>
<option value="1">Frau</option>
</select>
</div>
</div>

<!-- Example for grid with two input fields -->
<div class="row">
<div class="grid-4 label">
<label>Vorname, Nachname:</label>
</div>
<div class="grid-4">
<input type="text" name="firstname" placeholder="Hans" value="">
</div>
<div class="grid-4">
<input type="text" name="lastname" placeholder="Mustermann" value="">
</div>
</div>

Formularelemente responsive machen

Wer die Formatierungen aus dem obrigen Beispiel für die Input-Felder übernehmen möchte, der kann diese aus dem folgenden Codebeispiel entnehmen. Dabei ist zu beachten, dass alle Formularelemente eine Breite von 100% aufweisen, um die entsprechende Breite des Grid zu füllen. Alle andere Formatierung können nach Bedarf selbst angepasst werden.

/* formular input elements */
input, select, label, textarea {
  width:100%;
  padding:5px;
  min-height: 30px;
  font-size: 0.8em;
}

input, select, textarea {
  border: 1px solid #266590
}

select {
  background-color: rgba(0,0,0,0.02);
}

input:disabled, select:disabled, textarea:disabled {
  color: #999;
  border-color: #CCC;
}

input[type="checkbox"],
input[type="radio"] {
  width:auto;
  height:auto;
  padding:0;
  min-height: 16px;
}

.grid-1 input[type="checkbox"] {
  margin: 5px;
  display: inline-block;
}

/* special format for label element */
.label {
  margin-bottom: 5px;
  padding: 0 5px;
}

.label label {
  display:block;
  background-color:#266590;
  color: #fff;
  line-height:20px;
  white-space:nowrap;
  overflow:hidden;
  font-size: 0.8em;
}

.label.wrap label {
  white-space: normal;
}

Mediaqueries für spezielle Breakpoints

Wie etwas weiter oben erwähnt, ist es sinnvoll für einige Breakpoints Mediaqueries zu verweden. Diese kann man durch eine Zusatzklasse definieren, welche erst ab einem bestimmten Punkt aktiv wird. Der einfachheithalber habe ich im Folgenden einen Mediaquery für alle Auflösungen bis 500px definiert. (Mobile-First Verfechter, können das Ganze natürlich auch umdrehen.)

@media screen and (max-width: 500px) {
  .label {
    width:100%;
  }
  .grid-s-1 {
    width: 8.3333333333%;
  }
  .grid-s-2 {
    width: 16.6666666666%;
  }
  .grid-s-3 {
    width: 25%;
  }
  .grid-s-4 {
    width: 33.3333333333%;
  }
  .grid-s-5 {
    width: 41.6666666666%;
  }
  .grid-s-6 {
    width: 50%;
  }
  .grid-s-7 {
    width: 58.3333333333%;
  }
  .grid-s-8 {
    width: 66.6666666666%;
  }
  .grid-s-9 {
    width: 75%;
  }
  .grid-s-10 {
    width: 83.3333333333%;
  }
  .grid-s-11 {
    width: 91.6666666666%;
  }
  .grid-s-12 {
    width: 100%;
  }
}

Das HTML Beispiel ist von oben übernommen. Jetzt mit zusätzlichen Breakpoint-Klassen. Das Label Element wird nach unserer Formatierung ab dem Breakpoint (und kleiner) immer mit der gesamten Breite angezeigt, währenddessen für die Inputfelder entsprechend die Klassen gesetzt werden.

So ist das Select-Element unterhalb des Breakpoints 100% breit, während es oberhalb 3/12 des Platzes einnimmt. Im unteren Beispiel bleiben beide Inputfelder für den Vor- und Nachnamen nebeneinander. Da der Label jedoch durch 100% Breite darüber rutscht, wird der verfügbare Platz aufgeteilt, so dass beide Element zusammen die gesamte Breite einnehmen.

<!-- Example for grid with select box -->
<div class="row">
<div class="grid-4 label"><label>Anrede:</label></div>
<div class="grid-s-12 grid-3">
<select name="salutation">
<option value="1">Herr</option>
<option value="1">Frau</option>
</select>
</div>
</div>

<!-- Example for grid with two input fields and responsive classes -->
<div class="row">
<div class="grid-4 label">
<label>Vorname, Nachname:</label>
</div>
<div class="grid-s-6 grid-4">
<input type="text" name="firstname" placeholder="Hans" value="">
</div>
<div class="grid-s-6 grid-4">
<input type="text" name="lastname" placeholder="Mustermann" value="">
</div>
</div>

Im nächsten Artikel werde ich die CSS Klassen als "Mixin" für Sass beschreiben. Damit ist es sehr einfach das Grid-System zu erweitern und neue Breakpoints ohne viel Aufwand hinzuzufügen.

Kategorie: Webdesign | Tags: CSS Grid-System HTML