Gunther: EM basierte Media Queries

Hallo werte Selfgemeinde!

Ich bin gerade auf ein "Problem" gestoßen und würde gerne eure Meinung dazu hören/ lesen.
Und zwar geht es um Media Queries auf Basis von EM als Einheit.

Ich möchte hier jetzt nicht näher auf die Gründe für EM basierte Media Queries gegenüber solchen unter der Verwendung von PX als Einheit eingehen. Wer sich diesbezüglich "schlau" machen möchte, wird bei Google problemlos fündig.

Jetzt hat man bei der Verwendung von Media Queries ja grundsätzlich zwei Möglichkeiten.
Entweder man verwendet "überlappende" (overlapping) MQs, oder sich "stapelnde" (stacking) MQs.

Beide Varianten haben, wie eigentlich immer im Webdesign, Vor- und Nachteile.
Persönlich sehe ich u.a. einen der Vorteile von sich stapelnden MQs darin, dass man nicht darauf achten muss, ggf. vorherige Anweisungen wieder zu überschreiben. Aber auch das soll jetzt nicht näher erörtert werden. Gehen wir also bitte einmal davon aus, dass ich sich stapelnde MQs mit EMs als Einheit verwenden möchte.

Dabei tritt jetzt folgendes Problem auf:
Bei sich stapelnden MQs muss die Abgrenzung ja normalerweise pixelgenau erfolgen. Und genau hierin besteht das Problem bei der Verwendung von EMs.

Beispiel:
Angenommen der User hat seine Basis-Schriftgröße im Browser so eingestellt, dass diese 16px entspricht. Dann wären die beiden folgenden MQ Regeln identisch

  
@media only screen and (max-width: 20em) {...}  
@media only screen and (max-width: 320px) {...}  

Die nächste Regel würde bei Verwendung von PX als Einheit dann wie folgt aussehen:

  
@media only screen and (min-width: 321px) and (max-width: ...px) {...}  

Um diese Regel jetzt aber mit EMs zu formulieren, muss man rechnen. Aufgrund unserer obigen Annahme, entspricht 1px jetzt ja 1/16em, oder dezimal 0,0625em. Und unsere MQ Regel sähe also folgendermaßen aus:

  
@media only screen and (min-width: 20.0625em) and (max-width: ...em) {...}  

Hat ein User aber seine Basis-Schriftgröße bspw. auf 24px eingestellt, dann ergibt unser Dezimalwert für 1px in EM: 0,0625 * 24 = 1,5
Und da Browser am Ende ja nur mit ganzzahligen Pixelwerten arbeiten können, wird dieser Wert also auf 2 aufgerundet. Und schon haben wir eine "Lücke" in unserem MQ Regelhaufen, die u.U. dazu führen kann, dass keine Regel "matched".

Umgekehrt, falls ein User eine kleinere Basis-Schriftgröße eingestellt hat, besteht ein ähnliches Problem. In diesem Fall besteht die Möglichkeit, dass sich Regeln überschneiden!

Die Lösung für dieses Problem wäre ganz einfach, nämlich wenn Browser die calc() Syntax in MQs unterstützen würden. Wenn man also schreiben könnte:
@media only screen and (min-width: (20em + 1px)) and (max-width: ...em) {...}

Wie seht, bzw. macht ihr das?

Gruß Gunther

  1. Hallo,

    Hat ein User aber seine Basis-Schriftgröße bspw. auf 24px eingestellt, dann ergibt unser Dezimalwert für 1px in EM: 0,0625 * 24 = 1,5
    Und da Browser am Ende ja nur mit ganzzahligen Pixelwerten arbeiten können, wird dieser Wert also auf 2 aufgerundet. Und schon haben wir eine "Lücke" in unserem MQ Regelhaufen, die u.U. dazu führen kann, dass keine Regel "matched".

    Ja, gut. Das stimmt im Prinzip. Das Problem kann ich im Firefox nachvollziehen. Es kann sein, dass bei einem Pixel nach der Schwelle keine der beiden Stacked Media Queries angewendet wird. Das ist natürlich fies, weil dann das Layout kaputt sein kann.

    ABER: Ist das nicht völlig hypothetisch? Dass der Nutzer die Schriftgröße so ändert, halte ich für unwahrscheinlich. Dass er sie so ändert, dass ein Rundungsproblem entstehen kann, ist noch unwahrscheinlicher. Dass der Viewport zusätzlich exakt Schwellenwert + 1px groß ist, verringert die Wahrscheinlichkeit weiter.

    Realistisch gesehen gibt es Schwellen wie 320, 480, 640, 960, 768, 1024 usw. Dazwischen gibt es theoretisch gesehen alles, aber praktisch ist das sehr selten. Da muss ich mein Browserfenster auf genau 321, 481, 961, 769, 1025 usw. ziehen und dann auch noch wild an der Basis-Schriftgröße drehen, damit der Fehler auftritt. Wer das macht: Selbst schuld, kein Mitleid. Genauer geht Responsive Design gerade noch nicht.

    Wenn ich das als realistisches Problem sähe, würde eher Overlapping Media Queries nutzen oder Stacked und Overlapping kombinieren, sodass im Fehlerfalle ein Grundlayout angewendet wird.

    Ich sehe es aber nicht als realistisches Problem, daher würde mit gutem Gewissen min-width: 20.0625em verwenden. :)

    Grüße,
    Mathias

    1. Hallo Mathias,

      schön dass wenigstens einer antwortet - danke! :-)

      Ich fasse deine Antwort mal zusammen:

      Das stimmt im Prinzip.
      Ist das nicht völlig hypothetisch?
      Realistisch gesehen ... muss ich mein Browserfenster auf genau 321, 481, 961, 769, 1025 usw. ziehen und dann auch noch wild an der Basis-Schriftgröße drehen, damit der Fehler auftritt.
      Wer das macht: Selbst schuld, kein Mitleid. Genauer geht Responsive Design gerade noch nicht.

      So in etwa sehe ich das wohl auch.
      Von den von dir genannten "common breakpoints" würde ich jedoch abweichen, u.a. schon wegen der Problematik, dass Chrome und Opera eine evt. vorhandene Scrollleiste nicht mit berücksichtigen.

      Also nochmals besten Dank!

      Gruß Gunther

      1. Kleiner Tipp noch, beim Testen ist mir aufgefallen, das em-Media-Queries im aktuellen Chrome 26 falsch interpretiert werden – als wäre 1em kleiner als 16px (meine Standardschriftgröße).

        Der Fehler scheint glücklicherweise in Chrome Canary (identifiziert sich als Version 28) behoben zu sein.

        Es wunderte mich schon, einen so gravierenden Bug in einem aktuellen Browser zu finden…

        Grüße,
        Mathias

        1. Hallo Mathias!

          Kleiner Tipp noch, beim Testen ist mir aufgefallen, das em-Media-Queries im aktuellen Chrome 26 falsch interpretiert werden – als wäre 1em kleiner als 16px (meine Standardschriftgröße).

          Das ist ja "interessant" ...!
          Ich verwende zum Testen u.a. die 'View Responsive Layouts' Funktion der Webdeveloper Toolbar in Chrome (26.0.1410.64) unter Windows. Da ist mir dieses Verhalten bisher gar nicht aufgefallen.

          Und auch bei meinem Chrome (26.0.1410.58) unter Android auf dem Smartphone konnte ich das bisher nicht feststellen.

          Hast du mal ein Beispiel?

          Der Fehler scheint glücklicherweise in Chrome Canary (identifiziert sich als Version 28) behoben zu sein.

          Es wunderte mich schon, einen so gravierenden Bug in einem aktuellen Browser zu finden…

          Mich "ärgert" etwas anderes viel mehr ... - im Moment jedenfalls. ;-)

          Besten Dank!

          Gruß Gunther