HTML5 Iframe-Attribut seamless schon jetzt nutzen (Alle Informationen und Beispiele)

Es gibt sie auf fast jeder Internetseite und trotzdem mag sie kein Webentwickler: Iframes. Früher wurden sie verwendet um ganze Internet-Auftritte umzusetzen (Stichwort: nav.html, content.html), heute Fristen sie ein unscheinbares Dasein als Container-Elemente unzähliger Social-Media- und Werbe-Boxen. Das Arbeiten mit Iframes wird jedoch durch HTML5 bald um einiges angenehmer werden. Welche Vorteile das hat, wie man die Features teilweise schon jetzt nutzen kann und warum Iframes gar nicht so böse sind, erklärte Ben Vinegar vor einiger Zeit in einem Vortrag. Die Slides dazu gibt es hier, die eingedeutschte Zusammenfassung mit Beispielen in diesem Artikel.

Keine Zeit? Hier geht’s direkt zur Demo-Seite inkl. Code.

Sind Iframes wirklich böse? Nein!

seamless-Iframe Attribut schon jetzt nutzen
Das seamless-Attribut und seine Möglichkeiten

Iframes, also quasi Webseiten in Webseiten, sind vom Rest der Seite isoliert, bilden eine sogenannte Sandbox. Das hat Nachteile für Webentwickler: CSS wird nicht in den Frame übernommen, Links innerhalb des Iframes verweisen nicht auf die einbindende Seite und die Größe des Frame-Elements passt sich nicht an den Inhalt darin an. Doch genau dieses Sandbox-Prinzip hat Vorteile: JavaScript-Konflikte werden verhindert und Sicherheit und Datenschutz des Users gewahrt. Services wie Flattr, Google Adsense und viele Andere können und müssen via Iframe in die eigene Seite eingebunden werden.

HTML5 und das seamless-Attribut

Da derzeitige Nachteile nicht zukünftig das Arbeiten mit Iframes verhindern sollen, wurde das HTML5-Attribut seamless hinzugefügt. Ein einfaches Beispiel:

[html]<iframe seamless src="http://www.solife.cc"></iframe>[/html]

CSS-Eigenschaften werden dadurch direkt in den Frame übernommen und die Links öffnen korrekt im übergeordneten Fenster. Außerdem passt sich der Iframe mit dem Attribut der Höhe des Inhalts an und Linien sowie Scrollbalken werden standardmässig nicht angezeigt. Wie bei allen neuen Errungenschaften im Web gibt es Dinge zu beachten und Kompromisse einzugehen:

  • Es wird nur http://, nicht aber file:// unterstützt
  • Kein einziger Stable-Browser verfügt derzeit über Support
  • Nur Google Chrome Canary (Version 22 und höher) unterstüzt derzeit das Attribut
  • Die Implementierung der anderen Browser kann als oberflächlich bezeichnet werden

Schon jetzt die neuen Vorteile nutzen

Um schon jetzt die Vorteile des seamless-Attributes zu Nutzen bedarf es einiger Tricks. Zu aller erst muss sowohl auf der Hauptseite, als auch im Iframe selbst, JavaScript-Code eingefügt werden. Damit beide Bereiche kommunizieren können, wird die window.postMessage-Methode genutzt. Die Optik der “nahtlosen” Darstellung kann mit etwas CSS nachgebaut werden.

Einrichten von postMessage und CSS

Code der Hauptseite:

[js]<iframe seamless id="myFrame" src="iframe.html"></iframe>

<script>
var iframe = document.getElementById("myFrame");
// Erste Test-Nachricht an den Iframe
iframe.onload = function() {
iframe.contentWindow.postMessage(‚Hallo Iframe!‘, "*" );
};
</script>[/js]

Da die Nachricht erst gesendet werden soll, wenn der Iframe schon geladen ist, verwende ich den onload-Event-Handler.

JavaScript-Code für den Iframe:


[js] // Wird aufgerufen bei einer neuen Nachricht
function listener(e){
alert(e.data);
}

// Listener für alle Browser
if (window.addEventListener){
window.addEventListener("message", listener, false);
} else {
window.attachEvent("onmessage", listener);
}
[/js]
Wir haben nun die erste Test-Nachricht via Hauptseite an den Iframe gesendet. Die Vorteile von postMessage können wir nun nutzen, um unterschiedliche Werte an den Frame zu übermitteln und das seamless-Attribut teilweise zu simulieren.

CSS für die Hauptseite (Nahtloser Iframe-Effekt):

[css]iframe[seamless]{
background-color: transparent;
border: 0 none transparent;
padding: 0;
overflow: hidden;
}[/css]

Um Links innerhalb des Iframes korrekt zu öffnen, könnte man bei jedem Link das Attribut target="_parent" hinzufügen. Das ist allerdings Wartungsintensiv und überladet das Markup. Dank des <base>-Tags und etwas Java-Script kann dies automatisiert werden.

Im <head>-Bereich des Iframes einfügen:

[html]<base href="http://www.solife.cc/" target="_parent">[/html]

Die angegebene URL des href-Attributes ist nicht zwingend notwendig, da sie mittels Javascript gleich mit der dynamischen Seiten-URL getauscht wird.

Im JavaScript (onLoad-Bereich) der Hauptseite einfügen:

[js] // Schicke aktuelle URL an Iframe
iframe.contentWindow.postMessage([‚referrer‘, window.location.href], ‚*‘);
[/js]

Javascript des Iframes empfängt Nachricht und ändert Base-URL:

[js] // Neue Listener-Funktion
function listener(e){

var eventName = e.data[0],
data = e.data[1];

switch (eventName) {
case ‚referrer': setNewBase(data); break;
}

}

// Aktualisiere Base-URL
function setNewBase(url) {
document.getElementsByTagName(‚base‘)[0].href = url;
}
[/js]

Styles in den Iframe übernehmen

Es ist keine perfekte Lösung, aber es können beliebige Style-Eigenschaften wie Schriftart, Schriftgröße und Schriftfarbe via Nachricht dem Iframe übergeben werden. In diesem Beispiel wird dies Mithilfe von jQuery gelöst:

[js] iframe.onload = function() {

….
// Style-Eigenschaften an Iframe senden
iframe.contentWindow.postMessage([‚styles‘, getIframeStyles(iframe)], ‚*‘);

};

// Styles auslesen (Dazu wird ein leeres span-Element erstellt)
function getIframeStyles(iframe) {

var $span = $(‚<span>‘).appendTo(iframe.parentNode);

var styles = {
color: $span.css(‚color‘),
fontFamily: $span.css(‚font-family‘),
fontSize: $span.css(‚font-size‘)
};

$span.remove(); // Cleanup
return styles;

}
[/js]

Natürlich können beliebig viele Styles an den Iframe übergeben werden. Auch ist es möglich ganze CSS-File-URL’s zu versenden, um sie später einzufügen. Wir bleiben bei der einfachen Methode der Werte-Übermittlung.

Beim Iframe selbst nun folgenden Code einfügen:

[js]function listener(e){

….

switch (eventName) {
case ‚referrer': setNewBase(data); break;
case ‚styles': injectStyles(data); break;
}

}

function injectStyles(styles) {
$(document.body).css(styles);
}
[/js]
Wie oben beschrieben gibt es viele Wege die gewünschten Style-Eigenschaften in den Frame zu bekommen. Dem Webworker ist überlassen wie er diesen Prozess umsetzt.

Höhe des Iframes automatisch anpassen

Jeder Coder der bereits einmal ein Gästebuch oder ähnliches via Iframe einbinden musste, kennt das Problem: Welche Höhe definiert man dem Iframe-Element? Gerade bei dynamischen Seiten ist diese Frage schwer zu beantworten – die Lösung ist meist eine Höhe von weit über 1000 Pixel zu wählen. Dank postMessage kann die korrekte Höhe nun direkt übertragen werden.

Da in diesem Schritt die Hauptseite, nicht wie bisher, Nachrichten sendet, sondern auch empfängt, muss ein ähnlicher Code wie im Iframe eingebunden werden.
[js] // Wird aufgerufen bei einer neuen Nachricht
// Auf Hauptseite nur um Höhe anzupassen
function listener(e){

var eventName = e.data[0],
data = e.data[1];

switch (eventName) {
case ‚setHeight': $(iframe).height(data); break;
}

}

// Listener für alle Browser
if (window.addEventListener){
window.addEventListener("message", listener, false);
} else {
window.attachEvent("onmessage", listener);
}
[/js]

Das JavaScript des Iframes aktualisieren:
[js] // Resize-Funktion zum Ermitteln der Höhe
function resize() {
window.parent.postMessage([‚setHeight‘, $(‚html‘).height()], ‚*‘);
}
[/js]
Jetzt muss die resize()-Funktion nur noch aufgerufen werden. Auch hier gibt es mehrere Möglichkeiten der Umsetzung:

  • Die Funktion wird permanent via Interval alle 500 Millisekunden odgl. aufgerufen
  • Die Funktion feuert erst wenn ein bestimmtes Event eingetreten ist
  • Wie Ben Vinegar in seinem Vortrag, mit der Debounce-Methode (Code)

Zur einfacheren Vorstellung verwende ich für dieses Beispiel die Interval-Methode.
[js] // Alle 500 Millisekunden die Höhe des Frames anpassen
window.setInterval(resize, 500);
[/js]
Das Iframe passt sich nun immer der Höhe des Inhalts darin an.

Resume

Mit diesen wenigen Code-Zeilen ist es möglich das Arbeiten mit Iframes erheblich zu verbessern und das seamless-Attribut zumindest teilweise nachzubauen. Die window.postMessage-Methode wird in allen Browser, bis auf Internet Explorer 6 und 7 unterstützt. Bis alle Browser nachgerüstet haben bleibt dieser Workflow eine passable Alternative.

Zur Demo-Seite inkl. Code.

Ajax File Upload mit HTML5 und XHR2 (ohne Plugin oder Iframe-Hack)

Ajax File Upload mit HTML5
In wenigen Zeilen zum File-Ajax-Call

Bilder oder andere Dateien via Ajax zu übermitteln war mit XMLHttpRequest Level 1 bis dato eine äußert unschöne Angelegenheit – denn nur einfache Daten konnten gesendet werden. Um den Ajax-File-Upload trotzdem zu realisieren, verwendeten Webworker deshalb Iframe-Hacks in verschiedensten JavaScript-Plugins. XHR 2 bietet nun allerdings die Möglichkeit die Scripts der bisherigen Webseiten aufzuräumen und ganz nativ Dateien via Ajax an den Server zu senden.

FormData() macht es möglich

XHR 2 bietet mit dem FormData()-Interface nun die Möglichkeit Bilder oder andere Dokumente für den darauffolgenden Ajax-Call aufzubereiten. Nach dem Initialisieren in einer Variable, kann via append()-Methode jeder einzelne Parameter hinzugefügt werden. Ein einfaches Beispiel mit jQuery:


$(‘body’).on('change', '#fileUploader', function() {

    // Post-Daten vorbereiten
    var data = new FormData();
    data.append('file', this.files[0]);
    data.append('foo', 1);

    // Ajax-Call
    $.ajax({
        url: ‘/fileupload.php’,
        data: data,
        type: ‘POST’
        processData: false,
        contentType: false,
        success: function(evt) { // Bild anzeigen }
    });

});

Das File-Input mit der ID #fileUploader triggert bei jeder Änderung (und somit jedem Upload) die change-Funktion. Via FormData() und .append(key, value) werden die einzelnen Parameter für den Call vorbereitet. Mit this.file[0] gelangt man zur ersten hochgeladenen Datei dieses Inputs. Multi-File-Uploads via Ajax können somit ebenfalls problemlos durchgeführt werden.

Der $.ajax()-Methode von jQuery müssen folgende Konfigurationen hinterlegt werden: processData und contentType auf false.


Im PHP-Dokument fileupload.php kann nun ganz normal mit $_FILE[] auf die Dateien bzw. $_POST[] auf die anderen Parameter zugegriffen werden.

Browser-Support

Gute Nachricht: Moderne Browser (Firefox, Chrome, Opera, Safari) unterstüzen XHR2 und somit FormData() komplett. Der Internet Explorer leider erst ab Version 10. Wer an Backends oder anderen modernen Webseiten bastelt, die also nicht Browserübergreifend gleich funktionieren müssen, eine denkbare Lösung. Alternativ kann natürlich auch ein Fallback zu einem Java-Script Plugin mit Iframe Hack eingerichtet werden.

Page Visibility API – Erklärung und Beispiele

Screenshot Google Code Page Visibility API

Schnell erklärt, die Page Visibility API

Inzwischen haben sich Tabs in Browsern durchgesetzt und werden von jedem Internet-Nutzer oft und gerne benutzt. Viele User schließen Websites wie Facebook, Google Mail oder weitere gar nicht mehr – sie lassen sie im Hintergrund weiterlaufen. Durch die HTML5 Visibility API ist es dem Webworker nun möglich abzufragen, ob die eigene Website gerade sichtbar bzw. unsichtbar für den Benutzer ist und ermöglicht es darauf zu reagieren.

Wofür kann man die Page Visibility API nutzen?

Gerade bei ajax- und medienlastigen Websites ist es keine Seltenheit, dass permanent Daten vom Server geladen werden, um die Seite, ohne das Eingreifen des Benutzers, aktuell zu halten. Mit der Page Visibility API kann verhindert werden, dass unnötige Requests abgesendet werden, wenn der Internet-User die Website gar nicht mehr im Blickfeld hat. Einige Beispiele für eine mögliche Anwendung:

  • Ein News-Portal auf dem alle 30 Sekunden via Ajax neue Nachrichten gepusht werden. Hat der User die Seite 15 Minuten im Hintergrund geöffnet, würde man dem Server durch die Nutzung der API 30 sinnlose Requests ersparen.
  • Ein Video auf YouTube wird abgespielt und der Nutzer verlässt den Tab. Es wäre möglich nun das Video zu stoppen und erst dann wieder abzuspielen wenn der User den Tab wieder aktiviert hat.
  • Eine Seite mit Bilder-Slideshow, die alle paar Sekunden vom Server neue Bilder bezieht und diese lädt. Es wäre nützlich dies zu stoppen, um dem User unnötigen Datentransfer zu ersparen, deren Ergebnis er ohnehin nicht sieht.

Wie teste ich ob meine Website gerade sichtbar ist?

Über die Variable document.hidden erfährt man ob die Seite gerade sichtbar ist. Man erhält entweder true oder false als Wert. Zu Beachten ist hier, dass es wie bei experimentellen CSS-Eigenschaften, Vendor-Prefixe gibt. Diese lauten für Webkit document.webkitHidden, für den Firefox document.mozHidden und für den Internet Explorer document.msHidden. Sofern der Browser die API nicht unterstützt wird als Wert undefined geliefert.

Detailliertere Informationen erhält man allerdings über document.visibilityState (Vendor-Prefixe document.webkitVisibilityState, document.mozVisibilityState bzw. document.msVisibilityState). Derzeit definierte Rückgabewerte sind:

  • visible
    Die Website ist zumindest teilweise sichtbar. Das bedeutet, dass sie zumindest in einem Browser gerade aktiv in einem Tab geöffnet wird und der Browser nicht minimiert ist.
  • hidden
    Die Website ist nicht sichtbar. Das kann zwei Gründe haben: Entweder ist im Browser gerade ein anderer Tab geöffnet oder das Browser-Fenster ist komplett minimiert.
  • prerender
    Der Inhalt der Seite wird noch vorgeladen und ist für den Benutzer noch nicht sichtbar. Die Website hat diesen Wert nur zu Beginn und kommt später nie wieder in diesen Zustand zurück.

Es wird ausdrücklich darauf hingewiesen, dass es hier noch mehr mögliche Rückgabe-Werte geben wird. Somit sollte man auch diese Funktion bevorzugen, um detailliertere Informationen zu erhalten.

Veränderungen des Benutzers bemerken

Via Event-Listener visibilitychange kann auf Änderungen der Website-Sichtbarkeit reagieren werden. Auch hier gibt es wieder Vendor-Prefixe: webkitvisibilitychange, mozvisibilitychange und msvisibilitychange. Ein einfaches Beispiel:


function handleVisibilityChange() {
if (document.hidden) {
pauseSimulation();
} else {
startSimulation();
}
}
document.addEventListener("visibilitychange", handleVisibilityChange, false);

 

Ein Beispiel wie das in der Praxis aussehen könnte gibt es hier (Chrome vorrausgesetzt). Einige weitere Code-Beispiele gibt es auf der Google Code Site zur API – Zwei Beispiele zeigen auch die Vorteile der Eigenschaft “prerender” (zum Beispiel das Zählen von Pageviews nur dann, wenn die Seite tatsächlich fertig geladen wurde).

Brauchen wir das und wo geht es jetzt schon?

Die API ist noch in einem sehr frühen Entwicklungsstadium. Folgende Browser unterstützen mit den genannten Vendor-Prefixen schon jetzt diese Funktionen: Chrome ab Version 13, Firefox ab Version 10 (Aurora) und der Internet Explorer auf Version 10 – Für Opera und Safari ist noch keine Implementierung bekannt (Stand 13. November 2011).

Für oben genannte Beispiele bietet die API einen starken Mehrwert und daher ist eine Implementierung in die eigene Website schon jetzt denkbar. Ältere Browser verhalten sich wie bisher, moderne bieten eine verbesserte Funktion. Ein klassisches Beispiel für Graceful degradation mit HTML5 – so soll es sein.


Weiterführende Links:

Dieser Artikel erschien in der Februar/März-Ausgabe des PHP-Magazins.

Battery Status Event – Erklärung und Beispiele

Screenshot W3C Battery-Status-Event

Ein Entwurf ist bereits verfügbar

Die Zeiten in denen Browser lediglich klassische Webseiten darstellen mussten sind längst vorbei. Das Internet rüstet sich für den nächsten großen Paukenschlag – Webapplikationen. Ein weiterer kleiner Schritt hin zum Browser und weg vom klassischen Betriebssystem ebnet das W3C mit dem Entwurf des Battery-Status-Events. Mit diesem soll es möglich sein, Abfragen über den Batterie-Zustand des vom Benutzer verwendeten Gerätes abzusetzen, eine Batterie-Anzeige nachzubauen und bei Bedarf auf Veränderungen zu reagieren.

Tolle Sache, wie funktioniert es?

Der Entwurf des Batterie-Status-Events ist noch sehr jung und eine Implementierung der Browserhersteller steht noch aus (Stand 13. Mai 2011) – Ein erstes Testen ist daher nicht möglich. Der voraussichtliche Funktionsumfang kann allerdings schon jetzt in der Spezifikation nachgelesen werden.

Die Attribute und Events

Über das window.batterystatus Objekt können künftig vier Informationen über die Batterie bezogen werden:

  • isBattery
    Nutzt der gerade verwendete Rechner überhaupt eine Batterie, dann wird true zurückgegeben. Ansonsten, beispielsweise bei einem Standrechner, false.
  • isCharging
    Sofern isBattery true ist, also der Rechner eine Batterie zur Stromversorgung nutzt, kann überprüft werden, ob das Gerät im Moment geladen wird. Auch hier wird true oder false als Rückgabewert verwendet.
  • level
    Mit diesem Attribut kann abgefragt werden wieviel Prozent Akku in der Batterie vorhanden ist – man erhält eine Zahl zwischen 0 und 100. Sofern der Zustand nicht ermittelt werden kann, liefert das Attribut null zurück.
  • timeRemaining
    Wieviel Sekunden der Computer mit dem derzeitigen Batterie-Stand noch ladefähig ist, kann man über dieses Attribut erfahren. Hier wird ebenfalls null zurückgegeben, sofern der Wert nicht ermittelt werden kann.

Für all diese Attribute gibt es auch Events, die sobald eine Änderung am Batterie-Status eintritt feuern. Bei level geschieht dies, wenn eine Änderung mit mindestens 1% vorliegt, bei timeRemaining wenn sich mehr als eine Minute seit dem letzten Aufruf verändert hat.

Wie bei jedem Event gibt es auch hier die Möglichkeit via addEventListener auf Ereignisse zu warten oder mit der window.onbatterstatus-Methode eine Funktion zu definieren, die bei einem Wechsel ausgeführt wird.

Beispiele

Aus mangelndem Browser-Support sind meine Beispiele eher als persönliche Interpretation der Spezifikation zu verstehen. Trotzdem ein kleiner Einblick einer möglichen Anwendung:

<script>
    window.addEventListener('batterystatus', function (event) {
        if(event.level < 3) {
            alert(“Ihr Akku neigt sich dem Ende, wollen Sie das Dokument speichern?”);
        }
        if(event.timeRemaining) {
            infoBox.innerHTML(“Sie können noch ” + (event.timeRemaining / 60)
+ ‘Minuten mit Ihrer Batterie arbeiten.’);
        }
    }, true);
</script>

 

Brauchen wir das überhaupt?

Ob Informationen über den Batteriezustand in einer Web-Applikation etwas zu suchen haben oder nicht, kann diskutiert werden. Es gibt allerdings Anwendungsfälle, die für Webentwickler interessant sein könnten. Sofern sich der Batteriezustand des Benutzers auf unter 3% bewegt, könnte man beginnen, einen Warnhinweis anzuzeigen bzw. die Benutzerdaten zu sichern, um Datenverlust zu vermeiden. Und seien wir ehrlich, so ein Batterie-Icon, gesteuert mit JavaScript, ist nerdig genug, um es zumindest einmal probiert zu haben! Mal sehen welcher Browser dieses Event zuerst implementiert. Sobald es Änderungen an dieser Front gibt, veröffentliche ich hier erste Real-Demos und weitere Informationen.

HTML5-Neuerungen für nummerierte Aufzählungen

Canvas ist großartig, neue semantische Elemente zum Strukturieren des Codes sind endlich hier und dank unzähliger APIs sparen wir uns zukünftig viel Tipparbeit bei Webprojekten. HTML5 ist unumstritten eine tolle Sache. Unter der Spezifikationshaube verstecken sich neben den großen neuen Technologien aber auch einige kleine Neuerungen die eine Erwähnung wert sind. Grund genug diesen versteckten kleinen Änderungen einen Platz zu geben und sie vorzustellen. Heute am Plan: Neue Attribute für nummerierte Aufzählungen.

Allgemeines zu nummerierten Aufzählungen

Das <ol>-Element verwendet man für nummerierte Aufzählungen. In diesem HTML-Element werden die einzelnen Aufzählungspunkte als <li>-Elemente definiert. Bis auf die Verwendung von Klassen und Ids führt ein Großteil der Entwickler, bei diesem Tag, auch keine weiteren Änderungen mehr durch. Als es XHTML noch nicht gab und überall HTML 4.01 verwendet wurde, gab es allerdings Attribute, die, zumindest semantisch gesehen, bei diesem Element verwendet werden durften und nützliche Vorteile boten. Mit HTML5 und der dazugehörigen Spezifikation im Gepäck, dürfen diese wieder benutzt werden. Ein Blick darauf lohnt sich.

Zähler manipulieren mit dem value-Attribut

Mit dem value-Attribut des <li>-Elementes kann die dargestellte Zahl einer Aufzählung manipuliert werden – Egal wo sich das Listenelement befindet. Die weitere Zählung der Elemente wird dadurch nicht beeinflusst. Ein Anwendungsbeispiel wäre die doppelte Notierung zweier Elemente. Die gute Nachricht: Das value-Attribut funktioniert in jedem Browser und kann somit schon heute genutzt werden.

<ol>
    <li>Das ist ein Test</li>
    <li value="1">Und hier möchte ich eine andere Nummer haben</li>
    <li>Hier gehts aber ganz normal weiter</li>
</ol>

Startwert von Listen festlegen

Soll die Liste erst mit einer bestimmten Zahl zu zählen beginnen, gibt es das start-Attribut für <ol>-Elemente. Auch diese Eigenschaft kann schon bedenkenlos in HTML5-Dokumenten verwendet werden.

<ol start="12">
    <li>Zählt ab 12 aufwärts</li>
    <li>Und so weiter...</li>
</ol>

Rückwärts zählen

Wer Listen darstellen möchte, deren Aufzählung rückwärts laufen, kann laut Spezifikation das reversed-Attribut nutzen. Browser-Support gibt es allerdings noch nicht. Sofern man also damit arbeiten mag, muss entweder das value-Attribut oder die Verwendung von JavaScript herhalten.

<ol reversed>
    <li>Diese Zählung läuft rückwärts</li>
    <li>Sofern Browser dies darstellen könnten!</li>
</ol>

Aufzählungstyp definieren

Wer derzeit römische Zahlen bei Listenelementen verwenden möchte, musste auf CSS zurückgreifen. Dieser Ort ist vermutlich, da es sich um die Gestaltung eines Elementes handelt, auch nicht ganz falsch. Gegenargumentiert ist es rein semantisch jedoch nur via CSS zu erkennen, um welche Art der nummerischen Aufzählungen es sich handelt. Zur Deklaration im Markup gibt es nun das type-Attribut für <ol>-Elemente. Möglich sind decimal (Dezimalzahlen), lower-latin (kleingeschriebenes Lat. Alphabet), upper-latin (großgeschriebenes Lat. Alphabet), lower-roman (kleingeschriebene römische Zahlen) und upper-roman (großgeschriebene römische Zahlen). Auch das ging bereits früher und funktioniert somit auch weiterhin problemlos in allen Browsern.

<ol type="lower-roman">
    <li>Kleingeschriebene römische Zahlen sind toll</li>
    <li>Und das ganz ohne CSS</li>
</ol>

Die Ergebnisse aller Beispiele können hier angesehen werden. Unterm Strich können wir ab jetzt (wieder), bzw. baldigst, Dinge mit nummerierten Aufzählungen anstellen, die bisher eher umständlich oder gar nicht zu bewerkstelligen waren. Eine kleine Neuerung also die man kennen und im besten Fall, bereits heute nutzen sollte.