Responsive Webseiten gestalten

Flexibel entworfene Webseiten können helfen, sowohl Nutzern von Mobil- als auch von Desktopgeräten ein gutes Anwendererlebnis zu vermitteln. Die Umsetzung erfordert allerdings einige Überlegungen.

In Pocket speichern vorlesen Druckansicht
Lesezeit: 17 Min.
Von
  • Roberto Bez
Inhaltsverzeichnis

Flexibel entworfene Webseiten können helfen, sowohl Nutzern von Mobil- als auch von Desktopgeräten ein gutes Anwendererlebnis zu vermitteln. Die Umsetzung erfordert allerdings einige Überlegungen.

Themen wie Mobile First, Performance sowie Vor- und Nachteile von Responsive Webdesign wurden im Vorgängerartikel zum Thema ausführlich erklärt. Jetzt geht es darum, den praktischen Teil unter die Lupe zu nehmen: Wie weit lässt sich ein Layout mit MediaQueries umsetzen? Was passiert mit großen Bildern auf kleinen Geräten? Wie kann man Formulare benutzerfreundlich gestalten? Darüber hinaus soll betrachtet werden, welche Techniken es momentan gibt, aber auch welche in Arbeit sind und in naher Zukunft die breite Masse erreichen.

MediaQueries sind ein mächtiges Werkzeug und ein zentraler Bestandteil des Responsive Web Design. Sie sorgen dafür, dass sich die Webseiten "responsiv" verhalten und den Ausgabemöglichkeiten des Geräts optimal anpassen. Die Regeln sind kinderleicht und verstehen sich meistens von selbst. Als Beispiel beachtet ein Desktop-PC die Angabe von min-width: 800px, ein kleineres Smartphone hingegen kann sie problemlos ignorieren. Vor allem wenn bei der Entwicklung einer Webseite der Mobile-First-Ansatz beachtet wird, lassen sich Regeln Schritt für Schritt hinzufügen, ohne dabei die bestehenden ändern zu müssen.

@media only screen and (min-device-width : 768px) 
and (max-device-width : 1024px) and
(orientation : landscape) {
}

Die obige Regel kommt beispielsweise nur zum Einsatz, wenn der Besucher ein Tablet verwendet und es quer hält. Bereits heute gibt es neben orientation (portrait, landscape) weitere nützliche Angaben, wie
webkit-device-pixel-ratio: 2 oder resolution: 96dpi für die Optimierung auf Geräten, die mit Bildschirmen mit einer besonders hohen Pixeldichte ausgestattet sind. Auch Typ-Angaben wie screen oder tv werden schon verwendet.

@media (-webkit-min-device-pixel-ratio: 1.5),
(min-resolution: 144dpi){
/* Optimierungen für retina / high-res */
}
@media screen and (device-aspect-ratio: 16/9),
screen and (device-aspect-ratio: 16/10) { ... }
@media tv and (scan: progressive) { ... }

Bis zu einem gewissen Maß an Komplexität lassen sich allerlei Optimierungen mit MediaQueries vornehmen, irgendwann kann allerdings kein Entwickler mehr den Durchblick behalten. Die Anzahl an CSS-Klassen wird unüberschaubar und die Redundanz vieler Angaben steigt, denn mit einem bisschen Copy-and-paste lassen sie sich an vielen Stellen im Code wiederverwenden. Dieses Problem lässt sich durch CSS-Präkompilierung mit einem SASS- oder LESS-Compiler schnell vermindern, häufig kann sich jedoch der Einsatz eines Grid-Systems als vorteilhafter erweisen.

Ein Grid sorgt für die Unterteilung des Layouts in Zeilen und Spalten. Jedes Gerät entscheidet anhand des verfügbaren Platzes, ob es die Spalten neben- oder untereinander darstellt. Viele Frameworks wie Twitter Bootstrap, Foundation oder Skeleton enthalten ein entsprechendes Werkzeug.

Zwar lassen sich komplexe Layouts ebenfalls mit floats und inline-blocks umsetzen, das ist meistens allerdings vergleichsweise aufwendig – gerade dann, wenn unterschiedliche Geräte zu berücksichtigen sind. Außerdem ist es ohne JavaScript nicht möglich, Elemente auf der Webseite anders anzuordnen. Mittlerweile gibt es Vorschläge für flexiblere Alternativen, zu denen die Flexbox und das CSS3 Grid Layout zählen.

Was ein display:block macht, sollte jedem Webentwickler bekannt sein. Laut Definition ist block ein Layout-Modus der beschreibt, dass Elemente einen Block bilden – ähnlich p oder dem div-Element. Durch den flex-Modus ergeben sich neue Möglichkeiten, Elemente innerhalb eines Containers auszurichten oder den Abstand zwischen den einzelnen Elementen automatisch zu optimieren. Der Container versucht dabei, die Elemente zu vergrößern, um den zur Verfügung stehenden Platz auszunutzen, oder zu verkleinern, um ein Überlappen zu verhindern.

Mit einem flex-Container lässt sich die Ausrichtung mittels flex-flow: row oder flex-flow: column den Kind-Elementen vererben. Je nachdem, welche Variante verwendet wurde, passt sich der Abstand links und rechts (row) beziehungsweise oben und unten (column) an.

.container {
display: flex;
flex-flow: row;
justify-content: center;
}

Mit der flex-flow-Eigenschaft lassen sich Elemente beliebig anordnen. Dabei passt sich der Abstand zwischen den Elementen automatisch an. (Abb. 1)

Anders als beim Flexbox-Modell ermöglicht das Grid-Layout eine flexible Positionierung von Elementen in Zeilen und Spalten innerhalb eines Containers. Bei RWD bedeutet das, dass sich Elemente optisch je nach Auflösung anders positionieren lassen. Momentan unterstützt nur der Internet Explorer (10+) dieses Feature, und es bleibt offen, ob WebKit oder mobile Browser nachziehen.

Die Position eines Elements innerhalb eines Grid-Containers können Entwickler über ein Koordinatensystem festlegen:

#container {
display: grid;
}

#element1 {
grid-column: 1;
grid-row: 1
}

#element2 {
grid-column: 3;
grid-row: 1;
}

Laut aktuellen Statistiken, besteht bei einer durchschnittlichen Webseite der größte geladene Anteil mit 62 Prozent aus Bildern. Grund genug, um ein absoluter Performancekiller bei RWD zu sein. Wie optimal in der responsiven Welt mit Bildern umzugehen ist, bleibt heute noch ein ungelöstes Rätsel. Doch eines ist jedem klar: Ein Bild mit hoher Auflösung auf einem kleinen Gerät mit langsamer Verbindung anzuzeigen, ist weder für den Besucher noch für die Bandbreite eine Lösung.

Im Idealfall sollte je nach Auflösung ein optimiertes Bild dargestellt werden. Das einzige Problem dabei ist, dass es für den Server keinen Unterschied macht, wer das Bild gerade anfordert. Selbst eine Abfrage der User Agents, sprich des Browsers, der sich anmeldet, bleibt eine ungünstige Lösung – vor allem da es im Moment viele unterschiedliche gibt und in Zukunft noch viele weitere hinzukommen. Außerdem sagt ein User Agent nur bedingt etwas über die Größe des Bildschirms und dessen Auflösung aus.

Die Auflösung lässt sich nicht auf Serverseite überprüfen, da sie erst clientseitig, also im Browser, zu ermitteln ist. Als Lösung bietet sich beispielsweise an, ein Cookie mit der Auflösung des Geräts zu setzen, bevor das erste Bild der Webseite geladen wird. Der nötige Wert lässt sich anschließend bei der Anfrage für das Bild auf dem Server ermitteln. Theoretisch funktioniert dieses Vorgehen ausgesprochen gut, denn das Setzen eines Cookies auf dem Client erfordert kein komplettes Laden der Seite.

In so gut wie jeder Technik gibt es die Möglichkeit, auf bestimmte Dateien wie Bilder zu horchen und die Anfragen so zu verarbeiten, dass sich Bilder dynamisch zuschneiden lassen. Ein Ablauf kann wie folgt beschrieben werden:

  • Ein kleiner Code-Schnipsel, der ein Cookie mit Informationen über die Auflösung setzt, wird beim Laden der Webseite im Head platziert.
  • Der Browser sendet bereits bei der ersten Anfrage eines Bildes den Cookie-Header mit. (Der Bereich im Head wird vor dem Body ausgeführt.)
  • Der Server routet die Bild-Anfragen (etwa über die .htaccess-Datei) an eine bestimmte Datei oder Komponente, die das Cookie ausliest, das Bild verkleinert und anschließend zurückliefert.
  • Die Komponente kümmert sich zusätzlich um das Ablegen des zurechtgeschnittenen Bildes im Cache (/image-cache/480/image.jpg), sodass es bei der nächsten Anfrage sofort zur Verfügung steht.

Diese Variante hat den Vorteil, dass am bestehenden HTML-Markup nichts zu ändern ist, allerdings kann sie sehr performanceintensiv sein und sie ist vom Ansatz her nicht ganz responsiv.

Die Responsive Images Community Group verfolgt mit dem Ansatz, verschiedene Bilder für verschiedene Auflösungen bereitzustellen, ein weiteres interessantes Konzept. Mit dem neuen picture-Element lässt sich ähnlich wie im HTML5-Video-Element die Ressource direkt in der HTML-Datei angeben:

<picture>
<source media="(min-width: 1024p)" src="image-hd.jpg">
<source media="(min-width: 480px)" src="image.jpg">
<source src="image-small.jpg">
<img src="image-small.jpg" alt="">
<p>Ein responsives Bild!</p>
</picture>

Apples Vorschlag an das W3C basiert auf Attributen, mit denen Entwickler Bilder steuern können. Wenn auch auf den ersten Blick mit etwas unverständlichen Angaben, besteht das srcset-Attribut aus dem Namen des Bildes, der Pixeldichte und des maximalen Viewports:

<img  alt="Ein responsives Bild!"
src="image.jpg"
srcset="image-hd.jpg 2x, image-phone.jpg 100w,
image-phone-HD.jpeg 100w 2x">

Die im Attribut verwendeten Regeln können wie folgt verstanden werden:

  • image.jpg: Standartbild
  • image-hd.jpg: für Geräte mit einer Pixeldichte (pixel ratio) größer als 2
  • image-phone.jpg: für Geräte mit einem maximalen Viewport von 100w (w steht hier für width)
  • image-phone-hd.jpg: für Geräte mit einem maximalen Viewport von 100w und einer Pixeldichte von höher als 2

Eine reine CSS-Lösung liegt als W3C Editor's Draft ebenfalls vor und wird bereits von Safari 6+ und Chrome 21+ unterstützt:

background-image: image-set( "image.jpg" 1x,
"image-hd.jpg" 2x,
"image-druck.jpg" 600dpi );

Letztendlich sollen die neuen Features voraussichtlich mit HTML 5.1 verfügbar sein, bis dahin ist eine JavaScript-Lösung höchstwahrscheinlich das Beste für einen produktiven Einsatz. Dafür bringt zum Beispiel PictureFill eine Reihe von mit data-Attributen versehenen Elementen ins Spiel, die, wenn auch nur mit JavaScript, zum selben Ergebnis führen, sprich anhand der Auflösung ein geeignetes Bild laden:

<span data-picture data-alt="Ein responsives Bild!">
<span data-src="image-klein.jpg"></span>
<span data-src="image-medium.jpg" data-media="(min-width: 400px)">
</span>
<span data-src="image-large.jpg" data-media="(min-width: 800px)">
</span>

<!-- Fallback content für non-JS Browsers. -->
<noscript>
<img src="image.jpg" alt="Ein normales Bild!">
</noscript>
</span>

Von einer anderen Sichtweise betrachtet, könnte vielleicht ein anderer, nicht von der Webseite abhängiger Weg zur Lösung dieses Dilemmas führen. Der Browser rendert ein klassisches Bild (zum Beispiel im JPG-Format) nach dem Top-to-bottom-Verfahren, das heißt, er baut es von oben nach unten auf. Einen anderen Ansatz verfolgen sogenannte Progressive JPGs: Sie werden erst in einer kleinen Auflösung geladen und dann (progressiv) immer schärfer. Die Bandbreite profitiert von der Idee nicht, es kann aber die Benutzerfreundlichkeit erhöhen, da sofort – wenn auch unscharf – ein Bild zu sehen ist.

Bilder sollten optimiert ausgeliefert werden, und eine weitere Herangehensweise zeigt, dass eine bestimmte Kombination von Auflösung und Kompressionsrate interessante Ergebnisse liefert. Rendert man ein Bild mit der doppelten Auflösung und einer höheren Kompressionsrate, benötigt es zwar weniger Speicher, lässt sich aber dennoch auf Bildschirmen mit hoher Auflösung relativ scharf anzeigen.

Das Privileg, mit pixelunabhängigen Vektorgrafiken zu arbeiten, blieb bisher den Designern vorbehalten. Mithilfe von SVG-Grafiken (Scalable Vector Graphic) lassen sich derart erstellte Bilder auch im Browser anzeigen. Mit einer kleinen Speichergröße, einer Skalierung ohne Qualitätsverlust und einer perfekten Darstellung – auch auf hochauflösenden Bildschirmen – eignet sich das Format ideal für responsive Webseiten. Icon-Fonts sind nur eine von vielen sinnvollen Einsatzmöglichkeiten. Ab Internet Explorer 9 und Android 2.3 können die entsprechenden Browser in den vollen Genuss dieser Technik kommen, für den Rest steht ein normales PNG-Bild per JavaScript-Fallback zur Auslieferung bereit:

<img src="bild.svg" onerror="this.onerror=null; this.src='bild.png'">

Auch Frameworks wie Mondernizr oder SVGeezy bieten kleine Helferlein, um mit JavaScript auf die Kompatibilität prüfen zu können:

if (!Modernizr.svg) {
$(".logo img").attr("src", "images/logo.png");
}

Eine funktionierende Navigation ist bei RWD essenziell. Der Besucher soll sich mobil, aber auch auf dem Desktop schnell zurechtfinden. Eine einzige Hauptnavigation mit vielen Punkten kann sich negativ auf die Benutzerfreundlichkeit mancher Geräte auswirken. Viele Webseiten wandeln das Menü auf kleineren Geräten in Dropdown-Listen um, was bei einer begrenzten Anzahl an Punkten zwar übersichtlich sein mag, aber spätestens ab einer tieferen Struktur mit mehreren Ebenen unübersichtlich wird. Es ist also in den meisten Fällen nicht empfehlenswert, mit Input-Elementen ein Pseudo-Menü-Control zu erstellen.

Das Beispiel des auf Mobilgeräten zugeklappten Menüs findet sich auf immer mehr Webseiten wieder. Ab einer bestimmten Auflösung verschwindet das Menü innerhalb eines Liste-Icons und wird erst bei Klick beziehungsweise Touch angezeigt (ein Implementierungsbeispiel ist im Exkurs "Responsive Navigation" zu finden). Diese Art der Umsetzung bringt einige Vorteile, denn es lassen sich mehrere Ebenen ineinander verschachteln, und durch die Implementierung auf zahlreichen Webseiten verstehen sie viele Besucher automatisch. Außerdem lässt sie sich für jede Auflösung optimieren, um beispielsweise auf einem Tablet in einer linken Spalte aufzuklappen, wie es native Anwendungen vormachen. Es gibt noch keine Pauschallösung, die in jedem Fall zu 100 Prozent die richtige ist, aber das Rad muss auch nicht neu erfunden werden, denn es haben sich schon viele Entwickler und Designer mit diesen Konzepten auseinandergesetzt.

Eine aufklappbare Navigation hat viele Vorteile und findet sich auf zahlreichen Webseiten wieder. (Abb. 2)


Mit vielen Textfeldern und unübersichtlichem Design bei Formularen ist ein Ausstieg der Nutzer auf mobilen Webseiten garantiert. Deshalb ist es wichtig, sie nicht nur kurz, sondern auch übersichtlich zu halten. Beispielsweise lassen sich Textfelder in vielen Fällen viel eleganter mit einer Checkbox, Radio-Buttons oder einer Dropdown-Liste ersetzen.

Bei der Validierung der Eingabe ist es besonders wichtig, dem Besucher sofort einen Hinweis auf fehlerhafte Eingaben zu geben. Beim Absenden des Formulars ist es meistens zu spät, denn ein Formular ist im Normalfall viel länger als ein Smartphone-Bildschirm hoch, was zu unnötiger Verwirrung führen kann.

Zahlreiche Frameworks bieten eine große Palette für hübsche Formulare und eine mächtige Validierung. Als Krönung bringt HTML5 einige Neuerungen mit, wie das require-Attribut für Eingabeelemente. Ganz ohne JavaScript erfährt der Besucher, dass es sich um ein Pflichtfeld handelt. Auch neue Form-Controls, wie ein number-, email-, range- oder date-Input, sorgen gerade auf mobilen Geräten für neue Interaktionsoptionen. So kann beim Fokussieren eines Datumsfeldes der mobile Browser sofort einen nativen Kalender öffnen, ohne immer auf eine Framework-UI-Komponente wie dem jQuery-Datepicker zurückgreifen zu müssen.

Da sie zum Teil nicht auf Touch-Geräte optimiert sind, kann eine lästige Überlappung von anderen Elementen die Folge sein. Bei E-Mail- oder Zahlenfeldern kann sich der Browser ebenso dafür entscheiden, eine angepasste und optimierte Tastatur anzuzeigen, um dem Besucher Zeichen wie "@" sofort anzeigen zu können.

date Ein Control für Datumsfelder, welches auf viele mobile Browser den nativen Kalender anzeigt <input type="date">
datetime Für das Datum und Zeit im UTC-Format <input type="datetime">
datetime-local Für das Datum und Zeit unter Verwendung der aktuellen Zeitzone <input type="datetime-local">
month Auswahl für Monat und Jahr <input type="month">
time Auswahl für die Zeit <input type="time">
week Auswahl für Woche und Jahr <input type="week">
color Ein Feld für die Eingabe von einfachen Farb-Werten (hexadezimal) <input type="color"">
email Ein Feld für die Validierung von e-Mail Adressen <input type="email">
tel Ein Feld für die Validierung von Telefonnummern gegen ein optionales Pattern <input type="tel">
search Für die Suche in einem Datenset (zum Beispiel in einem <datalist> HTML element) <input type="search">
range Ein Slider-Element für die einfache Auswahl einer Zahl, welcher zwischen zwei Zahlen liegt <input type="range">
number Ein Feld, welches nur Zahleneingaben akzeptiert <input type="number">
url Ein Feld, welches nur korrekte URLs akzeptiert <input type="url">

Nicht ohne Grund gibt es ab HTML5 zahlreiche neue Input-Felder (Tab. 1)

HTML5-Input-Felder bringen auf mobilen Geräten vielerlei Vorteile. (Abb. 3)


Eine responsive Webseite lässt sich auf vielerlei Arten testen – im einfachsten Fall, indem das Browser-Fenster größer und kleiner gezogen wird. Das lästige Ändern des Browser-Fensters lässt sich durch Werkzeuge wie die Chrome-Entwicklertools oder Online-Tools wie responsinator, responsivepx oder screenfly einfach ersetzen, inklusive vordefinierter Breakpoints für MediaQueries. Es ist aber zu beachten, dass die Online-Tools meist nur mit IFrame-Einbettung oder mit ergänzenden Scrollbalken arbeiten und somit nicht hundertprozentig pixelgenau sind. Die Simulation kann bei der Entwicklung von enormen Vorteil sein und eine wahre Zeitersparnis darstellen, trotzdem sollte das Ergebnis am Ende noch ausgiebig auf den jeweiligen Geräten getestet werden.

Die Chrome Entwicklertools zeigen, wie es geht: Per Mausklick lässt sich ein beliebiges Gerät emulieren, inklusive Einstellungen für Bildschirm, UserAgent und Sensoren. (Abb. 4)

Mit vielen Vorteilen, aber auch deutlichem Mehraufwand für Entwickler, präsentiert sich RWD als momentaner Hype in der Webszene. Mithilfe der richtigen Werkzeuge gestaltet sich das Erstellen einer responsiven Webseite angenehm unkompliziert. Eine eindeutige Empfehlung bei der Entscheidung für das richtige Frameworks gibt es allerdings nicht. Es ist also je nach Anwendungsfall zu überlegen, welches die meisten Vorteile mitbringt, welche die ideale Lösungen für Bilder ist und wie die Navigationbenutzerfreundlich bleibt. Grundlegende Patterns wie jene einer aufklappbaren Navigation und der HTML5-Input-Formulare sind mittlerweile weit verbreitet und lassen sich meist ohne große Bedenken einsetzen. Die Kosten-Nutzen-Analyse ist und bleibt momentan als Entscheidungshilfe unschlagbar und dient vielen Entwicklern und Unternehmen als Richtlinie.

Roberto Bez
ist passionierter Webentwickler und begeistert von neuen Technologien, die er versucht, in die tägliche Anwendungsentwicklung miteinzubringen.

Die hinterlegte Datei zeigt eine Beispielanwendung mit responsiver Navigation. Das Navigationselement ist wie folgt aufgebaut:

<header id="header">
<h1>Responsive Nav</h1>
<a class="nav-btn" id="nav-open-btn" href="#nav"></a>
</header>
<nav id="nav">
<a class="close-btn" id="nav-close-btn" href="#top"></a>
<ul>

<li>Willkommen</li>
<li>Über mich</li>
<li>Kontakt</li>

</ul>
</nav>

Mit den entsprechenden Anweisungen im CSS stellt sich Flexibilität ein:

body 
{
margin: 0;
padding: 0;
color: White;
font-family: Verdana;
}

#header
{
background-color: #343434;
padding: 20px;
text-align: center;
}

#nav
{
width: 100%;
background-color: #343434;
border-bottom: 3px solid black;
}

#nav-open-btn,
#nav-close-btn
{
position: absolute;
right: 10px;
top: 10px;
background-image: url(nav-icon.png);
display: block;
width: 20px;
height: 20px;
display: none;
}

#nav ul
{
list-style: none;
padding: 10px;
margin: 0;
text-align: center;
}

#nav ul li
{
display: inline-block;
padding: 5px;
}

#nav ul li:hover, .selected
{
background-color: #26a5e0;
}

@media (max-width: 480px)
{
#nav {
position: absolute;
top: 0px;
}

#nav ul {
margin-top: 25px;
}

#nav ul li
{
display: block;
}

/* Der Link zum öffnen/schließen des Menüs ändern den Anker #nav */
#nav:not(:target)
{
display: none;
}

#nav-open-btn, #nav-close-btn
{
display: block;
}
} (jul)