protofunc()

Das Problem mit dem HTML 5 Video Element

Tags: HTML 5, deutsch, javascript, video

Ich arbeite in letzter Zeit immer wieder mit dem HTML 5 Video Element. Bis auf einige kleinen Problemchen mit der API sowie einigen grausamen Implementierungsbug im Safari (betrifft nicht Chrome), bin ich eigentlich ganz zufrieden.

Es gibt aber letztendlich eine Sache die mich extrem rasend macht. Schaut man sich die Youtube HTML5 Demo an und vergleicht diese mit der Spezifikation wird einem klar, daß Youtube mit HTML5 nie so aussehen kann, wie diese Demo einem glauben machen will.

Die Demo zeigt einen Fullscreen-Button. Leider ist die HTML5 Spezifikation hier sehr einduetig. Einerseits ist keine API für einen möglichen Fullscreen-Modus definiert andererseits werden Browserhersteller mit fetter, roter Schrift ausdrücklich davor gewarnt, eine solche zu implementieren. Als Begründung wird auf mögliche “Nervigkeiten” sowie Angst vor Sicherheitsproblemen, genauer Phishing Attacken, abgestellt.

Letztendlich ist die Begründung vollkommen überholt und daneben. Das Security Argument stimmt nicht, da

  • ein Videoelement beim Starten des Vollbildmous grundsätzlich einen entsprechenden Hinweis zeigen soll
  • ein Videoelement im Vollbildmodus, unabhängig vom Vorhandensein des controls-Attribut, die Kontrollelemente anzeigen muß
  • es im Vollbildmodus gar nicht möglich ist – und das wäre das eigentliche Sicherheitsrisiko – Tastaturevents abzufangen

Auch das Risiko einer Belästigung des Users ist gering, wenn man es mit ähnlichen Einschränkungen implementieren würde wie dies bei Adobe Flash getan wurde. Gerade Flash, welches häufig für nervige Dinge wie Werbebanner eingesetzt wird, hat eine API für den Fullscreenmodus, anstatt daß dies mich nervt, empfinde ich es als extrem nützlich.

Hier lag wohl auch augenscheinlich das Problem. Eine API für den Fullscreenmodus wurde mit Methoden wie window.open oder window.resize verglichen, ohne zu erkennen, daß das Anschauen von Videos im Vollbildmodus ein wesentlich nützlicheres Feature ist als das ungefragte Öffnen von Popups und Verschieben von Browserfenstern.

Meine große Hoffnung liegt nun darin, daß entweder irgendein Browser (zum Beispiel: Chrome 4 oder 5 oder Internet Explorer 9) aus der Reihe tanzt und zeigt wie man ein cooles, sicheres Feature implementiert oder daß bei der Zugänglichkeits- (oder vielleicht auch Usability-) überarbeitung des Elements auffällt, daß ein Fullscreenmodus nicht allein mit der rechten Maustaste als Kontextmenü realisiert werden darf.

Ich kotze.

Written January 19, 2010 by
alexander farkas

Meinung zu HTML5: Semantik noch Flop, progressive enhancement Top

Tags: HTML 5, deutsch, javascript

Ich bin ein großer Freund von HTML5. Allerdings kann ich nicht nachvollziehen, in welcher Form einige – bereits heute – HTML5 nutzen wollen bzw. zu nutzen empfehlen. Die tollen HTML5-Elemente (nav, aside, header, footer..), die wir mit dreckigen Tricks nutzen könnten, bringen nichts. Kein Browser, kein Screenreader und auch keine ernstzunehmende Suchmaschine unterstützen die Semantik der neuen Tags, gleichzeitig bereiten Sie in allen Versionen des Internet Explorer sowie im Firefox 2 erhebliche Probleme und machen einiges kaputt.

Auf der anderen Seite gibt es die schönen WAI-Aria-Landmarks. Sie sind für eine zusätzliche Semantik definitiv der bessere Weg, weil sie im Gegensatz zu den oben genannten HTML 5 Element einfach funktionieren, helfen und nichts kaputt machen.

Andere Elemente wie figure und legend können teilweise durch aria-labelledby/aria-describedby substituiert werden.

Dies ist kein Widerspruch zu HTML 5. Im Gegenteil der HTML 5 Validator validiert inzwischen nicht nur Teile von Wai-Aria, sondern eben auch die Aria-Landmarks.

Neben den problemlos verwendbaren Aria-Attributen, gibt es in HTML5 viele schöne neue Sachen zu entdecken.

  • Man kann sich endlich den doctype merken.
  • Das canvas-Element wird von allen modernen Browsern unterstützt und kann mit excanvas auch im Internet Explorer zum Laufen gebracht werden (allerdings mit deutlich geringerer Performance).
  • Attribute wie autocomplete sind endlich Bestandteil von HTML 5. Ohne dieses Attribut sind mit Javascript erstellte Auto-Suggest-Listen für Eingabefelder unmöglich.
  • Es gibt neue, befreiende Verschachtelungsregeln.
  • Best practices wie beispielsweise document.documentElement.className += ‘js-on’; erzeugen endlich validen Code.

Vor allem jedoch bietet HTML 5 – insbesondere bei Formularelementen – semantische Extras, die Javascript-Entwickler, gleichgültig von der derzeitigen Unterstützung im Browser, dringend benötigen, um eleganten, unobtrusiven Code schreiben zu können.

Wie zusätzliche semantische HTML5-Attribute beim Aufbau von Javascript helfen

Man stelle sich vor, man möchte einen Slider mit numerischen Werten realisieren. Dieser Slider soll jeweils einen vom Backend vorgegeben Startwert, Mindestwert und Höchstwert kennen. Als Javascript-Fallback soll ein einfaches Texteingabefeld dienen.

Während HTML 4 sowie XHTML 1.0 lediglich ein Attribut für den Startwert bieten, hilft uns HTML 5 ebenso beim Mindest- und Höchstwert unseres unobtrusiv zu erstellenden Sliders.

<input type=“number“ value=“3“ min=“1“ max=“10“ />
<!-- oder in Schritten -->
<input type=“number“ value=“3“ min=“1“ max=“10“ step="1" />
<!-- oder gleich als 'slider' -->
<input type=“range“ value=“3“ min=“1“ max=“10“ />

HTML 5 und progressive enhacement

HTML 5 bietet einige interessante Features, welche bereits heute mit Hilfe von Javascript implementiert werden können.

Das oben beschriebene canvas-Element ist ein Beispiel hierfür, ein weiteres sind die zahlreichen Erweiterungen für Formularelemente, welche in Teilen bereits von Browsern implementiert wurden.

Die HTML 5 – Attribute liefern hierbei die semantische Grundlage für die Aktivierung und Konfiguierung des Javascripts.

Vor der Implementierung mit Javascript sollte man grundsätzlich testen, ob das Feature nicht bereits Teil des Browsers ist. Da die neuen HTML-Attribute in der Regel mit einem DOM-Interface korrelieren, ist dieser Test kinderleicht. Hier einige Beispiele mit jQuery:

(function($){

	var form = $('<form><fieldset><textarea /></fieldset></form>');

	$.extend($.support, {
		//wird die Constrain Validation unterstützt?
		checkValidity: !!(form[0].checkValidity),
		// wird das maxlength-Attribut am textarea-Element unterstützt?
		textareaMaxlength: !!( $('textarea', form)[0].maxLength !== undefined || $('textarea', form)[0].maxlength !== undefined)
	});

})(jQuery);

Eine Beispielimplementierung für das placeholder-Attribut

Das placeholder-Attribut bietet ein Formularfeature, welches Frontend-Entwickler tagtäglich bereits heute mit Javascript in Webseiten nutzen; nämlich das Entfernen von vorbelegten Werten in Eingabefeldern. Hierbei ist das Standardverhalten wie folgt definiert: Der Placeholder stellt einen kurzen Hinweistext dar, welcher dem User als vorläufiger Wert im Eingabefeld angezeigt wird, solange das Feld keinen Wert hat und nicht fokusiert ist. Das placeholder-Attribut ist kein Ersatz für ein assoziertes label-Element!

<label for="birthday">Ihr Geburtstag</label>
<input type="text" placeholder="TT.MM.JJJJ" name="birthday" id="birthday" />

In HTML4/XHTML 1 ist die Unterscheidung ob das Eingabefeld einen Wert, welcher sich wie ein Placeholder verhalten soll oder nicht, nicht gelöst. Die derzeit eleganteste Javascript-Technik verwendet hierzu einen Vergleich zwischen der value- und der defaultValue-Eigenschaft. Diese Form der Implementierung kommt jedoch an Ihre Grenzen, wenn der User beispielsweise ein Suchformular absendet und der Suchbegriff aus Usability-Gründen wiederholt wird, um es dem User zu gestatten, ohne Neueingabe den Suchbegriff zu erweitern, verkürzen oder sonst wie zu modifizieren. Da in diesem Beispiel ausnahmsweise der defaultValue nicht die Aufgabe eines Placeholders besitzt, fehlt dem Javascript die entscheidende Information sich korrekt zu verhalten. Dieses Problem kann letztlich nur durch Hinzufügen dieser Extrainformation gelöst werden. Und die Standardisierung dieser Extrainformation stellt gerade eben das placeholder-Attribut dar.

Wie könnte nun eine placeholder-Implementierung aussehen?

Als erstes erweitern wir unseren oben genannten HTML5-Implementierungstest:

var form = $('<form><fieldset><input type=“text“ /><textarea /></fieldset></form>');

$.extend($.support, {
	checkValidity: !!(form[0].checkValidity),
	textareaMaxlength: !!( $('textarea', form)[0].maxLength !== undefined || $('textarea', form)[0].maxlength !== undefined),
	placeHolder: !!($('input', form)[0].placeholder !== undefined || $('input', form)[0].placeHolder !== undefined)
});

Wird das placeholder-Attribut nicht unterstützt, kann mit der Implementierung durch Javascript fortgefahren werden, was wie folgt aussehen könnte.

if(!$.support.placeHolder){

	function resetInput(){
		if(this.value == this.getAttribute('placeholder')){
			this.value = '';
		}
	}

	function fillInput(){
		if(!this.value){
			this.value = this.getAttribute('placeholder');
		}
	}
	$(function(){
		$('input[placeholder]')
			.each(function(){
				var placeHolder = this.getAttribute('placeholder').replace(/\n|\r|\f|\t/g, '');
				this.setAttribute('placeholder', placeHolder);
				if(!this.value){
					this.value = placeHolder;
				}

			})
			.bind('blur', fillInput)
			.bind('focus', resetInput)
		;
	});
}

Das schöne, das Script kann bereits heute für ein besseres placeholder/input-rest-Script eingesetzt werden. (Ich kenne keines mit einem besseren Verhalten). Bei Browsern (zum Beispiel Safari 4), welche dieses Attribut bereits unterstützen, funktioniert das ganze dann auch ohne Javascript. Die Benutzung ist sehr einfach. Konfiguration und Start des Scripts geschehen komplett automatisch.

<label for="birthday">Ihr Geburtstag</label>
<input type="text" id="birthday" placeholder="TT.MM.JJJJ" name="birthday" />

Hier das gesamte Script:

(function($){

var form = $('<form><fieldset><input type=“text“ /><textarea /></fieldset></form>');

$.extend($.support, {
	checkValidity: !!(form[0].checkValidity),
	textareaMaxlength: !!( $('textarea', form)[0].maxLength !== undefined || $('textarea', form)[0].maxlength !== undefined),
	placeHolder: !!($('input', form)[0].placeholder !== undefined || $('input', form)[0].placeHolder !== undefined)
});

if(!$.support.placeHolder){
	$(function(){
		$('input[placeholder]')
			.each(function(){
				var placeHolder = this.getAttribute('placeholder').replace(/\n|\r|\f|\t/g, '');
				this.setAttribute('placeholder', placeHolder);
				if(!this.value){
					this.value = placeHolder;
				}

			})
			.bind('blur', function fillInput(){
				if(!this.value){
					this.value = this.getAttribute('placeholder');
				}
			})
			.bind('focus', function resetInput(){
				if(this.value == this.getAttribute('placeholder')){
					this.value = '';
				}
			})
		;
	});
}
})(jQuery);

Fazit

HTML 5 hat deutlich mehr zu bieten als nicht funktionierende HTML-Elemente. Diese sind oftmals nicht mehr als semantischer „Zuckerguß“. HTML 5 kann jetzt schon vielmehr: Es ermöglicht wirklich elegantes und unobtrusives Javascript.

Written August 16, 2009 by
alexander farkas