Quantcast
Viewing all 231 articles
Browse latest View live

Wenn’s mal wieder schneller gehen muss …

Image may be NSFW.
Clik here to view.
Tachometer
Client-Server-Kommunikation mit Socket.io

Will man Informationen möglichst in Echtzeit zwischen Client und Server austauschen, kann das Nachladen von Inhalten in Intervallen mittels Ajax zu unpraktisch sein. Eine einfache, aber vielseitig einsetzbare Methode bietet Socket.io.

Um Informationen auf einer Webseite zu aktualisieren, gibt es typischerweise drei unterschiedliche Vorgehensweisen:

  • Vollständiger Reload der Seite
  • Nachladen von Inhalten mittels Ajax
  • regelmäßige Abfrage in Intervallen (Polling)

All diese Methoden haben ihre Berechtigung, werden aber spätestens dann unpraktisch, wenn Informationen möglichst schnell zu Verfügung müssen oder mehrere Clients über einen Server miteinander kommunizieren. Wäre es nicht von Vorteil, ein Event-System für Client/Server-Kommunikation zu haben, wie es auch aus dem DOM heraus bereits bekannt ist?

Hier kommen WebSockets ins Spiel, ein auf TCP basierendes Netzwerkprotokoll, das parallel zur HTTP-Anfrage des Browsers eine weitere Verbindung zum Server herstellt, die für die gesamte Dauer des Seitenbesuchs permanent bestehen bleibt. Da es auch hier – wie so oft in der Browserwelt – unterschiedliche Implementierungsstände gibt, hilft das Framework http://socket.io. Es setzt auf unterschiedliche Transportmethoden, um eine möglichst große Kompatibilität herzustellen. Damit läuft die Kommunikation unter Internet Explorer 5.5+, Safari 3+, Google Chrome 4+, Firefox 3+, Opera 10.61+, iOS Safari und Webkit auf Android und WebOS.

Praktische Anwendungsfälle

Es gibt viele unterschiedliche Anwendungsmöglichkeiten für Socket.io, die sich in der Regel in vier Bereiche unterteilen lassen:

  1. Benachrichtigung
    Alle serverseitigen Prozesse, die eine längere Laufzeit haben, sollten dem User ein regelmäßiges Feedback geben. Eine weit verbreitete Anwendung ist etwa der Upload von mehreren Dateien oder die Prozessierung von Daten. Hier lassen sich der aktuelle Fortgang der Bearbeitung und eventuelle Fehler direkt kommunizieren.
    So verwendet beispielsweise der Service log.io Benachrichtigungen mit Socket.io zum Real-Time-Monitoring von Serverlogfiles im Browser.

  2. Kommunikation
    Nachrichten lassen sich (z.B. in einem Chat) schnell und mit geringer Serverlast versenden, da nur dann eine Aktualisierung stattfindet, wenn diese erforderlich ist. Es lassen sich sowohl einzelne Clients, Gruppen (über Namespaces in den Event-Namen) als auch alle verbundenen Clients (Broadcast über io.sockets.emit()) mit Nachrichten versorgen.

  3. Spiele
    Ebenfalls bietet sich Socket.io für Online-Spiele an, um beispielsweise Position von Spielfiguren oder einzelnen Einheiten zu synchronisieren.

  4. Steuerung
    Nicht zuletzt lassen sich mit dieser Technik beliebige Dienste steuern, bis hin zu einem angeschlossenen Microcontroller, der Sensordaten liefert oder Motoren ansteuert.

Installation

Socket.io setzt auf Node.js als serverseitigem Framework auf. Nachdem der entsprechende Installer für seine Plattform heruntergeladen und ausgeführt wurde, muss ein beliebiges Verzeichnis für ein neues Projekt angelegt und darin über die Konsole npm install socket.io aufgerufen werden, um Socket.io selbst zu installieren.

Wer Socket.io mit anderen serverseitigen Plattformen nutzen möchte, kann zu einer der zahlreichen Portierungen greifen, die es unter anderem für Java, C++, Perl, Python, Ruby aber auch für Android und Objective-C (iOS) gibt.

Hello world

Wie funktioniert nun die Kommunikation zwischen Client und Server mit Socket.io? Für einen ersten Test benötigen wir dazu nur zwei kurze Stücke JavaScript (GitHub Gist), zuerst für den Server (server.js):

  1. // Kleiner HTTP-Server auf Port 8080
  2. var app = require('http').createServer(serveStaticIndex).listen(8080);
  3.  
  4. // Laden von Socket.io
  5. //(Gibt für die Demo nur Fehler/Warnungen auf der Konsole aus)
  6. var io = require('socket.io').listen(app).set('log level', 1);
  7.  
  8. // Zugriff auf das Dateisystem (zum Ausliefern der index.html)
  9. var fs = require('fs');
  10.  
  11. // Liefert die Startseite aus
  12. function serveStaticIndex(req, res){
  13. var fileStream = fs.createReadStream(__dirname + '/index.html');
  14. res.writeHead(200);
  15. fileStream.pipe(res);
  16. }
  17.  
  18. // Socket.io-Events
  19. io.sockets.on('connection', function(socket){
  20. console.log('[socket.io] Ein neuer Client (Browser) hat sich verbunden.\n');
  21.  
  22. console.log('[socket.io] SENDE "welcome"-Event an den Client.\n');
  23. socket.emit('welcome', "Hello world");
  24.  
  25. socket.on('user agent', function(data){
  26. console.log('[socket.io] EMPFANGE "user agent"-Event vom Client:');
  27. console.log(data, '\n');
  28. });
  29. });

Und dann eine HTML-Seite (index.html), die wir im Browser aufrufen:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Socket.io Test</title>
  5.  
  6. <!-- Dieses Script wird von Socket.io automatisch zu Verfügung gestellt -->
  7. <scriptsrc="/socket.io/socket.io.js"></script>
  8.  
  9. <script>
  10. // Mit dem Socket.io-Server verbinden
  11. var socket = io.connect('http://localhost');
  12.  
  13. // Warten auf Nachrichten
  14. socket.on('welcome', function (data) {
  15. console.log('[socket.io] "welcome"-Event vom Server empfangen:\n' + data);
  16.  
  17. // Eigenen Event vom Client an den Server schicken
  18. socket.emit('user agent', navigator.userAgent);
  19. });
  20. </script>
  21. </head>
  22.  
  23. <body>
  24. </body>
  25.  
  26. </html>

Das ist eigentlich schon der gesamte Code, der benötigt wird. Um das Beispiel auszuprobieren, muss der Server mit node server.js gestartet werden. Anschließend kann die Seite dann über http://localhost:8080/ aufgerufen werden. Die Konsole des Browsers und der Kommandozeilenausgabe im Terminal zeigen daraufhin die Nachrichten an, die zwischen Client und Server übermittelt werden: Sobald die Seite im Browser aufgerufen wird, erhält der Server darüber eine Benachrichtigung und sendet seinerseits eine Willkommensnachricht zurück an den Client, der daraufhin seinen User Agent-String als Beispiel wieder an den Server zurückschickt.

socket.on(, function(){}) wartet auf einen Event und reagiert auf ihn, socket.emit(, ) löst einen Event aus. Beides funktioniert auf Client und Server identisch. Soll hingegen eine Nachricht an alle angeschlossenen Clients versendet werden, nutzt man stattdessen io.sockets.emit().

Als Standard-Events gibt es connection, disconnect und message, darüber hinaus können beliebige Namen für Events verwendet werden.

Fazit

Socket.io bietet ein einfaches, eventbasiertes System für Echtzeitbenachrichtigungen. Dank der breiten Browserunterstützung lässt es sich für vielfältige Anwendungen einsetzen.

Frederic Hemberger

Darf man nicht? Darf man wohl!

Image may be NSFW.
Clik here to view.
Zettel mit dem Text »Baumängel« vor Holzbrettern
Meinung: Ausnahmen von Best Practices

Geht nicht! Gibt’s nicht! Darf man nicht! Bei bestimmten Themen weiß jeder Webworker reflexartig, was sich gehört und wie man es richtig macht. Alles andere ist böse! Darf das HTML oder CSS vielleicht auch mal nicht validieren? Darf ein Webworker target="_blank" nicht doch benutzen? Darf er nicht? Doch, darf er. Wenn er einen guten Grund dafür vorweisen kann.

HTML und CSS müssen validieren

Nö, aktuell müssen HTML und CSS nicht unbedingt in jedem Fall validieren. Oder genauer: Es kommt darauf an. HTML und CSS entwickeln sich laufend weiter. Unter Umständen ist der Validator bei bestimmten Elementen nicht auf der Höhe der Zeit. Bzw. ändern sich einige Schemata so schnell, dass der Validator nicht nachkommt. Etwa beim Thema RDFa. Auf Wikipedia ist aktuell ein Beispiel für HTML 5 + RDFa 1.1 zu finden. Ergänzt um den HTML5-Doctype lautet es:

  1. <!DOCTYPE html>
  2. <html prefix="dc: http://purl.org/dc/elements/1.1/"lang="en">
  3. <head>
  4. <title>John's Home Page</title>
  5. <basehref="http://example.org/john-d/" />
  6. <meta property="dc:creator"content="Jonathan Doe" />
  7. <linkrel="foaf:primaryTopic"href="http://example.org/john-d/#me" />
  8. </head>
  9. <body about="http://example.org/john-d/#me">
  10. <h1>John's Home Page</h1>
  11. <p>My name is <span property="foaf:nick">John D</span> and I like
  12. <ahref="http://www.neubauten.org/"rel="foaf:interest"
  13. lang="de">Einstürzende Neubauten</a>.
  14. </p>
  15. <p>
  16. My <spanrel="foaf:interest" resource="urn:ISBN:0752820907">favorite
  17. book is the inspiring <span about="urn:ISBN:0752820907"><cite
  18. property="dc:title">Weaving the Web</cite> by
  19. <span property="dc:creator">Tim Berners-Lee</span></span>
  20. </span>
  21. </p>
  22. </body>
  23. </html>

Der HTML-Validator aber meldet drei Fehler und sechs Warnungen. Auch Beispiele des W3C zum RDFa Core 1.1 validieren nicht. Wer Zeit und Muse hat, kann sich näher einarbeiten und findet vielleicht eine Variante, die der Validator kennt und akzeptiert. Aber auf größeren Webseiten werden die Autoren ja nicht alle Elemente selbst per Hand eintragen. Das wird ein entsprechendes RDFa-Modul übernehmen. Statt daran rumzuschrauben, kann es viel einfacher sein, auf ein Update des Moduls und/oder des Validators zu warten. In der Zwischenzeit validiert die Seite eben nicht.

Image may be NSFW.
Clik here to view.
Ergebnis im Validator des W3C
Das Ergebnis des RDFa-Beispiels im Validator des W3C

Hinweis: Es existiert auch ein eigener RDFa Validator. Der meldet bei dem Wikipedia-Beispiel zwar keinen Fehler, prüft aber auch nur das RDFa und nicht den Rest einer HTML- oder XML-Datei.

Ähnliches gilt für CSS. Wir nutzen für viele Eigenschaften noch Browser-Prefixes. Beispielsweise für Transitions, damit diese in möglichst vielen Browsern korrekt funktionieren. Da die Prefixes Erweiterungen der Browserhersteller sind, die nicht zum Standard gehören, können diese zwangsläufig nicht validieren. Immerhin werden sie nur als Warnung angezeigt. Der CSS-Validator produziert also trotzdem ein ersehntes: Dieses Dokument wurde als CSS level 3 validiert!

Anders verhält es sich bei experimentellen Features: neuen CSS-Eigenschaften in einem frühen Draft oder auch Ideen einzelner Browser-Hersteller. Wer sich zum Beispiel näher mit Typografie beschäftigt, wird eventuell auf die Eigenschaft text-rendering aufmerksam. Vielleicht sorgt diese Eigenschaft bereits jetzt schon in modernen Browsern für eine bessere Lesbarkeit. Grund genug sie auch einzusetzen. Allerdings wird der CSS-Validator melden: Die Eigenschaft text-rendering existiert nicht. Und damit validiert das CSS nicht mehr.

Image may be NSFW.
Clik here to view.
Rendering der Wörter »Web Validator Tastatur ff fi«
Anzeige via text-rendering mit den Werten optimizeLegibility, optimizeSpeed und geometricPrecision in Chrome

Das heißt: In weiten Teilen und auf »normalen«, »einfachen«, »üblichen« Webseiten sollten HTML und CSS tatsächlich validieren, ja. Aber bei einigen Projekten mag es interessant sein, mit neuen Möglichkeiten zu spielen, die vielleicht nur in manchen Browsern funktionieren – und auch nicht validieren.

Der Validator ist nur ein Werkzeug. Es ist unser Job, richtig damit umzugehen; und die angezeigten Fehler und Warnungen zu verstehen und entsprechend einzuordnen.

target="_blank" gehört verboten

Unter Webworkern hat es sich durchgesetzt, dass allein der Besucher entscheiden soll, ob sich ein Link in demselben oder einem neuen Fenster (Tab) öffnen soll. Insofern gilt erst einmal: das Relikt target="_blank" nervt und gehört verboten.

Eine Ausnahme geben Kunden vor. Wenn die eine Liste mit Partnern auf ihrer Webseite pflegen, kommen sie irgendwann auf die Idee, dass sich solche Links doch bitte in einem neuen Tab öffnen sollen. Da können wir dann argumentieren. Manchmal gewinnen wir, manchmal gewinnt der Kunde. Als Dienstleister fügen wir wenn nötig eben das target="_blank" ein; auch wenn wir es selbst anders handhaben würden.

In einem Fall aber finde ich target="_blank" sogar sinnvoll. Und zwar immer dann, wenn Links in der Nähe eines Formulars vorkommen. Wir haben unten in den Kommentaren unsere Hausregeln und die Gravatare verlinkt. Auf anderen Webseiten können das Hinweise zum Datenschutz oder Hilfen für HTML-Formate sein. Für erfahrene Webworker ist das kein Problem. Die nutzen automatisch STRG + Mausklick (oder ⌘ + Mausklick). Aber ich habe schon mehrere Projekte betreut, bei denen sich die Kunden beschwert haben, dass der Text »plötzlich« verschwindet, nur weil sie auf einen der Links geklickt haben. Es kann nämlich passieren, dass die das Formular schon ausfüllen, und später erst auf die Idee kommen, auf den Link zu klicken. Hier sorgt target="_blank" zumindest dafür, dass der Text in den Formularen erhalten bleibt. In diesem Fall ziehe ich die Usability für unerfahrene Nutzer vor.

Alternativ könnten wir solche Links natürlich auch per JavaScript in einer Lightbox öffnen. Dann bleibt der Text im Formular ebenso erhalten. Aber dann bräuchten wir trotzdem eine Lösung, falls JavaScript ausgeschaltet wäre.

Insofern: target="_blank" ist zwar eigentlich böse, wird aber in bestimmten Fällen explizit gewünscht und kann sogar nützlich sein.

JavaScript richtig einbinden

An welcher Stelle packen wir unser JavaScript auf die Seite? Am besten in den Fuß, kombiniert mit all den anderen JS-Dateien und ordentlich minifiziert. Natürlich, das ist besser für die Performance.

Auch hier bestätigen Ausnahmen die Regel. Die Bibliothek Modernizr zum Beispiel empfiehlt, das JavaScript im <head> einzubinden (weil 1. das HTML5 Shiv vor dem <body> ausgeführt werden muss und 2. ein Flash Of Unstyled Content vermieden werden soll).

In Content-Management-Systeme kann es – abhängig von den installierten Modulen – vorkommen, dass die JavaScripte nicht mehr funktionieren, wenn sie erst im Fuß eingebunden werden. Das spricht manchmal für ein schlecht programmiertes Modul. Aber in der Regel will ich ja keine Module überarbeiten, sondern Webseiten bauen. Dann stehen die JavaScripte eben im <head>– auch wenn es der Best Practice widerspricht.

Es gibt auch (seltene) Fälle, in denen JavaScripte nicht mehr richtig arbeiten, wenn sie minifiziert und kombiniert werden. Das deutet erst recht auf ein schlecht geschriebenes Modul hin. Hier gilt es also abzuwägen: Brauche ich das Modul? Bin ich in der Lage, es selbst zu verbessern? Wird mir die Zeit dafür bezahlt? Oder verzichte ich aufs Minifizieren/Kombinieren und hoffe, dass sich niemand den Quellcode anschaut?

Pixel-Größen für Schriften sind böse

Eigentlich seltsam, dass das (in dieser Form) immer noch kursiert. Früher sind wir brav auf em-Werte für Fonts umgestiegen, weil die Internet Explorer keinen reinen Text-Zoom bei Pixel-Werten hinbekommen. Das hat uns beim schon IE6 genervt, aber auch die IE 7 bis 9 scheitern daran kläglich.

Allerdings hat sich die Zoom-Situation in den letzten Jahren grundlegend geändert. Während wir zunächst überall einen reinen Text-Zoom hatten, haben alle Browser mittlerweile standardmäßig auf einen Seiten-Zoom umgestellt. Und wenn wir die komplette Seite vergrößern, wächst eben auch die Schrift mit. Im Sinne der Barrierefreiheit und WCAG 2.0 sind Pixel-Angaben im Zusammenspiel mit dem Seiten-Zoom durchaus ok.

Genauer: Der Seiten-Zoom reicht für die Stufe AA der WCAG 2.0. Bei AAA hingegen ist kein waagerechter Scrollbalken mehr erlaubt. Wenn also AAA angepeilt wird, dann sind Zoom-Layouts meist nicht mehr ausreichend. AA ist jedoch weitgehend Standard, beispielsweise auch in den kommenden EU-Vorgaben für Ausschreibungen im ICT-Bereich, die im Rahmen von Mandat 376 entstehen.
Es kommt also auf das konkrete Projekt an und nach welchem Maßstab die Barrierefreiheit geprüft wird. Beim BITV-Test etwa muss auch die reine Textvergrößerung bei 150% – bzw. »Schriftgrad am größten« im IE – erfüllt sein (entgegen WCAG 2.0, die von 200% spricht).

Insofern sind Pixel-Größen nicht mehr grundsätzlich böse. Durch den Seitenzoom ist die Barrierefreiheit sogar erst einmal erfüllt. Allerdings können wir es besser machen, wenn wir auch den reinen Text-Zoom berücksichtigen wollen (oder müssen).

Die Website muss perfekt werden

Bei vielen Projekten können wir uns schnell davon verabschieden, auch nur im Ansatz an einem »Perfekt« zu kratzen. Aus Zeit- oder Budgetgründen holen wir ohnehin »nur« das Beste heraus, was zu machen ist. Und haben im Kopf eine lange Liste von möglichen Verbesserungen im Detail. Bei unseren eigenen Projekten sieht es schon ganz anders aus. Wir wissen ja, worauf es ankommt. Was wir alles bedenken wollen und sollten. Und vor allem: Was, wenn die Kollegen da mal genauer hinschauen? Da können wir ja nicht etwas nur Fast-Fertiges ins Web stellen. Das muss schon Hand und Fuß haben!

Ja, bis zu einem gewissen Grad muss es das. In erster Linie aber gilt: Hauptsache online. Alles andere können wir auch im laufenden Betrieb verbessern. Sonst würde dieser Adventskalender zum Beispiel auch noch im alten Design erscheinen. Die perfekte Webseite gibt es ohnehin nicht.

Nicolai Schwarz

Webseiten zum Anfassen

Image may be NSFW.
Clik here to view.
Vier Finger markieren Punkte auf einem Touchscreen
Touch-Events

Touchscreens auf Handys, Tablets und touch-fähigen Laptops eröffnen Entwicklern ganz eue Interaktions-Möglichkeiten. In dieser Einführung schauen wir uns die Grundlagen zur JavaScript-seitigen abhandlung von Touch-Events an.

Grundlagen zur Bearbeitung von Touch-Events

Mobile Browser sind von Haus aus darauf ausgerichtet, existierende Webseiten so gut wie möglich auf Handys und Tablets darzustellen und benutzbar zu machen. Da die meisten Seiten im Web Interaktion mittels Maus erwarten, simulieren Browser auch auf Touch-Geräten die meisten Maus-Events, die wir schon von jeher kennen.

Obwohl es kleinere Unterschiede zwischen den verschiedenen Browsern gibt, sieht das Ganze meistens so aus: wenn ein User auf den Touchscreen tapt, feuert der Browser eine Reihe an Events, um sicherzustellen, dass mausorientierte Scripts so wie auf traditionellen Desktops ausgeführt werden.

Image may be NSFW.
Clik here to view.
Screenshot Beispiel 1
Beispiel 1 – Simulierte Maus-Events
  1. mouseover > mousemove > mousedown > mouseup > click

Wie wir sehen, werden selbst auf Touchscreens die meisten Maus-Events abgefeuert: zuerst ein mouseover, als ob der User frisch mit der Maus auf das Element gefahren wäre; danach ein einzigermousemove, der wirklich nur aus Kompatibilität mit Scripts, die darauf reagieren, vorhanden ist; und zuletzt mousedown, mouseup und click, um das Drücken der Maustaste komplett zu simulieren. Man beachte, dass diese Events in dieser Reihenfolge praktisch ohne Zwischenpausen abgesandt werden.

Wenn wir also eine Webseite haben, die auf spezifische Events wie click oder mouseover reagiert, wird diese Seite in den meisten Fällen ohne jegliche Veränderung auch auf Touch-Geräten benutzbar sein. Aber wie so oft hat diese Event-Emulation im Browser – bedingt durch die besonderen Eigenschaften von Handys und Tablets – auch ihre Nachteile.

Aus diesem Grund bieten Browser auf touch-fähigen Geräten neben der Maus-Emulation eine Reihe an neuen, touch-spezifischen JavaScript Events. Diese Events wurden zuerst für iOS Safari eingeführt und im Nachhinein offiziell in der W3C Touch Events Spezifikation standardisiert.

Die neuen Events, die uns zur Verfügung stehen, sind: touchstart, touchmove, touchend, touchcancel. Die ersten drei Events sind die Touch-Alternativen zu den Maus-Events mousedown, mousemove und mouseup. touchcancel gibt hingegen an, dass eine Touch-Interaktion abgebrochen wurde – in den meisten Fällen, wenn der User den Finger außerhalb des Dokuments (zum Beispiel in die Browser-UI) bewegt.

Image may be NSFW.
Clik here to view.
Screenshot Beispiel 2
Beispiel 2 – Maus- und Touch-Events

Die Abfolge der Touch- und Maus-Events sieht in Browsern auf touch-fähigen Geräten nun so aus:

  1. touchstart > [touchmove]+ > touchend > mouseover > mousemove > mousedown > mouseup > click

Zuerst werden also die touch-spezifischen Events abgefeuert: touchstart, mindestens ein touchmove (bei leichter Fingerbewegung während des Taps können es aber auch mehr sein – man beachte aber, dass zuviel Bewegung den Browser dazu führt, die Berührung nicht mehr als Tap zu interpretieren, sondern als einen Swipe oder als Scroll-Geste, und somit wird die Event-Reihenfolge dann nach dem Hochheben des Fingers abgebrochen) und touchend. Danach werden, wie schon vorher gesehen, die simulierten Maus-Events abgesandt.

Obwohl diese Touch-Events in Firefox, Opera und Webkit-basierten Browsern unterstützt werden, gibt es eine Ausnahme: Microsoft hat in Internet Explorer 10 eine eigene Spezifikation für Pointer- und Gesture-Events eingeführt, und diese auch nachträglich zur Standardisierung beim W3C eingereicht. Nun gibt es seit dem 11. Dezember Microsofts Pointer-Events-Vorschlag auch schon als W3C Working Draft von der neuen W3C Pointer Events Working Group.

Microsofts Ansatz schlägt ein neues Event-Modell vor, das alle verschiedenen Input Methoden (Maus, Keyboard, Touch, usw.) zusammenfasst. Obwohl dieses Modell sehr vielversprechend ist, können diese neuen Events momentan nur im IE10 eingesetzt werden. Aus diesem Grund konzentrieren wir uns hier nur auf die spezifischen Touch-Events. In den weiterführenden Links am Ende des Artikels findet ihr aber Ressourcen, die es ermöglichen, beide Arten an Events zu unterstützen.

»Feature detection« für Touch-Events

Um programmatisch festzustellen, ob ein Browser touch-fähig ist, reicht ein einfacher JavaScript Test – es gibt hier mehrere Varianten, aber am häufigsten scheint diese Methode benutzt zu werden:

  1. if('ontouchstart'in window){/* Touch Unterstützung vorhanden */}

Hierbei ist allerdings Vorsicht geboten: nur weil ein Browser angibt, dass Touch-Events vorhanden sind, heisst dies noch lange nicht, dass eine Webseite nur exklusiv auf Touch-Events reagieren sollte: spätestens seit der Einführung von Windows 8 gibt es jetzt hybride Laptops, die sowohl Trackpad und Keyboard als auch einen Touchscreen haben. Nur weil ein Browser auf einem touch-fähigen Gerät läuft, sollte man also trotzdem immer noch auf die traditionellen Interaktionsmethoden achten.

Verkürzte Reaktionszeit bei Events

Im Gegensatz zu Mausclicks, ist auf Touch-Geräten eine Berührung des Bildschirms nicht unbedingt gleich ein click. Um zu verhindern, dass Elemente unbeabsichtigt aktiviert werden, warten Browser auf Touch-Geräten nach einer Berührung deshalb erstmal, um sicherzustellen, dass es sich hier nicht etwa um eine Scroll-Interaktion, ein »double tap« zum Ein- oder Auszoomen, ein »long click« um Text zu selektieren oder ein Context-Menu zu aktivieren, oder einer anderen Browser/OS-spezifischen Geste handelt.

Erst nach einer spürbaren Verzögerung – die je nach Browser bis zu einer halben Sekunde dauern kann – werden die verschiedenen Maus- und der Click-Event dann ausgelöst.

Im Gegensatz zu den simulierten Maus-Events werden Touch-Events ausgelöst, sobald der User mit dem Touchscreen interagiert. Um dies zu verdeutlichen, schauen wir uns kurz einen kleinen Vergleich von Touch- and Click-Events an.

Image may be NSFW.
Clik here to view.
Screenshot Beispiel 3
Beispiel 3 – Touch- und Maus-Event Delay

Wenn wir also unser JavaScript so auslegen, dass es nicht nur auf click, sonder auch direkt auf touchstart reagiert, können wir vor allem bei Web Applikationen die Reaktionszeit unserer Scripts deutlich reduzieren und unsere User-Experience viel geschmeidiger machen.

Wie auch immer ist hier aber Vorsicht geboten. Das folgende JavaScript-Schnipsel, das leider schon oft als »Performance Trick« für Touch angepriesen wird, reagiert – je nach Touch-Unterstützung – entweder auf clickodertouchstart Events.

  1. /* Pseudo-code: entweder click oder touch Events abfangen */
  2.  
  3. var event = 'click';
  4.  
  5. if('ontouchstart'in window){
  6. event = 'touchstart';
  7. }
  8.  
  9. foo.addEventListener(event, function(){ ... }, false);

Solche Scripts sind zwar gut gemeint, aber sind natürlich im Fall von hybriden Geräten nicht ideal. Deshalb ist es besser, unsere Event-Listener so auszulegen, dass sie auf beide Arten von Events reagieren.

  1. foo.addEventListener('click', function(){ ... }, false);
  2. foo.addEventListener('touchstart', function(){ ... }, false);

Der Nachteil ist hier, dass unsere Funktion dann in den meisten Fällen doppelt ausgeführt wird, da der Browser ja beide Events abschickt. Wie alle anderen JavaScript Events können wir dieses Standardverhalten vom Browser mittels preventDefault() unterdrücken.

  1. foo.addEventListener('click', function(e){ ... }, false);
  2. foo.addEventListener('touchstart', function(e){
  3. ...
  4. e.preventDefault();
  5. }, false);

Dies funktioniert zwar, hat aber auch so seine Tücken: wenn wir touchstart Events abfangen und mittels preventDefault() jede weiter Bearbeitung unterdrücken, werden auch die normalen Browserfunktionen wie Scrolling, »long click« und Zoom unterbunden. In einigen Fällen ist das wohl ganz praktisch, aber generell sollte diese Methode nur sehr sparsam eingesetzt werden.

Finger-Bewegungen verfolgen

Wie wir schon in Beispiel 1 gesehen haben, wird bei einem Tap auch ein mousemove Event ausgelöst. Man beachte aber, dass es sich hier wirklich nur um einen einzigenmousemove Event handelt: wenn der User mit dem Finger über den Touchscreen fährt, werden nicht – wie bei einer normalen Mausbewegung – weitere Events abgefeuert. Das mag bei den meisten Webseiten kein Problem sein, aber für bestimmte Web Applikationen (nicht zuletzt HTML/JS-basierte Spiele) ist dies natürlich nicht ideal.

Als Beispiel schauen wir uns eine kleine canvas-Spielerei an. Die spezifische Implementierung ist hier nicht so wichtig – was uns in erster Linie interessiert ist, dass das Script auf mousemove reagiert.

Image may be NSFW.
Clik here to view.
Screenshot Beispiel 4
Beispiel 4 – Maus-Tracker
  1. var posX, posY;
  2. ...
  3. function positionHandler(e){
  4. posX = e.clientX;
  5. posY = e.clientY;
  6. }
  7. ...
  8. canvas.addEventListener('mousemove', positionHandler, false);

Zwar ist es möglich, dieses Beispiel auch auf Touch-Geräten zum Laufen zu bringen, aber auf eigentliche Finger-Bewegungen reagiert das ganze nicht – nur die erste Berührung auf dem Touchscreen (die dann die simulierten Maus-Events abfeuert) wird registriert. Um Finger-Bewegungen auf Touch-Geräten zu verfolgen, stehen uns aber touchstart und touchmove Events zur verfügung.

Bevor wir uns diesen neuen Events widmen, müssen wir zuerst etwas weiter ausholen. Gemäß der DOM Level 2 Events Spezifikation wird Funktionen, die auf einen traditionellen Maus-Event als Listener registriert sind, ein MouseEvent-Objekt als Parameter übergeben, in dem unter anderem Attribute wie clientX und clientY vorhanden sind.

  1. /* Pseudo-code: klassische mousemove Funktion */
  2.  
  3. foo.addEventListener('mousemove', function(e){
  4. ...
  5.  
  6. /* WebIDL Definition:
  7.   interface MouseEvent : UIEvent {
  8.   readonly attribute long screenX;
  9.   readonly attribute long screenY;
  10.   readonly attribute long clientX;
  11.   readonly attribute long clientY;
  12.   readonly attribute boolean ctrlKey;
  13.   readonly attribute boolean shiftKey;
  14.   readonly attribute boolean altKey;
  15.   readonly attribute boolean metaKey;
  16.   readonly attribute unsigned short button;
  17.   readonly attribute EventTarget relatedTarget;
  18.   void initMouseEvent(...);
  19.   };
  20.   */
  21.  
  22. /* Koordinaten vom Maus-Pointer relativ zu 'foo' */
  23. x = e.clientX; y = e.clientY;
  24. ...
  25. }, false);

Bei Touch-Events sieht das ganze ziemlich ähnlich aus, aber mit einem entscheidenden Unterschied: da Touch-Geräte meistens auch multitouch-fähig sind, bekommen wir in unserer Listener-Funktion zwar ein TouchEvent-Objekt, aber die Koordinaten aller verschiedenen Berührungspunkte sind hier in separaten TouchList-Objekten enthalten.

  1. /* Pseudo-code: touchmove Funktion */
  2.  
  3. foo.addEventListener('touchmove', function(e){
  4. ...
  5.  
  6. /* WebIDL Definition:
  7.   interface TouchEvent : UIEvent {
  8.   readonly attribute TouchList touches;
  9.   readonly attribute TouchList targetTouches;
  10.   readonly attribute TouchList changedTouches;
  11.   readonly attribute boolean altKey;
  12.   readonly attribute boolean metaKey;
  13.   readonly attribute boolean ctrlKey;
  14.   readonly attribute boolean shiftKey;
  15.   };
  16.   */
  17.  
  18. ...
  19. }, false);

Wie wir sehen, beinhaltet ein TouchEvent drei verschiedene TouchList Objekte:

touches
alle Touch-Punkte, die momentan auf dem Touchscreen und dem insgesamten Dokument aktiv sind – also auch Punkte, die nicht direkt über unserem 'foo'-Element sind.
targetTouches
nur die Touch-Punkte, die auch auf 'foo' angefangen haben – selbst wenn der Touch-Punkt später außerhalb des 'foo' Elements bewegt wurde und sich momentan nicht mehr direkt über 'foo' befindet.
changedTouches
die Liste aller Touch-Punkte, die sich seit dem letzten Touch-Event verändert haben – falls zum Beispiel in einem Multitouch-Szenario ein Finger von der Touchscreen-Oberfläche entfernt wurde, oder ein extra Finger hinzugekommen ist, werden diese Touch-Punkte hier nochmals explizit aufgezählt.

Diese TouchList-Objekte lassen sich dann wie normale Arrays bearbeiten, um dann – wie schon bei den altebekannten MouseEvent-Objekten – an die individuellen Koordinaten der Berührungspunkte mittels der verschiedenen Attribute wie clientX und clientY zu kommen.

  1. /* Pseudo-code: touchmove Funktion mit TouchList Objekten */
  2.  
  3. foo.addEventListener('touchmove', function(e){
  4. ...
  5.  
  6. /* Nur Touch-Punkte, die auf 'foo' zutreffen */
  7. var t = e.targetTouches;
  8.  
  9. for(var i=0; i<t.length; i++){
  10.  
  11. /* WebIDL Definition:
  12.   interface Touch {
  13.   readonly attribute long identifier;
  14.   readonly attribute EventTarget target;
  15.   readonly attribute long screenX;
  16.   readonly attribute long screenY;
  17.   readonly attribute long clientX;
  18.   readonly attribute long clientY;
  19.   readonly attribute long pageX;
  20.   readonly attribute long pageY;
  21.   };
  22.   */
  23.  
  24. /* Koordinaten vom Touch-Punkt relativ zu 'foo' */
  25. x = t[i].clientX; y = t[i].clientY;
  26.  
  27. }
  28.  
  29. ...
  30. }, false);

Gehen wir nun zurück zu unserem Beispiel. Zuerst modifizieren wir unsere Listener-Funktion so, dass sie sowohl auf Maus-Events als auch auf Touch-Events reagiert. Zuerst wollen wir nur einen einzigen Touch-Punkt verfolgen, deshalb können wir uns erstmal das Abarbeiten der TouchList-Objekte sparen und einfach den ersten Berührungspunkt nehmen:

  1. var posX, posY;
  2. ...
  3. function positionHandler(e){
  4. if((e.clientX)&&(e.clientY)){
  5. posX = e.clientX;
  6. posY = e.clientY;
  7. }elseif(e.targetTouches){
  8. posX = e.targetTouches[0].clientX;
  9. posY = e.targetTouches[0].clientY;
  10. e.preventDefault();
  11. }
  12. }
  13. ...
  14. canvas.addEventListener('mousemove', positionHandler, false);
  15. canvas.addEventListener('touchstart', positionHandler, false);
  16. canvas.addEventListener('touchmove', positionHandler, false);
Image may be NSFW.
Clik here to view.
Screenshot Beispiel 5
Beispiel 5 – Touch-Tracker

Wenn wir unser Beispiel jetzt erweitern wollen, um auch auf mehrere Touch-Punkte gleichzeitig zu reagieren, müssen wir etwas tiefer in unser Script greifen: anstatt eines einzigen Koordinatenpaares speichern wir einen Array an Punkten (wir klauen uns dafür direkt die targetTouches-TouchList), den wir dann in einer Schleife durchlaufen.

  1. var points = [];
  2. ...
  3. function positionHandler(e){
  4. if((e.clientX)&&(e.clientY)){
  5. points[0] = e;
  6. }elseif(e.targetTouches){
  7. points = e.targetTouches;
  8. e.preventDefault();
  9. }
  10. }
  11. ...
  12. function loop(){
  13. ...
  14. for(var i = 0; i<points.length; i++){
  15. /* Kreis zeichnen */
  16. ...
  17. }
  18. ...
  19. }
Image may be NSFW.
Clik here to view.
Screenshot Beispiel 6
Beispiel 6 – Multi-Touch-Tracker

Noch eine kurze Anmerkung zur Performance: wie es auch bei mousemove Events und traditionellen Maus-Interaktionen der Fall ist, werden bei einer Fingerbewegung eine recht hohe Anzahl an touchmove Events abgesandt. Daher ist es – vor allem mit Hinsicht auf ältere, weniger performante Touch-Geräte – ratsam, unsere touchmove Funktion nicht mit prozessorlastigen Operationen zu überladen. In unserem Beispiel speichert die Funktion nur die momentan aktiven Touch-Punkte – der Code, der diese Koordinaten dann umsetzt, wird separat (mittels setTimeOut) aufgerufen.

Fazit

Mittels Touch-Events ist es relativ einfach, Webseiten und Applikationen so zu gestalten, dass sie auch auf Touchscreens optimal bedienbar sind. In diesem Artikel haben wir nun wirklich nur einen Blick auf die Grundlagen geworfen, um die Reaktionszeit unserer click-Skripte zu verbessern und um an die eigentlichen Touch-Punkte zu gelangen.

Es ist natürlich durchaus möglich, diese Informationen noch weiter zu bearbeiten und Apps noch mit nativ-ähnlichen Swipe- oder Multitouch-Gesten nachzurüsten, wie zum Beispiel in der Picture Organizer Demo. Die Details hierzu würden aber den Rahmen dieser kleinen Einführung sprengen.

Weiterführende Links

Patrick Lauke

Retina-Bildschirme und das Pixel als Maßeinheit

Image may be NSFW.
Clik here to view.
Zweimal das Wort »Webtypo« in weiß auf grünem Grund
Webtypografie und hochauflösende Bildschirme

Wie hat sich der marktübliche Schriftgrad im Webdesign im Laufe der Jahre verändert, und wie hängt das mit den immer hochauflösenderen Bildschirmen zusammen? Die modernen Retina-Displays lassen uns ganz neu über Skalierbarkeit und die Sinnhaftigkeit des Pixels als Grundlage allen Screendesigns nachdenken.

Dieser Beitrag ist ein Auszug aus dem #webtypobuch von Gerrit van Aaken, das seit Dezember 2012 online erhältlich ist. Alle Infos zum Buch findet ihr auf webtypobuch.de.

Seit es Computermonitore im freien Handel gibt, ist deren Pixeldichte langsam aber stetig gestiegen. Zu Beginn der Desktop-Publishing-Revolution, Mitte der Achtzigerjahre, waren es noch die berühmten 72 ppi (pixel per inch), die bei professionellen Layoutbildschirmen dafür sorgten, dass ein einzelnes Pixel genauso groß war wie ein Typografischer Punkt, nämlich 0,35 × 0,35 mm. Das hatte den pragmatischen Vorteil, dass man Drucksachen tatsächlich in physischer Originalgröße am Bildschirm entwerfen konnte (Ausdrucken war teuer), und eine 12-Punkt-Helvetica am Bildschirm mit 12 Pixeln dargestellt wurde. So ließ es sich leichter rechnen.

Später kletterten die Bildschirmauflösungen dann locker über die 100er-Grenze, bis hin zu besonders protzigen Geräten mit bis zu 150 ppi. Letztere vor allem bei hochpreisigen Windows-kompatiblen Laptops Mitte der Nullerjahre, zum Beispiel ein Dell Dimension mit 15,4" Bildschirmdiagonale und 1.920 × 1.200 Pixeln. Viel höher jedoch konnte die Pixeldichte dann nicht mehr werden – zumindest nicht ohne Quantensprung. Und zwar weniger aus technischen, sondern aus konzeptionellen Gründen; das Problem an kleineren Pixeln ist nämlich, dass nicht nur die einzelnen Pixel im Vergleich schrumpfen, sondern mit ihnen alles, was aus ihnen gebildet wird. Und das ist zum großen Teil Text, der von menschlichen Augen gelesen werden soll. Eine heikle Angelegenheit, denn die gleiche 11-Pixel-Arial, welche auf dem 112-ppi-Monitor noch einigermaßen gut zu erkennen ist, kann auf einem 147-ppi-Monitor schon zu winzig sein, um sie ohne Lesebrille entziffern zu können; eine deutlich erhöhte ppi-Zahl führt bei sonst gleichbleibenden Parametern zu deutlich kleinerer Schriftdarstellung.

Die Webdesignwelt hat glücklicherweise darauf reagiert und in den letzten sieben bis acht Jahren die früher üblichen 11 oder 12 Pixel großen Fließtexte schrittweise zu den heute eher üblichen 14 bis 16 Pixeln transformiert. Damit einher ging auch die maximal empfohlene Layoutbreite von anfangs 640 Pixeln über später 800 Pixel auf heute 1024 Pixel. (Einige verwegene Webdesignkollegen versuchen es zwar inzwischen auch mit 1280 Pixeln oder experimentieren gar mit absichtlich horizontal scrollenden Inhalten, doch davor rate ich im Allgemeinen ab.)

Diese Anpassung des marktüblichen Leseschriftgrads an die steigenden Auflösungen der Monitore geht natürlich nur dann gut, wenn sich das Ganze über mehrere Jahre hinweg langsam entwickelt. Doch was passiert, wenn ein Hardware-Hersteller auf einmal nach vorne prescht und die Auflösung eines Gerätes auf einen Schlag, sagen wir: verdoppelt? Nun. Apple hat im Jahr 2010 genau das getan und mit dem iPhone 4 einen Bildschirm am Markt platziert, der statt 163 ppi satte 326 ppi darstellen konnte. Also für jeden Pixel des Vorgängerscreens vier Pixel auf dem neuen Screen – denn die Verdoppelung der Auflösung bezieht sich ja auf beide Richtungen, horizontal und vertikal.

Wenn Apple bei diesem Quantensprung das Gleiche getan hätte wie bei der bisher üblichen Evolution, stünden die Dinge in Sachen Lesbarkeit nicht zum Besten. Eine 12-Pixel-Arial wäre dann nämlich so außerordentlich winzig, dass wahrscheinlich selbst kerngesunde Teenager mit 120 % Sehkraft eine Lupe benötigten.

Statt dessen griff Apple zum einzig sinnvollen Trick und verdoppelte nicht nur die Auflösung, sondern auch die dargestellte Pixelanzahl aller angezeigten Elemente. Unsere 12-Pixel-Arial wird automatisch zu einer 24-Pixel-Arial, die dann den gleichen physischen Platz einnimmt wie früher, mit dem Unterschied, dass sie aus mehr Geräte-Pixeln besteht und von daher viel schärfer und detailreicher ist.

Damit wir uns nicht falsch verstehen: Die Entwickler von Apps und Websites müssen nichts an ihren Stylesheets ändern! Statt dessen nimmt man bei diesen hohen Auflösungen eine Trennung zwischen der virtuellen und der physischen Auflösung vor. Etwas vereinfacht gesprochen behauptet das iPhone intern weiterhin, nur 320 × 480 statt der tatsächlichen 640 × 960 Pixel zu besitzen. Man rechnet als Designer auch weiterhin in den kleineren Größen, nennt das Pixel dann aber bisweilen Punkt/Point, oder auch logisches Pixel. Erst sobald es an die konkrete Darstellung geht, verwendet das Betriebssystem die zusätzlichen Hardwarepixel dafür, Schriften und Grafiken schärfer und detailreicher zu machen.

(Über die fachgerechte Bespielung von hochaufgelösten Bildschirmen, auch über typografische Gesichtpunkte hinaus, hat Frontend-Guru Thomas Fuchs mit »Retinafy Me« ein empfehlenswertes E-Book geschrieben: retinafy.me)

Dieses Prinzip hat das Potenzial, einiges auf den Kopf zu stellen – auch und gerade im Webdesign. Denn in Zukunft wird es immer mehr sogenannte High-PPI-Bildschirme geben, bei denen ein 1:1-Verhältnis zwischen Software- und Hardware-Pixel nicht mehr sinnvoll ist. Genau genommen hat es auch in der offiziellen CSS-Spezifikation nie eine zwingende Übereinstimmung zwischen Hardware-Pixel und CSS-Pixel gegeben. Es war nur viele Jahre so, dass ein font-size:14px; fast immer zu einer in 14 Pixeln dargestellten Schrift geführt hat. Jetzt ist das immer häufiger nicht mehr der Fall.

Entwickler für die Smartphone-Plattform Android kennen diese zusätzliche Abstraktionsebene übrigens schon ein wenig länger. Bereits in recht frühen Versionen von Googles Smartphone-Betriebssystem gab es den Density-Faktor, der von einer Basis-Auflösung 160 ppi ausgeht und für jedes Hardware-Gerät einen ausgleichenden Wert annimmt. Android-Telefone mit 120 ppi erhalten einen Density-Wert von 0.75, während ein 320-ppi-Gerät (analog zum Retina-Display des iPhones) eine Density von 2.0 erzeugen würde. Wenn man diesen Faktor brav beachtet, bleiben die physischen Größenverhältnisse der Bedienelemente ungefähr gleich, was für die Touch-Bedienung mit dem Finger nicht ganz unwichtig ist. Die Darstellungqualität hingegen verbessert oder verschlechtert sich eben je nach Displaydichte.

(Kleine Anmerkung für die nerdigen Leser: Die Sache mit dem Viewport-Zooming auf Smartphone-Browsern lasse ich an dieser Stelle aus, weil es meine Erläuterung unnötig kompliziert machen würde. Aber: Ja, das käme als weitere Abstraktionsschicht potenziell auch noch hinzu.)

Obwohl also das Konzept der Virtuellen Auflösung zum ersten Mal bei den Smartphones in größerem Stil eingesetzt wurde: Die Idee der Auflösungsunabhängigkeit geistert auf Computern mit klassischen Betriebssystemen (Windows/Mac OS) auch schon sehr lange durch den Raum, ohne bisher jemals tatsächlich konsequent umgesetzt und vermarktet worden zu sein. Und irgendwo verspüren viele Webdesigner auch keinen besonderen Drang, es tatsächlich einzufordern, denn eine Unsicherheit bezüglich der virtuellen und physischen Auflösung erschwert natürlich die bequeme pixelbasierte Planung und Umsetzung, wie man sie seit Jahren gewohnt ist. Im Zweifelsfall werden die Pixelkonstrukte beim Endkunden verkleinert oder vergrößert dargestellt, dadurch unscharf oder komisch gekrümelt, je nach Density-Wert. Nicht nur Auftraggeber hätten damit Probleme.

Doch der Trend geht trotzdem ganz klar weg vom klassischen Pixel, dessen Breite man »irgendwo zwischen 0,2 mm und 0,3 mm« ansiedeln konnte. Das Hardwarepixel wird heutzutage immer kleiner, flexibler und unberechenbarer, und damit letztlich auch immer unwichtiger, zumindest als Einheit zum Rechnen und Layouten. Es lohnt sich im Gegenzug mehr denn je, auf Vektorgrafiken und -fonts zu setzen, wo immer es geht, und auf Pixelgrafiken für Layoutelemente möglichst zu verzichten!

Noch sind wir allerdings nicht so weit, das Pixel vollständig vernachlässigen zu können, denn es gibt mehr als genug konventionelle Bildschirme, auf denen man sehr wohl unscharfe Halbpixelkanten erkennen kann, welche bei der Skalierung von Vektorformen oftmals entstehen. Man beachte insbesondere die untere Kante des 40-Pixel-Icons (ganz rechts):

Image may be NSFW.
Clik here to view.
Demonstration von Halbpixelkanten anhand zweier Beispiele

Bei der Produktion von Icon-Sets – ob vektorbasiert oder nicht – verwenden professionelle Screendesigner nach wie vor ein 32er- oder 48er-Raster, um solche Nebeneffekte zu reduzieren. Aber in ein paar Jahren, so glaube ich, wird unseren Kindern der Pixelfetischismus im Webdesign der Nuller- und Zehnerjahre ähnlich lustig erscheinen wie uns die drolligen Pixelklötzchen der 8-Bit-Games aus den Achtzigern.

Gerrit van Aaken

webEdition

Image may be NSFW.
Clik here to view.
Logo webEdition
CMS

Content-Management-Systeme gibt es mittlerweile für die unterschiedlichsten Anforderungen. Allerdings sind darunter nur wenige, die Entwicklern auf einfache Weise volle Kontrolle über den Quellcode gewähren. webEdition ist eines dieser Systeme.

Das CMS webEdition bietet volle Kontrolle über den Quellcode bei einer überschaubaren Lernkurve für die Umsetzung von Layouts in Templates mit Hilfe der eigene Meta-Sprache. Funktionen, für die bei anderen Systemen Plugins benötigt werden, sind in webEdition bereits integriert.

Gähnende Leere statt vorgefertigte Themes

Nach erfolgreicher Installation des CMS, die mit Hilfe eines Assistenten in wenigen Schritten erfolgt, sieht man – im Gegensatz zu anderen Systemen – erst einmal noch nichts. Während andere Systeme mit fertig gestalteten Themes/Templates aufwarten, ist webEdition zu Beginn völlig leer. Dies bedeutet zwar am Anfang – wie bei allen derartigen Systemen – eine gewisse Einarbeitungsphase (wobei sich hiervon niemand entmutigen lassen sollte), im Gegenzug aber die absolute Kontrolle über den ausgegebenen Quellcode.

Auf dem Weg zur ersten Vorlage

Die Lernkurve auf dem Weg zur ersten eigenen Seitenvorlage ist nicht sonderlich steil. Beim Anlegen einer Vorlage wird diese mit Beispiel(-Template)-Code gefüllt, anhand dessen sich die Basis-Funktionen erklären lassen. Seltsamerweise wird bei diesem Code, trotz HTML5-Doctype, eine Layout-Tabelle verwendet, die natürlich einfach entfernt werden kann, wie im folgenden Code zu sehen.

  1. <!doctype html>
  2. <html dir="ltr" lang="<we:pageLanguage type="language" doc="top" />">
  3. <head>
  4. <we:title></we:title>
  5. <we:description></we:description>
  6. <we:keywords></we:keywords>
  7. <we:charset defined="UTF-8">UTF-8</we:charset>
  8. </head>
  9. <body>
  10. <article>
  11. <h1><we:input type="text" name="Headline" size="60"/></h1>
  12. <p><we:input type="date" name="Date" format="d.m.Y"/></p>
  13. <we:ifNotEmpty match="Image">
  14. <we:img name="Image" showthumbcontrol="true"/>
  15. </we:ifNotEmpty>
  16. <we:textarea name="Content" width="400" height="200" autobr="true"
  17. wysiwyg="true" removefirstparagraph="false" inlineedit="true"/>
  18. </article>
  19. </body>
  20. </html>

Das Kernstück bei der Entwicklung eines webEdition-Templates sind die sog. we-Tags. Mit dieser Meta-Sprache lassen sich auf einfache Weise unterschiedliche Eingabemöglichkeiten (Textfeld, Textarea, Bild etc.) für Redakteure integrieren. Dabei ist die Syntax der we-Tags in den meisten Fällen selbsterklärend. So steht <we:img … /> für die Eingabe eines Bildes, <we:input … /> für ein einzeiliges Textfeld und <we:textarea … /> für ein mehrzeiliges Textfeld inklusive eines WYSIWYG-Editor. Dieser eigens für webEdition entwickelte Editor kann individuell an die Bedürfnisse der Redakteure angepasst werden, um deren »Gestaltungsfreudigkeit« Grenzen zu setzen. Ab der demnächst erscheinenden Version 6.3.4 kann alternativ auch eine angepasste Version des TinyMCE als WYSIWYG-Editor verwendet werden. Das Layout im Backend, das die Redakteure zu Gesicht bekommen, ist vergleichbar mit dem im Frontend, so dass eine visuelle Orientierung bei der Bearbeitung der Inhalte möglich ist.

Template-Bearbeitung

Bei der Bearbeitung des Template-Codes stehen verschiedene integrierte Editoren (reine Textarea, Java-Editor, JavaScript-Editor, CodeMirror2 mit hilfreichen Tooltips zu den we-Tags) zur Verfügung. Außerdem kann über das Editor-Plugin der Quellcode auch in einem externen, lokalen Editor geöffnet, der Inhalt durch lokales Speichern zurück in das webEdition-Backend übertragen und dort dann gespeichert werden. Diese vielseitigen Editier-Optionen erleichtern das Erstellen und Überarbeiten von Templates sehr.

Image may be NSFW.
Clik here to view.
webEdition - Screenshot Template Artikel
Artikel-Template im Backend
Image may be NSFW.
Clik here to view.
webEdition - Screenshot Template Tooltip
Tooltip für we-Tags
Image may be NSFW.
Clik here to view.
webEdition - Screenshot Backend Artikel
Artikel-Bearbeitungsmaske für die Redakteure im Backend
Image may be NSFW.
Clik here to view.
webEdition - Screenshot Frontend Artikel
Artikel-Ansicht im Frontend

Artikel-Liste

Eine Auflistung von Seiten dieses Typs z.B. als Artikel-Liste kann ebenso einfach erstellt werden. Der Code hierfür sieht ähnlich übersichtlich aus:

  1. <!doctype html>
  2. <html dir="ltr" lang="<we:pageLanguage type="language" doc="top" />">
  3. <head>
  4. <we:title></we:title>
  5. <we:description></we:description>
  6. <we:keywords></we:keywords>
  7. <we:charset defined="UTF-8">UTF-8</we:charset>
  8. </head>
  9. <body>
  10. <h1><we:input type="text" name="Headline" size="60"/></h1>
  11. <we:listview type="document">
  12. <we:repeat>
  13. <article>
  14. <h2><we:field type="text" name="Headline" size="60"
  15. hyperlink="true"/></h2>
  16. <we:ifFieldNotEmpty type="img" match="Image">
  17. <we:field type="img" name="Image" showthumbcontrol="true"
  18. thumbnail="100x100"/><br />
  19. </we:ifFieldNotEmpty>
  20. <p>(<we:field type="date" name="Date" format="d.m.Y"/>)
  21. - <we:field name="Content"max="100" /></p>
  22. </article>
  23. </we:repeat>
  24. </we:listview>
  25. </body>
  26. </html>
Image may be NSFW.
Clik here to view.
webEdition - Screenshot Template Artikel-Übersicht
Artikelübersicht-Template im Backend
Image may be NSFW.
Clik here to view.
webEdition - Screenshot Frontend Artikel-Übersicht
Artikelübersicht im Frontend

webEdition-Meta-Sprache

Sind beim Erstellen von Templates bestimmte we-Tags unklar, so hilft webEdition auf der Template-Maske mit einer Tag-Hilfe. Hier können alle we-Tags, inklusive möglicher Attribute, nachgeschlagen, sowie direkt konfiguriert und per Mausklick in den Code eingefügt werden.

Image may be NSFW.
Clik here to view.
webEdition - Screenshot Tag-Hilfe
Tag-Hilfe auf der Template-Maske

Die we-Tags für die Eingabe im Backend sind nur ein paar einfache Beispiele. Mit dieser Meta-Sprache lässt sich nahezu jede für eine durchschnittliche anspruchsvolle Website benötigte Funktionalität umsetzen. Stößt sie an ihre Grenzen kann jederzeit eigener PHP-Code in den Templates verwendet werden. Wenn das noch nicht reichen sollte, können mit etwas mehr als grundlegenden PHP-Kenntnissen sogar eigene we-Tags erstellt werden.

Mit Hilfe dieser Grundlagen kann bereits ein in HTML und CSS umgesetztes Layout einfach als »Template« in webEdition angelegt und um die benötigten Eingabemöglichkeiten ergänzt werden.

Möglichkeiten zur Verwaltung von Inhalten

Natürlich kann im Rahmen dieses Artikels nur ganz leicht an der Oberfläche der Möglichkeiten eines CMS gekratzt werden. Neben der Möglichkeit, Inhalte Dokument-/Seiten-basiert vorzuhalten, gibt es in webEdition noch das Datenbank-/Objekt-Modul, mit dessen Hilfe die Inhalte in neutraler Form verwaltet werden können, um diese dann an unterschiedlichen Stellen in unterschiedlichen Darstellungen auszugeben.

Weitere Funktionen

Wie die meisten anderen Systeme enthält webEdition eine feingliedrige Benutzer-/Rechte-Verwaltung sowie eine Kundenverwaltung, eine Bannerverwaltung, ein Shop-Modul, ein Workflow-Modul, Import-/Export-Möglichkeiten und etliche weitere Module, die bei den meisten anderen »nur« als Drittanbieter-Plugins zur Verfügung stehen. Selbstverständlich kann man mit webEdition die URLs jeder Seite individuell bearbeiten und somit für Suchmaschinen optimieren.

Vom kommerziellen CMS zum Open-Source-Projekt

Die Arbeit an webEdition begann im Jahre 2000 und bereits 2001 kam das CMS als kostenpflichtiges Produkt der Astarte New Media AG auf den Markt. 2003 wurde es von der neu gegründeten webEdition Software GmbH übernommen und weiterentwickelt, die 2006 in living-e AG umfirmiert wurde. Ab November 2008 stellte die living-e AG das CMS ab der Version 6 unter der GPL-Lizenz zur Verfügung und beendete im Juni 2009 die Weiterentwicklung. In der Folge wurde diese von einer Community vorangetrieben, die sich im Februar 2010 zum gemeinnützigen webEdition e.V. zusammenschloss. Somit ist nicht nur der Fortbestand des CMS, sondern auch dessen Weiterentwicklung durch die wachsende Community (10.000 Installationen seit Gründung des Vereins) gesichert. Seit 2011 findet die jährliche webEdition-Konferenz statt, bei der sich Entwickler und Designer sowohl über die Zukunft des CMS als auch über dessen Einsatzmöglichkeiten austauschen können.

Fazit: Quellcode-Kontrolle und einfache Backend-Bearbeitung

Wer auf der Suche nach einem CMS ist, das absolute Kontrolle über den ausgegebenen Quellcode bietet, der sollte sich webEdition einmal näher anschauen. Ein weiterer Pluspunkt ist die einfache, visuell am Frontend angelehnte Bearbeitung im Backend, so dass aufwändige Schulungen für Redakteure wegfallen. Wer allerdings eine Plugin-Vielfalt für die unterschiedlichsten Anwendungsfälle erwartet, wie sie viele der anderen Systeme bieten, der wird enttäuscht sein. Allerdings bietet webEdition die Möglichkeit, diese Funktionalitäten durch einfache eigene Entwicklungen abzudecken.

Nähere Informationen gibt es auf der Website des webEdition e.V. sowie in dem erst vor Kurzem (Oktober 2012) erschienenen ersten Buch über webEdition.

Michael Grosch

Web-Applikationen mit Backbone.js

Image may be NSFW.
Clik here to view.
Logo: Backbone.js
Komplexen JavaScript-Code strukturieren

Bei der Strukturierung von JavaScript-basierten Web-Applikationen hilft Backbone.js: nach dem Baukasten-Prinzip können Webworker verschiedene Komponenten erstellen – vom einfachen Tab-View bis zur komplexen Single-Page-Application.

In den Anfangsjahren des Webs war das Modell sehr einfach: Ein Klick auf einen Link lädt eine neue HTML-Seite. Insbesondere Web-Applikationen setzen aber auf ein anderes Aktionsmodell, das denen von Desktop-Apps näher kommt: Während traditionell die komplette HTML-Seite mit leicht verändertem Inhalt neu geladen wird, tauschen Web-Applikationen gezielt einzelne Bereiche aus, zeigen Popups an, oder führen flüssig durch komplexe Navigationsstrukturen.

Backbone.js ist ein Baukasten für solche Web-Applikationen oder Single Page Applications und wurde vor gut zwei Jahren von Jeremy Ashkenas für DocumentCloud, einer Dokumentverwaltungs-Software für Journalisten geschrieben. Seitdem findet es auch auf vielen anderen Websites Anwendung, etwa bei der mobilen Website von LinkedIn und SoundCloud, auf AirBnB oder beim Projektmanagement-System Trello.

Backbone.js kommt modular daher und erlaubt dem Programmierer, die gerade benötigten Teile der Bibliothek zu verwenden – von einfacher Strukturierung des JavaScript-Codes bis zum Bau komplexer Single Page Applications im Stile von Google Mail bietet Backbone.js Hilfestellungen, die den Prozess deutlich beschleunigen. Im Vergleich zu ähnlichen Frameworks wie ember, Spine oder Googles AngularJS bietet Backbone zwar weniger Hilfestellungen und klare »Best Practices«, dafür lässt einem Backbone viel Spielraum, da es fast immer mehrere Wege zum Ziel gibt.

Models, Views und Router

Backbone.js funktioniert nach dem bekannten »Model-View-Router«-Prinzip: Die Applikation wird in diese drei Teile strukturiert:

In der Abkürzung MV* steht M für Models, V für Views und * für den Rest. Traditionell gibt es bereits seit den siebziger Jahren die MVC-Architektur, wobei C für Controller steht. Diese reagieren auf Benutzereingaben und veranlassen das Darstellen von Models via Views. Backbone.js implementiert dieses Schema allerdings nur lose und stellt statt Controllern sogenannte »Router« bereit, die eine ähnliche Funktion übernehmen.

Models dienen dazu, Daten zu repräsentieren, etwa einen Eintrag in einer Datenbank, der neu angelegt, verändert oder gelöscht werden kann. Views sind verantwortlich für die Anzeige des Inhalts: Sie vermitteln zwischen dem Benutzer und dem Model. Die Idee ist, dass ein Model viele verschiedene Views haben kann, um etwa auf unterschiedliche Weise angezeigt zu werden. Der Routerübernimmt die Navigation innerhalb einer Seite und veranlasst etwa, dass ein neuer View angezeigt wird, wenn der Benutzer auf einen Link klickt, oder dass beim Neuladen der Seite an die richtige Stelle im Interaktionsfluss gesprungen wird.
Zusätzlich gibt es noch Collections, die einen Spezialfall eines Models darstellen und mehrere Models des gleichen Typs gruppieren.

Dabei sind alle drei Komponenten nur lose miteinander verbunden; eine Backbone-Applikation kann auch nur eine oder zwei der Komponenten verwenden, etwa wenn keine Models existieren, oder kein Navigationsfluss existiert, der abgebildet werden muss.

Wir werden uns nun die verschiedenen Komponenten von Backbone.js anhand einer Kochbuch-Applikation ansehen. Hier ist vorab schon einmal das spätere Kochbuch zu sehen.

Models

Ein einfaches Model für Rezepte in unserer App sieht folgendermaßen aus:

  1. var Recipe = Backbone.Model.extend({
  2. defaults: {
  3. title: "New Recipe",
  4. ingredients: "",
  5. instructions: ""
  6. }
  7. });

Objekte vom Typ Recipe erben nun alle Methoden des Basis-Models und werden mit den entsprechenden Standard-Werten initialisiert. Ein neues Rezept wird mit new Recipe() erstellt. Optional können wir schon bei der Erstellung einige Werte setzen:

  1. var recipe = new Recipe({
  2. title: "Spiegeleier",
  3. ingredients: "2 Eier",
  4. instructions: "Eier in die heiße Pfanne geben. Warten."
  5. });

Alle Models haben einige Methoden, mit denen wir die Daten verändern und auslesen können (.set()/.get()/.has()).

Das Model-Objekt kümmert sich wirklich nur um die Speicherung der Daten und hat keinerlei Funktionen, um etwa HTML-Elemente zu generieren. Allerdings löst eine Veränderung der Werte an einem Objekt eine Reihe von change-Events aus. Wenn ein View gerade ein Model anzeigt, kann er von diesem benachrichtigt werden, um die Werte im DOM zu verändern.

Views

Views dienen dazu, den Inhalt eines Models anzuzeigen. Dabei können mehrere Views dasselbe Model anzeigen, und ein View kann eine Kombination aus mehreren Models anzeigen. In Backbone.js hat jeder View ein Haupt-DOM-Element, das den Inhalt repräsentiert. Der View kann dann auf Events reagieren, die innerhalb dieses Views auftreten.

In unserem Kochbuch soll man natürlich Rezepte bearbeiten können. Der View dafür sieht folgendermaßen aus:

  1. var EditView = Backbone.View.extend({
  2. template: _.template($('#template-edit').html()),
  3.  
  4. events: {
  5. 'click input[type="submit"]': 'save'
  6. },
  7.  
  8. save: function(){
  9. this.model.set({
  10. title: this.$el.find('#title').val(),
  11. ingredients: this.$el.find('#ingredients').val(),
  12. instructions: this.$el.find('#instructions').val()
  13. });
  14. this.trigger('finished');
  15. returnfalse;
  16. },
  17.  
  18. render: function(){
  19. this.$el.html(this.template(this.model.toJSON()));
  20. returnthis;
  21. }
  22. });

Backbone verwendet seinerseits das Underscore-Framework für interne Funktionen, das unter anderem eine Template-Engine mitbringt. Backbone.js ist aber nicht explizit auf ein Template-System festgelegt und kann mit jedem System (oder ganz ohne) verwendet werden.

Weiterhin definiert unser View ein Event: Der Schlüssel ist ein String, der aus dem Event-Namen und einem Selektor besteht, der Wert ist ein Methodenname innerhalb des Views. Alleine durch diese Definition werden alle click-Events auf Submit-Buttons innerhalb des Views die save()-Methode aufrufen. Diese speichert die Werte aus dem Formular zurück in das Model und erzeugt – in unserem Fall – ein finished-Event. Das dient dazu, dem übergeordneten View mitzuteilen, dass die Bearbeitung des Rezepts nun beendet ist. Um ein tatsächliches Abschicken des Formulars zu verhindern, geben wir außerdem false zurück.

Schließlich gibt es noch eine render()-Methode, die den HTML-Code für den View erzeugt (hier per Underscore-Template). Der Name render ist frei gewählt und erfährt kein spezielle Behandlung von Seiten Backbones.

Collections

Meistens gibt es von einem Model nicht nur eine Instanz. Deswegen bietet Backbone Collections an, um mehrere Instanzen eines Typs zusammenzufassen, etwa um alle Rezepte gleichzeitig vom Server zu laden. Collections enthalten normalerweise nur Objekte eines Typs. In unserem Kochbuch-Beispiel gibt es folgende Collection:

  1. var Cookbook = Backbone.Collection.extend({
  2. model: Recipe
  3. });

Im einfachsten Fall gibt es dann von einer Collection nur eine Instanz: Bei unserem Kochbuch-Beispiel gibt es genau eine Collection: this.cookbook = new Cookbook();. In dieser befinden sich dann alle Rezepte aus unserem Kochbuch.

Router

Backbone.js kann auch das Routing in einer Applikation übernehmen. Dazu wird der Klick auf einen Link abgefangen und stattdessen der Pfad dem Router übergeben. Dieser führt dann die entsprechende Methode aus, um etwa den aktuellen View zu ändern. Backbone.js unterstützt auch Platzhalter in den URLs, was nützlich für Detailansichten ist. Eine stark vereinfachte Version des Kochbuch-Routers sieht so aus:

  1. var CookbookApp = Backbone.Router.extend({
  2. routes: {
  3. '': 'home',
  4. 'recipe/add': 'add',
  5. 'recipe/:id': 'display'
  6. },
  7.  
  8. home: function(){/* ... */},
  9. add: function(){/* ... */},
  10. display: function(){/* ... */}
  11. });

Wenn der Benutzer die Seite lädt, sieht sich der Router zunächst den Teil nach dem #-Symbol an und führt dann die entsprechende Aktion aus. So wird sichergestellt, dass der Benutzer einfach URLs aus der Adresszeile kopieren kann, und sich dennoch an der richtigen Stelle in der Applikation befindet.

Wie alle anderen Komponenten in Backbone ist auch der Router optional. Natürlich müssen wir nicht alle Klicks in der Web-Applikation abfangen, so dass kein einziger Reload passiert, sondern etwa nur jene, bei denen sich nur ein kleiner Teil der Seite ändert.

Navigation

Web-Applikationen verhalten sich anders als das bisherige Interaktionsmodell. Insbesondere funktioniert der »Zurück«-Button nicht mehr wie gewohnt: Der Benutzer bleibt immer auf derselben HTML-Seite. Um das zu verhindern, bietet Backbone zwei Möglichkeiten:

Verändern des URL-Hashes
Per document.location.hash kann nur der Teil der URL nach dem # verändert werden. Normalerweise wird der verwendet, um zu Ankern in einer HTML-Seite zu springen, aber alle Browser können diesen auch auslesen und per JavaScript verändern. Jede Änderung erzeugt einen neuen Eintrag in der Browser-History. Wenn der Benutzer auf den Zurück-Button klickt, wird das onhashchange-Event ausgelöst und Backbone ändert die entsprechende Ansicht.
HTML5 pushState
Der Teil nach dem # wird bei einem Seitenaufruf nicht an den Server gesendet. Der Server kann also bei einem neuen Aufruf nur die Startseite zurückliefern – ein großes Problem etwa für SEO. Deshalb gibt es in HTML5 die pushState-API. Mit ihr können wir direkt die URL verändern, und zwar auch die Teile vor dem #. Eingesetzt wird sie beispielsweise schon bei GitHub zur Repository-Navigation. Backbone kann das Routing auch mit dieser API durchführen, sofern sie denn verfügbar ist (Der Internet Explorer unterstützt sie erst ab Version 10).

Persistenz

Die meisten Web-Applikationen interagieren mit dem Server. Dazu stellt Backbone standardmäßig eine AJAX-Schnittstelle bereit: Per model.save() wird ein Request mit den Model-Daten an den Server geschickt; mit model.fetch(id) können wir neue Models nachladen.

Allerdings kann Backbone auch mit anderen Persistenz-Modellen umgehen: Backbone.localStorage verwendet die localStorage-API um Daten direkt im Browser zu speichern. So können wir Web-Applikationen bauen, die komplette ohne Server arbeiten – alles ist lokal gespeichert.

Weitere Informationen

Wer jetzt Lust hat, selbst eine Backbone-App zu schreiben, findet im Internet viele gute Tutorials und Referenzen:

  • Kochbuch: Ein Zip-File mit dem Beispiel aus diesem Artikel.
  • Backbone-Dokumentation: Gut strukturierte Übersicht, allerdings fehlen Best-Practices.
  • Backbone Fundamentals: Sehr gutes Online-Buch über Backbone. Im März 2013 soll das Buch in gedruckter Form bei O’Reilly erscheinen.
  • JavaScript Web Applications: O’Reilly-Buch über Single-Page-Apps. Der Autor hat das Spine-Framework geschrieben und der Teil über Backbone fällt daher etwas dürftig aus. Allerdings gibt es hier sehr viel Basiswissen zu Web-Applikationen im Allgemeinen.
  • todomvc.com vergleicht viele Backbone-Alternativen und zeigt die Implementierung einer Todo-Applikation in jedem Framework.
  • Marionette hilft bei der Strukturierung von Backbone-Apps durch Vorgabe klarer Workflows
Konstantin Käfer

Barrierefreie Wissenschaft?!

Image may be NSFW.
Clik here to view.
Aufgeblätterte Seiten in einem alten Buch
Open Access

Open Access ist sicherlich kein klassisches Webworker-Thema, geht es doch hauptsächlich um den freien Zugang zu wissenschaftlichen Dokumenten. Wissenschaftliche Werke, Forschungsergebnisse usw. stehen jedoch nicht isoliert von den Websites, auf denen sie sich befinden.

Open Access steht für eine kostenfreie und öffentlich zugängliche Wissenschaft ohne finanzielle, gesetzliche und technische Barrieren: Jeder soll kostenlos auf wissenschaftliche Volltexte zugreifen, darin lesen und suchen und sie herunterladen können. Zugleich bietet Open Access Wissenschaftlern die Möglichkeit, ihre Forschungsergebnisse schnell, zeitgemäß und häufig kostenlos zu veröffentlichen und damit am nationalen und internationalen wissenschaftlichen Diskurs teilzunehmen. Hauptstrategien von Open Access sind

der Goldene Weg,
die Erstveröffentlichung in einem expliziten Open-Access-Publikationsorgan, und
der Grüne Weg,
die Parallelveröffentlichung (z.B. auf einer eigenen Webseite oder einer Universitätsseite.

Der Startschuss der internationalen Open-Access-Bewegung fiel in den frühen 1990er Jahren. Ihr wichtigstes Organ, die Budapest Open Access Initiative, wurde 2001 gegründet; sie koordiniert die weltweiten Aktivitäten für den offenen Zugang zu Wissenschaft. Mit der Berliner Erklärung über offenen Zugang zu wissenschaftlichem Wissen vom 22. Oktober 2003 wurden Gegenstand und Ziele von Open Access von rein wissenschaftlichen Texten auf das kulturelle Erbe ausgedehnt und in die Open-Access-Bestrebungen integriert. Unterzeichnet wurde die Berliner Erklärung von Vertretern der wichtigsten deutschen Forschungsinstitutionen; heute fühlen sich zahlreiche Bibliotheken, Wissenschaftler und Verlage dem Open-Access-Gedanken verpflichtet.

Zugänglichkeit und/oder Barrierefreiheit?

Ein wichtiger Leitsatz der Open-Access-Bewegung ist:

»Der barrierefreie Zugang zu wissenschaftlichen Informationen fördert die internationale Vernetzung und trägt damit zur besseren Wahrnehmung europäischer Forschung weltweit bei.«

Dabei wird in der Open-Access-Bewegung unter barrierefreiem Zugang vornehmlich die grundsätzliche Abrufbarkeit wissenschaftlicher Werke im Web verstanden – quasi nach dem Motto: »HTML und PDF sind doch bereits (im Web) zugänglich«.

Tatsächlich stehen zahlreiche Open-Access-Publikationen meist sowohl als HTML als auch als PDF frei zur Verfügung. Rein grafische und für blinde Nutzerinnen und Nutzer erst einmal unzugängliche Zeitschriften und Dokumente finden sich zwar auch – scheinen bei neueren Veröffentlichungen jedoch die Ausnahme zu sein. Das trifft leider aber auch für barrierefrei umgesetzte PDF zu und auf manchem Webangebot wurde allenfalls marginal auf Barrierefreiheit geachtet.

Barrierefreiheit, wie Webworker den Begriff verstehen, spielt in der Open-Access-Bewegung ingesamt noch eine untergeordnete Rolle.

Problem: Historische Dokumente

Nicht alle wissenschaftlichen Werke und Quellen aus allen Jahrhunderten können vollständig und für jeden barrierefrei und unter Bewahrung der Originaltreue aufbereitet werden. Dies gilt für historische Schriften und alte Drucke sowie (eingeschränkt) für Briefwechsel und damit für Dokumente, bei denen es auf Inhalt und visuellen Eindruck ankommt.

Warum aber sollen z.B. sehende Tastaturbenutzer diese wichtigen Quellen wissenschaftlicher Forschung z.B. wegen eines schwachen oder gar unsichtbaren Fokus nur über Erraten ansteuern können? Ein Beispiel ist der digitalisierte Briefwechsel des Philosophen Ernst Cassirer: Er kann weitgehend – allerdings leider nicht ganz vollständig – mit der Tastatur bedient werden. Sehende Tastaturbenutzer benötigen aufgrund des unsichtbaren Fokus jedoch ein Userstyle oder Userscript wie »Highlight every focus Element«. Nicht jedem sind diese Möglichkeiten bekannt.

Und: Natürlich müssten – besonders in diesem Fall – Transkriptionen und damit Textalternativen für blinde Nutzer geschaffen werden. Bei dieser Gelegenheit sollte auch darauf geachtet werden, dass alle grafischen Bedienelemente Alternativtexte erhalten. Und eine gute Überschriftenstruktur ist selbstverständlich auch für Webseiten dieser Art wichtig.

Accessibility und Open Access in der Förderung

Im Oktober 2012 erschien die empfehlenswerte Informationsbroschüre »Open Access Strategien für wissenschaftliche Einrichtungen (PDF)«. Sie gibt einen guten Überblick über die Implementierung von Open Access anhand von Bausteinen und Beispielen. Auch hier wird Barrierefreiheit nur auf Basis der oben genannten Definition thematisiert, und leider ist das Dokument selber nicht barrierefrei. Selbstverständlich handelt es sich bei den vorgestellten Projekten und Strategien um Überblicksdarstellungen. Interessant ist also, ob Barrierefreiheit bei den großen Förderern eine Rolle spielt?

Ist Barrierefreiheit bei der DFG ein Thema?

Bei der DFG – steuerfinanziertem, wichtigem Geldgeber und Unterstützer von Open Access Projekten – scheint Barrierefreiheit bisher kein Vergabekriterium zu sein. Zumindest lieferte die Suche nach typischen Begriffen, wie »Barrierefreiheit«, »BITV«, »WCAG« und »barrierefrei« nur ein relevantes Dokument aus dem Jahr 2005 in die Trefferliste: »Retrospektive Digitalisierung von Bibliotheksbeständen«. Diesen »Evaluierungsbericht über einen Förderschwerpunkt der DFG« kennzeichnet eine Reduzierung auf blinde Nutzer; Basis war eine »grobe Bewertung« mit dem Textbrowser Lynx. Ergebnis: Nur »50% (der untersuchten Angebote sind) selbst nach großzügigen Maßstäben« barrierefrei.

Der Evaluierungsbericht vermittelt den Eindruck, dass die weitaus größeren anderen Nutzergruppen bei der Evaluierung unter den Tisch fielen: Es wird zwar auf die noch 2005 relevanten Web Content Accessibility Guidelines 1.0 als »de-facto-Standard« verwiesen. Die Verfasser kommen jedoch zu dem Schluss:

»(…) U.E. sind die üblichen Kriterien von Barrierefreiheit im Kontext der Retrodigitalisierung nur bedingt brauchbar: Wenn ein Webangebot wesentliche Teile der durch dieses Angebot transportierten Information über Bilddateien transportiert, so scheint uns die Barrierefreiheit des Rests des Angebotes weniger signifikant.«

Dennoch wurde »ein verbindlicher Standard für die Barrierefreiheit« empfohlen, der sich jedoch »an einer pragmatischen Interpretation der tatsächlich an den Forschungseinrichtungen verfügbaren Ausrüstung orientiert – (…und) festgeschrieben werden (sollte).«

Beispiel: DFG Science TV

Barrierefreien Nachholbedarf gibt es etwa bei DFG Science TV, dem Wissenschaftsfernsehen der Deutschen Forschungsgemeinschaft. DFG-geförderte Projekte können hier ihre Forschungstätigkeit der Öffentlichkeit kostenfrei zugänglich machen. Das bedeutet jedoch nicht, dass die Inhalte für alle nutzbar sind:

Der recht guten Dokumentstruktur stehen deutliche Probleme bei der Tastaturbedienbarkeit (Tastaturfalle inkl.) gegenüber. Screenreadernutzer werden mit einer Palette leerer alt-Attribute für Web 2.0-Icons begrüßt und jeder Nutzer auf der Startseite mit einem automatisch ablaufenden Video. Für blinde Besucher des Webangebots kommt es so quasi zu einer babylonischen Sprachverwirrung – sofern nicht die Sprachausgabe des Sceenreaders abgeschaltet und sich auf die Suche nach dem Stop-Button gemacht wird , was durch die Tastaturfalle am Seitenbeginn zumindest beim Durchtabben problematisch ist.

Image may be NSFW.
Clik here to view.
Screenshot der Social Media Icons mit eingeblendeten leeren alt-Attributen (lineare Seitenansicht)
Abbildung 1: Social Media Icons mit eingeblendeten leeren alt-Attributen (lineare Seitenansicht)

Für die hochwertigen Projektfilme existieren weder Untertitel noch Transkripte. Damit stehen wesentliche Inhalte des Wissenschaftsfernsehens gehörlosen und hochgradig schwerhörigen Menschen kaum zur Verfügung. Nachbesserungsbedarf gibt es außerdem bei den Seitentiteln. Sie verraten nicht immer, worum es auf den Unterseiten geht. Und die Kontrastverhältnisse von teilweise nur 2,3:1 (z. B. Links auf blauem Hintergrund) erschweren die Nutzbarkeit für Menschen mit Sehbehinderung.

Image may be NSFW.
Clik here to view.
Screenshot Beispiel für schwachen Kontrast - Blaue Schrift auf hellblauem Hintergrund.
Abbildung 2: Beispiel für schwachen Kontrast
– Blaue Schrift auf hellblauem Hintergrund.

Nicht nur für die Nutzer, auch für die Forschungsprojekte ist das mehr als schade.

Barrierefreiheit bei der Helmholtz-Gemeinschaft

Die Helmholtz-Gemeinschaft ist »mit 17 Forschungszentren und einem Jahresbudget von rund 3,3 Milliarden Euro die größte Wissenschaftsorganisation Deutschlands«. Sie gehörte zu den Erstunterzeichnern der Berliner Erklärung über den offenen Zugang zu wissenschaftlichem Wissen. Leider scheint – ähnlich wie bei der DFG – Barrierefreiheit bei der Forschungsförderung im Schwerpunkt Open Access keine Rolle zu spielen. Zumindest förderte eine Suche keine eindeutigen Treffer zu Tage. Relevant allenfalls:

»Universities should develop institutional policies and strategies that foster the availability of their quality controlled research results (in the form of research papers and other outputs) for the broadest possible range of users, maximising their visibility, accessibility and scientific impact.«

aus dem Dokument »Open Access. Positionen, Prozesse, Perspektiven«. Schaut man sich jedoch den Kontext an, so ist fraglich, ob Barrierefreiheit oder die bloße technische Erreichbarkeit gemeint ist.

Open Access – Eine Chance für Alle

Open Access kann eine der wichtigsten wissenschaftlichen Bewegungen des digitalen Zeitalters werden. Zugängliche und für alle nutzbare Fachzeitschriften (und generell Veröffentlichungen) stehen für Chancengleichheit in wissenschaftlicher Ausbildung, Arbeit und Vernetzung. Technische Barrieren entstehen jedoch nicht nur, wenn wissenschaftliche Werke nur als Print zur Verfügung stehen. Sie entstehen auch dann, wenn die Inhalte zwar kostenfrei im Web zugänglich sind, aber als grafische PDF bzw. und/oder ungenügend unstrukturierte PDF und HTML auf schwer oder nicht nutzbaren Webseiten stehen. Sie können sich dann für Menschen mit Behinderungen und durchaus auch für ältere Nutzer

  • zu finanziellen Barrieren werden,
  • sich als Zeitfresser entpuppen,
  • die gewünschte und erhoffte Vernetzung mit anderen (Wissenschaftlern) behindern und
  • die Möglichkeiten und Chancen einer an alle gerichteten Wissenschaftskommunikation verringern.

Nicht nur wünschenswert, sondern nötig ist die Aufnahme einer echten Barrierefreiheit im Sinne der Zugänglichkeit und Nutzbarkeit für alle in die Vergabekriterien großer Forschungsgemeinschaften. Weitere wichtige Maßnahmen sind aus meiner Sicht u.a.:

  • Beratung der geförderten Projekte bei der Umsetzung
  • Schulungen der Beteiligten
  • Wissenstransfer
  • Erstellen und Austausch von Autorenrichtlinien zu barrierefreien, strukturierten Dokumente
  • Sichten und Beseitigen von Barrieren in Frontend und Backend gängiger Publikationssysteme, wie dem verbreiteten Open Journal System sowie das
  • Erstellen zweisprachiger Informationsmaterialien

Kompetenz sollte an zentraler Stelle aufgebaut und aufgrund des internationalen Charakters der Open-Access-Bewegung auf Basis der Web Content Accessibility Guidelines 2.0 erarbeitet werden.

Erst wenn die rein technische Zugänglichkeit um die Nutzbarkeit für alle ergänzt und Barrierefreiheit als integraler Bestandteil gesehen wird, kann das Ziel erfüllt und die Verheißung von Open Access als (immerhin meist öffentlich geförderter) Wissenschaftskommunikation für alle eingelöst werden.

Vielen Dank an Lambert Heller für wichtige Hinweise und Anregungen zum Thema Open Access.

Kerstin Probiesch

Türchen für Türchen

Image may be NSFW.
Clik here to view.
Illustration: Weihnachtsbaum mit Geschenken vor grauem Hintergrund
Tutorial: Digitaler Adventskalender

Ab und zu lohnt sich ein Blick hinter die Kulissen. Dazu reißen wir heute unseren eigenen Adventskalender auseinander. Wie steht es mit Inhalten, Usability und Barrierefreiheit? Wie reagiert der Kalender in einem Responsive Design? Wie sehen Alternativen und Ergänzungen für eure eigenen Kalender im nächsten Jahr aus?

Seit Jahren bieten wir im Dezember unseren Adventskalender an. In diesem Jahr wollten wir die Aktion mit einem grafischen Kalender begleiten. Mit Türchen, die sich öffnen und einen Artikel offenbaren. Die Idee birgt in sich bereits ein paar Probleme mit der Usability. Wie ein echter Kalender sollten die Türchen wild verteilt sein, so dass ein Besucher erst einmal suchen muss. Und hinter den Türchen wird vermutlich nicht genug Platz zur Verfügung stehen, um unsere üblichen Teaser mit Teaserbild, Dachzeile, Titel, Autorenzeile und Teasertext zu beherrbergen. Diese Unzulänglichkeiten liegen in der Natur der Sache. Da wir aber ohnehin einen Menüpunkt für die Artikel haben und der Adventskalender auch über die Serie erreichbar ist, gibt es für den Zugang genug Alternativen zum grafischen Kalender.

Die Basis

Semantisch haben wir hier eine nummerierte Liste von Artikeln. Für die Teaser sehen wir an dieser Stelle erst einmal Dachzeile, Titel, Autor, Datum und Teasertext vor. Am 2. Dezember könnten die ersten drei Artikel gegen 5 Uhr morgens so aussehen.

  1. <ol>
  2. <li>
  3. <p>Responsive Images</p>
  4. <h2><ahref="http://webkrauts.de/artikel/2012/responsive-images">
  5. Optimiert für Groß und Klein</a></h2>
  6. <p>von Christoph Zillgens am 1.12.2012</p>
  7. <pclass="teaser">Responsive Webdesign macht seit geraumer Zeit die
  8. Runde. Während sich langsam Best Practices und sinnvolle Techniken
  9. etablieren, gibt es einen Bereich, der etwas kniffliger zu lösen ist:
  10. Die Rede ist von Responsive Images – reaktionsfähigen Bildern,
  11. für die an einer HTML-Erweiterung gearbeitet wird.</p>
  12. </li>
  13. <li>Der heutige Artikel wird im Laufe des Vormittags veröffentlicht.</li>
  14. <li>Dieses Türchen öffnet sich erst am 3. Dezember</li>
  15. </ol>

Die Basis: Stand der Artikel früh morgens am 18.12. in einem Basis-Layout

Mit PHP füllen wir nun täglich alle 24 Listenelemente neu mit einer dieser drei Optionen.

Das Grunddesign

Nun brauchen wir einen Kalender mit Türchen, die sich auch irgendwie öffnen lassen. In unserem Fall nehmen wir eine Illustration, die wir in 6x4 Felder teilen. Bei einem Mouse-Over sollen sich in einem Feld zwei Türflügel nach links bzw. rechts bewegen. Außerdem soll der Tag des Monats links oben erscheinen und sich mit der linken Seite mitbewegen. Unser Markup für das erste Türchen sieht nun so aus:

  1. <olid="ak2012">
  2. <liclass="active"id="ak1">
  3. <p>Responsive Images</p>
  4. <h2><ahref="http://webkrauts.de/artikel/2012/responsive-images">
  5. Optimiert für Groß und Klein</a></h2>
  6. <p>von Christoph Zillgens am 1.12.2012</p>
  7. <pclass="teaser">Responsive Webdesign macht seit geraumer Zeit die
  8. Runde. Während sich langsam Best Practices und sinnvolle Techniken
  9. etablieren, gibt es einen Bereich, der etwas kniffliger zu lösen ist:
  10. Die Rede ist von Responsive Images – reaktionsfähigen Bildern,
  11. für die an einer HTML-Erweiterung gearbeitet wird.</p>
  12. <divclass="left"><span>1</span></div>
  13. <divclass="right"></div>
  14. </li>
  15. </ol>

Die Liste bekommt eine id, um sie direkt ansprechen zu können. Mit den Klassen active und inactive unterscheiden wir freigeschaltete Tagen von zukünftigen Tagen. Jedes Listenelement bekommt noch eine eindeutige id ak1 usw., um den Tag später im Kalender zu positionieren.

Ein einzelnes Türchen soll die Maße 250 Pixel x 150 Pixel bekommen, mit einem 1px-border nach rechts und unten. Die ol bekommt ihrerseits denselben Border nach oben und links. Innerhalb der Liste werden die Listenelemente absolut positioniert, um die Reihenfolge optisch durcheinanderzuwirbeln. Per background geben wir den einzelnen Teilen der Türchen (den Klassen left und right) nun einen Ausschnitt desselben Bildes mit. Die Illustration nutzen wir analog zu einem CSS-Sprite. Das hat den Vorteil, dass wir für andere Jahre/Kalender einfach nur ein einzelnes Bild austauschen müssten.

Image may be NSFW.
Clik here to view.
Illustration: Weihnachtsbaum mit Geschenken vor grauem Hintergrund
Für unser Beispiel nutzen wir die Illustration: »Floral-Ribbon Christmas Tree« von fangol, via sxc.hu

Außerdem wollen wir noch bei einem Mouse-Over per Tooltip anzeigen, dass sich ein zukünftiges Türchen erst am Tag X öffnet. Für die Tooltips erweitern wir die Listenelemente um das title-Attribut:

  1. <liclass="inactive"id="ak18"title="Der heutige Artikel wird im Laufe des Vormittags veröffentlicht.">
  2. <p>Der heutige Artikel wird im Laufe des Vormittags veröffentlicht.</p>
  3. <divclass="left"><span>18</span></div>
  4. <divclass="right"></div>
  5. </li>
  6. <liclass="inactive"id="ak19"title="Dieses Türchen öffnet sich erst am 19. Dezember.">
  7. <p>Dieses Türchen öffnet sich erst am 19. Dezember.</p>
  8. <divclass="left"><span>19</span></div>
  9. <divclass="right"></div>
  10. </li>

Zwischenstand: Das Layout in 4x6 Feldern, ohne Öffnen der Türchen

Alternativer Aufbau

In diesem Fall haben wir den Kalendertag per HTML und CSS über das Bild gelegt. Alternativ ist auch denkbar, bei dem die Tage bereits im Bild enthalten sind. Das hätte den Vorteil, dass der Tag nicht doppelt im HTML vorkommt (die ol ist ja bereits nummeriert) und die Tage hübscher gestaltet werden könnten. Aber unsere Lösung ist bei Änderungen flexibler, falls wir etwa die Reihenfolge der Tage, Schriftfarbe oder Hintergrund des Datums ändern wollten.

Bei unserem Kalender geben wir immer eine Liste mit 24 Elementen an. Stattdessen könnten wir auch nur die bereits belegten Türchen ausgeben. Das reduziert die Liste um noch nicht benötigte Elemente. Da wir aber die Tooltips nutzen wollen, bleiben wir bei 24 Listenelementen.

Türchen öffne dich

Noch verdecken die Türflügel unsere Inhalte. Wir benötigen einen Mouseover-Effekt. Außerdem möchten wir gerne die gesamte Fläche des Türchen verlinken, also erweitern wir zunächst das HTML versuchsweise um eine Linkfläche a.area:

  1. <olid="ak2012">
  2. <liclass="active"id="ak1">
  3. <p>Responsive Images</p>
  4. <h2><ahref="http://webkrauts.de/artikel/2012/responsive-images">
  5. Optimiert für Groß und Klein</a></h2>
  6. <p>von Christoph Zillgens am 1.12.2012</p>
  7. <pclass="teaser">Responsive Webdesign macht seit geraumer Zeit die
  8. Runde. Während sich langsam Best Practices und sinnvolle Techniken
  9. etablieren, gibt es einen Bereich, der etwas kniffliger zu lösen ist:
  10. Die Rede ist von Responsive Images – reaktionsfähigen Bildern,
  11. für die an einer HTML-Erweiterung gearbeitet wird.</p>
  12. <divclass="left"><span>1</span></div>
  13. <divclass="right"></div>
  14. <aclass="area"href="http://webkrauts.de/artikel/2012/responsive-images"></a>
  15. </li>
  16. </ol>

Nun fügen wir in CSS den Hover-Effekt hinzu:

  1. li.active a:hover.left{left: -125px; }
  2. li.active a:hover.right{left: 250px; }
  3.  
  4. li.active.left, li.active.right{
  5. -ms-transition: left0.5s;
  6. -o-transition: left0.5s;
  7. -webkit-transition: left0.5s;
  8. -moz-transition: left0.5s;
  9. transition: left0.5s;
  10. }
  11.  
  12. li.active a:hover.left, li.active a:hover.right{
  13. -ms-transition: left 1s;
  14. -o-transition: left 1s;
  15. -webkit-transition: left 1s;
  16. -moz-transition: left 1s;
  17. transition: left 1s;
  18. }

Damit verschieben wir die Türflügel nach links und rechts. Die Transitions sorgen dafür, dass sich die Türchen öffnen und etwas schneller wieder schließen. Das funktioniert in allen modernen Browsern. Natürlich nicht im Internet Explorer 8 oder 9 (ältere Versionen berücksichtigen wir bei webkrauts.de nicht mehr). In den IEs fällt aber lediglich die Transition weg, die Türen öffnen sich also quasi auf einen Schlag. Da nur ein Effekt wegfällt, die Inhalte aber erreichbar sind, nehmen wir hier keine weiteren Anpassungen für den IE vor.
Aus Platzgründen verstecken wir per CSS noch den Teasertext.

  1. .teasertext{text-indent: -9999px; }

Die Schrift hinter der Tür erscheint in Weiß auf Rot. Wenn die Seite zum ersten Mal aufgerufen wird, ist die Schrift oft schon sichtbar, während das Hintergrund-Bild für die Türen noch geladen wird. Das führt zu einem unerwünschten Aufblitzen des Textes. Daher setzen den Text erst einmal weiß auf weißen Hintergrund. Erst beim Mouse-Over ändern wir die Farben.

Zwischenstand: Das Layout in 4x6 Feldern, die Türen öffnen sich, die gesamte Fläche dient als Link

Barrierefreiheit

Der Screenreader hat keine Probleme, er kann die Türchen komplett mit Teaser und in der richtigen Reihenfolge erfassen. Beim zeilenweisen Lesen wird auch gesagt, dass sich zukünftige Türchen erst im Laufes des Vormittags oder am Tag X öffnen. Allein: die zusätzliche Angabe des Kalendertages ist überflüssig, deshalb verstecken wir ihn mit aria-hidden.

  1. <divclass="left"><span aria-hidden="true">1</span></div>
  2. <divclass="right"></div>

Die Texte erscheinen in Weiß (#FFF) auf Rot (#CD0000). Das ergibt einen Kontrast von 5.84 und erfüllt WCAG 2.0 AA. Das feste Format für die Türchen (250 Pixel x 150 Pixel) wird in Kombination mit einem Text-Zoom dafür sorgen, dass Text Stück für Stück nach unten aus dem Türchen herausgeschoben wird. Wer darauf Rücksicht nehmen will, kann zum Beispiel die Türchen etwas größer anlegen oder die Texte z.B. auf den Autor und den Titel beschränken, so dass der gesamte Text noch bei 150% zu lesen ist.

Aktuell haben wir aber die Tastaturnutzer verprellt. Beim Tabben erreichen wir zwar jeden Link. Aber jeden eben auch zweimal, weil wir bisher noch zusätzlich die Überschrift verlinkt haben. Vor allem aber öffnen sich die Türen nicht, was aber auch für Tastatur-Nutzer sinnvoll wäre. Die Lösung birgt ein etwas großzügigerer Gebrauch des Links. Wir setzen ihn einfach um alles herum:

  1. <liclass="active"id="ak1">
  2. <ahref="http://webkrauts.de/artikel/2012/responsive-images">
  3. <p>Responsive Images</p>
  4. <h2>Optimiert für Groß und Klein</h2>
  5. <p>von Christoph Zillgens am 1.12.2012</p>
  6. <pclass="teaser">Responsive Webdesign macht seit geraumer Zeit die
  7. Runde. Während sich langsam Best Practices und sinnvolle Techniken
  8. etablieren, gibt es einen Bereich, der etwas kniffliger zu lösen ist:
  9. Die Rede ist von Responsive Images – reaktionsfähigen Bildern,
  10. für die an einer HTML-Erweiterung gearbeitet wird.</p>
  11. <divclass="left"><span aria-hidden="true">1</span></div>
  12. <divclass="right"></div>
  13. </a>
  14. </li>

Ja, hier stecken Block-Level-Elemente innerhalb des Links. Für einige Webworker mag das vielleicht irgendwie »unsauber« aussehen, aber in HTML5 ist das erlaubt. Vor allem: es ist valide, und es funktioniert. Tastatur-Nutzer fokussieren beim Tabben den Link, so dass wir nun auch die Klassen left und right innerhalb des Links ansprechen können:

  1. #ak2012 a:hover.left, #ak2012 a:focus.left{left: -125px; }
  2. #ak2012 a:hover.right, #ak2012 a:focus.right{left: 250px; }

Die Tab-Reihenfolge richtet sich natürlich nach der Reihenfolge der Listenelemente. Dadurch »springt« ein Tab-Nutzer durch den Kalender, was vielleicht etwas ungewohnt ist, aber zur Chronologie passt. Nach dem 24. Dezember könnte man es optional allen Nutzern einfacher machen und die Türchen optisch in die chronologische Reihenfolge setzen. Das heißt, die Türchen begännen dann oben links mit 1 und gehen in gewohnter Leserichtung weiter.

Zwischenstand: Das Layout in 4x6 Feldern, die Türen öffnen sich nun auch für Tastatur-Nutzer

Ob breit, ob schmal

Nun haben wir webkrauts.de Ende November auf ein responsive Design umgestellt. Also muss unser Kalender auch bei kleineren Breiten funktionieren. Wir könnten überlegen, den Kalender skalieren zu lassen. Dann haben wir aber schnell das Problem, dass die Texte nicht mehr in die Felder passen. Hier haben wir das Glück, dass sich 24 Tage als 4x6, 3x8, 2x12 und 1x24 aufteilen lassen. Wenn das 4x6-Schema nicht mehr passt, wechseln wir also einfach auf 3x8 Felder. Dafür bereiten wir ein alternatives Hintergrundbild in den neuen Maßen vor und müssen nur noch die Türchen anders positionieren.

Werden wir noch schmaler, könnten wir mit 2x12 Feldern arbeiten. Dann muss man aber schon sehr viel hoch- und runterscrollen, um ein Türchen zu finden. Wenn also keine drei Felder mehr nebeneinanderpassen, verzichten wir lieber auf eine grafische Darstellung und bieten nur noch die Liste an. In dieser Darstellung können wir den Teasertext anzeigen, verstecken aber das span mit dem Kalendertag.

Ebenso fügen wir zwei Hinweise ein. Über dem Kalender: »Auch in diesem Jahr bieten wir euch jeden Tag Wissenswertes rund um Webstandards, Barrierefreiheit, Tools, Usability oder SEO. Neben der Kalender-Ansicht könnt ihr auch eine ›traditionelle‹ Artikel-Liste des Adventskalenders nutzen.«
Und unter dem Kalender: »Dieser Adventskalender nutzt CSS3-Transitions. Der Effekt funktioniert in allen modenen Browsern, aber ›natürlich‹ nicht im Internet Explorer 8 oder 9 (dort werden aber die Titel angezeigt und die Links funktionieren auch).«
Der Großteil davon sind nur sinnvoll, wenn die grafische Version des Kalenders zu sehen ist. Bei schmalen Breiten verstecken wir also Texte (über eine zusätzliche Klasse) und behalten nur noch »Auch in diesem Jahr bieten wir euch jeden Tag Wissenswertes rund um Webstandards, Barrierefreiheit, Tools, Usability oder SEO.«

Finale: Der komplette Kalender, mit Transitions, bedienbar für Tastatur-Nutzer, samt Responsive Design. Das Beispiel als zip zum Download.

Sahnehäubchen

Bisher schieben sich die Türchen des Kalenders nur zur Seite. Ein richtiger Kalender öffnet sich natürlich in 3D, die Türflügel kommen dem Nutzer entgegen. Wer etwas wagemutuger ist, versucht sich also an der dritten Dimension. Mit CSS3 3D-Transforms können wir den Effekt in modernen Browsern mittlerweile auch nachbauen. Einigermaßen jedenfalls.

Finale in 3D: Der komplette Kalender, mit 3D-Transitions, bedienbar für Tastatur-Nutzer, samt Responsive Design.

Ein kurzer Test in den aktuellen Desktop-Browsern (unter Windows) zeigt:

  • Chrome (23) öffnet die Türchen in 3D. Allerdings verschwinden Türchen, wenn links oder rechts Kalendertage stehen, die in der Liste später folgen. Außerdem ruckelt es gelegentlich.
  • Firefox (17) handhabt die verdeckten Türchen wie Chrome, ruckelt aber etwas mehr.
  • Safari (5.1.7) liefert das beste Ergebnis. Die animierten Türchen liegen automatisch immer über anderen Türchen. Damit ließe sich fast arbeiten. Allerdings gibt es manchmal seltsame Hicc-Ups, und die Türchen bewegen sich über den kompletten Viewport.
  • In Opera (12) und im Internet Explorer 9 bewegt sich gar nichts. Immerhin funktionieren die Linkflächen noch.

Bei so vielen Problemen allein schon auf den Desktop-Browsern unter Windows, muss man deutlich mehr Arbeit investieren. Zum Beispiel könnte man Modernizr bemühen und wahlweise die Türchen in 3D oder in 2D öffnen.

Damit kommt dann auch JavaScript ins Spiel, auf das wir bisher absichtlich verzichtet haben. Es gibt zwei weitere Ansätze, um den Kalender etwas aufzupeppen. In Touchscreens sorgt ein Tap auf einen Kalendertag bisher dafür, dass sich die Türchen aufschieben, sich direkt darauf aber der Link öffnet. Wir könnten zum Beispiel hammer.js zu Hilfe nehmen und die Türchen mit Tap und Doppeltap ausstatten, um das Mouse-Over und Klick auf einem Desktop abzubilden (siehe auch den Artikel über Touch-Events). Das erübrigt sich aber mit der nächsten Überlegung.

Bei einem üblichen Kalender nimmt man an einem Tag die Schokolade heraus, das Türchen bleibt danach geöffnet. Für die Usablity ist es ohnehin besser, wenn auf einen Blick alle offenen Themen erfasst werden können. Da wir aber extra die CSS-Transitions eingefügt haben und die Türchen also nicht sofort geöffnet erscheinen sollen, machen wir einen Kompromiss. Der Kalender erscheint erst einmal wie bisher, scrollt man herunter, öffnen sich der Reihe nach (und recht fix) die bisherigen Türchen. Ist JavaScript nicht aktiviert, bleibt der Kalender wie bisher bedienbar.

  1. <script src="js/jquery.min.js"></script>
  2. <script>
  3. $(document).ready(function(){
  4. $('body').addClass('js');
  5. $(window).scroll(function(){
  6. if( $(window).scrollTop()> 10){
  7. for(var i = 1; i < 25; i++){
  8. if( $('#ak'+i).hasClass('active')){
  9. $('#ak'+i+' .left').delay(i*80).animate({left: '-125px'}, 5);
  10. $('#ak'+i+' .right').delay(i*80).animate({left: '250px'}, 5);
  11. }
  12. }
  13. }
  14. });
  15. });
  16. </script>

Das Script nutzt jQuery. Sobald der User 10 Pixel nach unten scrollt, durchläuft die Schleife 24 Türchen-Elemente. Hat das Element die Klasse active animieren wir die Türchen. Mit delay() verzögern wir den Effekt bei jedem Türchen etwas mehr.
Nun sieht man aber keinen Unterschied mehr, wenn ein Nutzer mit der Maus über einem Feld hovert oder ein Link den :focus hat. Also ergänzen wir den Body mit der Klasse js, sobald die Animation startet und geben per CSS neue Anweisungen für den Hintergrund, :hover und :focus.

  1. body.js#ak2012 a {
  2. color: #FFF;
  3. background-color: #CD0000;
  4. }
  5. body.js#ak2012 a:hover,
  6. body.js#ak2012 a:focus{
  7. background-color: #FFF;
  8. }
  9. body.js#ak2012 a:hover p,
  10. body.js#ak2012 a:hover h2,
  11. body.js#ak2012 a:focus p,
  12. body.js#ak2012 a:focus h2 {
  13. color: #CD0000;
  14. }

Finale mit einer Prise JavaScript: Der komplette Kalender, mit Transitions, bedienbar für Tastatur-Nutzer, samt Responsive Design. Scrollt man etwas herunter, öffnen sich alle aktiven Türchen.

Und »schon« haben wir nicht nur einen grafischen Adventskalender, sondern auch gleich wichtige Anforderungen an Usability, Accessibility und Responsive Design erfüllt.

Andere Adventskalender

Nicht nur wir haben uns einen Adventskalender gebastelt. Hier ein paar andere Beispiele zur Inspiration:

Nicolai Schwarz

Start frei

Image may be NSFW.
Clik here to view.
Startbereich einer Rennstrecke in einem Sport-Stadion
Tipps für Berufsanfänger

Aller Anfang ist schwer. Zum Ausklag des Adventskalenders haben wir deshalb in diesem Jahr ein paar Ratschläge und Ideen für Berufsanfängern gesammelt. Webkrauts antworten auf die Frage: »Welchen Tipp hast du für Webworker, die gerade neu im Beruf anfangen / eine Ausbildung machen?«

Sucht euch gleich zu Beginn eine Gruppe oder Gemeinschaft, in die ihr euch einbringt und von der ihr lernen könnt. Das kann ein lokaler Webentwickler-Stammtisch sein oder auch eine Gruppierung wie die Webkrauts. Nehmt ohne Berührungsängste an Treffen und Austausch teil. Im späteren Arbeitsleben kann eine schnelle Nachfrage im Netzwerk stundenlanges Lesen von Dokumentationen oder mühsames Bugfixing ersparen. Wichtig hierbei: Geben und Nehmen sollten sich die Waage halten.

Stefan David

Ich empfehle jedem, kostenlose Kurse und User-Groups zu besuchen. In fast jeder größeren Stadt gibt es regelmäßig Veranstaltungen, bei denen erfahrene Webworker ihr Wissen weitergeben. Beispiele sind die RailsGirls und Webmontage. Auf meetup.com finden sich viele weitere Gruppen, von Design bis hin zu Programmierung.

Ein weiterer Tipp: Fangt an zu experimentieren! Baut kleine Sites und Demos oder schreibt Artikel und Scripte. Verbreitet sie über soziale Netzwerke und ladet andere zum mitmachen ein. Das bringt wertvolles Feedback, Zuspruch und Kontakte.

Mathias Schäfer

Meine Empfehlung lautet: »Kümmert Euch selbst um Eure Weiterbildung« – unabhängig davon, ob Ihr gerade in der Ausbildung seid, angestellt oder als Freelancer arbeitet. Webdesign und -entwicklung sind Bereiche, die sich wahnsinnig oft verändern und rasend schnell entwickeln. Oft geht das schneller, als es ein schulischer Ausbildungsweg abbilden könnte, vor allem aber ist es eine Tätigkeit, in der das Lernen nie aufhört.

Dankenswerterweise ist es gleichzeitig ein Bereich, in dem Weiterbildung zumindest teilweise unabhängig von Zeit, Ort und Mitteln funktioniert. Lest Blogs, lest aktuelle Fachbücher, hört Podcasts und schaut Videos von Vorträgen – regelmäßig, wenn es die Zeit irgendwie zulässt.

Matthias Mees

Der Erfolg eines Projektes ist in großem Maß von der Kommunikation aller Beteiligten abhängig. Angefangen bei der ersten Kontaktaufnahme bis hin zum Release und der Schlussrechnung – der kommunikative Kontext und die Art des Austauschs zwischen Auftraggeber und Auftragnehmer sind so bedeutsam wie das Pflichtenheft und die Dokumentation der geleisteten Arbeit.

Gegenüber Kunden, die in E-Mails und bei Meetings äußerst allgemein, sehr viel und zu wenig sachbezogen kommunizieren, empfehle ich eine klare Linie zu ziehen. Dabei verweise ich freundlich auf die Sachfragen und stelle mögliche Lösungen kurz und auf das Wesentliche reduziert vor. Keine Romane erzählen, die Sprache des Kunden verstehen und technische Details ggf. in die Kundensprache »übersetzen«. E-Mails kurz und informativ verfassen.

Matthias Koch

Achtet von Anfang an darauf, nicht den Spaß an der Arbeit zu verlieren. Immer wieder passiert es, dass Websites nicht eurem professionellen Anspruch genügen. Sei es, weil ihr durch Zeit- oder Budget-Vorgaben beschränkt werdet. Ihr nicht webgerechte Vorgaben zum Design bekommt. Oder weil ihr schreckliche Texte oder Fotos verwenden müsst. Das kann einem den Spaß am Webworking verderben.

Von Vorteil ist dann eine eigene Spielwiese. Das kann ein eigenes, kleines Blog sein. Eine Sammlung von CSS3-Experimenten. Oder gar ein eigenes Tool, Modul oder Theme, das ihr pflegt. Kurz: Ein Projekt, bei dem ihr alleine bestimmt, was wie gemacht wird. Je nach Lust und Laune könnt ihr an Text, Fotos, Icons, Typografie, Accessibility, Usability, SEO, Design etc. feilen. Eine Art virtueller Schrebergarten, ein Gute-Laune-Projekt.

Nicolai Schwarz

Schreibt auf, wie lange ihr für welche Arbeitsschritte braucht. Und zwar nicht nur bei Kundenprojekten, sondern auch bei internen Projekten, Prototypen oder Ausprobier-Basteleien. Gewöhnt euch gleich von Anfang an daran, selbst wenn ihr noch in der Ausbildung steckt und kein Projekt-Controller die Stundenzettel einfordert. Gerade zu Beginn ist ein solches Zeitprotokoll zugegebenermaßen ein wenig nervig. Doch es bringt langfristig unheimlich viel. Denn nach einer Weile könnt ihr auf Basis dieser Notizen den zeitlichen Aufwand für unterschiedliche Aufgaben gut einschätzen. Ihr werdet erstaunt sein, wie weit die anfängliche Selbsteinschätzung (»Das mache ich schnell mal zwischendurch …«) häufig von der Realität abweicht.

Nicht nur in zeitkritischen Projekten erweisen sich solche realistischen Zeiteinschätzungen als hilfreich. Zum einen vermeidet ihr – zumindest in einem gewissen Maß –, euch freiwillig mehr Arbeit aufzubürden, als ihr schaffen könnt. Zum anderen müsst ihr auf die verhasste Projektleiter-Frage »Wie lange wird das dauern?« nicht mehr so häufig hilflos mit den Schultern zucken. Und wenn ihr selbstständig seid oder Einfluss auf die Angebotserstellung eurer Agentur habt: Packt dieses Wissen in modulare Angebotsbausteine oder zumindest in eine große Kalkulations-Excel-Tabelle. Meine Erfahrungen mit der Einführung solcher Angebotskalkulationen in mehreren Agenturen sind durchwegs positiv. Spart Zeit, schont Nerven und lässt am Projektende die Kasse lauter klingeln.

Michael van Laar

Lernt Englisch, schlagt nach und hinterfragt. Diese Tipps mögen etwas seltsam klingen, sind aber durchaus ernst gemeint und meiner Meinung grundlegend für ambitionierte Webdesigner. Mein ehemaliger Professor für die Vorlesung »Grundlagen der Gestaltung« (Studienfach Digitale Medien, erstes Semester) sprach in der ersten Veranstaltung ohne Ankündigung ausschließlich Englisch. Und das in der pfälzischen Provinz. Englisch ist die Sprache der Medien folgte kurz darauf als Erklärung und recht hatte er! Die Sprachen, die wir fürs Web beherrschen müssen, bestehen ausnahmslos aus englischem Sprachgut und ein tiefes Verständnis der zugrundliegenden Sprache ist unumgänglich, wenn man saubere Arbeit abliefern will. Ihr versteht eine Bezeichnung, eine Funktion, oder eine bestimmte Technik nicht? Forscht, schlagt nach und hinterfragt vor allem. Neue Techniken, die als »heißer Scheiß« präsentiert werden, haben oftmals Fallstricke, die man nicht auf den ersten Blick erkennt.

Moritz Gießmann

Wer für das Internet entwickelt, sollte aus selbigem den überwiegenden Teil seiner Informationen beziehen. Bücher sind ein schönes Nachschlagewerk und können oftmals auch hilfreich sein, gerade am Anfang. Die Entwicklung im Internet (Browser, Standards) geht allerdings so schnell, dass viele Bücher nach zwei Jahren oft nur noch einen Bruchteil der Informationen beinhalten, die sie beinhalten müssten, um als vollständige Referenz angesehen werden zu können. Blogs, Twitter und diverse Online-Referenzen sind daher meist die bessere Informationsquelle.

Generell gilt im Internet: Learning by Doing. Viele Entwickler, die als engagierte Quereinsteiger in diesem Bereich tätig sind, beherrschen ihr Handwerk oft besser, als andere Entwickler mit guter theoretischer Fach-Ausbildung, aber dafür wenig praktischer Erfahrung.

Manuel Bieh

Neugierde ist der Schlüssel zum Erfolg. Durch Neugierde hört man nicht auf, sich fortzubilden. Das Lesen von Blogs und hin und wieder einem Buch ist essentiell, um nicht ganz den Anschluss zu verlieren. Neugierde sollte uns auch dazu treiben, die Arbeit anderer zu ergründen. Wie arbeiten andere Entwickler? Was tun Designer und wie denken sie? Verständnis für den Job anderer und Abgleich der eigenen Arbeitsweise mit der anderer Kollegen ist ein wichtiger Lernschritt.

Und last but not least sollte Neugierde auch dazu führen, unsere eigene Arbeitsweise zu hinterfragen. Wir sollten in der Lage sein, einen Schritt zurückzutreten und unsere eigene Arbeit kritisch zu betrachten. So können wir feststellen, ob wir Veränderungen an uns bzw. an unserer Arbeit vornehmen sollten. In einem so dynamischen Berufsumfeld ist es mehr als unwahrscheinlich, dass man jahrelang auf die gleiche Art und Weise mit dem gleichen Informationsstand arbeitet. Alle, für die das zutrifft, sind von der technischen Entwicklung abgehängt und damit Teil des Problems.

Jens Grochtdreis

Der Webworker sollte darauf achten, nicht jedes Mal das Rad neu zu erfinden. Eine gut sortierte Bibliothek mit Vorlagen, Modulen und Snippets, die in den verschiedenen Projekten immer wieder zum Einsatz kommen, hilft Zeit zu sparen und einen eigenen Stil zu entwickeln. Frameworks und Boilerplates sollten modifiziert und den eigenen Bedürfnissen sowie dem persönlichen Workflow angepasst werden. Wiederkehrende Dinge, die jedoch schwer von der Hand gehen, einmal richtig erstellen, ablegen, wiederverwenden und nur noch ans aktuelle Projekt anpassen.

Henry Zeitler

Werft immer auch einen Blick über den Tellerrand und versucht, die handwerklichen Grundbegriffe eurer Kollegen in anderen Bereichen zu lernen. Denn selten hört die Arbeit in einem Projekt an der eigenen Schreibtischkante auf – in der Webentwicklung greifen so viele Aspekte und Disziplinen ineinander, dass es wichtig ist, auch die »Sprache«, des jeweils anderen zu verstehen. Es vermeidet nicht nur viele Probleme und Missverständnisse im Arbeitsalltag, sondern hilft auch ungemein dabei, bessere Projekte zu entwickeln – auf die dann zurecht alle Beteiligten stolz sein können.

Frederic Hemberger

An Dokumentation für Webtechniken mitarbeiten

WebPlatform.org ist eine relativ neue, offene Entwicklercommunity mit dem Ziel, eine umfassende Dokumentation für Webentwickler, unabhängig von Marken, Browsern oder Plattformen, aufzubauen. WebPlatform.org wird vom W3C zusammengerufen und durch die Unterstützung der Web Platform Stewards möglich gemacht, darunter sind alle Browserhersteller, Nokia und Adobe.

WebPlatform.org ist ein Wiki, und als solches lebt es von aktuellem und möglichst umfassendem Inhalt. Um die Dokumentation schnell gemeinsam auf- und auszubauen gibt es sogenannte Doc Sprints. Bei diesen Dokumentations-Hackathons gibt es eine Einweisung in die Mechanik des Wikis sowie Inspiration und Ansatzpunkte zum Losdokumentieren.

Hierzu stehen Euch versierte Experten von den Web Platform Stewards bzw. aus den Reihen der Community mit Rat und Tat zur Verfügung. Neben der Arbeit fürs Gemeinwohl soll der Spaß nicht zu kurz kommen. Und selbstverständlich ist auch für das leibliche Wohl gesorgt. Es gibt eine kleine Party, Giveaways und das Netzwerken kommt ebenfalls nicht zu kurz.

Nach den beiden ersten Veranstaltungen dieser Art bei Adobe in San Francisco und zuletzt bei Google in Mountain View findet am 8. und 9. Februar 2013 der erste europäische Web Platform Doc Sprint in Berlin statt. Die Location wird Mitte Januar nach den tatsächlichen Anmeldungen ausgewählt. Es sollfür möglichst ideale Verhältnisse gesorgt werden.

Wer nun also Lust bekommen hat, an der Dokumentation der Webtechniken aktiv mitzuwirken, der sollte sich bei Eventbrite anmelden – und bei Lanyrd seine Teilnahme bekanntgeben.

Image may be NSFW.
Clik here to view.

Webmontag Karlsruhe

Ein Vortragabend für WebschaffendeBeim Webmontag Karlsruhe treffen sich Entwickler, Designer, UX Experten, Gründer, Studenten und Internet-Interessierte, um sich auszutauschen, und neue Kontakte knüpfen zu können. Bei den Talks gibt es interessante Vorträge zu aktuellen Themen rund um’s Web. Die Webmontag-Orga (zu Erreichen über den Twitter Account) freut sich über jeden Gast und noch mehr über Leute die sich durch einen Vortrag aktiv einbringen wollen.13.05.20132013Webmontag WikiTwitterFacebook
Hoepfner Schalander
Haid-und-Neu-Straße 18
76131  Karlsruhe
Deutschland

W3C.DE/AT HTML5-Tag 2013

Technische Universität München

Tagestutorial des Deutsch Österreichischen Büros des World Wide Web Consortiums (W3C.DE/AT)

09.04.20132013HTML5-Tag 2013
Technische Universität München
Raum 00.08.038, Fakultät Mathematik/Informatik (FMI)
Walther-Meißner-Straße 3
85748  Garching
Deutschland

CSS Day

Eight world-class speakers discuss CSS modules14.06.20132013Website
Compagnietheater
Kloveniersburgwal 50
1012 CX  Amsterdam
Deutschland

Web Developer Conference (WDC) 2013

Die Web Developer Conference (WDC), die Konferenz für Web-Entwickler findet vom 24.-27. Juni 2013 im NCC Ost in Nürnberg statt und richtete sich an Entwickler von Web-Applikationen, Content- und Online-Manager, Agenturen und Webmaster.

24.06.2013 bis 27.06.20132013Website
Nürnberg Convention Center NCC Ost
Messezentrum
90471  Nürnberg
Deutschland

Notiz: Reflections on Web Design Trends in 2013 - Alles nicht neu, aber eine schöne Zusammenstellung.


mUXCamp

mobile User eXperience BarCampDas mUXCamp, das BarCamp zu mobile User eXperience findet am 27.4.2013 an der FH Worms statt.27.04.20132013mUXCamp
Fachhochschule Worms
Erenburgerstraße 19
67549  Worms
Deutschland

Notiz: On Responsive Layout and Grids – "So for those who often enquire about my responsive grid 'solution' — it’s about 10 lines of code."

Notiz: HTML's New Template Tag – standardizing client-side templating. Kommt mit Chrome 26.

Webmontag Marburg 5

Der Marburger Webmontag findet alle zwei Monate statt. Am 15. April ist es wieder soweit und diesmal in anderen Räumlichkeiten. Wer teilnehmen möchte und / oder eine Session machen möchte, trage sich einfach in das Webmontagswiki ein. Beginn, Ende und alles weitere findet Ihr ebenfalls auf der hier verlinkten Wikiseite. Hashtag für den Webmontag Marburg ist #webmmr. Sponsor des 5. Webmontag Marburg ist die tripuls media innovations gmbh.15.04.20132013Webmontag Marburg (Wiki))Webmontag Marburg (Twitter)
tripuls media innovations gmbh
Neue Kasseler Straße 62a
35039  Marburg
Deutschland

Notiz: Behind the scenes of Firefox's new branding

Viewing all 231 articles
Browse latest View live