ECMAScript 5, die nächste Version von JavaScript – Teil 1: Ein Überblick

Veröffentlicht am 5. April 2011

Heimlich, still und leise hält die nächste Version von JavaScript Einzug in unsere Browser. Überschattet von Trubel um HTML5 und CSS3 merkt fast keiner, dass neben HTML und CSS auch das oft so verkannte JavaScript dabei ist, ein größeres Update zu erfahren und dass sich somit alle drei Grundpfeiler des Webs – HTML, CSS und eben JavaScript – weiterentwickeln. Dieser Artikel soll der Startschuss zu einer kleinen Serie sein, in der wir einen Blick auf ECMAScript 5 (oder kurz ES5) und damit die nähere Zukunft von JavaScript wagen werden. Besonderes Augenmerk werden wir natürlich darauf richten, in welchem Umfang die verschiedenen Neuerungen schon zu gebrauchen sind, doch unser erster Blick gilt den Hintergründe von ES5. Was ist eigentlich „ECMAScript“ und wieso hat es die Versionsnummer 5?

Was ist ECMAScript und wieso gibt es Version 5?

Als Anfang der 90er Jahre Brendan Eich für Netscape innerhalb weniger Tage eine kleine Browser-Programmiersprache zusammenschraubte, grassierte der Java-Wahn. Man war sich damals so sicher, dass Java die wichtigste Programmiersprache der Zukunft sein würde, dass man aus Marketinggründen entschied, die neue Browser-Programmiersprache JavaScript zu nennen – obwohl beide Technologien sich auch nicht nur im entferntesten ähneln. Dass man damit bis in alle Ewigkeit Verwirrung bei Webentwicklern stiften würde, war weniger wichtig, als dass man dort war, wo man damals „vorne“ vermutete.

JavaScript had to look like Java only less so, be Java’s dumb kid brother or boy-hostage sidekick.

 – Brendan Eich

Seither hat sich viel getan. Java hat überraschenderweise nicht die Weltherrschaft übernommen und stattdessen hat sich ausgerechnet JavaScript von einer Spielerei zur wichtigsten Programmiersprache der Welt verwandelt. Aufgrund des Namens-Deals, den Netscape seinerzeit mit dem Java-Entwickler Sun Microsystems eingefädelt hatte, liegen die Namensrechte heutzutage beim momentanen Sun-Besitzer Oracle, während die Spezifikationen der Sprache von einer privaten Normierungsorganisation namens Ecma International (ehemals ECMA – European Computer Manufacturers Association) gepflegt werden. Das, was wir alle als JavaScript kennen und bezeichnen, ist also eine Implementierung eines Standards namens ECMAScript bzw. ECMA-262.

Die letzte von allen heute verbreiteten Browsern unterstützte Fassung des Standards ist die dritte Edition von ECMA-262, die im November 2000 verabschiedet wurde. Die Pläne zu einer vierten Edition zerschellten unvollendet an ihren eigenen Ansprüchen – man wollte zu viel, konnte sich nicht einigen und stellte schließlich die Arbeit an der vierten Edition ein. So kam es, dass jetzt mit der fünften Fassung ein vergleichsweise bescheidenes Update im Anflug ist, ohne dass es je eine vierte gegeben hätte. Erklärtes Ziel von ECMAScript 5: die Sprache entrümpeln und robuster machen, damit man in Zukunft ein gutes Fundament für dann wieder hochtrabendere Pläne hat.

Was kann die neue Version?

Dafür, dass Brendan Eich nur wenige Tage Zeit hatte um JavaScript zu entwickeln und nebenbei unter enormem Druck aus der Netscape-Führungsetage stand, kann sich das Ergebnis sehen lassen.

I had to be done in ten days or something worse than JS would have happened.

 – Brendan Eich

Doch trotzdem haben sich aufgrund der Kürze der Zeit einige sehr sonderbare Eigenschaften in die Sprache eingeschlichen. Eine kleine Auswahl mit Beispielen, die sicher die meisten von uns kennen:

// Ergibt "object" statt "array"
typeof [];

// "bar" wird eine _globale_ Variable, weil das "var" vergessen wurde
function foo(){
    bar = 42;
}

// Ergibt "8"
parseInt('010');

Zwar hat jede Programmiersprache so ihre Macken, doch nur bei wenigen füllen die WTF-Momente ganze Websites und sogar Bücher. Oberstes Ziel von ES5 ist es, die Anzahl der genannten WTF-Momente zu reduzieren. Außerdem soll die Rubustheit von JavaScript erhöht werden – die Zeiten, als jedes Objekt jederzeit manipuliert werden konnte, sind vorbei. Und auch das Webentwickler-Leben soll durch eine Handvoll neuer Helferlein erleichtert werden. Im Einzelnen sind dabei:

  • Scripte und Teile von Scripts können in einen Strict Mode versetzt werden, in dem einige defekte JS-Altlasten (z.B. with(){}) nicht mehr verwendet werden können und der an einigen Stellen die Regeln von JavaScript so verändert, dass es weniger WTF-Momente gibt.
  • Mittel und Wege, um Objekte gegen Manipulationen zu sichern werden ebenso eingeführt wie Getter- und Setter-Methoden für Objekteigenschaften
  • Viele neue Helferlein lösen ganz alltägliche Probleme und reduzieren den Bedarf an kryptischen Eigenbau-Lösungen und Boilerplate-Code. Genannt seien unter anderem Object.create() (erstellt in einem Arbeitsschritt ein Objekt und legt seinen Prototyp fest), Array.isArray() und Array.prototype.forEach()

Einige dieser Features werden von heutigen JavaScript-Frameworks bereits bereitgestellt, so dass man sich durchaus fragen kann, ob ES5 einen überhaupt kümmern sollte.

Muss mich als jQuery-Nutzer ES5 überhaupt interessieren?

Wer wirklich niemals mehr macht, als via Framework ein paar DOM-Knoten durch die Gegend zu schrieben, kommt vermutlich die nächste Zeit auch ohne detaillierte Kenntnisse der meisten ES5-Features über die Runden. Einiges anderes, wie zum Beispiel die durchaus vorhandenen Gefahren des Strict Mode, sollte man aber in jedem Fall auf dem Schirm haben. Und schließlich gilt: die neuen Features einer Programmiersprache aus einer informierten Perspektive heraus zu ignorieren ist immer besser, als sie aus Gründen der Ignoranz nicht zu verwenden. Ebenfalls zu bedenken ist, dass JavaScript auch außerhalb des Browser mehr und mehr um sich greift. Egal ob Node.js oder Windows-Widgets, so manche Offline-Anwendung ist bereits heute in JS geschrieben. Und es ist nicht damit zu rechnen, dass sich dieser Trend so bald umkehrt – vor allem nicht, wenn die Sprache durch frische Features immer attraktiver wird.

Welche Browser unterstützen ES5 und wie geht es weiter?

JavaScript hat wie jede Browsertechnologie das Problem, dass man nicht einfach so eine neue Version rausbringen kann, die dann innerhalb kürzester Zeit überall verfügbar ist. Allerdings ist bei ES5 die Lage nicht ganz schlimm, wie man dieser Kompatibilitätstabelle entnehmen kann. Der Internet Explorer 8 ist, wie zu erwarten war, der Internet Explorer 6 von ES5, aber alle anderen Browser enthalten schon viele ES5-Features. Insbesondere bei Chrome, Firefox ab Version  4 und Internet Explorer ab Version 9 kann man von sehr guter Unterstützung sprechen. Die Lage stellt sich also rosig genug dar, um eine kleine Artikelserie zu rechtfertigen. Sofern sich genügend freie Zeit auftreiben lässt, werden es in den nächsten Wochen und Tagen noch vier weitere Artikel zum Thema ES5 erscheinen, die Einzelaspekte unter die Lupe nehmen. Wenn alles nach Plan läuft, werden wir in ein paar Tagen als erstes den Strict Mode behandeln – Feedback und Sonderwünsche sind dabei wie immer gern gesehen!

HTML5 ... und dann?

Veröffentlicht am 23. März 2011

Dieser Artikel ist Teil einer Serie:

  1. HTML5 im Überblick (externer Link; lokale Kopie)
  2. HTML5-Geolocation (externer Link; lokale Kopie)
  3. Semantisches HTML5 (externer Link; lokale Kopie)
  4. Das Canvas-Element (externer Link; lokale Kopie)
  5. HTML5 … und dann? (externer Link; lokale Kopie)

Wie wir an den bisherigen HTML5-Artikel gesehen haben, ist HTML5 nicht etwas für die ferne Zukunft, sondern es bereits im Hier und Jetzt angekommen. Alle modernen Browser unterstützen wichtige Teile des Funktionsumfangs schon heute und kein Browserhersteller macht Anzeichen, das Aufrüsten einzustellen. HTML5 ist die Gegenwart, HTML 4.01 und XHTML 1 die Vergangenheit. Da stellt sich natürlich die Frage, was die Zukunft denn nun anstelle von – oder ergänzend zu – HTML5 für uns bereit hält. Was bringt CSS3? Wohin wird sich JavaScript entwickeln? Und wann kommt HTML6?

Wohin geht die HTML5-Reise?

Aufgrund der im Geolocation-Artikel angesprochenen Probleme, “HTML5” genau zu definieren (allgemeiner Sprachgebrauch versus Spezifikationen versus Mehrfach-Spezifikationen) ist es nicht ganz einfach, eine Zukunftsvision zu formulieren. Klar ist allein: die Anzahl der nützlichen APIs in Webbrowsern wird in Zukunft nicht weniger werden. Viele neuere Browserreleases enthalten allerlei von HTML5 inspirierte Schnittstellen, die sich, wenn sie sich auf breiter Front durchsetzen sollten, als nützlich erweisen könnten – genannt seien als Beispiel die von Chrome bereits unterstützten Dateisystem- und Notification-APIs. An Spielzeug wird es dem experimentierfreudigen Webentwickler in Zukunft sicher nicht fehlen.

Etwas spannender ist die Frage, wohin das Nebeneinander von W3C und WHATWG führen wird. Die beiden Spezifikationsausfertigungen, die zwischenzeitlich beide als einigermaßen gleichberechtigte HTML5-Specs verstanden werden konnten, entwickeln sich mittlerweile in unterschiedliche Richtungen. Während das Werk der W3C-Arbeitsgruppe auf einen Snapshot des aktuellen HTML5-Entwicklungsstandes hinaus zu laufen scheint, hat die die WHATWG ihre Fassung zum „Living Standard“ erklärt und dokumentiert darin auch das Neueste vom Neuen. Was immer es an Neuentwicklungen im HTML-Universum gibt, die WHATWG-Spezifikationen nehmen sie nahtlos auf, während sich das W3C auf eine saubere Darstellung des stabilen Status Quo von vor ein paar Monaten konzentriert.

Das Ganze scheint für den Moment stabil, aber was passiert, wenn das W3C mit HTML5 fertig ist? Die WHATWG-Line besagt, dass HTML5 das Ende der Geschichte ist und dass alle Neuerungen nahtlos darin einfließen. HTML6 wird es demnach nie geben, eine versionierte Entwicklung von HTML sei angesichts der ständigen und schnellen Entwicklung von Webtechnologie überholt. Genau deshalb gibt in in “HTML5” auch kein Leerzeichen vor der 5 im Namen – das ist keine Versionsnummer, sondern “HTML5” ist ein eigenständiger Name. Diese Pläne kollidieren natürlich leicht mit den althergebrachten Versionierungsplänen des W3C. Wie all das endet, ob das Nebeneinander zementiert wird oder man sich vielleicht eines Tages auf eine gemeinsame Arbeitsgruppe (oder zumindest eine gemeinsame inhaltliche Linie) einigt, ist noch nicht abzusehen.

Welche Rolle spielt CSS3?

CSS3 wird manchmal mit HTML5 in einen Topf geworfen – manche sprechen sogar von “Web8” als Kombination aus HTML5 und CSS3. Allerdings ist diese Zusammenfassung schon etwas weit hergeholt, denn nicht nur haben beide Technologien historisch nichts miteinander zu tun, auch ist die Zielsetzung unterschiedlich. Während HTML5 die Welt mit Webapplikationen revolutionieren möchte, hat CSS3 eher allgemein gehaltene Neuerungen an Bord, die nicht nur für Webapplikationen, sondern auch für ganz normale Webseiten taugen. Neue Gestaltungsmittel kann man immer gebrauchen.

Diese neu eingeführten Gestaltungsmittel sind sehr zahlreich; die Anzahl der CSS-Eigenschaften hat sich im Vergleich zu CSS2.1 mehr als verdoppelt. Es gibt neue Möglichkeiten Farben anzugeben, Farbverläufe können erstellt werden, mehrere neue Layout-Techniken werden eingeführt und auch die Schriftgestaltung kommt nicht zu kurz. All das ist sowohl für Webseiten als auch -Applikationen nützlich und nur wenige Ausnahmen wie die appearance-Eigenschaft brechen aus dieser allgemeinen Auslegung der Neuerungen aus. Mit appearance kann man HTML-Elementen das aussehen von nativen UI-Elementen geben und so zum Beispiel Links wie Checkboxen aussehen lassen:

a {
    appearance:checkbox;
}

Das ist vermutlich für normale Websites von eher überschaubarem Nutzwert, kann aber helfen, Look & Feel von Webapplikationen besser an native Apps anzupassen. Allerdings ist die Unterstützung für appearance noch in allen Browsern nur sehr rudimentär vorhanden, was aber nicht für alle CSS3-Features gilt.

CSS3 ist keine monolithische Spezifikation, sondern ist in Module aufgeteilt. Diese Module werden komplett unabhängig voneinander entwickelt und sind verschieden weit gediehen und von so-gut-wie-Standard-Spezifikationen bis zum experimentellen Erstentwurf ist alles dabei. Der W3Viewer bietet ein bequemes Interface für den Modul-Dschungel. Aufgrund des Modulsystems gibt es ähnlich wie bei HTML5 keinen Tag X, an dem CSS3 fertig ist. Einige Teile wie das Farben-Modul oder CSS3-Selektoren sind seit Jahren stabil und in modernen Browsern einheitlich implementiert, andere haben noch einen langen, steinigen Weg vor sich.

Die Zukunft von JavaScript

Als Brendan Eich seinerzeit von den Netscape-Bossen genötigt wurde, innerhalb weniger Tage eine Programmiersprache für den Browser zusammenzuschustern, erschuf er mit JavaScript etwas, das es (in der Theorie) leicht macht, schnell kleine Scripts für Websites zu schreiben. Geplant war, dass Java-Applets für alle größeren Aufgaben aufnehmen und JavaScript nur für Kleinigkeiten zum Einsatz kommt. Die Geschichte nahm dann doch einen etwas anderen Verlauf und während Java-Applets heute wie ein Relikt aus der Altsteinzeit wirken, ist JavaScript (dem Web und HTML5 sei Dank) heute die verbreitetste und vielleicht schon wichtigste Programmiersprache der Welt. Das Problem daran ist, dass JavaScript für diese Aufgabe einfach nicht gebaut wurde.

Eich hatte nur wenige Tage Zeit, eine komplette Programmiersprache zu erfinden und für diese Umstände ihm ist JS sehr gut gelungen. Dennoch hat JavaScript einige Macken: null hält sich für ein Objekt, with {}produziert absolut Unvorhersehbares und unter welchen Umständen this in einer Funktion welches Objekt referenziert, ist komplizierter als Quantenfeldtheorie. Hinzu kommt, dass die Möglichkeit, jedes Objekt zu jeder Zeit beliebig zu verändern, heute mehr ein Ärgernis als ein Feature ist. Bastelt man nur ein kleines Script für eine Webseite, ist es ein Segen, dass man mal eben schnell Prototypen nativer Objekte erweitern oder Methoden überschreiben kann. Bei großen Webapplikationen gerät dies jedoch zu einem Problem, da man die Robustheit kritischer Programmteile nicht mehr garantieren kann. Des weiteren leiden Mammutprojekte wie Mini-Scripts unter dem etwas schmalen Sprachumfang von JavaScript, der das Schreiben von unnötig viel Boilerplate-Code nötig macht. Rettung naht in Form von ECMAScript5 und ECMAScript Harmony.

Der Name des Standards, der den JavaScript-Implementierungen der Browser zugrunde liegt, lautet ECMAScript und ECMAScript5 (kurz ES5) ist die nächste auf uns zukommende Ausfertigung von JavaScript. Hier werden mit kleineren Verbesserungen einige der Geburtsfehler von JS ausgebügelt. So wird ein Strict Mode, in dem z.B. with {} nicht mehr erlaubt ist, eingeführt und es werden dringend benötigte Funktionen wie Array.isArray() nachgerüstet. Das Einfrieren von Objekten ermöglicht die robustere Ausgestaltung von Scripts und es lassen sich Getter- und Setter-Methoden für einzelne Objekt-Eigenschaften definieren. Die ES5-Spezifikationen sind seit Ende 2009 fertig und Browser der neuesten Generation (Internet Explorer 9, Firefox 4, Chrome 10) unterstützen es bereits in großen Teilen.

ECMAScript Harmony ist einer der diversen blumigen Namen für die auf ES5 folgende ECMAScript-Version. An Harmony wird zur Zeit fleißig gearbeitet und der genaue Funktionsumfang ist noch nicht sicher, doch dass diesmal Änderungen von erheblicher Tragweite auf uns zukommen, ist abzusehen. Mit let statt var wird man Variablen deklarieren können, die nicht an einen Funktions- sondern an einen Blockkontxt gebunden sind, das arguments-Objekt wird eingestampft, es wird ein Modulsystem und Iteratoren geben. Viel von all dem steht bisher nur auf dem Papier, oder, wie im Falle von Brendan Eichs Wunschzettel Harmony Of My Dreams im Netz. Eine Ausnahme bildet die mächtige Proxy-Metaprogrammierungs-API, die man bereits heute vollumfänglich im Firefox 4 ausprobieren kann.

Ein Blick in die Glaskugel

Wie wir gesehen haben, ist die Zukunft in Form von HTML5, CSS3 und JavaScript-Updates bereits in den modernen Browsern gelandet. Damit entstehen neue Möglichkeiten für Entwicklung von Webapplikationen und in etwas geringerem Umfang gibt es auch neues Spielzeug für den Bau althergebrachter Websites. Was aber sind die Auswirkungen auf jene, die die neuen Webapps und -Seiten bauen?

Der Alleskönner-Webworker könnte in näherer Zukunft aussterben seltener werden. Jene, die neben dem Webdesign auch das HTML erledigen und das Endprodukt in ein CMS einprogrammieren, werden es angesichts der zunehmenden Komplexität aller WWW-Technologien und der damit verbundenen Themenbereiche (Performance, Barrierefreiheit) schwer haben. Spezialisierung ist das Zauberwort! Dies dürfte auch deshalb nötig sein, weil es immer schwieriger werden wird, auf den einzelnen Spezialgebieten auf dem neuesten Stand zu bleiben.

An das, was wir heute als “HTML5-Chaos” wahrnehmen, also dass extrem viele Neuerungen von Browsern extrem unterschiedlich gut unterstützt werden, können wir uns nämlich langfristig gewöhnen. Die Phase, als der Internet Explorer allein den Markt beherrschte und es statt ständiger Weiter- und Neuentwicklung stabile Standards gab, war eine Anomalie. Die aktuelle Entwicklungsgeschwindigkeit, die ein wenig dem im ersten Browserkrieg vorgelegten Tempo gleicht, scheint der Normalzustand des WWW zu sein, der nur dann unterbrochen wird, wenn ein Browser Marktanteile im 90%-Bereich verzeichnen kann und damit die Innovation blockiert.

Da dieses Szenario zur Zeit nicht abzusehen ist (es gibt mehr Browservielfalt als je zuvor) kann man die ruhigen Zeiten wohl zu den Akten legen – immer vorausgesetzt, man ist tatsächlich daran interessiert, die Möglichkeiten der Browser voll auszuschöpfen. Wer in Zukunft nur halbwegs statische Webseiten umzusetzen gedenkt, kann die Lage etwas entspannter sehen. Alle anderen dürfen in Zukunft wie zu seligen Netscape-Zeiten wieder intensiver mit den kleinen und großen Eigenheiten der diversen Browsern zu ringen haben.

Semantisches HTML5

Veröffentlicht am 20. März 2011

Dieser Artikel ist Teil einer Serie:

  1. HTML5 im Überblick (externer Link; lokale Kopie)
  2. HTML5-Geolocation (externer Link; lokale Kopie)
  3. Semantisches HTML5 (externer Link; lokale Kopie)
  4. Das Canvas-Element (externer Link; lokale Kopie)
  5. HTML5 … und dann? (externer Link; lokale Kopie)

HTML5 bietet uns mit vielen neuen JavaScript-APIs das Rüstzeug, um die Webapplikationen der Zukunft zu bauen, aber auch für normale Websites sind interessante Features an Bord. Neben einer Unzahl kleiner und kleinster Änderungen, die jedem Webentwickler das Leben einfacher machen, gibt es auch eine Handvoll waschechter Neuheiten, namentlich neue HTML-Elemente. Diese sind dringend nötig, denn die HTML5-Vorgänger HTML 4.01 und XHTML 1 beinhalten beide eine Auswahl an Elementen, die 1997 festgelegt wurde und auf das Web von heute nicht mehr so recht passt.

Neue strukturierende Elemente

Die durchschnittliche Website von Anno 1997 ist mit dem, was wir heute so sehen vom Aufbau her nicht zu vergleichen. Sofern man sich damals überhaupt eine ausgetüftelte Seitenstruktur zulegte, setzte man diese mit Frames um – das war damals auch das absolut angemessene Mittel der Wahl. Im Web von heute erfolgt die Einteilung einer Seite durch das HTML selbst, was zur Folge hat, dass Websites heute zu 90% aus dem<div>-Element zu bestehen scheinen. Uns das ist eigentlich ein absolut unnötiges Ärgernis, denn mittlerweile haben sich gewisse Mittel der Strukturierung etabliert. Fast jeder Seite hat irgendwelche Formen von Kopf-, Fuß-, Haupt- und Seitenbereichen. HTML5 gibt uns erstmals eigene HTML-Elemente hierfür.

Der erste Neuling ist das <section>-Element. Es nimmt an allen den Stellen den Platz des <div>-Elements ein, an denen ein inhaltlicher Abschnitt von einem anderen getrennt werden muss. Das <div> ist damit nicht ausgestorben –an jeder Stelle, an der man einfach irgendein Container-Element braucht, ist es weiterhin das Mittel der Wahl. Das <section>-Element ist allein für die Einteilung in Sinnabschnitte da. Ein naher Verwandter ist das <article>-Element, das ebenfalls Sinnabschnitte einteilt, aber für in sich geschlossene Serien-Inhalte steht, etwa für Blogposts, Forennachrichten oder Kommentare unter einer News-Meldung. Für angefügte Informationen steht das <aside>-Element bereit, das sich beispielsweise auf Website-Ebene für Seitenleisten oder innerhalb eines Abschnitts als Containerelement für Metainformationen anbieten würde.

Für Kopf- und Fußbereiche von sowohl ganzen Seiten als auch einzelnen <section>-und <article>-Elementen stehen <header> und <footer> bereit. Beide dürfen ihrerseits keine <header>- oder <footer>-Elemente enthalten, unterliegen aber sonst keinen Einschränkungen. Das <nav>-Element dient letztlich zur Auszeichnung von Navigationen. Es sollte nur auf wichtige Navigationsblöcke verwendet werden – nicht jeder kleine Link braucht ein eigenes <nav>.

Ein mit den neuen Elementen ausgezeichnetes Blog könnte wie folgt aussehen:

<header>
    <h1>Das HTML5-Blog</h1>
    <nav>
        <a href="/">Startseite</a>
        <a href="/about.html">Über dieses Blog</a>
    </nav>
</header>

<section id="hauptspalte">

    <article>
        <h2>Ein toller Beitrag über HTML5!</h2>
        <p>Text Text Text</p>
        <aside class="metainformationen">
            <p>Geschrieben am 12.08.2010</p>
        </aside>
    </article>

    <article>
        <h2>Ein älterer Beitrag über HTML5!</h2>
        <p>Text Text Text</p>
        <aside class="metainformationen">
            <p>Geschrieben am 10.08.2010</p>
        </aside>
    </article>

</section> <!-- Ende der Hauptspalte -->

<aside id="sidebar">

    <h2>Sidebar</h2>

    <section>
        <h3>Tagcloud</h3>
        <p>Tags Tags Tags</p>
    </section>

    <section>
        <h3>Blogroll</h3>
        <p>Link Link Link</p>
    </section>

</aside> <!-- Ende der Sidebar -->

<footer>
    <p>© 2011 HTML5-Blog</p>
</footer>

Die neuen strukturierenden Elemente verhalten sich in (modernen) Browsern ähnlich wie <div>-Elemente. Sie haben auf den ersten Blick keine besonderen CSS-Eigenschaften und verhalten sich wie generische Block-Elemente. Tatsächlich haben aber einige der Neulinge (<section>, <article>, <aside>) große Auswirkungen auf die Überschriftenstruktur der Webseite und tun nebenbei noch etwas für die Barrierefreiheit.

ARIA inklusive

Die neuen strukturierenden Elemente haben eingebaute ARIA-Attribute. ARIA (Accessible Rich Internet Applications) ist eine Spezifikation der Web Accessibility Initiative des W3C, die neue HTML-Attribute für barrierefreie Webanwendungen festlegt. Mit ihnen lassen sich aus generischen HTML-Elementen zusammengebaute Widgets für Screnreader und andere Assistenztechnologien verarbeitbar gestalten. Ein Beispiel:

<div id="fortschritt">
    <div id="anzeige">25%</div>
    <div style="width:25%;" id="abgespielt"></div>
</div>

Diese Konstruktion wird mit etwas CSS schnell zu einem sehr ansehnlichen Fortschrittsbalken – vorausgesetzt man hat zwei gesunde Augen. Screenreader würden hier nur einen Haufen unzusammenhängender <div>-Elemente zu sehen und entsprechend wäre der Nutzer des Screenreders aufgeschmissen. Aber ARIA hilft:

<div id="fortschritt"
    role="progressbar"
    aria-valuemin="0"
    aria-valuemax="100"
    aria-valuenow="25"
>
    <div id="anzeige">25%</div>
    <div style="width:25%;" id="abgespielt"></div>
</div>

Die wai-*- und role-Attribute machen es möglich, dass Assistenztechnologien wie Screenreader unser Widget nicht nur als Fortschrittsbalken erkennen, sondern sie geben auch gleich alle zur Interpretation der Anzeige nötigen Zahlen mit.

Eine genauere Einführung in WAI-ARIA würde an dieser Stelle den Rahmen sprengen; als empfehlenswerte Lektüre sei an dieser Stelle die deutschsprachige Einführung in WAI-ARIA verlinkt. Wichtig ist für uns, dass erstens HTML5 WAI-ARIA nahtlos integriert (man also die ARIA-Attribute nutzen kann ohne dass der HTML-Validator meckert) und dass zweitens viele Elemente in HTML5 eingebaute ARIA-Eigenschaften haben. So hat etwa das <nav>-Element immer das eingebaute role-Attribut navigation. Man muss es also dort nicht selbst eintragen und wenn man etwas anderes als navigation angeben würde, wäre es ein Fehler (und eigentlich ja auch recht widersinnig). Nur bei wenigen Elementen darf man das eingebaute role-Attribut überscheiben – so hat etwa das <article>-Element die vorgegebene Rolle article, darf jedoch alternativ auch die Rollen application, main oder document tragen.

Die komplette Liste der vorgegebenen ARIA-Attribute ist den HTML5-Spezfikationen zu entnehmen. Zu beachten ist, dass noch nicht alle Browser diesen ganzen Problemkomplex perfekt beherrschen – über die Einzelheiten gibt html5accessibility.com Auskunft.

Überschriften ohne Ende

Während man die HTML 4.01 und XHTML 1 durch die Elemente <h1> bis <h6> auf sechs Überschriften-Ebenen beschränkt ist, kann man in HTML5 unendlich viele Überschrift-Ebenen – und das obwohl man weiterhin nur die Elemente <h1>bis <h6> zur Verfügung hat. Wie das? Nehmen wir erst mal als Beispiel den folgenden HTML-Schnipsel:

<h1>HTML5</h1>
<h2>Neue Elemente</h2>
<h3>Das Section-Element</h3>

Die so abgebildete Dokument-Struktur ist die Folgende:

HTML5
    Neue Elemente
        Das Section-Element

Der Abschnitt “Neue Elemente” ist ein Unterabschnitt von “HTML5” und “Das Section-Element” ist ein Unterabschnitt von “Neue Elemente”. Würde man nun die neuen HTML5-Elemente zum Einsatz bringen um den Schnipsel strukturieren, würde das Ergebnis wie folgt aussehen:

<h1>HTML5</h1>
<section>
    <h2>Neue Elemente</h2>
    <section>
        <h3>Das Section-Element</h3>
    </section>
<section>

Der Clou ist nun, dass auch dieses HTML die Struktur des Schnipsels korrekt abbilden würde:

<h1>HTML5</h1>
<section>
    <h1>Neue Elemente</h1>
    <section>
        <h1>Das Section-Element</h1>
    </section>
<section>

Jedes Mal, wenn ein neues <section>-, <article>-, <aside>- oder <nav>-Element geöffnet wird, beginnt darin die Zählung der durch <h1> bis <h6> bezeichneten Überschrift-Ebenen von neuem, allerdings eine Hierarchieebene tiefer als in dem umgebenden Abschnitt. Moderne Browser wie der Internet Explorer 9 oder der Firefox 4 zeigen die so ermittelte Struktur auch optisch an. Obwohl in dem Dokument nur <h1>-Überschriften vorkommen, werden sie im folgenden Screenshot entsprechend ihrer Position in der Gesamtstruktur abgebildet, so dass die untergeordneten Überschriften das Aussehen von <h2> und <h3> annehmen:

Wenn in dem neu geöffneten Abschnitt keine <h1> vorhanden ist, beginnt die Zählung bei der höchstrangigen Überschrift die zu finden ist, so dass tatsächlich jeder der genannten Codeschnipsel gültiges HTML5 ist – allerdings ermöglicht nur das letzte Beispiel mit seinen <h1>-Überschriften und den verschachtelten <section>-Elementen die Verwendung unendlich vieler Überschrift-Ebenen. Zumindest ist das die Theorie. Noch unterstützen nicht alle Browser dieses HTML5-Feature und auch wie Suchmaschinen und Screenreader nach HTML5-Muster aufgebaute Dokumente verarbeiten, ist noch nicht umfassend erforscht. Vorsicht ist also geboten.

Alte Bekannte in neuen Rollen

Neben den neu eingeführten Elementen werde durch HTML5 einige alte Bekannte reaktiviert, die im Strict-Modus von HTML 4.01 und XHTML 1 eigentlich schon abgeschafft waren. So sind etwa <i>, <b> und <hr> in HTML5 wieder da, allerdings mit einer semantischen Bedeutung und nicht als reine Designelemente. Zwar werden sie im Browser noch immer dargestellt wie seit jeher, doch dieser Darstellung kann man bekanntlich mit CSS zu Leibe rücken. Was bleibt ist die neue semantische Bedeutung der ehemaligen Präsentationselemente. Einige Beispiele:

  • Das <i>-Element dient der Auszeichnung von Textabschnitten, die vom Rest des Textes abgesetzt sind, die dabei keine besondere Gewichtung haben und deren übliche typographische Darstellung kursiver Text wäre (z.B. fremdsprachige Wörter oder Fachbegriffe)
  • Das <b>-Element dient der Auszeichnung von Textabschnitten, die vom Rest des Textes abgesetzt sind, die dabei keine besondere Gewichtung haben und deren übliche typographische Darstellung fetter Text wäre (z.B. Produktnamen in einem Review)
  • Das <hr>-Element dient der Kennzeichnung von thematischen Umbrüchen innerhalb eines Textes auf Absatzebene (z.B. ein Wechsel der Erzählperspektive in einer Geschichte)
  • Das <s>-Element dient der Auszeichnung von Textpassagen, die als nicht (mehr) relevant, aber explizit noch Teil des Dokuments gekennzeichnet werden soll (z.B. eine durch einen Sonderpreis ersetzte Preisangabe in einem Webshop)

Die komplette Liste der auf diese Weise umdeklarierten Elemente würde zusammen mit den vielen Detailänderungen an anderen alten Bekannten den Rahmen dieses Artikels sprengen. Einen guten Überblick bietet HTML: The Markup Language Reference, eine zusammengestrichene Fassung der HTML5-Spezifikationen, die nur Informationen über neue und geänderte HTML-Elemente enthält – kryptische JavaScript-APIs bleiben außen vor.

Fazit

Die neuen (und alten, aber umdeklarierten) HTML5-Elemente kommen dem von Div-Suppen gestressten Webentwickler wie gerufen, aber es ist nicht alles Gold was glänzt. Ältere Browser, insbesondere die Internet Explorer 6 bis 8, sind auf die neuen semantischen Elemente nicht gut zu sprechen und wie Suchmaschinen eines Tages die Umstellung zur Auswertung von Überschriften nach HTML5-System managen werden, weiß auch noch niemand. Es ist also Vorsicht geboten und man sollte in jedem Fall sein HTML5-Markup gründlich testen. Und validieren sollte und kann man sein Werk auch – der gute alte HTML-Validator kann HTML5 genau so gut prüfen wie HTML 4.01 oder XHTML 1.

Das Canvas-Element

Veröffentlicht am 16. März 2011

Dieser Artikel ist Teil einer Serie:

  1. HTML5 im Überblick (externer Link; lokale Kopie)
  2. HTML5-Geolocation (externer Link; lokale Kopie)
  3. Semantisches HTML5 (externer Link; lokale Kopie)
  4. Das Canvas-Element (externer Link; lokale Kopie)
  5. HTML5 … und dann? (externer Link; lokale Kopie)

Gefühlte 90% aller HTML5-Demos im Web verwenden das Canvas-Element. Das machen sie auch nicht ohne Grund, denn das Element und seine APIs ermöglichen etwas Spektakuläres, das vorher in Browsern nicht möglich war: das Zeichnen und Animieren beliebiger Formen und Farben, bis auf den letzten Pixel kontrollierbar.

Das Canvas-Element eröffnet ganz neue Möglichkeiten, die weit über das über die bunten Kästchen hinausgehen, die man allein CSS und JavaScript durch den Browser schubsen kann, von statischen Diagrammen bis zum 3D-Shooter kann man alles rendern, was das Herz begehrt. Beispiele gefällig?

Bei so vielen Möglichkeiten versteht es sich von selbst, dass das Element über eine nicht gerade kleine Sammlung von API-Methoden verfügt, die man nicht mal eben zwischendurch auswendig lernen kann. Hinzu kommt, dass die API auf recht niedrigem Level ansetzt und nur die Funktionalität bietet, die es für jeden Anwendungsfall bieten muss.

So gibt es etwa keine Funktion, die einen Kreis zeichnen kann, denn nicht jede denkbare Canvas-Anwendung braucht so etwas – möchte man eine Kreisfunktion haben, muss man sie sich selbst schreiben. In den meisten Fällen wird man als Webentwickler nicht mit den normalen Canvas-Funktionen arbeiten, sondern mit Frameworks, die auf die Standardfunktionen aufsetzen.

Die größten Herausforderung liegen in den Besonderheiten von Pixelgrafik-Animationen und der händischen Programmierung dieser. Das Implementieren von Framebuffern oder Framerate-Limitern war bisher nicht täglich Brot eines Webentwicklers, aber wer mit dem Canvas-Element flüssige Animationen erschaffen möchte, kommt um diese Sorte fremdartiger Probleme nicht herum. Es gibt also viel neues zu lernen – packen wir es an!

So tickt das Canvas-Element

Es liegt in der Natur der Sache, dass wir im Rahmen dieses kleinen Artikels nicht den vollen Umfang der Canvas-API besprechen können. Selbst eine bloße Funktionsreferenz ohne zusätzlich Erklärungen würde viele Seiten füllen. Wir werden uns also auf einige konkrete Anwendungsbeispiele beschränken und daran Teilaspekte des Canvas-Elements beleuchten. Zunächst müssen wir aber ein solches Element in unser HTML5-Dokument setzen:

<canvas id="canvas" height="480" width="600">
    Dein Browser kann kein Canvas-Element. Dir entgeht unser 
    tolles Anwendungsbeispiel! 
</canvas>

Der Text zwischen dem öffnenden und dem schließenden <canvas>-Tag wird nur dann angezeigt, wenn der Browser das Element nicht darstellen kann. Die height- und width-Angaben verhalten sich wie bei einem <img>-Element – sie geben zwar die Größe des Elements vor, können aber von entsprechenden CSS-Regeln auch überstimmt werden.

Öffnet man diese Konstruktion jetzt in einem halbwegs modernen Browser (Firefox 3.5+, Opera 10+, Safari 4+, Chrome oder Internet Explorer 9) sieht man aber erst mal gar nichts. Das Canvas-Element ist in der Tat nichts weiter als eine leere Leinwand, die wir mit JavaScript befüllen müssen – ohne Programmierung läuft nichts. Also programmieren wir doch einmal etwas:

window.onload = function(){ 
    var canvas = document.getElementById('canvas'); 
    if(canvas.getContext){ 
        var context = canvas1.getContext('2d'); 
        context.fillStyle = "rgb(255, 0, 255)"; 
        context.fillRect(20, 20, 300, 240); 
    } 
}

Das Ergebnis sieht dann schon mal zumindest nicht nach Nichts aus:

Zur Erläuterung: Zeile 1 des Codeschnipsels (window.onload...) sorgt nur dafür, dass der folgende Code erst ausgeführt wird, wenn die Seite fertig geladen ist. Dann wird mit document.getElementById() eine Referenz auf das Canvas-Element in der Seite geholt und in Zeile 3 wird geprüft, ob das Element die Methode getContext() kennt. So kann zwischen Browsern mit Canvas-Unterstützung und jenen ohne unterschieden werden.

Die getContext()-Methode dient dazu, Zugriff auf die Zeichen-APIs (Kontexte genannt) des Canvas-Elements zu bekommen. In Zeile 4 wird auf diese Weise der Kontext mit der ID 2D in der Variablecontext gespeichert. Der 2D-Kontext ist der Standard-Zeichenkontext von HTML5, ein 3D-Kontext ist aber auch in Entwicklung. Der 2D-Kontext bietet uns mehrere Zeichenfunktionen und -Attribute, mit denen wir unsere Canvas zum Leben erwecken können.

In Zeile 5 wird ein solches Attribut, fillStyle (legt die Füllfarbe für alle folgenden Zeichenoperationen fest), auf Magenta festgelegt und Zeile 6 zeichnet mit dieser Farbe im Hinterkopf ein 300×240 Pixel großes Rechteck, dessen linke obere Ecke um je 20 Pixel auf X- und Y-Achse von der linken oberen Ecke des Canvas-Elements verschoben ist. Fertig ist unser „Hallo Welt“ für Canvas!

Der schwarze Rahmen wurde übrigens mit herkömmlichem CSS eingefügt. Da das Canvas-Element ein HTML-Element wie jedes andere ist, kann man es uneingeschränkt mit CSS und JavaScript traktieren – jQuery-Animationen und CSS3-Transformationen inklusive.

Auch wenn dieses Beispiel eher wenig praktische Relevanz hat, zeigt es einige der wichtigsten Prinzipien: Erstens laufen alle Zeichenoperationen über die API des Kontexts, nicht des Elements selbst, und zweitens müssen die Variablen für Zeichenoperationen erst gesetzt werden, bevor gezeichnet wird. Wir entscheiden uns erst für Magenta als Farbe und zeichnen danach.

Zeit für ein paar Beispiele mit (ein wenig) mehr Praxisbezug. Ein besonders praktisches Feature des Canvas-Elements ist, dass man es nicht zwingend händisch mit bunten Rechtecken füllen muss, sondern (unter anderem) per <img> eingebundene Bilder als Datenquelle nutzen kann. Und hat man diese Bilder einmal auf die Canvas gebracht, kann man sie Pixel für Pixel manipulieren.

Anwendungbeispiel 1: Fotomanipulation

Mit der Kontext-Methode drawImage() kann man ein im Dokument vorhandenes Bild auf die Canvas bannen. Man nehme dazu ein Bild sowie Canvas-Element …

<img id="original" height="320" width="406" src="original.jpg" alt="">
<canvas id="canvas" height="320" width="406"></canvas>

 …mache gebrauch von der drawImage()-Methode …

window.onload = function(){ 
    var original = document.getElementById('original'); 
    var canvas   = document.getElementById('canvas'); 
    if(canvas.getContext){ 
        var context = canvas.getContext('2d'); 
        // Original-Bild auf die Canvas zeichnen
        context.drawImage(original, 0, 0); 
    } 
}

 …schon kann man das Bild 1:1 kopieren (Original-<img> links, Canvas-Element rechts):

So weit, so unspektakulär. Hat man aber erst mal das Bild auf ein Canvas-Element gebracht, kann man mit der MethodegetImageData() Zugriff auf die Farbwerte jedes einzelnen Pixels bekommen und kann diese dann nach Herzenslust manipulieren. Als Argumente für getImageData() muss man die Eckpunkte des Canvas-Ausschnitts angeben, für den man die Pixel abgreifen möchte (Koordinaten der linken oberen Ecke + Maße des Ausschnitts).

Zurück erhält man ein Objekt, dessen Eigenschaft data ein Array mit den Farbwerten aller Pixel im Ausschnitt enthält –erst kommt der Rot-Wert des ersten Pixels, dann der Grün-Wert des ersten Pixels, der Blau-Wert des ersten Pixels, der Alpha-Wert des ersten Pixels, dann der Rot-Wert des zweiten Pixels und so weiter.

Wenn man in diesem Array nun alle RGB-Werte modifiziert (z.B. die Farben einfach umdreht) und das Endergebnis mit putImageData() wieder zurück auf die Canvas schreibt, macht das Ergebnis schon etwas mehr her:

window.onload = function(){ 
    var original = document.getElementById('original'); 
    var canvas   = document.getElementById('canvas'); 
    if(canvas.getContext){ 
        var context = canvas.getContext('2d'); 
        // Original-Bild auf die Canvas zeichnen
        context.drawImage(original, 0, 0); 
        // Pixeldaten auslesen, in imgData speichern 
        var imgData = context.getImageData(0, 0, canvas.width, canvas.height); 
        var r, g, b, i = 0; 
        // Alle Pixel durchlaufen ... 
        while(i < imgData.data.length){ 
            // ... Rot-Wert umkehren ... 
            imgData.data[i] = 255 – imgData.data[i++]; 
            // ... Grün-Wert umkehren ...
            imgData.data[i] = 255 – imgData.data[i++]; 
            // ... Blau-Wert umkehren ... 
            imgData.data[i] = 255 – imgData.data[i++]; 
            // ... und den Alpha-Wert unverändert lassen 
            i++; 
        }
        // Verändertes imgData auf die Canvas zeichnen 
        context.putImageData(imgData, 0, 0);
    } 
}

An dieser Stelle ist erwähnenswert, dass aufgrund der Same-Origin-Policy Bilddaten nicht auf lokalen Daten (z.B. c:\foo.html) hin- und herkopiert werden können; der Aufruf über einen richtigen Host (z.B. localhost) ist Pflicht.

Anwendungbeispiel 2: Malprogramm

Das Canvas-Element ist ein HTML-Element wie jedes andere, man kann es via CSS stylen, anklicken, und JavaScript-Funktionen in die normalen DOM-Events einhängen. Also ist eine dynamische Malfläche, Paint im Browser, kein Hexenwerk. Man nehme ein Canvas-Element und ein paar <div>-Elemente nebst CSS-Styles …

<style>
    div, canvas { cursor:crosshair; border:1px solid black; float:left; margin:1em; }
    div { cursor:pointer; height:40px; width:80px; }
</style>

<canvas id="canvas" height="320" width="406"></canvas>
<div id="red" style="background:red;"></div>
<div id="blue" style="background:blue;"></div>
<div id="green" style="background:green;"></div>

 …und schon steht die Oberfläche für unser Canvas-Malprogramm:

Die bunten Boxen dienen zur Auswahl der Farbe, mit der auf dem Canvas-Element gemalt werden soll. Sie zum Funktionieren zu bringen ist einfach: beim Klick auf eine Farbbox muss sich nur context.fillStyle (wir erinnern uns, das ist der Wert, der die Füllfarbe für alle folgenden Zeichenoperationen festlegt) passend ändern.

var context = document.getElementById('canvas').getContext('2d');

// Rote Farbe wählen
document.getElementById('red').onclick = function(){
    context.fillStyle('red');
}
// Blaue Farbe wählen
document.getElementById('blue').onclick = function(){
    context.fillStyle('blue');
}
// Grüne Farbe wählen
document.getElementById('green').onclick = function(){
    context.fillStyle('green');
}

Schon fehlt nur noch die Programmierung des Zeichnens selbst. Hierfür nutzen wir das Mousemove-Event auf dem Canvas-Element und schalten bei den Mousedown- und Mouseup-Events zwischen „aktivem“ und „inaktivem“ Modus hin- und her, so dass nur gezeichnet wird, wenn auch tatsächlich die Maustaste gedrückt ist.

Ein hilfreiches Detail, das das folgende Codeschnipsel nutzt, ist dass die Kontext-Variable in ihrer Eigenschaft canvas immer eine Referenz auf das Canvas-Element, zu dem der Kontext gehört, bereithält. So ist die Programmierung der Events ein Kinderspiel:

// Aktiv-Modus hin- und herschalten
var active = false;
context.canvas.onmousedown = function(){
    active = true;
}
context.canvas.onmouseup = function(){
    active = false;
}

// Nur zeichnen wenn "active" true ist, d.h. die Maustaste gedrückt ist
context.canvas.onmousemove = function(event){
    var x = event.clientX - context.canvas.offsetLeft; // Mausposition X
    var y = event.clientY - context.canvas.offsetTop; // Mausposition Y
    if(active){
        context.fillRect(x - 5, y - 5, 10, 10);
    }
}

Und fertig! Schon kann man drauflosmalen:

Abspeichern kann man sein fertiges Meisterwerk im übrigen ganz einfach per Rechtsklick → Datei speichern unter.

Anwendungbeispiel 3: Pimp your Canvas API

Die beiden bisher gezeigten Beispiele sind etwas krude ausgefallen. Der Grund dafür liegt in der Canvas-API selbst, die sich wie eingangs erwähnt auf die allernötigsten Funktionen beschränkt. Sie kennt von Haus aus keine Objekte oder Animationsfunktionen, hat keine Methode für Kreise an Bord und macht einem ganz allgemein das Leben schwer. So muss man selbst für simpelste Grafiken wie dieses Strichmännchen …

 …in Canvas-Code mit den diversen Pfad-Funktionen viel zu viel tippen:

// Körper
context.beginPath();
context.moveTo(240, 100);
context.lineTo(240, 200);
// Beine
context.lineTo(190, 250);
context.moveTo(240, 200);
context.lineTo(290, 250);
// Arme
context.moveTo(240, 150);
context.lineTo(190, 150);
context.moveTo(240, 150);
context.lineTo(290, 150);
// Linien ziehen
context.lineWidth = 4;
context.strokeStyle = '#CC0000';
context.stroke();
context.closePath();
// Kopf
context.beginPath();
context.arc(240, 80, 35, 0, Math.PI * 2, false);
// Linien ziehen und füllen
context.fillStyle = '#CC0000';
context.fill();
context.stroke();
context.closePath();

Was tun? Frameworks oder andere Hilfsmittel bauen! Die Canvas-API ist gar nicht dafür gedacht, dass man direkt mit ihr Grafiken programmiert, sondern dass JavaScript-Bibliotheken auf sie aufsetzen oder dass IDEs den Canvas-Code generieren. Ein Framework zu programmieren ist kein Hexenwerk; mit nur 60 Zeilen Framework-Code lässt sich das Strichmänchen dank verketteter Befehle gleich viel einfacher zusammenbauen:

// Körper
context.moveTo(240, 100).lineTo(240, 200);
// Beine
context.lineTo(190, 250).moveTo(240, 200).lineTo(290, 250);
// Arme
context.moveTo(240, 150).lineTo(190, 150).moveTo(240, 150).lineTo(290, 150);
// Linien ziehen
context.set({'lineWidth': 4, 'strokeStyle': '#CC0000'}).stroke().closePath();
// Kopf
context.beginPath().arc(240, 80, 35, context.deg2rad(0), context.deg2rad(360), false);
// Linien ziehen
context.set('fillStyle', context.get('strokeStyle')).fill().stroke().closePath();

Canvas-Frameworks gibt es bereits wie Sand am Meer. Einige sind, wie das gezeigte Verkettungs-Framework, eher allgemeiner Natur, andere auf spezielle Aufgabengebiete zugeschnitten. Eine kleine Auswahl:

  • CamanJS bietet Funktionen für Bildmanipulation (Sepia-Effekt usw.)
  • EaselJS portiert das aus Flash bekannte Objekt- und Interaktionssystem nach Canvas
  • Für schicke Diagramme sorgt RGraph
  • Für den 3D-Kontext gibt es auch bereits mehrere Frameworks bzw. 3D-Engines, unter anderem CopperLicht, GLGE und SceneJS

Fazit

Das Canvas-Element haucht unseren Browsern ganz neue Möglichkeiten ein – wo man buchstäblich jede nur denkbare Grafik rendern kann, sind der Kreativität keine Grenzen gesetzt. Zwar sind einige fiese Klippen, die zum Beispiel das Themen Barrierefreiheit und Performance betreffen, noch nicht endgültig umschifft, doch alles in allem ist das Canvas-Element ein Werkzeug, mit dem wir in naher Zukunft sicher viel Vergnügen haben haben. Es funktioniert in allen modernen Browsern zuverlässig (mit diesem Trick sogar in den Internet Explorern 6 bis 8) und bietet viel Potenzial – was will man mehr?