Mobile First & IE8 Fallback mit Sass

Um die Begriffsklärung „Mobile First“ soll es heute nicht gehen. Das ist teils eine philosophische Frage und viele behaupten zurecht, bevor man sich über Design und die Umsetzung Gedanken macht, sollte der Content, für den man gestaltet, vorliegen — also quasi „Content First“. Für viele hat aber „Coffee First“ am Morgen eines Arbeitstages die höchste Priorität. ;)

In dem Artikel geht es um die technischen Möglichkeiten für den Internet Explorer 8 automatisiert eine optimierte ähnlich gute Ansicht der Responsive Website zu generieren.

Problem: der IE8 unterstützt keine Media Querys.

Wenn man technisch gesehen „Mobile First” entwickelt, bedeutet das, dass der erste Media Query kein Media Query ist und alle Geräte zuerst die „mobile Ansicht“ bekommen. Die Layout-Anpassungen mit Media Querys würden von klein zu groß gemacht, nicht umgekehrt. Da der IE8 keine Media Querys unterstützt, ignoriert er die Styles, die innerhalb diesen definiert sind, und macht die Anpassungen nicht mit. Demzufolge zeigt er die „Smartphone-Ansicht“. Oftmals wäre das nicht mal so schlimm, das Ergebnis ist oft übersichtlicher und performanter. ;)

Andererseits ist es natürlich auch nachvollziehbar, dass das Kunden nicht ausreicht und man den Usern mit IE8 eine „Desktop-Ansicht“ präsentieren möchte.

IE8 Verbreitung in Deutschland

StatCounter browser version DE-monthly 2012/11-2013/11
Statistik über Browser-Versionen in Deutschland

Was ich grundsätzlich nie empfehle, dem IE8 über Scripte wie respond.js oder CSS3-mediaqueries.js ein responsives Verhalten zu implementieren. Den IE8 gibt es nicht auf mobilen Endgeräten, er ist fast ausschließlich auf Windows XP Rechnern, vereinzelt noch auf Vista Rechnern, installiert. Hier surfen die User sehr häufig mit dem IE über die volle Bildschirmbreite. Seiten, die bisher nicht ins Fenster gepasst haben, bekamen einen horizontalen Scrollbalken. Das ist der Ansatz, den ich immer empfehle: Der IE8 bekommt eine Desktop-Ansicht. Diese kann auch ein Stück weit flexibel (mit min- und max-width) sein, aber passt sich nicht „responsive“ an. Die zusätzlichen Scripte machen den IE8 nur noch langsamer, als er schon ist.

responsive Hinweis
Die responsiven Frameworks Foundation sowie Bootstrap sind technisch auch auf den „Mobile First” Ansatz umgestiegen und unterstützen somit den IE8 nicht mehr. Das sollte man beachten, wenn man diese Frameworks produktiv einsetzt.

IE8-Fallback-Stylesheet mit Sass

Oft werde ich gefragt, wie ich das mache und sage dann meist „ganz einfach – mit Sass“. ;)

Sass-IE von Jake Archibald ist ein kleines Mixin-Plugin, mit dem man „Mobile First“ Media-Querys schreiben kann und gleichzeitig ein Stylesheet für IE < 9 ohne @media Angaben generiert wird. Grundsätzlich benötigt man zwei sog. Sass-Manifest-Dateien, im Beispiel von Sass-IE ist das all.scss und all-old-oldie.scss. In der all.scss werden all (haha) unsere Sass-Dateien importiert und eine Variable $fix-mqs auf false gesetzt.

// all.scss
$fix-mqs: false !default;
@import styles.scss;

In der Datei all-old-oldie.scss wird die Variable $fix-mqs auf den Wert gesetzt, der für den IE als „Desktop-Min-Width“ gelten soll. Hier im Beispiel 65em. Zudem muss die Variable $old-ie: true; gesetzt sein und die all.scss importiert werden.

// all-old-oldie.scss
$old-ie: true;
$fix-mqs: 65em;
@import 'all';

Media Querys werden in Sass nun wie folgt benutzt:

.component {
  color: red;
  @include respond-min(32em) { color: green; }
  @include respond-min(65em) { color: blue; }
}

Sass generiert daraus folgendes CSS.

/* all.scss */
.component {
  color: red;
}
@media screen and (min-width: 32em) {
  .component {
    color: green;
  }
}
@media screen and (min-width: 65em) {
  .component {
    color: blue;
  }
}
/* all-old-ie.scss */
.component {
  color: red;
  color: blue;
}

Das Mixin „respond-min“ im Detail:

$fix-mqs: false !default;
@mixin respond-min($width) {
  // wenn die Ausgabe an ein fixed Media Query erfolgen soll
  @if $fix-mqs {
    // wenn $fix-mqs einen Wert hat
    @if $fix-mqs >= $width {
      // und der Wert größer/gleich 
      // der übergebenen Breite ist
      // dann den übergebenen Inhalt parsen
      @content;
    }
  }
  @else {
    // andererseits ein Media Query Bereich generieren 
    // und Inhalt parsen
    @media screen and (min-width: $width) {
      @content;
    }
  }
}
// es gibt natürlich auch ein respond-max mixin, 
// das das macht, was man erwartet

$old-ie: false !default;

CSS in die HTML-Datei integrieren

Die beiden CSS-Dateien werden über Conditional Comments in die Seite eingebunden. Zuerst die oldIE-Datei, dann unsere CSS-Datei mit den Media Querys. Der IE8 erkennt das oldIE Stylesheet und ignoriert den zweiten Conditional Comment, da er anscheinend für den Internet Explorer größer IE8 gilt. Der IE9 merkt, dass der erste Conditional Comment nicht für ihn bestimmt ist und lädt das zweite Stylesheet. Der IE10/IE11 und alle anderen modernen Browser ignorieren Conditional Comments und laden das zweite Stylesheet. Das Besondere an dieser Stelle ist, dass der HTML-Kommentar hinter dem öffnenden Conditional Comment gleich wieder geschlossen wird: <!-->. Moderne Browser erkennen, dass der zweite Conditional Comment sofort wieder geschlossen wird und laden die verlinkte CSS-Datei.

<!--[if lte IE 8]>
  <link rel="stylesheet" href="css/all-old-ie.css">
<![endif]-->

<!--[if gt IE 8]><!-->
   <link rel="stylesheet" href="css/all.css">
<!--<![endif]-->

Einzelne Eigenschaften (Hacks) nur für oldIE
Die kleine Mixin-Library von Jack bringt noch ein kleines old-ie Mixin speziell für einzelne IE-Hacks mit.

@mixin old-ie {
    // Only use this content if we're dealing with old IE
    @if $old-ie {
        @content;
    }
}

Man könnte hier z.B. eine Fallback-Lösung für RGBA-Farbwerte mitgeben.

So schön wie die Lösung funktioniert, hat sie doch ein paar Nachteile. Media Querys werden nur für einen Wert (min-width bzw. max-width) und ein Medium (@media screen …) ausgegeben. Es ist also nicht möglich ein Media Query für zwei Werte zu schreiben. @media screen and (min-width: 450px and max-width: 650px) geht damit leider nicht. Dennoch ist es ein großer Gewinn ein Stylesheet, dass schon zum größten Teil für die Desktop-Darstellung im IE8 optimiert ist, automatisch bei der „Mobile First“ Entwicklung zu generieren.

5 thoughts on “Mobile First & IE8 Fallback mit Sass”

  1. „Was ich grundsätzlich nie empfehle, dem IE8 über Scripte ein responsives Verhalten zu implementieren. (…) Die zusätzlichen Scripte machen den IE8 nur noch langsamer, als er schon ist.“

    Hast Du mal gemessen, was respond.js in Sachen Performance tatsächlich ausmacht? So lange jemand nicht ständig die Größe des Fensters ändert – was der normalsterbliche User wohl eher nicht tut (unsterbliche User benutzen keinen IE8) – sortiert das Script die CSS Angaben doch nur passend.

    „Responsive“ bedeutet ja nicht nur „mobile“, die Hürde „Laptop zu HD+“ ist genau so wichtig diese Tage. Warum sich zusätzliche Arbeit machen, der IE8 kann doch, sofern man ihn unterstützen will, mittels Script genau so daran teilhaben wie alle anderen Browser auch. Oder?

  2. Danke für deinen Kommentar, aber der IE8 muss sterben! Da neige ich eher dazu zu sagen, dass er gar keine Extrawurst bekommt. Und eine Website im IE8 Fullscreen 100% auf 1920px muss auch nicht sein. ;) Aber grundsätzlich gebe ich dir Recht, das muss von Fall zu Fall geprüft werden.

  3. Ach so, ich dachte, hier ginge es um die Extrawurst :D … ja, sterben muss er, das stimmt. Diese Meinung kann man unter Umständen beim Client-from-hell aber nur schwer vertreten. Also, die Ansicht schon, nicht aber die Erklärung warum die Website des Kunden zu diesem Vorhaben beitragen soll ;)

  4. Hallo Sascha,

    ich habe vor ca. 2 Jahren mal einen respond.js Test gemacht für das H5BP. Dort kam raus, dass der Chrome durch die Ausführung von respond.js im Head (sonst macht es ja sowieso keinen Sinn) einen Delay von ~110ms bekommt + Ladezeit des Scripts an sich.
    Dies im Chrome (damals der einzig messbare Browser).

    Für den IE8 gilt damit: Renderzeit für JS ca. 4-8x so lange wie Chrome = 400-800ms. Außerdem ist es wahrscheinlich, dass der IE das Script delayen muss, weil seine 4 offenen parallelen Requests schon voll mit CSS und anderem sind. Das bedeutet, dass man sogar in den Sekundenbereich geht, was ein respond.js ausmachen kann.
    Grob gefühlt nachgemessen (analog, da keine Tools dafür da), habe ich das ungefähr bestätigen können im IE8 – eine halbe Sekunde war es bestimmt, die respond.js das Rendering der Seite blockierte.
    Das als kleiner Denkanstoß dazu. Wie gesagt, nicht wissenschaftlich belegt, aber durchaus fundiert nachgemessen im Chrome.

Kommentare sind geschlossen.