Gründe für responsive Design

Schätzung der Anteile unterschiedlicher Geräteklassen im WWW

“Mobile First” und “Responsive Design”

Unterschiedliche Philosophien in Bezug auf das dominante Gerät
Keine harten technischen Unterschiede
“Responsive Design” stellt das Desktopgerät in den Vordergrund
Darstellung wird für große Auflösungen geplant und “nebenher” auch auf kleinen Bildschirmen ermöglicht
“Mobile First” stellt das Mobilgerät in den Vordergrund
Schränkt das Design stark ein und hebt dafür die eigentlichen Inhalte hervor

Zur Anregung: mediaqueri.es

CapRadio Go Anywhere Raffle
CapRadio Go Anywhere Raffle
Think With Google
Think With Google

Technische Grundlage: CSS Media Queries

Einfache logische Ausdrücke um CSS-Selektoren oder -Dokumente einzuschränken
Angabe als Teil eines Selektors oder als Teil einer <link>-Referenz
Beschränken die Menge an Regeln, die vom Browser berücksichtigt werden
Regeln “hinter” unpassenden Media Queries sind quasi nicht existent

Unterscheidung von Geräteklassen

Gröbste Variante: Einschränkung anhand von Medientypen
Jedes Gerät entspricht nur einem speziellen Medientyp
Standardtyp: all
Die Regeln im Dokument sollen für alle Anzeigegeräte greifen
Typ screen für alle Arten von Bildschirmen
Feinere Unterscheidung anhand der im folgenden aufgeführten Eigenschaften möglich
Typ print für Druckausgabe
Nicht Thema dieser Veranstaltung, Darstellungsregeln weichen teilweise vom Browser ab
Typ speech für Sprachassistenzsysteme
Bisher nicht vernünftig definiert
Veraltet: tty, tv, projection, handheld, braille, embossed, aural
Haben sich nicht durchgesetzt und sollten nicht mehr verwendet werden

Unterscheidung anhand von “Media Features”

Selektion auf Basis von “Media Features”, also bestimmten Eigenschaften des Anzeigegerätes
  • width und height stehen für die Dimensionen des Viewports
  • aspect-ratio für das Seitenverhältnis des Viewports
  • orientation für die Ausrichtung des Geräts (portrait oder landscape)
Für numerische Eigenschaften: Angaben von Grenzen mit min und max Varianten
  • Für z.B. width stehen auch die Eigenschaften min-width und max-width zur Verfügung
  • Syntax beugt Kollisionen mit den > und < Klammern von HTML und CSS vor
Nicht-Anzeigeeigenschaften mit Media Queries Level 4
  • pointer Ist das primäre Eingabegerät ein “Zeigegerät” und wie akkurat ist es (none, coarse, fine)?
  • hover Ist das primäre Eingabegerät in der Lage “über” Elementen zu “schweben”?
  • scripting Steht eine Skriptsprache (faktisch: JavaScript) zur Verfügung?
Mehrere Eigenschaften können über logische Operatoren kombiniert werden
  • Logisches “UND” mit dem and-Operator
  • Logisches “ODER” als komma-separierte Aufzählung
  • Logische Negation mit dem not-Operator

Beispiele für Media Queries

Syntax: Vergleichende Angaben stets in Klammern, Medientypen können direkt genannt werden
Angabe des Medientyps ist optional, implizit wird dann all angenommen
Hinweis: Angaben wie min-width und max-width nutzen stets die bzw Operatoren
Bei Angabe von identischen Größen also Überlappungen
(width: 1024px) and (height: 768px)
Selektor für alle Geräte mit exakt 1024 * 768 Bildpunkten
screen and (min-width: 1024px) and (min-height: 768px)
Selektor für alle Bildschirme mit mindestens 1024 * 768 Bildpunkten
screen or ((max-width: 1024px) and (max-height: 768px))
Selektor für Bildschirme oder alle Ausgabegeräte mit maximal 1024 * 768 Bildpunkten
Nutzung des Attributs media
Wert ist die anzuwendende Media Query

Syntax für Media Queries als Teil von Selektoren

Syntax: Angabe von Media Queries hinter dem @media-Schlüsselwort
Gültigkeitsbereich wird durch einen Block mit geschweiften Klammern definiert
  • responsive/media-query-selector.html | Validieren
    <h1 class="portrait">Hochformat!</h1>
    <h1 class="landscape">Querformat!</h1>
    
  • responsive/media-query-selector.css
    @media screen and (max-width: 300px) {
        body { background-color: red; }
    }
    
    @media screen and (min-width: 301px) and (max-width: 1024px) {
        body { background-color: green; }
    }
    
    @media screen and (min-width: 1025px) {
        body { background-color: blue; }
    }
    
    @media (orientation: portrait) {
        .landscape { visibility: hidden; }
    }
    
    @media (orientation: landscape) {
        .portrait { visibility: hidden; }
    }
    
    

Konflikte bei der Verarbeitung von Media Queries

Allgemein: Media Queries blenden enthaltene Regeln aus oder ein
Regeln in nicht zutreffenden Media Queries quasi nicht existent
Daher: Vereinigung aller Regeln, deren Media Queries zutreffen
Gewichtung nach den bekannten Regeln für Spezifität

Zur Größe von Pixeln

Moderne Mobilgeräte bieten Full-HD Auflösungen (und mehr) auf ~ 5”-Bildschirmen
Zweck ist eine schärfere Darstellung von Vektorelementen, insbesondere Text
Angabe von z.B. width: 300px auf solchen Geräten im Allgemeinen nicht sinnvoll
Pixel sollten sich stattdessen ungefähr “wie auf dem PC” verhalten
Daher: Pixel sind ein Winkelmaß, deren Größe möglichst nah am an einem gut sichtbaren “Referenzpixel” ist

“The reference pixel is the visual angle of one pixel on a device with a pixel density of 96dpi and a distance from the reader of an arm’s length. For a nominal arm’s length of 28 inches, the visual angle is therefore about 0.0213 degrees.”

Durch “überzählige” Pixel bei hohen Pixeldichten wird das Bild also schärfer
(Sofern das zu betrachtende Material dies zulässt)
Definition des CSS-Pixels
Definition eines Pixels
Umsetzung von CSS-Pixeln auf Gerätepixel
Umsetzung von CSS-Pixeln auf Gerätepixel

Für Mobilgeräte: Viewport einstellen

Historisch: Seiten wurden für Auflösungen ≥ 1024x768 optimiert
Und mussten trotzdem auf den ersten Smartphones angezeigt werden können
Folge: Mobile Browser gehen von Desktop optimierten Seiten aus
“Beweis” des Gegenteils notwendig, Seiten müssen sich explizit als kompatibel ausweisen
Mittel: Angabe der nicht standarisierten meta-Eigenschaft viewport
Für Interessierte: “A tale of two viewports” von Peter-Paul Koch - Teil 1, Teil 2
Syntax: Komma-separierte Liste von Schlüssel-Wert-Paaren
Kopiervorlage: <meta name="viewport" content="width=device-width, initial-scale=1.0">
Eigenschaften width und height legen die Größe des Viewports fest
Praktisch relevant: Skalierung der Breite mit width=device-width
Eigenschaft initial-scale setzt den initialen Zoom-Faktor
  • Mit dem Attribut user-scalable (mögliche Werte: on und off) kann dem Benutzer die Anpassung des Zooms verweigert werden
  • Mit den Attributen minimum-scale und maximum-scale lassen sich die Skalierungsmöglichkeiten beschränken

Praktisches Beispiel: Responsive Flexboxen

Grundidee: Umschalten verschiedener Flexbox-Eigenschaften je nach Größe des Anzeigegerätes
Identischer HTML-Code für alle Anzeigegeräte

Die Ausgangslage

Zur Erinnerung: Dreispaltiges Layout mit Flexboxen
Unpraktische Anzeige auf Mobilgeräten
  • responsive/flex-style.css
    body {
        background-color: yellow;
    }
    
    header, nav, article, aside, footer {
        background: lightgray;
        border: 1px solid black;
        padding: 10px;
    }
    
    nav, article, aside {
        min-height: 100px;
    }
    

Anpassung für Mobilgeräte

  • responsive/flex-mobile.css
    #flex {
        display: flex;    
    }
    
    @media (min-width: 601px) {
        nav, aside {
            width: 200px;
        }
    
        article {
            flex-grow: 1;
        }
    }
    
    @media (max-width: 600px) {
        #flex {
           flex-direction: column;
        }
    }
    
  • responsive/flex-mobile.html | Validieren
    <header>
      Drei Spalten mit Flex
    </header>
    
    <div id="flex">
      <nav>nav</nav>
      <article>article</article>
      <aside>aside</aside>
    </div>
    
    <footer>footer</footer>
    

Typische Umsetzung: Gridsysteme

Menschen denken gerne in Layouts aus Zeilen und Spalten
Intuitives Verständnis ohne lange Einarbeitungszeiten
Folge: Viele Frameworks mit künstlichen CSS-Klassen für Zeilen und Spalten
Zum Beispiel Bootstrap, Foundation, Bulma, …
Semantisch eine fragwürdige Entscheidung, aus Sicht der Frameworks aber alternativlos
Gestaltung nur mit CSS-Klassen bietet größtmögliche Flexibilität
Anschauungsbeispiel von Bootstrap
Zeigt neben dem eigentlichen Grid-System noch fortgeschrittene Funktionalität
In nicht all zu ferner Zukunft: CSS-Grids
Lesezeichenempfehlung: A Complete Guide to Grid

Grundproblem: Grenzen für die Media-Query-Selektoren

Welche konkreten Werte sollen für min-width und max-width eingesetzt werden?
Konkret: Wann wird von der Smartphone-Darstellung auf die Tablet-Darstellung gewechselt?
Lässt sich nicht allgemeingültig beantworten
  • Wann ist ein Smartphone kein Smartphone, sondern ein Tablet?
  • Was ist mit “Profi-Tablets” wie dem 12.9”-iPad Pro?
  • Wieviele Geräteklassen gibt es überhaupt? Und wieviele können wir unterstützen?
Im Falle von Bootstrap: 5 Größenklassen
  • Extra Small, <576px
  • Small, ≥576px
  • Medium, ≥768px
  • Large, ≥992px
  • Extra Large, ≥1200px

Grundlagen für ein (sehr einfaches) Grid-System

  1. Grundsätzliche Entscheidung: Eine Zeile kann bis zu 6 Spalten haben
    Praktische Wahl wäre 12 (T12= {1,2,3,4,6,12}), das schreibt sich aber umständlich
  2. Grundsätzliche Entscheidung: Unterstützung von drei Geräteklassen
    phone (< 576px), tablet (> 576px) und desktop (> 992px)

Definition einer Zeile

Trivial: Direkte Nutzung von Flexboxen
Zusätzlich: Umbrüche erlauben mit flex-wrap

Definition einer Spaltenklasse

Ähnlichkeiten zur flex-grow-Eigenschaft, aber:
  • Umbruch in die nächste Zeile bei zu vielen Spalten (≥ 7)
  • “Halbvolle” Zeilen erwünscht
Redundant: CSS-Regeln können nicht parametrisiert werden, daher müssen für alle verfügbaren Breiten eigene Regeln geschrieben werden
Nutzung von relativen Angaben erlaubt Verschachtelung von Zeilen
  • responsive/grid-column.css
    .row {
        display: flex;
        flex-wrap: wrap;
    }
    
    .col-1 { width: calc(1 * (100% / 6)); }
    .col-2 { width: calc(2 * (100% / 6)); }
    .col-3 { width: calc(3 * (100% / 6)); }
    .col-4 { width: calc(4 * (100% / 6)); }
    .col-5 { width: calc(5 * (100% / 6)); }
    .col-6 { width: calc(6 * (100% / 6)); }
    
    /* Optische Hervorhebung */
    [class^="col-"] {
        background-color: yellow;
        box-sizing: border-box;
        border: 1px solid red;
    }
  • responsive/grid-column.html | Validieren
    <div class="row">
      <div class="col-6">.col-6</div>
    
      <div class="col-5">.col-5</div>
      <div class="col-1">.col-1</div>
    
      <div class="col-4">.col-4</div>
      <div class="col-2">.col-2</div>
    
      <div class="col-2">.col-2</div>
      <div class="col-2">.col-2</div>
      <div class="col-2">.col-2</div>
    
      <div class="col-2">.col-2</div>
      <div class="col-1">.col-1</div>
    
      <div class="col-5">.col-5</div>
      <div class="col-4">.col-4</div>
      <div class="col-3">.col-3</div>
      <div class="col-4">.col-4</div>
    </div>
    

Definitionen spezieller Spaltenklassen

Noch mehr Redudanz: CSS-Regeln wurden für Desktop- oder Tablet-Geräte dupliziert
Auf Mobilgeräten: Jede Spalte mit voller Breite
  • responsive/grid-responsive-column.css
    .row {
        display: flex;
        flex-wrap: wrap;
    }
    
    @media (min-width: 992px) {
        .col-desktop-1 { width: calc(1 * (100% / 6)); }
        .col-desktop-2 { width: calc(2 * (100% / 6)); }
        .col-desktop-3 { width: calc(3 * (100% / 6)); }
        .col-desktop-4 { width: calc(4 * (100% / 6)); }
        .col-desktop-5 { width: calc(5 * (100% / 6)); }
        .col-desktop-6 { width: calc(6 * (100% / 6)); }
    }
    
    @media (min-width: 576px) and (max-width: 991px) {
        .col-tablet-1 { width: calc(1 * (100% / 6)); }
        .col-tablet-2 { width: calc(2 * (100% / 6)); }
        .col-tablet-3 { width: calc(3 * (100% / 6)); }
        .col-tablet-4 { width: calc(4 * (100% / 6)); }
        .col-tablet-5 { width: calc(5 * (100% / 6)); }
        .col-tablet-6 { width: calc(6 * (100% / 6)); }
    }
    
    @media (max-width: 575px) {
        .col-tablet-1, .col-tablet-2, .col-tablet-3,
        .col-tablet-4, .col-tablet-5, .col-tablet-6,
        .col-desktop-1, .col-desktop-2, .col-desktop-3,
        .col-desktop-4, .col-desktop-5, .col-desktop-6 {
            width: 100%;
        }
    }
    

Manchmal notwendig: Elemente ausblenden

Einfachste Lösung: Eigenschaft display auf den Wert none setzen
Verhindert jede Darstellung und jeden Einfluss auf das Layout

Umgang mit Druckern

Problem: Interaktive Elemente wie Suche oder Navigation sind auf Druckern wertlos
Interaktion schlicht nicht möglich
Problem: Farbausgabe potenziell teuer und auch keine Verbesserung des Schriftbilds
Viele Browser ignorieren daher Hintergrund-Farbangaben im Druck
Gewünscht: Explizite Quellenangabe für den Ausdruck
URL wird von einigen Browsern nicht mit vermerkt

Umgang mit Grafiken

Problem: Bilder sollten für unterschiedliche Endgeräte in unterschiedlichen Auflösungen vorliegen
Kein Mobilgerät möchte mit Bildern für 4K-Bildschirme bombardiert werden
Lösung: Vektorgrafiken skalieren perfekt
Problem: Eignen sich nicht für alle Arten von Bildern
Lösung: <picture>-Element in Kombination mit Media-Queries
Keine Unterstützung vom Internet Explorer, Darstellung dennoch möglich
  • responsive/picture.html | Validieren
    <picture>
      <source srcset="/assets/screenshot/game-high.png"
              media="(min-width: 1000px)">
      <source srcset="/assets/screenshot/game-low.png"
              media="(max-width: 400px)">
      <img src="/assets/screenshot/game-mid.png">
    </picture>