CSS/Tutorials/Einstieg/Media Queries

Aus SELFHTML-Wiki
< CSS‎ | Tutorials‎ | Einstieg
Wechseln zu: Navigation, Suche

Was vielen nicht bewusst ist: HTML ist von Haus aus responsiv - Elemente wie Überschriften oder Absätze nehmen die gesamte Breite des Viewports ein und brechen überstehenden Text um, so dass er nach unten in einer neuen Zeile dargestellt wird. Erst eine starre Mehrspaltigkeit verhindert die passende Darstellung auf mobilen Geräten.

Dieses Tutorial zeigt, wie Sie Webseiten so erstellen, dass sie flexibel und repsonsiv auf jedem Gerät dargestellt werden.


responsiv - was ist das?[Bearbeiten]

Webseiten sollen responsiv sein und sich flexibel an den verfügbaren Platz anpassen. Dabei müssen die Inhalte nicht gleich aussehen, sondern gut lesbar sein - welcher Nutzer vergleicht eine Seite gleichzeitig auf mehreren Geräten?

Moderne Handys sind vollwertige Computer mit kleinen Bildschirmen. Sie versuchen Webseiten so zu verkleinern, dass diese auf den kleinen Bildschirm „passen“. Dann ist allerdings die Schrift viel zu klein und die Seite muss erst mit den Fingern auseinandergezogen werden. Um dies zu vermeiden, müssen Sie eine Zeile in den head Ihrer Weseite einfügen:

<meta name="viewport" content="width=device-width, initial-scale=1.0">

Mit dieser Zeile erreichen Sie, dass die Webseite von Anfang an in „normaler“ Schriftgröße angezeigt wird und dann vom Benutzer weiter gezoomt werden kann.

Media queries[Bearbeiten]

Eine Stärke von CSS liegt darin, die Darstellung eines Dokuments mit Hilfe von Medienabfragen (media queries) je nach Ausgabemedium verschieden festlegen zu können. So können Sie im Druckbereich von der normalen Bildschirmansicht abweichende Formatierungen festlegen. Ihre volle Stärke entfalten Media Queries mit Hilfe von Medienmerkmalen, mit denen Sie z.B. unterschiedliche Viewport-Breiten berücksichtigen können.

Breakpoints: Inhalt über Design[Bearbeiten]

Für welche Geräte muss ich wann Breakpoints setzen?

So oder ähnlich lauten viele Fragen im Forum. Die Antwort darauf lautet: "Gar nicht!"

Viewportauflösungen heutiger Geräte
Quelle: https://opensignal.com/reports/fragmentation.php

Derzeit aktuelle Geräteauflösungen können morgen schon überholt sein. Richten Sie lieber die Breakpoints am Inhalt aus:

  • Überlegen sie sich, ab wann dieser bei einer bestimmten Viewportbreite nicht mehr gut aussieht.
  • Bei Text ist es eigentlich egal, höchstens ein max-width: 60em;, damit die Zeilen nicht zu lang werden.
  • Bei Grafiken und bestimmten Seitenelementen sollten Sie flexible, prozentuale Breiten verwenden, damit Bilder
    • auf schmalen Bildschirmen 100% breit dargestellt werden
    • auf Tablets in landscape-Modus nebeneinander oder
    • auf breiten Bildschirmen drei oder vier nebeneinander dargestellt werden.

Hierbei gibt es zwei Ansätze:

Desktop first[Bearbeiten]

Erstellen Sie die Seite, schieben Sie Ihr Browserfenster zusammen und fügen Sie dort Media Queries ein, wo Ihnen das Layout um die Ohren fliegt. Das nennt sich Desktop-First.

Beispiel: umständliche Vorgehensweise mit Desktop first!
aside {
  float: left;
  width: 50%;
}

@media (max-width: 50em) {
  aside {
    float: none;
    width: auto;
  }
}

Mobile first[Bearbeiten]

Alternativ ziehen Sie das Browserfenster eng zusammen und erstellen die Seite. In einem zweiten Schritt ziehen Sie das Fenster auseinander und fügen Media Queries dort ein, wo die zusätzliche Breite sie sinnvoll machen. Das nennt sich dann Mobile-First.

Designing for mobile first forces you to embrace these contraints to develop an elegant mobile-appropriate solution. But the benefits go well beyond mobile. Small screen sizes force you to prioritize what really matters to your customers and business.

Luke Wroblewski, Mobile First[1]

Luke W. betont, dass dieser Ansatz Webentwickler dazu zwingt, elegante Lösungen für mobile Geräte zu entwickeln, sich aber auch bei großen Viewports auf das Wesentliche zu konzentrieren.

Beispiel: empfehlenswerte Vorgehensweise mit Mobile first!
aside {
  /* nur Farb- und Hintergrundformatierungen */
}

@media (min-width: 50em) {
  aside {
    float: left;
    width: 50%;
  }
}
Empfehlung:
Verwenden Sie den Mobile first! -Ansatz.
Dieser ist (wie in den oberen Beispielen ersichtlich) kürzer und ermöglicht einen übersichtlicheren Aufbau der Webseite.

flexibles Grid Layout[Bearbeiten]

Das Beispiel aus dem vorherigen Kapitel hatte drei, auf kleinen Geräten sehr schmale Spalten. Mit media queries wird nun die Breite des Bildschirms abgefragt und das Layout entsprechend angepasst:

Beispiel: flexibles Grid-Raster ansehen …
@media (min-width: 50em) {
  article {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
  }
}
Dieses Beispiel besticht durch seine Einfachheit:
  • Das article-Element wird ab einer Mindestbreite von 50em durch display: grid zum flexiblen Grid-Container.
  • Dieser erhält mit grid-template-columns: repeat(3, 1fr); drei gleichbreite Spalten
  • Die einzelnen section-Elemente und das aside verteilen sich ohne weitere Festlegung gleichmäßig auf den verfügbaren Raum.

Fügen Sie im Frickl ein neues Kindelement von article ein. Was können Sie beobachten?

Dies Beispiel kann noch verfeinert werden: Während das aside mit seinen Links nur ca. 15em Platz benötigt, sollte der Text in den section-Elementen so viel Raum wie möglich zur Verfügung gestellt werden.

Deshalb sollte das aside-Element bei genügend Platz in einer weiteren Spalte rechts angeordnet werden, die section-Elemente aber erst dann in Spalten dargestellt werden, wenn auch dafür genug Platz ist.

Beispiel: responsives Layout 2 ansehen …
@media (min-width: 30em) {
  article {
    display: grid;  
	grid-template-columns:  2fr 15em;
  }	
  section {
    grid-column-start: 1;
  }
  aside {
    grid-column-end:  -1;
    grid-row-start:    1 ;
  }
}

@media (min-width: 60em) {
 article {
   grid-template-columns: repeat(3,1fr);
 }	
   section {
    grid-column-start: auto;
  }
}
Dieses Beispiel folgt dem Grundsatz "Mobile first!" und enthält nach den Farbfestlegungen zwei media queries:
  • Auf kleinen Viewports nehmen alle Blockelemente ohne weitere Festlegungen die volle Breite ein.
  • Ab einer Mindestbreite von 50em trifft die Medienabfrage @media (min-width: 30em) zu und es wird ein zweispaltiges Raster angelegt: Während die rechte Spalte eine feste Breite von 15em hat, nimmt die linke den verfügbaren restlichen Raum ein und gibt so dem Fließtext der section-Elemente den nötigen Platz.
    Normalerweise würde das zweite section-Element die zweite Rasterzelle einnehmen -
    • grid-column-start: 1; legt fest, dass diese immer die Zellen der linken Spalte belegen.
      Das aside enthält ähnliche Angaben
    • grid-column-end: -1;: Das Ende soll die letzte (-1 entspricht der ersten von hinten) Spaltenlinie sein
    • grid-row-start: 1 ;: Der Beginn soll in der ersten Reihe sein
  • Ab einer Mindestbreite von 50em wird mit grid-template-columns: repeat(3, 1fr); das normale Dreispaltenlayout eingeführt.
    • Damit sich das zweite section-Element automatisch auf die zweite Spalte verteilt, wird der Wert von grid-column-start auf auto gesetzt.

relative Größen[Bearbeiten]

Ein wie eingangs erwähntes Konzentrieren auf die Auflösungen bestimmter Geräte führt zu einer mangelnden Flexibilität, da User durch strg + + oder ein Fingerauseinanderziehen die Schriftgröße einer Seite verändern können. Dies führt bei festen Größen, die schlimmstenfalls sogar noch in Pixeln angegeben sind, zu einem zerschossenen Layout.[2] Zell Liew hat dies getestet und in einem anschaulichen Artikel PX, EM or REM Media Queries? verarbeitet.[3]

Beispiel: relative Größen
/* Mobile first */

nav li {
  display: block;
}

@media (min-width: 35em) { 
  /* Festlegungen */ 
  nav li {
    display: block;
    width: 50%;
  }

@media (min-width: 50em) { 
  nav li {
    display: inline;
    width: 50%;
  }
}
In einem ersten Block werden Formatfestlegungen der einzelnen Elemente ohne Breitenangaben notiert. Dadurch dehnen sie sich komplett über den verfügbaren Raum aus.

Ab einer Breite von 35em, was nicht nur von der absoluten Breite des Viewports, sondern auch der vom Benutzer eingestellten Schriftgröße abhängt, werden manche Inhalte, wie z.b. die einzelnen Links der Navigation in zwei Spalten dargestellt.

Ab einer Breite von 50em könnte man dann alle Links nebeneinander darstellen.


Empfehlung:
Um benutzereigene (Schrift-)Größenänderungen zu berücksichtigen, sollten Sie
  • relative Schriftgrößen wie em oder rem
  • das Medienmerkmal width anstelle des starren device-width
verwenden.[4]

min-width vs. max-width[Bearbeiten]

In welcher Reihenfolge Sie media queries verwenden, hängt auch von der Defaultdarstellung in Browsern ab. Blöcke (section, article, div etc.) werden untereinander dargestellt – so wie man es für kleine Viewports haben möchte. Wenn Sie auf größeren Viewports Blöcke nebeneinander haben möchten, dann ändern Sie das Defaultverhalten nur für größere Viewports – mit @media (min-width: …).

Für responsive Tabellen bspw. wäre es aber unsinnig, erst

table, caption, colgroup, col, thead, tbody, tfoot, tr, th, td { display: block }

zu setzen und dann mit

@media (min-width: …)
{
  table    { display: table }
  caption  { display: table-caption }
  colgroup { display: table-column-group }
  col      { display: table-column }
  thead    { display: table-header-group }
  tbody    { display: table-row-group }
  tfoot    { display: table-footer-group }
  tr       { display: table-row }
  th, td   { display: table-cell }
}

mühsam den Ursprungszustand wiederherzustellen.

Stattdessen ändern Sie die Defaultdarstellung eben nur für kleine Viewports – mit max-width:

@media (max-width: …)
{
  table, caption, colgroup, col, thead, tbody, tfoot, tr, th, td { diplay: block }
}

So stehen dann @media (min-width: …)- und @media (max-width: …)-Regeln in friedlicher Koexistenz im selben Stylesheet.[5]

ultraweite Breakpoints[Bearbeiten]

Die Monitore auf den Schreibtischen und bei Home Entertainment Systemen an der Wand werden immer größer und größer und ein Ende der Entwicklung ist nicht abzusehen.

Anstelle von ultraweiten Breakpoints empfiehlt es sich hier einfach eine maximale Breite anzugeben.

Beispiel: maximale Breite bei sehr großen Bildschirmen
#container {
    margin: 0 auto;
    max-width: 100em; 
}

Exkurs: Magic Numbers[Bearbeiten]

Mit festen Zahlenwerten (auch engl. „Magic Numbers“ genannt) erreichen Sie unter bestimmten Umständen das Gewünschte, aber in anderen Kontexten wie geänderten Viewport- oder Schriftgrößen wird das Layout zerstört. Meistens wurden sie von Entwicklern verwendet, die nur in ihrem eigenen Browser unter Idealbedingungen getestet wurden.

Empfehlung: Verwenden Sie
  • keine festen Werte für die Breite
  • keine festen Werte für die Höhe eines Elements, sondern lassen dem Inhalt (auch bei geänderter Schriftgröße) den nötigen Platz. Regeln Sie Abstände über padding.
  • relative relative Längenmaße wie em, die sich an geänderte Schriftgrößen anpassen.

weitere Medienmerkmale[Bearbeiten]

Pixeldichte[Bearbeiten]

Gerade bei großen Monitore ist nicht nur die Auflösung, sondern auch die Pixeldichte entscheidend für die perfekte Darstellung[6]. Natürlich können Sie diese ebenfalls per Medienmerkmal abfragen:


Beispiel: Pixeldichte
@media 
(-webkit-min-device-pixel-ratio: 2), 
(min-resolution: 192dpi) { 
    /* Retina-spezifische Angaben */
}
Das Medienmerkmal resolution überprüft, welche Pixeldichte der Bildschirm hat. Ein Anwendungsfall wären Hintergrundbilder, die auf hochauflösenden Bildschirmen zweimal geladen würden.


Empfehlung: Verwenden Sie das proprietäre Medienmerkmal device-pixel-ratio nur als Fallback.

Inhalte mit Media Queries beeinflussen[Bearbeiten]

Für Webentwickler ist die Versuchung groß, eine Webseite an einem großen Bildschirm zu entwickeln und den verfügbaren Raum zusätzlich zum Hauptinhalt mit weiteren, eigentlich aber nicht notwendigen Inhalten zu füllen. Es ist sinnvoll, auf einer mobilen Seite mit kleinem Viewport, geringeren Datenübertragungsraten und Volumensbegrenzungen nur die eigentlichen Inhalte anzuzeigen.

Während es früher sehr schwierig war, durch Conditional Comments, Auslesen der User-Agent-Kennung oder ein Auslesen von innerHeight Geräte zu erkennen, können Sie heute Media Queries auch in JavaScript einsetzen.

Die matchMedia()-Methode ermöglicht es bequem Medienmerkmale abzufragen und dann z. B. passend zusätzliche Inhalte nachzuladen.


Beispiel
if (window.matchMedia("(min-width: 35em)").matches) {
  // Der Viewport ist mindestens 35em breit 
} else {
  // Das Medienmerkmal trifft nicht zu, alle anderen Viewports 
}
Beachten Sie: Eine weitere Abfrage, ob anstelle von :hover touch Events verwendet werden sollen, ist keine Frage der Bildschirmabmessungen. Es gibt auch 27-Zoll-Touchgeräte sowie kleine Bildschirme mit Tastaturbedienung.

Quellen[Bearbeiten]

  1. Luke W: Mobile First
  2. creativebloq: Determining breakpoints for a responsive design
  3. Zell Liew: PX, EM or REM Media Queries?
  4. sitepoint: Media Queries: Width vs. Device Width
  5. Selfhtml-Forum: min-width vs. max-width von Gunnar Bittersmann
  6. css-tricks: Retina Display Media Query

Weblinks[Bearbeiten]


Siehe auch[Bearbeiten]