Artikelformat

Modernizr: HTML5 und CSS3 geschickt nutzen

Als PHP-Entwickler schreibt man nicht nur am Backend, sondern muss auch eine optisch-ansprechende Oberfläche bieten. Inzwischen sind viele Effekte die unter HTML 5 und CSS 3 zusammengefasst werden können in den verschiedenen Browsern implementiert. Die Browser-Hersteller haben zum Teil eigene Feature implementiert, zum Teil Working Drafts umgesetzt und somit haben wir den Zustand, dass eine einheitliche CSS oder JavaScript nicht überall gleich aussieht bzw läuft.

Wenn man nun die Features dennoch nutzen möchte, so kann man oftmals auf Fallback-Lösungen zurückgreifen. Farbverläufe lassen sich bspw. durch einfache Farben ausdrücken oder möglicherweise durch Bilder ersetzen.

Um den verschiedenen Methoden einer Implementierung Rechnung zu tragen, müsste man die in den Urzeiten des Internets beliebten Banner „optimiert für Browser XY“ einbauen, oder eine automatische Browserweiche nutzen. Eine ausgefeilte Art ist heutzutage eine Feature-Weiche. Das bedeutet, dass nicht nur nach Browser und Version unterschieden wird, sondern je nach implementierten Feature. Das heißt, ist ein Feature durch eine neue Version eines Browsers verfügbar, sieht die Seite – falls entsprechend umgesetzt – direkt besser aus.

Eine sehr gute Bibliothek, die eine Überprüfung der angebotenen Feature auf CSS- und JavaScript-Ebene bietet ist der Modernizr. Die Bibliothek umfasst nur 3.7kb und lässt sich leicht in eine bestehende Seite integrieren. Danach findet man im HTML-Tag eine ganze Reihe CSS-Klassen. Diese repräsentieren die einzelnen Features und zeigen ebenfalls ob das entsprechende Feature genutzt werden kann.

Der oben genannte Farbverlauf zum Beispiel wird durch die cssgradients Klasse ausgedrückt. Wenn der Browser dieses Feature nicht unterstützt, dann findet sich die Klasse no-cssgradients im HTML-Tag. In der CSS Datei kann man dies dann verwerten.

Möchte man Features nutzen, die im JavaScript Bereich Anwendung finden, wie bspw. Webworker, Websockets u.ä., so kann man auch auf eine Property des Modernizr Objekts zugreifen. Im Farbverlauf-Beispiel wäre dies Modernizr.cssgradients.

Zu beachten ist, dass Modernizr keine neuen Funktionen in einen Browser einbaut, sondern nur eine Schnittstelle liefert.

Den Modernizr baut man wie bei JavaScript üblich im Header der Seite ein:

<html>
<head>
...
<script src="mordernizr-1.7.min.js" type="text/javascript"></script>
...
</head>
...
</html>

Die vielfach angesprochenen Farbverläufe sehen dann im css bspw. so aus:

.no-cssgradients #nav {
    background-color:#E7F9FF;
}
.cssgradients #nav {
    background-image: -moz-linear-gradient(center bottom, #E7F9FF 25%, #FFFFFF 100%);
    background-image: -o-linear-gradient(bottom, #E7F9FF, #FFFFFF);
    background-image: -webkit-gradient( linear, left bottom, left top, color-stop(0.25, #E7F9FF), color-stop(1.0, #FFFFFF));
}

Tip für die Blogger:
Es gibt auch ein WordPress-Plugin, das den Modernizr sehr einfach einbindet.

8 Kommentare

  1. „Den Modernizr baut man wie bei JavaScript üblich im Header der Seite ein:“

    üblich vielleicht, optimalerweise aber direkt vorm schließenden tag 😉

    Antworten
    • Na klar. Man kann auch noch combining nutzen. Also Optimierungen sind immer erlaubt.

  2. Ich hab mir sowas vor ein paar Tagen selbst schreiben müssen, weil …

    … modernizr muss in den head eingebaut werden

    … modernizr testet tausend Sachen, die ich niemals brauchen werde und man kann diese nur von Hand aus dem Quelltext entfernen. Ich wollte ein Pluginsystem

    … modernizr bringt keinen Performancegewinn (wie z. B. head.js)

    … modernizr bringt keine neuen Funktionen, wie z. B. eine JS Alternative für media query (mit denen ich im Moment viel mache)

    Antworten
  3. Ich habe mal über den Kommentar von wusa geschlafen und siehe da, schon gibt es neue Anmerkungen.

    Aber trotzdem muss ich sagen, dass der Modernizr in den Head gehört.
    Da die Reihenfolge in der die weiteren Skripte geladen werden wichtig ist, kann man zwar head.js nutzen aber es werden css-Klassen ins öffnende HTML-Tag eingefügt.
    Wenn man nun den Moderinzr ans Ende der Seite packt, wird diese gerendert, dann werden die Klassen geändert und sie muss wieder gerendert werden.
    Das ist ein ziemlicher Overhead.

    @Oliver: kann man dein Skript irgendwo sehen?

    Antworten
  4. Wenn man nun den Moderinzr ans Ende der Seite packt, wird diese gerendert, dann werden die Klassen geändert und sie muss wieder gerendert werden.
    Das ist ein ziemlicher Overhead.

    Browser sind dafür gebaut, Webseiten und andere Elemente ständig neu zu rendern. Wenn Du die Fenstergröße änderst müssen ja auch alle Elemente neu aufgebaut werden. Bei Media Queries können sich ja ganze Seitenabschnitte radikal ändern. Die größte Performancebremse, die ich gefunden habe war, dass der Browser wartet bis das Javascript runtergeladen und ausgeführt ist. Ich lass mal modernizr dabei weg und nehm nur head.js in das Beispiel.

    Folgendes Beispiel: seite, head.js, jquery im schlimsten Szenario bei deaktiviertem Cache, mittelmässiger Verbindung und langsamen Rechner

    Szenario 1: Nur jQuery im header => Die Seite bleibt weiß, bis jQuery geladen und ausgeführt wurde, was je nach Rechner/Verbindung schon mal 2 bis 3 Sekunden dauern kann.

    Szenario 2: Nur jQuery im Footer => Die Seite wird in Teilen geladen und blockiert kurz vor Ende merkbar bis jQuery geladen und ausgeführt ist.

    Szenario 3: head.js im header. Die Seite wird sofort angezeigt. Andere Javascripte werden nachgeladen. Der Haken ist, dass auch hier der Browser nur eine weiße Seite anzeigt bis head.js komplett geladen und ausgeführt ist. Das geht aber schneller als bei jQuery.

    Szenario 4: Mein Script im footer. Seite wird geladen und wird sofort angezeigt. Kurz vor Fertigstellung blockiert die Seite kurz und lädt dann die anderen Scripte nach. Die Blockierung hält sich dabei allerdings in Grenzen, weil meine Version noch kleiner als head und modernizr sind, wegen der fehlenden Tests (Ich teste nur auf wenige Sachen). Die Seite ist aber fühlbar schneller und sofort les- und benutzbar. Da mein Rechner nicht der schnellste ist, ergibt sich noch ein kleiner Vorteil. Die Prozessorlast wird besser verteilt, da der Browser sich zunächst auf das runterladen und rendern konzentriert und erst danach den Javascriptfoo zaubert. Dadurch hat der Browser erst Gelegenheit alles anzuzeigen und danach die volle Prozessorlast zum nacharbeiten zu nutzen.

    Bei letzter Version sind ein paar Sachen zu beachten:

    Das Javascript darf nicht direkt in den dom schreiben also kein document.write verwenden, aber das macht ja hier keiner.
    Man darf in der Seite keine Aufrufe von jQuery machen. Mit einem $(document).ready() kann der Browser während der Ladezeit nichts anfangen. Man muss immer nachträglich mit jQuery prüfen, ob es z.B. ein Objekt gibt, das ein Eingreifen nötig macht.
    Die Seite muss auch ohne Javascript benutzbar sein. Wird der Inhalt immer per Ajax nachgeladen, macht das keinen Sinn, weil die Ausführung von Javascript einfach nach hinten verschoben wird und damit im Ergebnis langsamer daher kommt. Diese Lösung ist nur dann sinnvoll, wenn Javascript erweiternd eingreift z. B. Elemente oder Funktionen für die Javascript nötig ist, nachträglich anzeigt oder einfügt werden wie bei Formularüberprüfungen.

    @Oliver: kann man dein Skript irgendwo sehen?

    Ich teste da noch rum und werd dann wohl meine Erkenntnisse an head.js weitergeben, damit die alternativ ein foot.js machen können.

    Antworten
  5. Nunja, es gibt Browser die rendern schneller geschickter als andere. Das mögliche „Zucken“ der Seite beim erneuten Rendern durch Änderungen der CSS-Klassen kann vom Benutzer als störend empfunden werden.

    Übrigens kann man mit Caching die Downloadzeit gegen 0 drücken. Dann geht es wirklich nur noch um das verarbeiten des Javascripts. Und der Modernizr bietet (erst ab Version 2, wenn ich mich richtig erinnere) die Möglichkeit, nur die Tests im JS bereitzustellen, die der Entwickler braucht. Somit kommt man noch unter die 3.7kb.

    Vielleicht sollte ich verschiedene Ansätze vergleichen und dazu mal etwas schreiben?

    Antworten
  6. Nunja, es gibt Browser die rendern schneller geschickter als andere. Das mögliche “Zucken” der Seite beim erneuten Rendern durch Änderungen der CSS-Klassen kann vom Benutzer als störend empfunden werden.

    Stimmt, mit 40% IE8 und 15% IE6 wäre ich da auch vorsichtig, allerdings würde ich auch dann nicht auf html5 und css3 setzen.

    Das Zucken habe ich insofern nicht, weil ich Javascript visuell möglichst dezent einsetze. Da passiert zwar im Hintergrund viel, aber in der Ansicht ändert sich wenig. Also z. B. Links auf Ajaxfunktionen zu ändern – klickt ein User zu schnell, hat er halt den normalen Link.

    Was geht, versuche ich mit CSS zu lösen wie den Fallback bei css3 gradients und wenn ein Element unbedingt eine bestimmte css3 Funktion benötigt, weil es sonst nix aussieht, dann blende ich die standardmässig aus und verteile ein position:absolute, damit sich der Aufbau nicht ändert. Bei zusätzlichen Buttons oder Icons ebenfalls. Wenn JS deaktiviert ist, muss die Seite ja trotzdem voll funktionsfähig sein.

    Ich habe auch was bei headjs dazu ausführlicher geschrieben.
    https://github.com/headjs/headjs/issues/143

    Übrigens kann man mit Caching die Downloadzeit gegen 0 drücken.

    Ja, es geht nur um den ersten Aufruf oder wenn der Cache deaktiviert ist. Aber gerade das kann wichtig sein. Wenn ich eine Landingpage hab und die braucht 4 Sekunden, bis sie überhaupt mal irgendwas anzeigt, dann hab ich zu viele Kunden verloren. Der gemeine Surfer hat halt keine Zeit. 🙂

    Vielleicht sollte ich verschiedene Ansätze vergleichen und dazu mal etwas schreiben?

    Warum nicht!?

    Antworten

Schreibe einen Kommentar

Pflichtfelder sind mit * markiert.