Quantcast
Channel: Webkrauts - für mehr Qualität im Web
Viewing all 231 articles
Browse latest View live

Interactive Storytelling

$
0
0
Screenshot: Snow FallGeschichten erzählen mit modernen Webtechniken

Mit modernen Webtechniken lassen sich beeindruckende multimediale Präsentationen erstellen. Aus Text, Bildern, Daten, Audio- und Video-Elementen entstehen so spannende Geschichten und Welten, die Leser interaktiv entdecken können. Die grundlegenden Techniken eignen sich auch für kleinere Projekte.

Am Anfang bestand das Web aus wenig ansehnlichen Texten, die auf andere Texte verwiesen. Seit der ersten Stunde wurde versucht, Webseiten medial anzureichern und interaktiver zu gestalten. Nach fast zwanzig Jahren Web-Geschichte ist es endlich möglich, beeindruckende Webseiten ohne Plugins zu entwickeln. Heutzutage stehen dafür leistungsfähige Webstandards und Browser zur Verfügung.

Zwar gibt es schon länger künstlerische Arbeiten und technische Demos, die Text, Grafik, Video und Audio geschickt kombinieren. Doch anspruchsvolle Webpräsentationen, die eine zusammenhängende Geschichte erzählen, sind etwas Neues. Das interaktive Geschichtenerzählen – Interactive Storytelling – ist im letzten Jahr vor allem durch Feature-Artikel und Reportagen im Online-Journalismus bekannt geworden, aber auch durch Produktpräsentationen. Diese Geschichten wollen informieren, unterhalten, aufrütteln oder schlicht verkaufen. Dabei sprechen sie die Neugier, den Spieltrieb und den Sinn für Ästhetik an.

Beispiele

Fünf Beispiele sollen die konzeptionellen und technischen Aspekte von Interactive Storytelling demonstrieren:

Snow Fall – The Avalanche at Tunnel Creek, Ende 2012

»Snow Fall« ist das bekannteste Beispiel. Die aufwändige Reportage der New York Times erzählt die Geschichte von 16 Freeskiiern, die in ein Lawinenunglück im Nordwesten der USA verwickelt waren. Der Text ist verwoben mit Illustrationen, Interviews, Steckbriefen und Fotogalerien.

Firestorm – The story of the bushfire at Dunalley, Mai 2013

Ebenfalls mit einer Naturkatastrophe beschäftigt sich »Firestorm«, eine Reportage der britischen Zeitung »The Guardian« über eine tasmanische Familie, die nur knapp einen verherrenden Buschbrand überlebt. Die Präsentation besteht aus mehreren Kapiteln, die in Screens aufgeteilt sind. Darin werden Text, Interviews, Naturaufnahmen, Fotos und Sounds gemischt.

Greenpeace: Into the Artic, seit März 2013

Die Greenpeace-Kampagne gegen Ölförderung und Industriefischerei in der Arktis ist im Stil einer Wissensdatenbank aufgebaut. Im Zentrum steht eine Karte, auf der Pfade, Standorte und Ereignisse verzeichnet sind, die mit Statusmeldungen und Artikeln verknüpft sind. Eine Geschichte ist die Reise des Greenpeace-Schiffs »Arctic Sunrise«, welches Ölbohrinseln ansteuerte. Die Medien berichteten jüngst über die Aktion, nachdem die russische Küstenwache das Schiff enterte und die Aktivisten festnahm.

National Geographic: The Serengeti Lion, August 2013

Das für spektakuläre Naturfotografie bekannte Magazin »National Geographic« liefert eine interaktive Tierdokumentation mit bildschirmfüllenden Foto- und Videoaufnahmen von Löwen im Serengeti-Nationalpark. Die Präsentation besteht aus 24 Galerien, die in keiner festen Reihenfolge stehen. Die Aufnahmen sind mit Originalgeräuschen unterlegt und werden durch zuschaltbare Audio-Kommentare und Beschriftungen ergänzt.

The Dangers of Fracking, 2012

Die kompakte Webseite der Interaktions-Designerin Linda Dong visualisiert die Funktionsweise der umstrittenen Ölabbau-Technik und zeigt deren Risiken auf. Geschickt wird das vertikale Scrolling eingesetzt, um die Geschichte fortzuerzählen.

Was ist das Neue an Interactive Storytelling?

Verschiedene Autoren sind sich einige, dass Interactive Storytelling im Web nichts fundamental Neues darstellt. Vielmehr handelt es sich um eine gekonnte und stimmige Kombination bekannter Elemente. Mit HTML5-Video und -Audio, Visualisierungstechniken wie Canvas und SVG sowie CSS-Animationen ist eine nahtlose Integration der verschiedenen Medien möglich. Mit JavaScript werden die Elemente zu einer interaktiven Präsentation verschmolzen.

Die gezeigten Beispiele sind interdisziplinäre Arbeiten. Interactive Storytelling vereint Recherche, journalistisches Schreiben, Fotografie, Filmproduktion – klassische journalistische und publizistische Arbeiten – mit Design und Programmierung fürs Web. Damit das Resultat in verschiedener Hinsicht überzeugt, sind gleichsam interdisziplinäre Teams nötig.

Nach dem phänomenalen Erfolg von »Snow Fall« und ähnlichen Veröffentlichungen wurde heiß diskutiert, ob dies nun die ZukunftdesJournalismus sei. Die meisten Kommentare sind skeptisch: Wenige zeitaufwändige Multimedia-Features sind nicht in der Lage, genügend Werbeeinnahmen zu erzielen und Leser zu binden.

Es steht jedoch außer Frage, dass Interactive Storytelling das Web bereichern kann. Die gezeigten Präsentationen wirken auf verschiedenen Ebenen: Sie erzählen spannende Geschichten, machen Fakten zugänglichen, vermitteln Wissen, wecken Emotionen und appellieren an den Leser.

Typische Elemente

So zahlreichdie Beispiele auch sind, es sind häufige Gemeinsamkeiten festzustellen. Die meisten Geschichten nutzen ein raumgreifendes, minimalistisches Design ohne Schmuckelemente. Anstatt die Inhalte in ein klassisches Layout mit Header, Footer und Seitenleisten zu zwängen, nehmen sie den gesamten Bildschirm ein und sprechen für sich. Dahinter steht ein Design-Trend, der Zurückhaltung und Reduktion aufs Wesentliche beinhaltet.

Auch wenn Text nur noch ein erzählerisches Element unter vielen ist ist, so gewinnt die Typographie an gestalterischer Bedeutung. Die verbleibende Schrift ist von Wichtigkeit und Aussagekraft, daher wird mit großen, fast bildschirmfüllenden Überschriften und Teaser-Texten sowie vergleichsweise großem Fließtext gearbeitet.

Das vertikale Scrolling ist eine bekannte Möglichkeit, um weitere Inhalte einer Webseite zu erreichen. Daher nutzen viele Präsentationen die Scrollfunktion, um zwischen den Kapiteln und Abschnitten zu navigieren. Manche Präsentationen wie das Fracking-Beispiel koppeln die Scrollbewegung gar an das Objekt der Erzählung, das vom Nutzer fortbewegt wird und damit die Geschichte vorantreibt.

Als visuelle Medien finden sich hochauflösende Fotos, Infografiken, Datenvisualisierung und Karten. Videos werden für informative Animationen, für Interviews oder zur Erzeugung von Stimmung genutzt. Tonaufnahmen sind zumeist O-Töne aus Interviews oder Hintergrundgeräusche zur Erzeugung von Stimmung.

Die Präsentationen entfalten ihr Potenzial dann, wenn sie Text, Bild und Ton miteinander sowie mit Zeit, Ort und Person verknüpfen. Beim Lesen des Textes wird beispielsweise das Beschriebene in einem Schaubild illustriert, ein Steckbrief des Protagonisten verlinkt oder der Ort des Ereignisses auf einer Karte fokussiert.

Was heißt Interaktivität?

Wenn hier von interaktiven Geschichten die Rede ist, so stellt sich die Frage, was das Erzählen interaktiv macht. Wie viel Entscheidungsfreiheit hat der Leser wirklich?

Zumeist bildet das Gerüst ein fortlaufender Text, der eine Geschichte mit klassischem Spannungsbogen erzählt. Dieser Text will linear von vorne bis hinten gelesen werden, hat allerdings Marginalien mit Zusatzinfos und eingebetteten Medien, die der Leser auch überspringen kann. Lorenz Matzat spricht deshalb von »Pseudo-Interaktivität«: »Man könnte bei vielen neueren ›interaktiven‹ Formaten schlicht von Slideshow 2.0 sprechen: Letztlich besteht die Interaktionen mit ihnen daraus, Abzweigungen zu nehmen, um die Erzählrichtung zu ändern oder in ein Thema tiefer einzusteigen.«

Doch es gibt auch Gegenbeispiele. Die Löwen-Aufnahmen von National Geographic haben keine lineare Struktur. Der Leser kann frei durch einen großen Fundus an verschiedenen Medien navigieren. Auch die Greenpeace-Publikation ist eher eine Wissendatenbank, die Ereignisse, Orte und Hintergrundinformationen verknüpft und zum explorativen Lesen einlädt.

Das erinnert an die ursprüngliche Idee des Hypertextes: »Jeder Leser komponiert den Gegenstand seiner Lektüre durch aktive Selektion der vorgegebenen Links. (…) Lesen ist nicht länger ein passiver Vorgang der Rezeption, sondern wird zu einem Prozeß der kreativen Interaktion zwischen Leser, Autor und Text.« (Hypertextualität im World Wide Web, Mike Sandbothe, 1996).

Storytelling: Klein anfangen

Die vorgestellten Beispiele sind sehr umfangreich und ausgereift, sollen aber nicht vom eigenen Experimentieren abhalten. Jedem Webentwickler ist es möglich, Geschichten zu erzählen. Ihr könnt einfach klein anfangen:

Zunächst einmal sucht euch Mitstreiter, deren Fähigkeiten sich ergänzen. Stellt ein Team zusammen, das verschiedene Bereiche wie Entwicklung, Gestaltung, Schreiben und Medienproduktion abdeckt.

Am Anfang der inhaltlichen Arbeit steht die Grundidee bzw. ein Thema. Der Hauptstrang und eventuelle Nebenstränge der Erzählung werden identifiziert. Welche Erzählperspektive(n) werden eingenommen? Welche Orte, Personen, Ereignisse und Daten kommen vor? Gibt es eine lineare Kapitelstruktur oder eine nichtlineare Navigation? Gibt es eine klare Absicht, gar einen Appell an den Leser? Wodurch wird eine Stimmung erzeugt, Lebendigkeit erreicht? Wie werden die Leser eingebunden?

Auf die Konzeptionsphase folgt das Sammeln von Texten, Bildern, Videos, Tönen, Gegenständen usw. Dabei können auch vorgefertigte freie Fotos, GIF-Animationen, YouTube-Videos, Vine- und Instagram-Bilder, Karten- und Kommentar-Widgets eingebunden werden.

Um die Grundstruktur der Erzählung zu skizzieren, eignet sich das aus der Filmproduktion bekannte Storyboard, auf dem die Materialien arrangiert und die Interaktionen angedeutet werden. Aus dem Webdesign sind Wireframes als Entwurfswerkzeug bekannt.

Technische Umsetzung

Für eine gelungenes Interactive Storytelling müssen verschiedene Techniken zusammengeführt werden. Die detaillierte Umsetzung des Beispiels »Snow Fall« erörtern der Artikel Snow Fall Breakdown und das Interview How we made Snow Fall.

Am Anfang steht ein HTML-Dokument, das strukturierten Text enthält, andere Medien einbettet sowie die Präsentation in Gang setzt. Neben der HTML5-Textstrukturierung können die video- und audio-Elemente zur direkten Einbettung von Video- und Audiodaten verwendet werden. Falls ein komplexer Player zur Steuerung nötig ist oder ein Flash-Fallback gewünscht ist, so hilft die Übersicht HTML5 Video/Audio Player bei der Auswahl.

Mittels CSS wird die Typographie und ein anpassungsfähiges Layout umgesetzt. Dafür können klassische Float-Layouts mit Media-Queries, aber auch das Flexbox zum Einsatz kommen. Für flüssige Übergänge und Bewegung sorgen einfache CSS3-Transitions sowie leistungsfähige Keyframe-Animationen, die von neueren Browsern hardwarebeschleunigt dargestellt werden. Bei der Erstellung von Keyframe-Animationen helfen die (kostenpflichtigen) Programme Adobe Edge Animator und Sencha Animator.

In den meisten Fällen ist JavaScript der Kleber, der alle Teile zusammenfügt und interaktiv werden lässt. Mit JavaScript wird zwischen den Kapiteln navigiert, Animationen werden angestoßen, Medien werden geladen und gesteuert. Die DOM-Bibliothek jQuery stellt eine gute Ausgangsbasis dar. Es ist ratsam, die Storyboard-Struktur in JavaScript-Code umsetzen: Der Code wird in Screens und Übergängen (Transitions) zwischen den Screens aufgeteilt. Darüber steht eine Logik, die die Screens verwaltet sowie den Initialisierungscode der Transitions und der Screens aufruft.

Für diese Zwecke kommen verschiedene jQuery-Plugins in Frage. Wenn die Präsentation auf das Scrolling reagieren soll, so eignen sich die Events scroll sowie mousewheel. jquery.inview feuert einen Event, wenn sich ein Element im Viewport befindet. Damit können automatisch Medien geladen und gegebenenfalls abgespielt werden.

Empfehlungen

Was macht das interaktive Geschichtenerzählen im Web erfolgreich?

Im Gegensatz zu vielen konventionellen Webseiten sollten Geschichten dezent statt aufdringlich sein, indem sie sich auf ihre Stärken fokussieren. Sie sollten die Neugier der Leser wecken und Entscheidungen ermöglichen. Dabei hilft eine klare Grundstruktur, z.B. ein fortlaufender Text. Gleichzeitig sollte es Seitenpfade geben, auf denen es viel zu entdecken gibt.

Zurückhaltung ist auch bei visuellen Effekten und Animationen angesagt. Insbesondere Scrolling- und Parallaxen-Effekte sind im heutigen Web allgegenwärtig, sodass Leser ihnen schon überdrüssig sind. Effekte sollten mit Bedacht als bedeutungsvolles Erzählmittel eingesetzt werden. Scrolling zum Beispiel ist eine Möglichkeit, um von einem Element der Geschichte zum nächsten zu springen. Es sollte nicht verwendet werden, um sämtliche Seitenelemente einfliegen zu lassen. Bewegung zieht Aufmerksamkeit auf sich, kann Kontraste erzeugen und Übergänge vermitteln.

Das Schreiben von Geschichten im Web ist wie gesagt eine Teamarbeit, die ein gemeinsames Verständnis erfordert. Alle Beteiligten können ihre Perspektive auf die Geschichte einfließen lassen.

Mathias Schäfer

Mehr Sicherheit im Frontend durch HTTP Header

$
0
0
VorhängeschlossWebsites abdichten

Die Sicherheit von Webseiten wird von vielen Frontend-Entwicklern gerne als »Backend-Thema« abgeschoben – zu Unrecht, wenn man bedenkt, dass die meisten Angriffe das Einschleusen von Schadcode über das Frontend voraussetzen. Auch wenn es immer Mittel und Wege geben wird, die Sicherheit von Webseiten zu kompromittieren, kann potentiellen Angreifern mit einfachen Handgriffen ihre Arbeit deutlich erschwert werden.

Frontend-Entwickler können ihren Teil dazu beitragen, Web-Projekte sicherer zu machen und vor weit verbreiteten Attacken zu schützen. Nicht immer ist dazu ein Rückgriff auf Backend-Entwickler nötig. In den folgenden beiden Beispielen lässt sich alleine durch einfaches Setzen eines Eintrages in der HTTP-Antwort der Website die Sicherheit deutlich erhöhen. Das gestaltet sich so einfach, dass es eigentlich keine Ausrede gibt, diese nützlichen Features zu ignorieren.

Fall 1 – Ich klicke was, das du nicht siehst: Clickjacking

Clickjacking ist lediglich ein Beispiel für framebasierte Angriffe. Diese Angriffsmethode zielt darauf ab, den User mit einer vermeintlich harmlosen Website interagieren zu lassen, auf der dessen Mausklicks dann aber in Wirklichkeit andere (potentiell schädliche) Aktionen im Hintergrund ausführen. Für einen solchen Angriff wird die Zielseite in einem unsichtbaren iframe geladen.

Der Twitter-Button in iframe 1 dient zur Demo. Er ist anklickbar, hat aber keine echte Twitter-Integration.

iframe 1: Angriffsziel – Den »Folgen«-Button will eigentlich niemand klicken … oder?

iframe 2: Angreifende Webseite

  1. iframe {
  2. width: 850px;
  3. height: 370px;
  4. position: absolute;
  5. top: -198px;
  6. left: -424px;
  7.  
  8. /* Nur zur Demonstration auf 50% gesetzt. */
  9. filter: alpha(opacity=50);
  10. opacity: 0.5;
  11. }

Um die Art des Angriffes besser sichtbar zu machen, ist in dem Beispiel die Transparenz noch auf 50% gesetzt (opacity). Bei einem echten Clickjacking-Angriff wird sie aber auf 0% gesetzt, damit ist optisch nicht mehr zu erkennen, was in Wirklichkeit bei einem Klick passiert:

iframe 3: Angreifende Webseite mit vollständig transparentem iframe

Das mag in diesem Fall noch relativ harmlos wirken (Twitter, Facebook & Co. unterbinden Clickjacking schon seit einer Weile), andere Szenarien können durchaus unangenehmer sein:

  • Ändern von Privatsphäre-Einstellungen
  • Löschen von Accounts oder Daten
  • Auslösen von 1-Klick-Bestellungen, o.ä.

In der Vergangenheit gab es auf diese Weise sogar Attacken auf die Einstellungsseite des Flash-Plugins im Browser, um dort unbemerkt die Sicherheitseinstellungen zu ändern.

Wie lässt sich ein solcher Angriff verhindern?

Im Prinzip funktioniert die Abhilfe genau so, wie das »Frame-Busting« vergangener Zeiten:

  1. if(top.location !== self.locaton){
  2. parent.location = self.location;
  3. }

Es wird also verhindert, dass die eigene Webseite in einem Frame geladen werden kann. Da JavaScript als Sicherheitsmechanismus aber ungeeignet ist, da es leicht umgangen werden kann, verlässt man sich in diesem Fall auf den HTTP Header »X-Frame-Options«. Damit teilt der Server dem Browser mit, ob und von welcher Stelle aus eine Seite in einem iframe eingebettet werden darf.

Dazu gibt es drei unterschiedliche Einstellungen:

X-Frame-Options: SAMEORIGIN
Hier greift die Same-Origin-Policy des Browsers und erlaubt die Einbettung nur dann, wenn das Protokoll der Website (http:// oder https://) und die (Sub)Domain der einbettenden und der eingebetteten Seite identisch ist.
X-Frame-Options: DENY
Unterbindet das Einbetten der Seite in iframes vollständig
X-Frame-Options: ALLOW-FROM origin
Gestattet das Einbetten ausschließlich von einem bestimmten Ziel aus (z.B. http://www.example.com)

Man sollte sich vor dem Setzen dieser Eigenschaft allerdings Gedanken machen, ob es nicht auch Fälle gibt, in denen das Laden der eigenen Website in einem iframe nicht sogar gewünscht sein kann. Das häufigste Beispiel dürfte hierfür etwa die Detailseite der Google Bildersuche sein. Beispiele, wie der Header im eigenen Webserver gesetzt werden kann, finden sich am Ende des Artikels.

Browser, die X-Frame-Options unterstützen

  • Chrome 4+
  • Firefox 3.69+
  • Safari 4+
  • Internet Explorer 8+
  • Opera 10.50+

Fall 2 – (Un)geladene Gäste: Scripte und Ressourcen von anderen Websites

Mittlerweile laden Websites viele Dinge aus anderen Quellen: Webfonts, JavaScript-Bibliotheken von CDN-Servern, Werbung und Zählpixel, Sharing-Buttons sozialer Netzwerke und vieles mehr. Doch wie können wir sicher sein, dass über diese Kanäle immer das kommt, was wir haben wollen? Was unterscheidet beim Laden eines Scriptes im Browser google-analytics.com von evil.com?

Gar nichts. Und das kann mitunter ein Problem werden – im besten Falle gibt es nur Fehlermeldungen in der Entwickler-Konsole des Browsers, etwas ärgerlicher wird es, wenn dadurch unsere eigene Website nicht mehr korrekt funktioniert. Zu einem echten Problem wird es allerdings, wenn über eine dieser Quellen Schadcode ausgeführt wird, die etwa die Seite betrügerisch manipuliert, den Browser zum Absturz bringt, Cookies oder Session-Daten entführt oder anderweitig den User gefährdet. Man spricht dabei von sogenannten Cross-Site-Scripting-Attacken, oder auch kurz »XSS«. Dabei muss es noch nicht immer JavaScript sein: Auch eventuelle Browser-Fehler bei der Verarbeitung manipulierter Medien (z.B. Bilder, Webfonts, Videos) oder veraltete Plug-ins (Java, Flash-Player) können zu Sicherheitslücken führen.

Um diese Probleme künftig einzudämmen, wurde der HTTP-Header Content-Security-Policy (CSP) eingeführt. Anstatt allem blind zu vertrauen, was von externen Quellen in die Seite geladen wird, können Webworker jetzt explizit eine Whitelist der erlaubten Ressourcen definieren:

  1. Content-Security-Policy: "script-src 'self' http://code.jquery.com"

script-src listet die erlaubten Quellen für JavaScript-Dateien auf (getrennt mit Leerzeichen), in diesem Beispiel die aufrufende Seite selbst ('self', ohne Subdomains) und der jQuery-CDN-Server ('code.jquery.com'). Wird nun versucht, ein Script von einer anderen Quelle aus zu laden, erscheint in der Entwicklerkonsole des Browsers eine entsprechende Fehlermeldung.

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <scriptsrc="http://code.jquery.com/jquery.js"></script>
  5. <scriptsrc="http://evil.com/evil.js"></script>
  6. </head>
  7. <body>
  8. </body>
  9. </html>
Fehlermeldung bei aktiver CSP in der Konsole der Developer Tools von Google Chrome: "Refused to load the script 'http://evil.com/evil.js' because it violates the following Content Security Policy directive: script-src 'self' http://code.jquery.com".
Verletzungen der Content Security Policy in den Chrome Developer Tools

Sollen Inline-Scripte in der HTML-Seite erlaubt werden, muss zusätzlich noch 'unsafe-inline' angegeben werden.

  1. Content-Security-Policy: "script-src 'self''unsafe-inline' http://code.jquery.com"

Aber Vorsicht: Bei sogenannten »Stored XSS-Attacken« gelingt es Angreifern, Script-Tags etwa in der Datenbank der Website (CMS, Kommentarfunktion, o.ä.) dauerhaft zu speichern, so dass sie bei jedem Seitenaufruf geladen und ausgeführt werden. Inline-Scripten sollte grundsätzlich nur vertraut werden, wenn zusätzlich im Backend für einen XSS-Schutz gesorgt wird.

Darüber hinaus gibt es neben script-src noch weitere CSP-Regeln, mit denen Inhalte zusätzlich eingeschränkt werden können:

  • connect-src: Schränkt ein, zu welchen Servern sich die Seite selbst verbinden kann, etwa per Ajax oder WebSockets.
  • font-src: Web-Fonts (etwa TypeKit, Google Webfonts)
  • frame-src: Quellen, die per (i)frame in der Seite eingebettet werden dürfen (z.B. YouTube, Vimeo)
  • img-src: externe Quellen für Bilder …
  • media-src: … Audio/Video …
  • object-src: … sowie Flash und andere Plug-Ins.
  • style-src: Gegenstück zu srcipt-src für Stylesheets.

Wird eine CSP-Regel nicht im Header angegeben, werden Ressourcen von allen Quellen zugelassen. Einzelne Regeln werden mit einem Semikolon von einander getrennt:

  1. Content-Security-Policy: "script-src 'self' http://example.com; style-src 'self' http://fonts.googleapis.com/; font-src http://themes.googleusercontent.com/"

Bei einem komplexen Webangebot mit vielen externen Ressourcen (z.B. Werbung), empfiehlt es sich, sich zunächst erst mal einen Überblick zu verschaffen, welche Daten von welchen Servern geladen werden. Dazu kann der CSP-Header im »Report-Only-Modus« verwendet werden, es werden also zunächst keine Inhalte vom Browser blockiert, sondern alle externen Inhalte mitgeloggt. Mathias Bynens hat dazu ein kleines Tool in PHP geschrieben.

  1. Content-Security-Policy-Report-Only: "default-src 'self'; ...; report-uri /csp-reporter.php"

Wer schon einen genaueren Überblick hat, kann die erforderlichen Einstellungen direkt mit dieser Chrome-Extension testweise vornehmen. Da sie direkt auf der Website des Entwicklers zu Verfügung gestellt wird und nicht aus dem Google Web Store kommt, muss die Datei für die Installation heruntergeladen und per Drag & Drop in die Erweiterungsliste von Chrome gezogen werden.

Screenshot der geöffneten CSP-Tester Extension in Google Chrome
CSP-Tester Extension für Google Chrome

Sind alle erlaubten Quellen zusammengestellt, kann man die Konfiguration nun auf dem eigenen Webserver übernehmen. Gerade wer Werbung auf seiner Website einblendet, sollte nochmal alle Einstellungen genau prüfen und auch gegebenenfalls mit dem Anbieter der Werbeplattform Rücksprache halten, ob auch alle möglichen Werbequellen in die Liste der erlaubten Domains aufgenommen wurden. Gegebenenfalls müssen noch Browser-Extensions berücksichtigt werden, die Scripte von anderen Quellen in eine Website einfügen.

Ist alles nach Wunsch fertig konfiguriert, wurde in modernen Browsern die Angriffsfläche für XSS-Attacken auf die eigene Website mit relativ wenig Aufwand erheblich reduziert.

Browser, die Content-Security-Policy unterstützen:

  • Chrome 25
  • Firefox 4+ (Versionen kleiner 23 als »X-Content-Security-Policy«)
  • Safari 6.1+
  • Internet Explorer 10 (eingeschränkt)

Wie setze ich die vorgestellten HTTP Header in meinem Webserver?

Für den meistverwendeten Webserver Apache genügt es, eine .htaccess-Datei Im Stammverzeichnis abzulegen:

  1. <IfModule mod_headers.c>
  2. Header always set X-Frame-Options SAMEORIGIN
  3. </IfModule>

In der web.config von Microsofts IIS werden die Einträge im Abschnitt <customHeaders> hinzugefügt:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <configuration>
  3. <system.webServer>
  4. <httpProtocol>
  5. <customHeaders>
  6. <add name="X-Frame-Options"value="SAMEORIGIN" />
  7. </customHeaders>
  8. </httpProtocol>
  9. </system.webServer>
  10. </configuration>

Zu guter Letzt können die Header in nginx entweder im http, server oder location-Abschnitt der Konfiguration hinzugefügt werden:

  1. add_header X-Frame-Options SAMEORIGIN;

Fazit

Auch wenn es absolute Sicherheit im Netz nicht gibt: Da heute immer mehr alltägliche Aufgaben online erledigt werden, müssen Webworker stets im Blick behalten, dass sich die Nutzer nicht nur wohl, sondern auch sicher fühlen. Das ist die Verantwortung eines jeden Entwicklers.

Weitere Ressourcen

X-Frame-Options
Content Security Policy
Sicherheit im Allgemeinen
Frederic Hemberger

Einfaches Dropdown oder elegantes Styling

$
0
0
Die responsive Navigation gehört heute zwingend in die Planung eines WebauftrittsNavigation im Responsive Design &ndash; Teil I

Eine moderne Website berücksichtigt mobile Endgeräte. In vielen Fällen setzen Webworker dafür auf CSS3-Media-Queries, bekannt unter dem Begriff »Responsive Design«. Auch die Navigation wäre einfach mit CSS zu gestalten, gäbe es da nicht das Problem mit der Hover-Funktion auf Touchscreen-Geräten. Wer für die mobile Navigation einfach nur die geschachtelte Liste des Menüs sichtbar macht, sorgt für Benutzerfreundlichkeit. Ein optischer Leckerbissen ist das aber nicht. Glücklicherweise gibt es Alternativen.

Inzwischen setzen eine Menge Webangebote auf eine der unzähligen Varianten des Hover-Menüs à la Suckerfish. Doch diese sind auf Touch-Geräten nicht nutzbar. Also muss eine Lösung her, die auf SmartPhones und Tablets eine gute Figur macht.

Doppelte Menüführung

Die einfachste, aber nicht sehr elegante Methode ist die Verdoppelung des Menübaums. Für die Nutzung mit der Maus gibt es die bekannte geschachtelte Liste, die mit CSS als Klappmenü standardmäßig sichtbar wird. Für Touch-Bildschirme kommt ein Select-Menü zum Einsatz, das zunächst mit display:none ausgeblendet wird. Die CSS3-Media-Queries bestimmen dann, wann welches Menü angezeigt wird.

Vorteile:

  • Das normale Klappmenü kann wie gewohnt erstellt werden.
  • Select-Menüs funktionieren auf nahezu jedem Touch-Device mit »Bordmitteln«.
  • Es wird kein JavaScript benötigt.

Nachteile:

  • Select-Menüs lassen sich kaum mit CSS beeinflussen.
  • Jeder Browser stellt sie in seiner Optik dar.
  • Das Menü existiert doppelt in HTML.

Dropdown per JavaScript

Wenn CSS allein nicht rein, kommt JavaScript ins Spiel. In der bevorzugten, unaufdringlichen Form (»unobtrusive« genannt) ist JavaScript sehr effektiv und hinterlässt keine Spuren, wenn diese Funktion im Browser abgeschaltet ist. Möglich wäre also ein Select-Menü, das per JavaScript erzeugt wird. Eine Anleitung dazu bietet CSS-Tricks.

Vorteil:

  • Ohne JavaScript gibt es nur ein Menü.

Nachteil:

  • Bei eingeschaltetem JavaScript bleibt auch hier das Doppelpack im Quellcode sichtbar.

Elegante Variante

Wie wäre es, wenn die vorhandene Navigation für kleine Bildschirme quasi in eine handliche Schachtel gepackt würde? Im Klartext: Die normale, geschachtelte Liste bekommt einen Event-Button übergestülpt, der per JavaScript gesetzt wird. jQuery bietet dazu bereits die nötigen Funktionen und ist in den gängigen Content-Management-Systemen meist bereits vorhanden. Es reicht ein kleines Script, das die Toggle-Funktionen aktiviert und dem Button ein Click-Event hinzufügt.

Button zugeklappt
Button aufgeklappt

Auf ausreichend großen Bildschirmen kommt das normale Klappmenü nach Suckerfish-Vorbild zum Einsatz. Der Toggle-Button ist per display: none unsichtbar gemacht. Ist die in den CSS-Media-Queries festgelegte Mindestgröße unterschritten, wird der Button mit display: block sichtbar gemacht und das Menü zunächst ausgeblendet. Die nötigen CSS-Angaben übernimmt nun das JavaScript. Die Klick-Funktion toggelt das Menü und schaltet zwischen sichtbar oder unsichtbar hin und her. Fügt man der Funktion noch "slide-up" und "slide-down" aus dem jQuery-Vorrat hinzu, präsentiert sie den bekannten Slide-Effekt.

  1. showMenu = function(event){
  2. if(menu.is(":visible"))
  3. menu.slideUp({complete:function(){$(this).css('display','')}});
  4. else
  5. menu.slideDown();
  6. };

Die Anleitung mit Codebeispiel findet ihr bei danny-t.co.uk.

Vorteile:

  • Das Menü existiert nur einmal.
  • Es kann über die CSS-Media-Queries für kleinere Screens im Styling angepasst werden.
  • Platzsparend. Erst wenn das Menü gebraucht wird, ist es sichtbar.

Nachteil:

  • Kein Menü ohne JavaScript.

Fallback

Im Stylesheet steht das Menü jetzt auf display: none. Ohne die Hilfe von JavaScript ist die Seite nicht mehr navigierbar. Hier kann die Skript-Bibliothek Modernizr helfen. Sie überprüft alle unterstützten Features des genutzten Browser. So lässt sich u.a. feststellen, ob der Nutzer JavaScript eingeschaltet hat oder nicht. Modernizr setzt dann die Klasse "js" in das HTML-Tag. Darauf kann CSS problemlos zugreifen und die Angaben, die das Menü ein- oder ausblenden, auf die Klasse "js" beschränken. Der Link zur Skript-Bibliothek muss dazu im head-Bereich der Seite stehen. Wer JavaScript abschaltet, erhält dennoch ein intaktes Menü: Dieses ist dauerhaft eingeblendet und erfüllt seinen Zweck. Diese Methode kommt übrigens auch in obigem Beispiel zum Einsatz.

mobiles Menü dauerhaft ausgeklappt

Mehr Design fürs Menü

Wer sich nicht mit der einfachen Listenstruktur begnügen will, findet bei Filament Group eine Schritt-für-Schritt-Anleitung für ein mit Media-Queries und CSS gestyltes Menü. Auf den ersten Blick erscheint die Responsive-Navigation wie ein Dropdown. Hier ist der Toggle-Button so eingebunden, dass er dem Dropdown-Button in einem Select-Menü ähnelt.

Filament zugeklappt
Filament aufgeklappt

Die unterschiedlichen Bildschirmbreiten erhalten jeweils eine eigene Ansicht des Menüs. Einen Fallback gibt es auch hier. Der Toggle-Button ist auf dieselbe Weise eingebunden wie bereits oben beschrieben. Ohne JavaScript stehen die Menüzeilen über dem Inhalt.

Fazit

Mit wenigen Zeilen JavaScript lässt sich eine brauchbare Lösung für ein mobiles Menü erstellen. Ein paar Punkte sollten dabei aber unbedingt beachtet werden:

  • Immer eine Fallback-Lösung anbieten. Auch ohne JavaScript sollte das Menü mobil nutzbar sein.
  • Kein Inline-JS benutzen, sondern nur die im HTML verwendeten Klassen und IDs.
  • Mit JavaScript die innere Struktur des HTML-Markups, das Document Object Model (DOM) ansprechen.
  • Ein Link sollte ein Link bleiben. Außer dem Button mit der Klick-Funktion, sollten alle Links die normale a href-Struktur behalten, um immer die dazugehörige Seite aufrufen zu können. Auch unter SEO-Gesichtspunkten eine wichtige Prämisse.
  • Die Menüpunkte sollten zudem ausreichend groß sein, damit sie bequem auswählbar sind – und zwar einzeln.

Die ultimative Lösung ist wohl noch nicht geboren. Im Netz finden sich viele Varianten, die alle ihre Vor- und Nachteile haben.

Weitere Anregungen für die praktische Umsetzung:

Das Pattern Lab von Brad Frost zum Thema »Responsive Navigation«

Renate Hermanns

Komplexe Mobil-Navigation mit und ohne Javascript

$
0
0
Die mobile Ansicht bei Entertainment Weekly zeigt komplexe MenüstrukturenNavigation im responsive Design – Teil II

Bei Websites mit vielen Inhalten werden auch die Navigationen umfangreicher. Ein großes Menü, das auf dem Desktop optisch anspruchsvoll ausklappt, wirkt auf einem SmartPhone aber überladen und störend. Für solch komplexen Menüs braucht es also andere Lösungen im mobilen Bereich.

Menüstruktur

Ein übliches Hauptmenü, das auf dem Desktop übersichtlich aufklappt, lässt sich mit ein paar Zeilen JavaScript einfach in ein mobiles Menü verwandeln (siehe Teil 1: Einfaches Dropdown oder elegantes Styling). Bei größeren Auftritten mit mehr als 20 Unterseiten, wird solch ein einfach aufgeklapptes Listenmenü sehr lang. Sich durch ein solches Menü scrollen zu müssen, fördert nicht gerade die Übersicht. Spätestens jetzt muss die Menüstruktur für die mobile Verwendung überdacht werden.

Bereichsmenü
Das Menü wird schon kürzer, wenn Unterseiten nur für den aktiven Menüpunkt angezeigt werden. Denkbar ist auch, Haupt- und Unterpunkte nebeneinander anzuordnen, nach dem Vorbild des vertikalen Klappmenüs.
Mehrteiliges Menü
Das Untermenü lässt sich in mehrere Bereiche aufteilen. Jeder bekommt einen eigenen div-Container und eigenes Styling.

Bereichsmenü anzeigen

Ohne JavaScript zeigt ein Bereichsmenü die Unterseiten des aktiven Menüpunkts an. Dabei ist es egal, ob die Desktop-Version nur Hover-Menüs hat. Das statische Bereichsmenü lässt sich in den Media-Queries auch so definieren, dass es nur für die Smartphone-Breite gilt. Alle anderen Screenbreiten zeigen dann die Navigation mit Hover-Effekt. JavaScript ist dabei nur für einen Toggle-Button nötig, der das gesamte Menü ein- oder ausblendet (siehe Teil 1).

Alternativ kann das Menü nach dem Vorbild des horizontalen Klappmenüs angelegt werden: Das Untermenü positioniert sich jeweils rechts neben dem aktiven Hauptmenüpunkt. Längere Bezeichnungen in der Navigation sind dafür allerdings ungeeignet.

Das Menü wird kürzer, wenn nur das Untermenü im aktiven Navigationspunkt angezeigt wird.
Das Menü wird kürzer, wenn nur das
Untermenü im aktiven
Navigationspunkt angezeigt wird.
Das Menü wird noch kürzer, wenn Haupt- und Untermenü nebeneinander platziert sind.
Das Menü wird noch kürzer, wenn Haupt-
und Untermenü nebeneinander
platziert sind.

Mehrteiliges Menü

Vielleicht ist ja auch eine ganz andere Herangehensweise hilfreich, um komplexe Strukturen in den Griff zu bekommen und die Steuerzentrale »Menü« aus dem üblichen Kontext header + nav herauszuheben: Brad Frost spricht beispielsweise von »atomic Design«. Aus dieser Perspektive wäre das Menü ein »Organismus«, bestehend aus den Atomen li, dem Molekül der ungeordneten Liste ul und ggf. weiteren HTML-Elementen wie div und img.

Ein Beispiel für eine mobile Seite nach dieser Vorgehensweise beschreibt der Responsive Design Newsletter: Vorgestellt wird die mobile Seite von Entertainment Weekly. Das Menü ist sehr ansprechend und gut strukturiert. Es ist mit knapp einer Bildschirmhöhe auf dem Smartphone auch nicht zu lang und ermöglicht den Zugriff auf die Unterseiten auf einen Blick. Die sehr komplexen Inhalte strapazieren beim Laden auf dem Smartphone allerdings schon arg die Geduld des Nutzers.

Mobiles Menü auf dem Smart-Phone bei Entertainment Weekly
Mobiles Menü auf dem Smart-Phone
Auf dem Tablet erhält das mobile Menü zusätzlich Vorschaubilder.
Auf dem Tablet erhält das mobile Menü zusätzlich Vorschaubilder.

Ein Blick in den Quellcode zeigt: Die vier Menüelemente sind in der Hauptsache geschachtelte Listen, die teilweise in ein zusätzliches Div-Element gepackt wurden. Der Button oben rechts schaltet das Menü zwischen sichtbar und unsichtbar hin und her. Dieser »Toggle-Effekt« lässt sich wiederum mit einem kleinen JavaScript erzeugen. Die Navigation erhält je nach Status die Klasse "active" oder bleibt ohne. CSS schreibt für "active" dann opacity: 1– ansonsten 0. Im Smartphone schiebt das Menü den Inhalt nach unten und die kleinen Vorschaubilder fallen weg. Größere Bildschirme zeigen die Bilder, und mit position: absolute liegt die Navigation über dem Inhalt.

Tablets ticken anders

Mobiles Menü angelegt, alles in Butter. Wirklich? Was sagen denn die Tablets und Touch-Screens dazu? Ein einzelner Knopf in Bildschirmbreite sieht selten schick aus und ist zudem gar nicht nötig. Die aktuellen Tablets mit einer Auflösung von 1280 Pixel Breite und mehr können durchaus die Menüleiste aus der Desktop-Ansicht nutzen.

Fatal wirkt sich hier das Menü mit Hover-Effekt aus: Das Untermenü lässt sich zwar aufklappen, die darin enthaltenen Menüpunkte sind allerdings nur kurz zu sehen und lassen sich nicht anklicken. Denn der geklickte Link im Hauptmenü ruft ohne Verzögerung einfach nur die zugehörige Seite auf. Die Unterpunkte sind nur für die kurze Zeit sichtbar, die die neue Seite zum Laden braucht. Das Menü klappt anschließend wieder zu, und die Prozedur des Aufklappens beginnt von vorne. Der User hat keine Chance, an die Links im Untermenü und deren Seiten heranzukommen. Dieser Missstand schreit nach einer Lösung: Das Menü müsste länger geöffnet bleiben, und der enthaltene Link dürfte nicht sofort die zugehörige Seite aufrufen.

Hier kommt das jQuery-Plugin superfish.js in Verbindung mit hoverIntent.js ins Spiel. Zusätzlich zu jQuery werden die beiden Plugins im head-Bereich oder vor dem schließenden </body>-Tag der HTML-Seite eingebunden. Eine CSS-Datei bringt superfish.js auch gleich mit. Mit wenigen Zeilen JavaScript ist Superfish initialisiert und ruft automatisch hoverIntent.js mit auf.

Superfish initialisieren

  1. <script>
  2.  
  3. jQuery(document).ready(function(){
  4. jQuery('ul.sf-menu').superfish();
  5. });
  6.  
  7. </script>

Mit der Klasse .sf-menu wird das Wurzelelement der geschachtelten Liste gekennzeichnet. Superfish schreibt noch einige weitere Klassen in die Listenstruktur. Dazu gehören Anweisungen wie display: block und display: none, um das Untermenü ein- und auszublenden.

Optionen und Wirkweise

Mit knapp einem Dutzend Optionen lässt sich Superfish dem eigenen Bedarf anpassen, beispielsweise die Delay-Einstellung für die Zeit, die das Menü ohne Mausberührung geöffnet bleibt. Um das Menü nun nicht nur länger geöffnet zu halten, sondern auch die Unterpunkte klickbar zu machen, kommt "hoverIntent.js" ins Spiel. Es setzt jeweils zwei Zustände auf einen Menülink: Die erste Touch-Berührung klappt das vorhandene Untermenü auf, erst beim zweiten Mal wird der Link aktiviert. Zusammen mit einer ausreichend hohen Einstellung für die Verzögerung bleibt genügend Zeit, um die Unterpunkte zu berühren und beim zweiten Mal den enthaltenen Link auszuführen. Superfish ist übrigens nicht nur für Touch-Geräte konzipiert – auch die Hover-Menüs auf dem Desktop erhalten zusätzliche Funktionen wie sanftes Scrollen des Untermenüs.

Fallback

Der Anwender ohne JavaScript nutzt weiterhin den einfachen Klappeffekt des Hover-Menüs ohne sanftes Aufblenden. Hier ist Superfish nur ein »Nice-to-have«. Touchgeräte haben dann allerdings keine oder nur eine eingeschränkte Navigationsfunktion. Bei Tablets ist das Problem zu vernachlässigen, da ihre Nutzer meist die JavaScript-Unterstützung eingeschaltet haben. Aber es gibt noch Touch-Monitore und All-in-one-PCs. Ob man hier immer auf JavaScript setzen kann, ist fraglich.

Übrigens: Als begrüßenswerter Nebeneffekt von Superfish sind bei eingeschaltetem JavaScript die Dropdowns auf dem Desktop auch per Tastatur navigierbar.

Ohne Javascript - die Alternative mit :target

Einen völlig anderen Ansatz ohne JavaScript verfolgt Aaron Gustafson mit dem Einsatz des CSS3-Pseudoelements :target. Es kann prüfen, ob ein Anker gerade aktiv ist oder nicht und das Ziel entsprechend aktivieren. Dass der Internet Explorer dieses Pseudo-Element erst ab Version 9 unterstützt, ist im Hinblick auf mobile Plattformen zu vernachlässigen. Hier sind normalerweise die neueren Browser-Versionen im Einsatz. Sie unterstützen :target bereits so gut, dass es als Basis für eine alternative Lösung infrage kommt.

Aaron nutzt die Fähigkeiten des Pseudoelements, um ein zunächst unsichtbares Listenmenü zu öffnen. Das ist nichts anderes als der altbekannte Sprunglink, der schon immer das enthaltene Ziel anspringen konnte. Damit existiert auch gleich ein Fallback: Sollte :target nicht unterstützt werden, kann der Ankerlink das Menü direkt anspringen.

In diesem Fall wird die Navigation zunächst mit position:absolute an den Kopf der Seite positioniert und die enthaltenen Listenelemente mit height: 0 unsichtbar gemacht. Alle sonstigen CSS-Angaben, die eine Höhe aufspannen müssen natürlich auch auf 0 gesetzt werden. Erst mit :target bekommen die Menülinks ihre normalen Höhenmaße zurück.

Bei Aaron sieht das an dieser Stelle so aus:

  1. #nav a {
  2. border-bottom-width: 0;
  3. overflow: hidden;
  4. height: 0;
  5. line-height: 0;
  6. padding: 01em;
  7. }
  8. #nav:target a {
  9. border-bottom-width: 1px;
  10. line-height: 3em;
  11. height: 3em;
  12. }

Auch der Sprunglink steht am Kopf der Seite. Er enthält die ID des Menüs:

  1. <aid="jump"href="#nav">Navigation</a>

Wird der Link geklickt, erhalten die Elemente von #nav ihre normale Höhe und werden sichtbar. Das aktivierte Sprungziel erhält dabei einen höheren z-index und liegt damit auf der obersten Ebene. So weit so gut. Schließen lässt sich das Menü allerdings nicht mit dem Button. Die geniale Lösung: Das #nav-Element bekommt am unteren Ende einen zusätzlichen Listenpunkt mit einem »back-to-top«-Link. Aaron hat den Hintergrund des Backlinks transparent gemacht und ihn auf die gesamte Bildschirmfläche ausgedehnt. Ein Klick unter den Menü-Container entzieht ihm das :target und die Navigation schließt sich wieder. Der Rest ist CSS-Kosmetik. Aaron spendiert seinem Menü einen Slide-Effekt mit Transitions.

Genial auch, dass die Sprunglinks fürs Öffnen und Schließen nicht nur auf Touch-Screens funktionieren. Sie lassen sich auch mit der Tastatur ansteuern.

:target im Offscreen

David Bushell setzt dem Ganzen noch eins drauf. Im Smashingmagazine beschreibt er detailliert und anhand mehrer Beispiele ein sogenanntes Offscreen-Menü, das auf der oben beschriebenen Methode basiert. Bei Touch-Devices sind Offscreen-Elemente, die sich nach rechts oder links aus dem Viewport herausschieben lassen, nichts Ungewöhnliches.

Im Prinzip ist der Aufbau derselbe wie der von Aaron. Nur platziert David einen sichtbaren Backlink im Menü-Container. Im aktivierten Zustand verdeckt das Menü aufgrund des höheren z-index den Startlink. Dem Nutzer präsentiert sich so das gewohnte Verhalten eines Toggle-Menüs.

Der Menü-Container ist geschlossen, nur der Button zum Öffnen ist sichtbar.
Der Menü-Container ist geschlossen, nur
der Button zum Öffnen ist sichtbar
Das geöffnete Menü mit dem Button zum Schließen, der anstelle des Öffnen-Buttons eingeblendet wird.
Das geöffnete Menü mit dem Button zum
Schließen, der anstelle des
Öffnen-Buttons eingeblendet wird

Um das Menü in den Viewport zu verschieben und wieder zurück, wird das schon mehrfach erwähnte JavaScript für die Toggle-Funktion eingesetzt. Der Clou ist allerdings der Einsatz der CSS3-Eigenschaften transform und transition für das sanfte Gleiten. Modernizr prüft, ob der genutzte Browser diese Eigenschaften unterstützt. Falls nicht, bleibt es bei dem zuvor beschriebenen Screen-Menü. Diese Lösung setzt bis auf die Toggle-Funktion völlig auf CSS. David erwähnt auch, dass die CSS-Lösung für Transitions wesentlich schneller arbeitet als die Alternative mit jQuery und zeigt einen Geschwindigkeitstest.

Fazit

Alle diese Ansätze sind brauchbar und gar nicht so schwierig in ihrer Umsetzung. Die Kodierung mobiler Menüs ist kein Hexenwerk. Allerdings erfordern gerade komplexe Menüstrukturen unbedingt präzise Vorarbeit in der Konzeptionsphase. Gewisse Bereiche einfach auszublenden, um das Menü »genießbarer« zu machen, hinterlässt nur enttäuschte Besucher. Und das Bereichsmenü, das aus vielen Auftritten inzwischen »weggehovered« wurde, hat mobil durchaus seine Berechtigung.

Vielversprechend sind die Ansätze mit reinem CSS, die ein Mehr an Usability versprechen. Die große Herausforderung dürfte darin bestehen, die Hochglanzoptik mit der Benutzbarkeit zu verbinden.

Renate Hermanns

Von Keywordspam zu guten Inhalten

$
0
0
Brille auf einem BuchContenterstellung für SEO

Websites bestehen nicht nur aus Technik im Front- und Backend sondern auch aus Inhalten – zumindest sollte das so sein; wozu gäbe es sonst die Website? Aber wie müssen diese Inhalte beschaffen sein, um die Suchmaschinenoptimierung der Website zu unterstützen? Und das nicht nur kurzfristig, sondern möglichst nachhaltig?

Wie müssen Inhalte beschaffen sein, um einer Website oder einzelnen Seiten innerhalb der Website zu guten Platzierungen bei Google, Bing oder anderen Suchmaschinen zu verhelfen? Um diese Frage zu beantworten, muss man sich die Intention und die Arbeitsweise dieser Suchmaschinen ansehen. Dazu werfen wir einen Blick in die Vergangenheit und schauen anschließend in die Gegenwart und die vermutete Zukunft der Suchmaschinenoptimierung. Zu verstehen, wie Suchmaschinen arbeiten (wollen), ist die zwingende Voraussetzung, um Inhalte erstellen oder beauftragen zu können, die den nachhaltigen Erfolg von Websites ermöglichen.

Keyworddichte und Linkspam – SEO der alten Schule

Aus SEO-Gesichtspunkten wurden Texte früher folgendermaßen erstellt (manche in der Branche arbeiten heute noch immer so):

  1. Aus einer Auswahl von Schlüsselwörtern (Keywords) wird dasjenige ermittelt, das die höchste Anzahl an Besuchern verspricht.
  2. Zu diesem Keyword wird ein Text erstellt, der die folgenden Anforderungen erfüllt: Die Keyworddichte beträgt zwischen drei und fünf Prozent und die Textlänge mindestens 350 Wörter.
  3. Der Text wird auf der Seite veröffentlicht, die zu exakt diesem Begriff bei Google ranken soll.
  4. Aus allen verfügbaren Quellen werden Links auf diese Seite gesetzt, die möglichst auch noch das exakte Keyword als Linktext haben.

Dieser vereinfacht dargestellte Ablauf hat viele Jahre lang sehr gut funktioniert. Die erfolgreicheren Suchmaschinenoptimierer haben ihre Arbeitsweise und -abläufe oft so standardisiert und perfektioniert, dass Texte dieser Art und Qualität in großer Stückzahl in die Websites geschoben werden konnten. Bekannt ist das auch von vielen Shops, deren Kategorietexte aussehen wie das nebenstehende Beispiel eines völlig überflüssigen Texts über Hemden.

Screenshot eines überflüssigen und profanen Textes über Hemden.

Hier ist auch schnell das Problem zu erkennen: Solche Texte hatten eben nur das Ziel, die Platzierung bei Google zu verbessern. Nutzer der Seite sollten den Text möglichst gar nicht erst zu sehen bekommen. Inhaltlich wertvoll sind sie selten und noch viel seltener verkaufsstark, also dazu geeignet, einen Websitebesucher zum Kauf zu bewegen. Stattdessen sind es oft lieblos zusammengeklöppelte Texte, die sich nur vordergründig mit der Thematik beschäftigen, tatsächlich aber nur einen Rahmen für die sinnlose Wiederholung des Keywords bis zur Erreichen der vorgegebenen Keyworddichte bilden. Und der Text erreicht dabei auch immer nur die Mindestlänge von 350 Wörtern, mehr wurde ja nicht beauftragt und mehr gibt es vielleicht auch nicht zu sagen, wenn der Autor sich mit dem Thema nicht beschäftigen möchte. Wurde die Mindestlänge nicht erreicht, kamen wertvolle Hinweise wie »Für warme Tage sind auch Hemden mit kurzen Ärmeln empfehlenswert« zum Einsatz – und wir sind hier noch lange nicht bei den schlechtesten Texten dieser Art.

Wohlgemerkt: Ich spreche hier von der »alten Schule«– nicht von der »guten alten Schule«. Das wurde nicht gemacht, weil es gut war, sondern es wurde gemacht, weil es funktioniert hat. Es war der leichte Weg zum schnellen Ranking – quasi das Tabellenlayout des Suchmaschinenoptimierers. Für andere Typen von Websites gab es andere Abläufe, die sich aber nicht in der inhaltlichen Qualität, sondern eher in der Textlänge und der Anzahl der erforderlichen Links unterschieden. Noch öfter musste »Bernd Sonnensegel« sich in einem Blogkommentar für den tollen Beitrag bedanken und noch häufiger wurde von neuen Forenmitgliedern auf die "tolle Seite mit Sonnensegeln" hingewiesen, die sie gerade entdeckt hatten.

Diese Praktiken haben nicht ganz zu unrecht den schlechten Ruf von Suchmaschinenoptimierern begründet. Gerade bei Webentwicklern, die an ihre eigene Arbeit einen gewissen Qualitätsanspruch haben, sind solche Arbeitsweisen nicht angesehen. Aber zum Glück haben sich die Suchmaschinen weiterentwickelt und insbesondere Google ist in der qualitativen Beurteilung von Websites und einzelnen Dokumenten immer besser geworden und wird sich weiter verbessern; das deuten aktuelle Entwicklungen an.

Gute Inhalte für den Nutzer sind gute Inhalte für Suchmaschinen

Ein ganzer Zoo von Updates an den Google-Algorithmen ist in den letzten Jahren online gegangen und wird laufend weiterentwickelt. Mit dem Penguin genannten Update wurden schlechte Links entwertet, mit dem Panda wurde die Erkennung von qualitativ minderwertigen Inhalten verbessert und abgestraft, und mit dem im September veröffentlichten Hummingbird schafft Google es viel besser, die Intention einer Suche zu verstehen und Seiten mit passenden Inhalten zurückzuliefern, die das Keyword oder die gesuchte Formulierung aber nicht zwingend enthalten müssen. Diese Algorithmus-Updates haben zur Folge, dass die SEO-Taktiken der Vergangenheit immer seltener funktionieren, oder zumindest nicht lange funktionieren, also nicht nachhaltig ranken. Wer demnach Inhalte erstellen will, die nachhaltig für Besucher sorgen, muss seine Taktik ändern – und davon profitieren alle.

Natürlich ist der Inhalt eines Dokuments nur eines von vielen Signalen, die Google für thematische und qualitative Einordnung und die Platzierung in einer Trefferliste heranzieht. Aber weder sind Links oder soziale Signale das Thema dieses Artikels, noch ist es die technische Qualität und Performance der Website. Trotzdem sollte sich jeder Websitebetreiber bewusst sein, dass allein gute Inhalte keine Garantie für qualifizierte Besucher sind.

Ohne gute Inhalte wird es aber zukünftig schwer bis unmöglich werden, eine erfolgreiche Website zu betreiben. Sehen wir uns einfach mal stichpunktartig an, was Google mittlerweile an Signalen erkennen und auswerten kann oder in absehbarer Zeit können wird: Keywords, Suchabfragen, Synonyme, situative Kontexte, Aktualität, Kontinuität, holistische Intensität, Differenzierung, Lesbarkeit, Benutzbarkeit, Vertrauen, Authorship, Informationsdichte, Links, Infrastruktur, Datenpunkte, Besucherverhalten, Konversionen, Erwartungen, Erfüllungsgrad. (Die Liste wurde dem unten verlinkten Artikel »Gute Inhalte« entnommen.)

Seit dem Hummingbird-Update ist insbesondere den Suchabfragen und den situativen Kontexten mehr Aufmerksamkeit zu schenken. Google erkennt aus den Abfragen und dem Verhalten des Nutzers bei der Suche (Suchhistorie, erkannte Interessen etc.) immer besser die hinter der Suche stehende Intention. Schafft es der Inhalt nicht, die hinter der Suche stehende Intention zu befriedigen, werden es auch technische oder quantitative Signale nicht schaffen, dieses Dokument in der Trefferliste nach vorn zu bringen. Fraglich ist dabei auch, ob es wie in der Vergangenheit reicht, eine potenzielle Frage als Hauptüberschrift zu nehmen, wenn die Frage nicht tatsächlich beantwortet wird.

Fragen beantworten, Informationen liefern, Produkte verkaufen

Wenn Google es versteht, aus einer kurzen Suchabfrage die Intention des Suchenden zu erkennen, sollten wir auch davon ausgehen, dass es für die Suchmaschine machbar ist, aus einem längeren Artikel die thematische Ausrichtung zu erkennen. Und das passiert eben nicht anhand des Durchzählens von Keywords sondern anhand deutlich komplexerer Algorithmen und Signale.

Erkennt (oder vermutet) also Google, dass der Suchende ein tiefgehendes Informationsbedürfnis hat, werden auch nur Seiten vorn in der Trefferliste auftauchen, die dieses tiefgehende Informationsbedürfnis bedienen und befriedigen können. Ein Fachartikel kann das leisten, eine lieblose Pressemitteilung oder ein daraus entstandener Kurzbeitrag wohl kaum, unabhängig von der Qualität der Website, auf der er erschienen ist.

Umgekehrt kann aber auch eine Frage mit einem einfachen Datum oder einer ähnlich kurzgefassten Information beantwortet werden. Immer öfter macht Google das allerdings selbst, und so wird eine Website auch dann, wenn sie die Information liefern kann und sogar einen der vorderen Plätze in der Trefferliste belegt, kaum Besucher bekommen. Wer soll schon klicken, wenn die Antwort bereits bekannt ist?

Erkennt Google aus der Suchabfrage oder dem Verhalten des Suchenden aber eine Kaufabsicht, kann es wieder ganz anders aussehen. Davon ausgehend, dass der Suchende bereits alle nötigen Informationen erhalten hat und das Produkt nur noch erwerben möchte, wird Google den besten Shop präsentieren. Und das ist nicht zwingend der, der den ausführlichsten Produkttext hat, sondern der mit der besten Nutzererfahrung, der zuverlässigsten Technik und dem höchsten Vertrauen. Google verfügt zumindest über all diese Signale, und es darf höchstens noch spekuliert werden, ob sie derzeit schon genutzt werden oder ob das erst in der Zukunft der Fall ist. Für einige Signale wurde die Nutzung schon durch Google bestätigt, hier ist nur noch zu spekulieren, wie stark das Signal in die Bewertung der Website einfließt, wie z. B. die Performance der Website das Ranking beeinflusst.

Fazit

Doch wie stellt ein Websitebetreiber jetzt für das eigene Geschäftsmodell oder für seinen Kunden sicher, dass er die Inhalte mit Blick auf die Suchmaschinenoptimierung richtig erstellt oder erstellen lässt? Ganz einfach: Erwartungen erfüllen. Zielt er auf Besucher, die Informationen zu einem Themenkomplex suchen? Dann beantwortet er alle Fragen zu diesem Themenkomplex aus allen Blickwinkeln für diese Besucher. Zielt er auf Besucher, die eine sehr spezifische Information zu einem Thema suchen, liefert er die beste und weitgehendste Information zu genau diesem Thema für diese Besucher. Will er ein Produkt verkaufen, bietet er das beste Produkt zum besten Preis im besten Shop für diese Kunden. Dokumente und Websites, die diese Anforderungen erfüllen, möchte Google seinen Nutzern präsentieren. Websites, die das nur vorspiegeln, haben eine gute Platzierung in einer der Frage entsprechenden Trefferliste nicht verdient.

Im Grunde lässt sich die Frage nach dem besten Inhalt mit einer Frage an sich selbst beantworten: Warum sollte meine Website/mein Dokument bei einer Suchabfrage eines Suchenden mit einer bestimmten Intention vor den Websites/den Dokumenten stehen, die dort jetzt gelistet sind? Kann man diese Frage für sich ehrlich beantworten und die gewünschte Platzierung begründen, ist man der tatsächlichen Platzierung schon sehr nahe. Kann man die Frage nicht beantworten, weiß man zumindest, was zu tun ist. Und erst, wenn man das weiß, beginnt die Contenterstellung für SEO, denn erst dann weiß man, welchen Inhalt man zu erstellen oder zu beauftragen hat.

Möchte man mit Inhalten nachhaltigen Erfolg haben, schafft man die Inhalte für den Nutzer. Google möchte das, Google propagiert das und Google kann es immer besser erkennen. Und auch, wenn die algorithmische Erkennung von Textqualität für deutsche Texte schwieriger ist als für englische, ist sie nicht unmöglich und wird hier mit zunehmend besserer Trefferquote eingeführt werden.

Links zum Thema

Der Rahmen dieses Artikels reicht nicht aus, um die vielen Anforderungen detailliert zu erläutern, die an Inhalte gestellt werden, die zukünftig eine sehr gute Platzierung bei Google versprechen. Unten findet sich ein Link zu einem Blogartikel von Karl Kratz, der neben einem ausführlichen Text auch ein Video zum Thema enthält. In einem weiteren Artikel vom gleichen Autor wird dann auch beschrieben, warum die Keyworddichte eine denkbar ungeeignete Messgröße ist und welchen Algorithmus Google vermutlich stattdessen zur Beurteilung der inhaltlichen Qualität und der Thematik nutzt. Die Formel WDF*IDF hat mittlerweile eine gewisse Berühmtheit in SEO-Kreisen und darüber hinaus erlangt – nicht zu Unrecht.

  • Algorithmen (Informationen von Google zur Funktionsweise von Suchalgorithmen)
  • Gute Inhalte (Blogartikel von Karl Kratz zur Contenterstellung mit 18-minütigem Video)
  • WDF*IDF (Ausführliche Erläuterungen zum Thema Termgewichtung)
Stefan David

Like A Rolling Webdev

$
0
0
Mr. Kopozky und sein Team als RockbandKolumne

Eine Zeit lang war kaum ein (englischsprachiger) Artikel über Webentwicklung zu lesen, in dem nicht mindestens einmal der Begriff »Rockstar Web Developer« erwähnt wurde. Natürlich gehört dieser Begriff zu den üblichen, aus unserer Sicht übertriebenen, Metaphern solcher Artikel – aber ist vielleicht doch etwas dran? Wie viel Rock ’n’ Roll steckt eigentlich in den üblichen Rollen eines typischen Webworker-Teams?

Mr. Kopozky und sein Team als Rockband
Mr. Kopozky und sein Team rocken die Hütte

Grafik/Design

Kreativ an der Grenze zum Genie, dabei aber oft ein wenig divenhaft. Der grafische Entwurf ist immer das Wichtigste am Projekt, ohne Grafik geht ja quasi überhaupt nichts. Künstler halt. Muss immer das neueste Equipment (Creative Suite) haben, ist ständig auf der Suche nach kleinen Effekten (Brushes), die sein Werk aufpeppen. Kann aber auch mal »unplugged« spielen (Zettel und Stift), insbesondere, wenn improvisiert werden muss.

Ganz eindeutig: Die Grafik spielt Gitarre.

Frontend

Gehört nicht ganz zum Design, aber auch nicht so richtig zur Entwicklung. Wollte eigentlich Grafik machen, war dafür aber nicht gut genug. Das Frontend sitzt zwischen den Stühlen direkt an der Schnittstelle, steht Grafik und Backend nahe und verbindet beide – solide, aber meist unauffällig. Es fällt allerdings sofort auf, wenn es ungewöhnliche Spieltechniken (CSS3) einsetzen darf, und ohne Frontend würden Grafik und Backend vermutlich nicht zum gleichen Endergebnis kommen.

Man ahnt es schon: Das Frontend spielt den Bass.

Backend

Legt mit stoischer Ruhe die Basis des Projektes und gibt damit Rhythmus und Tempo vor. Kann antreiben oder das Tempo verschleppen, ohne aus dem Takt zu kommen. Schüttelt mitunter den Kopf, worüber sich »die Kreativen« schon wieder aufregen, macht dann aber einfach weiter. Hantiert bisweilen mit exotischen Instrumenten (Webserver, Datenbank, Java). Man kann natürlich Projekte ganz ohne Backend umsetzen, aber mal ehrlich – ist das noch Rock ’n’ Roll?

Keine Frage, das Backend sitzt am Schlagzeug.

Projektleitung

Bleibt idealerweise im Hintergrund und erledigt unauffällig, was zu tun ist, damit das große Ganze funktioniert. Springt ein, wenn Not am Mann ist (auch mal bei Dingen, die niemand sonst kann und die nicht vorgesehen waren), verzichtet aber auf große Solo-Einlagen – es sei denn, es gilt, das Publikum zu beeindrucken. Hat viel Arbeit schon erledigt, bevor die anderen überhaupt anfangen, neigt aber auch zum Drängeln, weil sie nicht versteht, dass die anderen nicht auf Knopfdruck loslegen können.

Klarer Fall: Die Projektleitung steht am Keyboard.

Bonustrack: Wer singt eigentlich?

Sie halten sich meist für fürchterlich wichtig, dabei spielen sie nicht einmal ein richtiges Instrument. (»Ich hab mal ein paar Gitarrenstunden gehabt, aber ich kann nur ein paar Akkorde. Gib’ mal die Gitarre, ich probier mal was!«) Kommt zu spät zu wirklich allen Terminen, weil wieder mal irgendetwas dazwischen kam. Wenn sie dann da sind, haben sie ein fürchterlich schlechtes Timing (»Wie, Einsatz verpasst? Spielt halt so, wie ich einsetze. Das kann doch nicht so schwer sein?«) und fordern Dinge, die so gar nicht gehen (»Wollen wir nicht mal einen Song mit einem Dudelsack-Solo machen? Das klingt bestimmt voll gut!«).

Letzten Endes ist es aber doch so: Ohne Sänger gäbe es oftmals keine Band. Sicherlich gibt es ein paar Musiker, die nur instrumental spielen, aber mal ehrlich: Es wird auf Dauer schnell langweilig und so richtig will sich dafür kein Publikum finden. Wirklich gute Sänger sind also selten – hat die Band einen gefunden, bemüht sie sich, dass er bleibt, auch wenn sie dafür Kompromisse eingehen muss.

Wer es nicht längst vermutete: Den Gesang in unserer Webdev-Band übernehmen unsere Kunden.

Disclaimer: Der Autor dieses Artikels ist Webentwickler und Bassist einer Rockband. Es ist nicht auszuschließen, dass dieser Umstand seine Sicht des Themas maßgeblich beeinflusst.

Wir bedanken uns recht herzlich bei Mr. Kopozky und seinem Team für ihren spontanen Gastauftritt!

Matthias Mees

Das role-Attribut: Worauf es ankommt

$
0
0
Graffiti: Totenkopf mit KopfhörerEinstieg in ARIA 1.0 – Teil I

Für Webworker bedeutet es immer eine Herausforderung, dynamische Anwendungen mit Barrierefreiheit in Einklang zu bringen. ARIA 1.0 (Accessible Rich Internet Applications) will diese Lücke schließen. Mit dem role-Attribut bietet ARIA dazu ein mächtiges Werkzeug. Allerdings muss dieses auch richtig eingesetzt werden, damit Tastatur- und Screenreader-Nutzer etwas davon haben.

Früher war nicht alles besser. Im barrierefreien Webdesign postulierten die 1999 veröffentlichten Web Content Accessibility Guidelines (WCAG) 1.0 noch, dass Webseiten ohne aktiviertes JavaScript funktionieren müssen. Obwohl diese Haltung weiterhin als Best-Practice gilt, wird es seit Veröffentlichung der WCAG 2.0 aus dem Jahr 2008 langsam, aber sicher möglich, JavaScript-Widgets mit WAI-ARIA (Web Accessibility Initiative - Accessible Rich Internet Applications) barrierefrei zu gestalten.

Das role-Attribut

Das Problem der Barrierefreiheit ist nicht JavaScript. Das Problem dynamischer Anwendungen bestand vielmehr in der fehlenden Semantik und der fehlenden Bedienbarkeit mit der Tastatur. Während die Tastaturbedienung als alter Schlendrian der Webentwicklung bezeichnet werden kann, stellte die Semantik durchaus eine Herausforderung dar. Wie sollen beispielsweise Tab-Panels oder Slider mit den HTML-Elementen in einem Screenreader erkannt werden? Die Antwort liefert die WAI-ARIA-Spezifikation: Das role-Attribut, das Anfang diesen Jahres als W3C-Empfehlung veröffentlicht wurde, sowie zahlreiche neue Attribute, die Zustände und Eigenschaften dynamischer Elemente beschreiben.

Hinweis: Bei Webstandards-Enthusiasten dürften sich bei nachfolgendem Code die Fußnägel aufrollen, bei manchen anderen leider nicht.

Das role-Attribut ist ziemlich mächtig. Mit diesem Attribut können Webentwickler die native Rolle eines Elements überschreiben. Aus einem span kann zum Beispiel eine Überschrift werden.

  1. <span role="heading">Überschriftentext</span>

Browser geben nun der Accessibility-Schnittstelle des jeweiligen Betriebssystems an, dass der Überschriftentext tatsächlich eine Überschrift ist. Entsprechend identifizieren die meisten Screenreader den Text als Überschriftentext. Besser ist selbstverständlich die Verwendung der vorgesehenen HTML-Elemente:

  1. <h1>Überschriftentext</h1>

Wann immer möglich, sollten HTML-Elemente nach ihrer Bedeutung eingesetzt werden.

Desweiteren sollte die Rolle semantisch bedeutsamer Elemente nicht mit role entfernt werden. Wenn eine Überschrift anklickbar sein soll, sollte nicht das Überschriftenelement mit einem role="link" versehen werden (dann handelt es sich nämlich nicht mehr um eine Überschrift), sondern ein enthaltenes Element soll die Interaktion ermöglichen, damit das Element sowohl als Überschrift als auch als Link identifiziert werden kann:

  1. <h1><span role="link"tabindex="0"onclick="foo();">Linktext</span></h1>

beziehungsweise als Best-Practice natürlich

  1. <h1><ahref="#"onclick="foo();">Linktext</a></h1>

Hinweis: Links und Steuerelemente müssen tastaturbedienbar sein. Ein span-Element ist von sich aus nicht mit der Tastatur bedienbar, und die Tastaturbedienbarkeit muss vom Webentwickler zusätzlich eingebaut werden. Das role-Attribut ändert die Semantik, aber nicht das Verhalten eines Elements!

Umgekehrt bleibt ein ursprünglich tastaturbedienbares Element auch nach einer Neudefinition mit role mit der Tastatur bedienbar:

  1. <ahref="seite.html" role="heading">Linktext</a>

Die »neue« Überschrift steht nach wie vor in der Tabulatorreihenfolge und das ursprüngliche Linkziel kann durch Klicken oder Drücken der Eingabetaste aufgerufen werden. Semantisch ist die Überschrift aber kein Link mehr – im Screenreader handelt es sich um eine fokussierbare Überschrift. Das role-Attribut ist deshalb mit Vorsicht einzusetzen beziehungsweise nur dort einzusetzen, wo Probleme tatsächlich behoben werden müssen.

Verschiedenartige Rollen und neue Attribute

In der WAI-ARIA-Spezifikation werden vier Arten von Rollen definiert. Die Rollen dienen unterschiedlichen Zwecken:

  • Bei den landmark roles geht es vor allem um ein Navigationskonzept für Tastatur- und insbesondere Screenreader-Nutzer. Die landmark roles dienen der strukturellen Navigation und werden die seit vielen Jahren genutzte Technik der Navigation über Überschriften ersetzen. Wenn sämtliche Inhaltsblöcke einer Seite mit passenden Rollen (Navigation, Inhalt etc.) versehen werden, können Screenreader-Nutzer eine Seite besser erkunden.
  • Die document structure roles sind im Gegensatz zu landmark roles nicht für die strukturelle Navigation vorgesehen, geben dem Aufbau der Seite aber ebenfalls eine zusätzliche Semantik. Auf vielen Websites werden sie bereits intensiv genutzt, was aber im Screenreader zu sehr vielen, meist überflüssigen Informationen führt.
  • Mit den widget roles werden komplexere, interaktive UI Komponente gekennzeichnet (zum Beispiel Tab-Panels, Baumstrukturen oder Akkordeons). Sie müssen oft mit weiteren Attributen ergänzt werden, um Zustände und Eigenschaften der Komponenten korrekt an den Browser vermitteln zu können. Teilweise erlauben Browser dann eine bessere Tastaturbedienbarkeit in Screenreadern; grundsätzlich muss aber die Bedienung mit der Tastatur vom Webentwickler bereitgestellt werden.
  • Die abstract roles sind für die Webentwicklung uninteressant; sie dienen der Klassifikation der anderen Rollen.

Es gibt zahlreiche Attribute für die einzelnen Rollen. Die WAI-ARIA-Attribute beginnen mit "aria-" (und bleiben somit von HTML5-Attributen unterscheidbar). Um beispielsweise ein Element mit der Rolle einer Überschrift auch die Eigenschaft einer Überschriftenebene zuzuweisen, wird das aria-level-Attribut eingesetzt:

  1. <h1 role="heading" aria-level="3">Überschriftentext</h1>

oder

  1. <span role="heading" aria-level="3">Überschriftentext</span>

Mit den ARIA-Attributen sollten alle Browser den Inhalt als Überschrift übersetzen und dem jeweiligen Accessibility-API des Betriebssystems durchreichen. Ein Screenreader holt die Informationen von der Accessibility-API ab und in beiden Fällen sollten die Screenreader-Nutzer eine Überschrift dritter Ebene vorfinden.

Statische oder dynamische Technik?

Wann WAI-ARIA-Attribute eingesetzt werden sollten, hängt immer vom HTML ab. WAI-ARIA ergänzt eine Auszeichnungssprache wie HTML und sollte zum Fine-Tuning eingesetzt werden. Alles, was mit HTML erledigt werden kann, sollte mit HTML umgesetzt werden, sei es im HTML selbst oder in Skripts.

Ob die Rollen und weiteren ARIA-Attribute im HTML stehen oder durch JavaScript der Webseite zugewiesen werden, ist im Prinzip ohne Belang. Während landmark und document structure roles ohne Weiteres im HTML stehen können, sind widget roles meist nur auf dynamischen Seiten zweckmäßig. Das heißt: Wenn JavaScript die Voraussetzung für die Funktionalität einer Seite ist, spielt es keine Rolle, ob die Attribute im HTML stehen oder erst später dynamisch zugewiesen werden. Wichtig ist, dass die Attribute für Zustände und Eigenschaften der Rollen korrekt mit JavaScript aktualisiert werden.

Handarbeit oder JavaScript-Bibliothek?

WAI-ARIA wird leider oft unterschätzt, vor allem bei den widget roles. Die tatsächliche Funktionalität hängt nicht nur von der Rolle und der Vergabe einiger weiterer Attribute ab, sondern von der korrekten Aktualisierung von Zuständen und Eigenschaften bei dynamischen Elementen auf einer Webseite. Auch ist die vollständige Unterstützung in Browsern und Hilfsmitteln wie Screenreader leider immer noch nicht gegeben. Und, obwohl es viele wohlklingende Tutorien draußen im Netz gibt, einiges funktioniert in der Praxis doch nicht. Teilweise werden falsche oder die Barrierefreiheit nicht unterstützende Attribute eingesetzt und manchmal fehlen HTML5-Attribute. Wo auch immer die Gründe für die Unzugänglichkeiten liegen mögen, ausführliche Tests mit Screenreadern sind unumgänglich, um die Barrierefreiheit sicherzustellen.

Es gibt einfache und komplexere Widgets; auch gibt es kombinierte Widgets. Während einfachere Widgets wie tri-state Checkboxen durchaus mit Marke Eigenbau erstellt werden können (und das morgige Türchen dieses Adventskalenders gibt dazu ein Beispiel), wird es bei zunehmender Komplexität einer Komponente immer ratsamer, eine der zahlreichen JavaScript-Bibliotheken einzusetzen. Der bloße Einsatz dieser Bibliotheken garantiert keinesfalls tastaturbedienbare oder screenreaderfähige Ergebnisse.

Für die drei Bibliotheken jQuery, Dojo und MooTools gibt es das unabhängige accessible component modules, das die Ausgabe verschiedener Widgets vor allem für die Tastaturbedienung und Nutzbarkeit in Screenreader optimiert. Die Ergebnisse dieser Module lassen sich sehen: Die Widgets sind mit der Tastatur und in Screenreadern getestet, allerdings nur in aktuelleren Versionen von JAWS und das kostenfreie NVDA. Andere Screenreader wie VoiceOver, Kobra, Supernova oder Window Eyes sowie die zahlreichen Vergrößerungssysteme mit unterstützender Sprachausgabe werden mit Sicherheit nicht die gleichen guten Ergebnisse erzielen.

Jan Eric Hellbusch

Tri-State-Checkbox: Mit Tastatur und Screenreader bedienbar

$
0
0
Drei Checkboxen mit drei unterschiedlichen ZuständenEinstieg in ARIA 1.0 – Teil II

Mit ARIA 1.0 können fortgeschrittene Steuerelemente für Screenreader barrierefrei gemacht werden. Insbesondere müssen die Tastatursteuerung und Semantik berücksichtigt werden. Wie eine konkrete Umsetzung aussehen kann, zeigt das Beispiel einer Tri-State-Checkbox.

WAI-ARIA ist die Brücke zwischen dynamischen Anwendungen und Barrierefreiheit in Screenreadern. Aus der WAI-ARIA-Spezifikation ist bislang nur wenig als offizielle Empfehlung des W3C verabschiedet worden — allen voran das gestern vorgestellte role-Attribut– aber vieles funktioniert bereits in gängigen Screenreadern wie JAWS oder dem kostenlosen NVDA.

WAI-ARIA dient unter anderem dazu, zwei Aspekte des Webdesigns zu verbessern: die Tastaturbedienbarkeit und die Semantik. Diese sind vor allem in dynamischen Anwendungen oft ein Problem. Es handelt sich bei WAI-ARIA um einen Satz zusätzlicher Attribute für HTML (und andere Techniken), die – korrekt eingesetzt – eine Menge bringen können, insbesondere für Screenreader-Nutzer. Die Praxis zeigt aber auch, dass WAI-ARIA aktuell oft nach dem Gießkannenprinzip eingesetzt wird; mit der Folge, dass manche Webseiten weniger zugänglich sind als zuvor.

Ein einfaches Beispiel

Wie WAI-ARIA sinnvoll eingesetzt wird, zeigt das folgende Beispiel anhand einer einfachen widget role, einer Tri-State Checkbox. Die Tri-State-Checkbox ist ein Kontrollkästchen, das drei Zustände (nicht aktiviert, teilweise aktiviert und aktiviert) annehmen kann.

Tri-State-Checkboxen in den Zuständen 'nicht aktiviert', 'teilweise aktiviert' und 'aktiviert'
Mehr als nur HTML erforderlich

Obwohl es in HTML die Checkbox gibt, kann sie in HTML nur zwei Zustände annehmen (aktiviert oder nicht aktiviert). Der dritte Zustand »teilweise aktiviert« ist in HTML nicht vorgesehen.

Üblicherweise wird bei Tri-State-Checkboxen mit Grafiken gearbeitet, damit auch der Zustand »teilweise aktiviert« dargestellt werden kann. Ein Blick in den Code im wilden Web weist meist wenig Erhellendes auf, denn die komplette Funktionalität wird mit JavaScript bereitgestellt. So ist das Grundgerüst meist nicht viel mehr als ein SPAN:

  1. <spanid="meineID"onmousedown="foo();"></span>

Zweck der Übung

Wenn ein span-Element die Grundlage für ein Widget ist, wird jedem sicher schnell klar, dass das kaum barrierefrei sein kann. Solche Inhalte werden mit der Tastatur nicht bedienbar sein und sie weisen keinerlei Semantik auf; vor allem wenn die span-Elemente der Positionierung von Hintergrundgrafiken dienen, werden diese Inhalte im Kontrastmodus des Browsers unsichtbar sein. Dabei gibt es für die meisten Widgets barrierefreie Lösungen, die nur einer Prise WAI-ARIA bedürfen. Folgende Aspekte müssen in Angriff genommen werden:

  • Das Element muss mit der Tastatur erreicht und bedient werden können.
  • Das Element muss als Checkbox identifiziert werden können (Rolle).
  • Der Zustand (aktiviert, teilweise aktiviert, nicht aktiviert) muss identifizierbar sein.
  • Das Steuerelement benötigt einen Namen (Beschriftung/label).

Der Kontrastmodus wurde hier nicht vergessen. Er wird durch die anderen Maßnahmen abgedeckt – zumindest in diesem konkreten Beispiel.

Tastaturbedienbarkeit

Wir haben es zunächst mit einem span zu tun, das praktisch keine Eigenschaften hat. Damit das Element mit der Tastatur angesteuert werden kann, benötigt es ein tabindex-Attribut:

  1. <spantabindex="0"onkeydown="bar();"id="meineID"onmousedown="foo();"></span>

Die Funktion, die mit dem onkeydown-Attribut aufgerufen wird, dient dazu, die zulässigen Tastendrucke für die Bedienung der Checkbox (Leertaste, Eingabetaste) zu ermitteln, um dann erst die eigentliche Funktion aufzurufen. Das kann im einfachen Fall wie folgt aussehen:

  1. function bar(){
  2. if(event && event . type == 'keydown'){
  3. if(event . keyCode){
  4. tastenCode = event.keyCode; /* IE */
  5. }
  6. elseif(event . which){
  7. tastenCode = event . which; /* Mozilla, Safari, Opera */
  8. }
  9. if(tastenCode != 13&& tastenCode != 32){
  10. returntrue;
  11. }
  12. }
  13. foo();
  14. }

Die Funktion soll nur bei Druck der Eingabe- oder Leertaste ausgelöst werden, nicht aber bei anderen Tasten. Das Filtern der Tastendrucke kann natürlich auch in der mausabhängigen Funktion eingebaut werden; in dem Fall sollte anstatt der beiden geräteabhängigen Event-Handler der Event-Handler onclick verwendet werden (bei Links und Formularelementen reagiert er auch auf Eingabe- und Leertaste).

Die Tastaturbedienbarkeit lässt sich einfacher mit einem interaktiven Element umsetzen. Da Grafiken für die drei Checkbox-Zustände benötigt werden, bietet sich ein input-Element des Typs image oder ein button-Element an. Wer größere Gestaltungsspielräume braucht, wird das button-Element einsetzen; für den einfachen Austausch von Grafiken reicht das input-Element:

  1. <inputtype="image"src="nicht-aktiviert.png"alt="Alle Optionen auswählen"id="meineTriStateID" />

Der Browser erkennt dieses Element und stellt die Tastaturbedienbarkeit bereit. Wenn also auf native interaktive HTML-Elemente zurückgegriffen werden kann, müssen keine weiteren Maßnahmen ergriffen werden, um das Element per Tabulatortaste erreichbar zu machen. Ein weiterer Vorteil des input-Elements ist, dass die Grafik auch im Kontrastmodus dargestellt wird.

Semantik hinzufügen

Ob mit span, input oder button: dem Element müssen noch Rolle und Zustand hinzugefügt werden. Die Rolle (role) des Elements ist eine Checkbox und der ursprüngliche Zustand (aria-checked) ist »nicht aktiviert«:

  1. <input role="checkbox" aria-checked="false"type="image"src="nicht-aktiviert.png"alt="Alle Optionen auswählen"id="meineTriStateID" />

Das aria-checked-Attribut kann die Werte false, mixed oder true annehmen. Ohne dieses Attribut ist das role-Attribut wertlos. Das heißt: Nur wenn beide Attribute gemeinsam eingesetzt werden, wird diese Checkbox auch für Screenreader-Nutzer semantisch richtig dargestellt werden können.

Im nicht-ARIA-fähigen Browsern ist der Name des Elements der Wert des alt-Attributs. In ARIA-fähigen Browsern muss aber das spezifischere Attribut aria-label eingesetzt werden, damit die Screenreader die Grafik richtig identifizieren können. Diese beiden Attribute sollten den gleichen Wert erhalten.

  1. <input aria-label="Alle Optionen auswählen" role="checkbox" aria-checked="false"type="image"src="nicht-aktiviert.png"alt="Alle Optionen auswählen"id="meineTriStateID" />

Wenn der Zustand der Checkbox sich nun ändert, muss das aria-checked-Attribut zusammen mit der Grafik, dem Alternativtext und der Beschriftung aktualisiert werden.

Demonstration

Die Funktionalität kann nachfolgend getestet werden. Ohne Screenreader kann lediglich die Tastaturbedienbarkeit überprüft werden. Die Semantik der Checkbox kann nur mit einem Screenreader getestet bzw. mit der Funktion unter den Checkboxen kontrolliert werden.

Beispiel: Tri-State-Checkbox mit WAI-ARIA

Welche Techniken beherrschst Du?

Die Demonstration gibt es auch als Download (ZIP).

Zusammenfassung

Für alle fortgeschrittenen Steuerelemente, die mit HTML alleine nicht abgebildet werden können, gilt, dass sie mit WAI-ARIA erst barrierefrei werden können. Folgende Schritte müssen dabei eingehalten werden:

  1. Tastaturbedienung gewährleisten
    • Jedes Steuerelement muss mit der Tastatur fokussiert werden können.
    • Die Tastatursteuerung von Widgets muss zusätzlich berücksichtigt werden; sie folgt anderen Mustern als die Maus- oder Touch-Screen-Eingabe.
  2. Semantik hinzufügen
    • Jedes Element benötigt eine Rolle. Wenn kein passendes HTML-Element eingesetzt werden kann, dann wird die Rolle mit dem role-Attribut zugewiesen.
    • Für Widgets gibt es zahlreiche Zustände und Eigenschaften. Diese Semantik muss mit ARIA-Attributen zugewiesen werden.
    • Im JavaScript müssen die ARIA-Attribute aktualisiert werden, wenn Zustände oder Eigenschaften der Widgets geändert werden.
  3. Ergebnisse mit Screenreadern testen.
Jan Eric Hellbusch

Ambient Light Responsive Webdesign

$
0
0
Gerätesensoren per Javascript und CSS nutzen

Responsive Websites können nicht nur auf die Änderung des Browserfensters reagieren – auch die Umgebungshelligkeit kann die Gestaltung beeinflussen. Mit Javascript lassen sich entsprechende Sensoren abfragen und für das Design nutzen.

Traditionell denkt man bei responsivem Webdesign an Layouts, die auf die Änderung der Browserfenstergröße – bzw. des Viewports – reagieren (wenn man bei einer so jungen Disziplin von Traditionen sprechen kann). In der Regel werden dann das Layout der Seite oder einzelne CSS-Eigenschaften verändert, z.B. die Schriftgröße, um die Benutzung für Besucher unter den für sie geltenden Bedingungen (besonders kleine oder große Bildschirme) zu verbessern. Tatsächlich gibt es aber ein ganze Reihe von Umgebungsbedingungen, auf die eine Website reagieren könnte.

Schön wäre es doch, wenn ein elegant Ton in Ton gestaltetes Design auch bei grellem Sonnenlicht gut lesbar wäre – indem sich der Kontrast den Lichtverhältnissen anpasst. Tatsächlich ist das möglich. Mit der W3C Candidate Recommendation Ambient Light Events hat die Mozilla Foundation eine Spezifikation eingereicht, mit der sich das über einen Lichtsensor gemessene Umgebungslicht auslesen und verwerten lässt (wenn auch momentan die Browserunterstützung noch sehr ausbaufähig ist). Auch der aktuelle Draft der Mediaqueries Level 4 sieht eine Reaktion auf Helligkeitsunterschiede vor – das Media Feature luminosity. Während die Mediaqueries noch nicht einmal testbar sind, lässt der Mozilla-Vorschlag mit Mobile Firefox > 15 oder auf FirefoxOS bereits nutzen (z.B. einem Nexus 7 der 1. Generation).

Die Abfrage an sich ist recht einfach. Mit einem Event Listener wird der Sensor direkt abgefragt:

  1. window.addEventListener("devicelight", function(light){
  2. var ambientlight = light.value;
  3. });

Mit dem gewonnenen Helligkeitswert in Lux könnt ihr nun Abfragen für die Anpassung des Design an die Umgebungshelligkeit schreiben. Der Wert lässt sich natürlich auch direkt anzeigen. Die folgende Funktion setzt je nach Helligkeit unterschiedliche Klassen und gibt den Lichtwert aus:

  1.  
  2. <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
  3. <script>
  4. var currentClass = 'medium';
  5. $('body').addClass(currentClass);
  6. function readLight(light){
  7. var header = "<h1>Ambient Light Responsive Webdesign &trade;</h1>";
  8. $('body').removeClass(currentClass);
  9. if(light.value> 1800){
  10. currentClass = 'sunny';
  11. header = "<h1>Ein schöner Tag!</h1>";
  12. }
  13. elseif(light.value< 500){
  14. currentClass = 'dark';
  15. }
  16. else{
  17. currentClass = 'medium';
  18. header = "<h1>Ein dunkles Grau vor hellgrauem Hintergrund ist elegant, aber schlecht lesbar.</h1>";
  19. }
  20. $('body').addClass(currentClass);
  21.  
  22. var d = document.getElementById("message");
  23. d.innerHTML = header + "<p>Der aktuelle Lichtwert beträgt <em>" + light.value + " Lux</em>.</p>";
  24. }
  25. window.addEventListener("devicelight", readLight, true);
  26. </script>

Das Skript wird im Kopf der Website platziert und stellt die vergebenen Klassen zum Styling zur Verfügung. Außerdem verändert es den Inhalt des Elements mit der id "message". Mit einer CSS-Transition könnt ihr den Übergang noch etwas verfeinern und für den Alltagseinsatz wäre es sinnvoll, die Schwellenwerte so zu gestalten, dass die Darstellung nicht andauernd umspringt (Hysterese).

Um den Effekt zu sehen, müsst ihr die Demoseite mit Mobile Firefox auf einem Gerät mit Helligkeitssensor aufrufen.

Es gibt noch mehr!

Auf die Umgebungshelligkeit zu reagieren, ist nur eine Möglichkeit, die wachsende Anzahl von Sensoren moderner Mobilgeräte zu nutzen.

Wie wäre es zum Beispiel, wenn die Website eines Restaurants beim Aufruf durch ein mobiles Gerät »in der Nähe« mit der prominenten Anzeige der Tageskarte und der Adresse reagieren würde? Die meisten modernen Smartphones haben außerdem einen Kompass und einen Neigungssensor an Bord, so dass sich die Position des Geräts im Raum exakt bestimmen lässt. Eine Kleinigkeit, nun auch noch die Entfernung und Richtung zum Ziel anzuzeigen.

Bei der Nutzung von Sensoren stellt sich natürlich die Frage nach Datenschutz und Überwachung. Da die Sensorendaten vom Gerät bereit gestellt werden und per Javascript verarbeitet werden, bleiben alle Informationen zunächst auch dort (natürlich lassen sie sich dann auch weitergeben). Manch Nutzer wird sich aber dennoch durch Funktionen irritiert fühlen, die zeigen, dass »die Website« seine Position kennt. Mit einem Datenschutzhinweis, der die Funktion erläutert, nehmt ihr diese Bedenken ernst. Im Zweifel könnt ihr Lokalisierungsfunktionen auch so umsetzen, dass sie erst eingeschaltet werden müssen.

Progressive Enhancement statt Bevormundung

Mobilsite ohne Informationen außer der Anschrift
So nicht – eine mobile Website ist mehr
als ein Adressaufkleber!

Bei aller Freude über zusätzliche Information solltet ihr jedoch nicht vergessen, dass Sensordaten immer nur Informationen aus zweiter Hand sind – einen Sensor für die Gedanken des Nutzers gibt es glücklicherweise (noch) nicht. Bietet daher aufgrund von sensorgestützten Vermutungen zusätzliche Verbesserungen an – trefft keine ausschließenden Entscheidungen für die Nutzer. Ein abschreckendes Beispiel sind »mobile Websites«, die nur die Anschrift eines Unternehmens anbieten, in der irrigen Annahme, dass mobile Nutzer ihr Smartphone oder Tablet immer nur unterwegs nutzen.

Kai Laborenz

Struktur und Organisation in SASS-Projekten

$
0
0
SASS-Schriftzug und OrdnerstrukturCSS-Präprozessoren

Alle Webworker, die CSS-Präprozessoren wie SASS nutzen, müssen sich die Frage beantworten: »Wie organisiere ich meine Dateien, um mir das (Arbeits-)Leben so einfach wie möglich zu machen?« Wer als Antwort auf diese Frage irgendwo das Ei des Kolumbus vermutet, wird erstaunt sein über die Vielfalt der Ansätze.

Viele Webworker haben sich hierzu kluge Gedanken gemacht und sind naturgemäß zu unterschiedlichen Ergebnissen gekommen (siehe auch die weiterführenden Links). Was allein deshalb nicht verwundert, da Strukturansätze immer auch unmittelbar die Gestaltungsprinzipien reflektieren, unter deren Prämisse ein Autor seine Styles schreibt. Und die sind oftmals sehr verschieden.

Es führen also mal wieder viele Wege nach Rom. Im Artikel stelle ich meinen Weg vor, Ordner und Dateien in einem SASS-Projekt zu organisieren und freue mich, wenn er Anregung ist, eigene Ideen zu entwicklen.

Viele Fliegen, eine Klappe

Ich vermeide es seit geraumer Zeit, eine individuelle Ordner- und Dateistruktur für neue Projekte anzulegen. Bis zu dieser Entscheidung musste ich meine Entwicklungsumgebung permanent anpassen; die gedankliche Umstellung kostete Zeit und war anstrengend. Im Laufe der kreativen Arbeit an einem Projekt permanent Entscheidungen über Organisation, Dateibenennung etc. treffen zu müssen, hemmt zudem den Arbeitsfluss und ist ineffizient.

Daher habe ich mir eine Mastervorlage erstellt, die seitdem Grundlage für jedes neue Projekt ist. Diese Mastervorlage besteht vorrangig aus einer bestimmten Ordner- und Dateistruktur, die sich bislang in sehr unterschiedlichen Projekten bewährt hat und mir erlaubt, mich ganz auf die Entwicklung des CSS eines Projektes zu konzentrieren. Ich habe mit ihr sowohl sehr einfach gehaltene Webseiten, als auch komplexere Projekte mit mehreren Teilbereichen umgesetzt.

Die Ordner- und Dateistruktur der Mastervorlage

  1. utilities/
  2. abstracts/
  3. base/
  4. extensions/
  5. sections/
  6. website/
  7. queries/
  8. vendor/
  9. overrides/
  10. _bootstrap.scss
  11. _website-configuration.scss
  12. website.scss

Für den Artikel ist die Mastervorlage schon um einen beispielhaften Projektbereich (website) erweitert. Was genau ein Projektbereich ist und was er enthält, beschreibt der Artikel im weiteren Verlauf.

utilities/

Hier liegen globale Mixins und Funktionen, die übergreifend in allen Projektbereichen einsetzbar sind. Als Teil der Mastervorlage stehen sie in jedem neuen Projekt unmittelbar zur Verfügung.

  1. utilities/
  2. _functions.scss
  3. _mixins.scss
  4. ...

abstracts/

In diesem Ordner befinden sich ausschließlichAbstraktionen. Eine Abstraktion ist eine Art CSS-Blaupause, die die grundsätzliche Darstellung eines HTML-Elementes festlegt, aber keine Vorgaben zu dessen Aussehen macht. Dieses wird im CSS des jeweiligen Projektbereiches festgelegt. Harry Roberts hat das Prinzip anhand der Nav Abstraktion sehr anschaulich erklärt.

Um von Anfang an für die Einbindung von externen CSS-Frameworks gerüstet zu sein, ist der Hauptordner abstracts/ in zwei Unterordner (base/, extensions/) unterteilt. Während die eigenen Abstraktionen ihr Zuhause im Ordner base/ haben, liegen die erweiterten Abstraktionen eines externen Frameworks im Ordner extensions/. Durch diese Unterteilung des Hauptordners ist die Herkunft einer Datei auf einem Blick ersichtlich. Ein nicht zu unterschätzender Vorteil, wird ein Projekt zu einem späteren Zeitpunkt erneut bearbeitet.

Sehr hilfreich ist, den Namen der im Ordner extensions/ liegenden Dateien mit einem Prefix zu versehen (hier: ext-). Werden in der Entwicklung Sourcemaps genutzt, ist es so ein leichtes, zwischen Original und angelegter Datei im Browser zu unterscheiden.

  1. abstracts/
  2. base/
  3. _name-der-abstraktion.scss
  4. ...
  5. extensions/
  6. _[ext]-name-der-abstraktion.scss
  7. ...

Webworker sollten soviel Zeit wie möglich auf die Erstellung eigener Abstraktionen verwenden! Da der Ordner abstracts/ Bestandteil der Mastervorlage ist, profitiert ihr davon in jedem neuen Projekt.

Tipp: Wurde während eines Projekts eine neue Abstraktion erstellt, solltet ihr immer überlegen, ob es ggf. sinnvoll ist, sie in die Mastervorlage zu übernehmen.

Abstraktionen vorbereiten

In jeder dieser Dateien, werden die eigentlichen Deklarationen mit einer @if Kontrollanweisung umschlossen, die so aussehen sollte:

  1. @if$use-abstract-[name-der-abstraktion] == true{
  2. ... Deklarationen ...
  3. }// eol condition

bzw. für erweiterte Abstraktionen externer Frameworks:

  1. @if$use-abstract-[ext]-[name-der-abstraktion] == true{
  2. ... Deklarationen ...
  3. }// eol condition

Wozu diese Kontrollanweisungen genutzt werden, wird zu einem späteren Zeitpunkt im Abschnitt zur Konfigurationsdatei erklärt.

sections/

Der Ordner sections ist das Herz eines Projektes. In ihm liegt mindestens ein Bereichsordner (im Artikel: website) oder beliebig viele. Jeder Bereichsordner enthält sämtliche (S)CSS-Partials, die für die Struktur, das visuelle Erscheinungsbild und das Verhalten auf unterschiedlichen Geräten des jeweiligen Bereiches zuständig sind.

Zu jedem Projektbereich gehört sowohl eine korrespondierende Konfiguration (im Artikel: _website-configuration.scss) als auch die zu kompilierende Projektdatei (im Artikel: website.scss). Dies ermöglicht, Stylesheets für jeden einzelnen Projektbereich separat zu erstellen.

Dass das sehr sinnvoll sein kann, macht folgendes Beispiel deutlich: Der Kunde möchte für das Weihnachtsgeschäft einige Kampagnenseiten lancieren, die sich in Struktur und visueller Gestaltung signifikant von der generellen Webseite unterscheiden und unter jeweils eigenständigen Domains laufen sollen. Dies könnte mit dem schon vorhandenen Projektbereich website realisiert werden. Das aber hätte gleich mehrere Nachteile: Die Konfigurationsdatei würde unübersichtlich, dadurch schwer zu verwalten und das generierte CSS würde weder für die Webseite noch die Kampagnenseiten optimal. Beide Seitenbereiche würden Styles laden, die nicht genutzt werden.

Der deutlich bessere Weg ist das Anlegen eines zusätzlichen, neuen Bereich, der hier naheliegend campaigns genannt wird. Die Projektstruktur würde anschließend so aussehen:

  1. ...
  2. sections/
  3. website/
  4. queries/
  5. campaigns/
  6. queries/
  7. ...
  8. _campaigns-configuration.scss
  9. campaigns.scss
  10. _website-configuration.scss
  11. website.scss

Media Queries

Jeder Bereichsordner beinhaltet einen Unterordner mit Namen queries/. Wie unschwer zu erraten, werden hier die media queries für den jeweiligen Bereich deklariert. Werden Media Queries in einer separaten Datei auf Ebene des Projektbereichs definiert, kann für jeden Teil des Projekts entschieden werden, wie er sich auf unterschiedlichen Geräten verhält und aussieht. So lange es in SASS nicht möglich ist Media Queries zu gruppieren, bevorzuge ich das Arbeiten in eigenständigen Dateien.

  1. sections/
  2. [name-des-projektbereichs]/
  3. ...
  4. queries/
  5. ...

vendor/

Im globalen Ordner vendor/ liegen CSS-Dateien externer Bibliotheken. Damit der CSS-Präprozessor diese Dateien einbinden kann, wird das Suffix jeweils von .css auf .scss geändert. In der _overrides.scss Datei werden die Styles der externen Bibliotheken bei Bedarf überschrieben. So gehen die Änderungen nicht verloren, wenn die originalen CSS-Dateien dieser Bibliotheken aktualisiert werden.

  1. vendor/
  2. // Bsp. prism.css => prism.scss
  3. prism.scss
  4. ...
  5. overrides/
  6. _overrides.scss

_website-configuration.scss

Die _[name-des-bereiches]-configuration.scss ist die Schaltzentrale eines jeden Projektbereiches (im Artikel: website). Ausschließlich hier werden die im jeweiligen Projektbereich genutzten Variablen deklariert. Die Datei teilt sich in mindestens drei Bereiche auf (zu viele kann es prinzipbedingt nicht geben. Seid kreativ!). Ein paar Tipps:

  1. Farben

    Die Definition von Farben sollte in zwei Bereiche unterteilt werden. Der Erste enthält Variablen, deren Benennung sich nach ihrem Wert richten (Bsp. $nearlyWhite: #f1f1f1;). Im zweiten deklariert ihr die Variablen, deren Name das widerspiegelt, wofür sie eingesetzt werden (Bsp. $pageBackgroundColor: $nearlyWhite!default;). Diese – und nur diese– werden im CSS genutzt. Was zuerst etwas umständlich wirkt, ist tatsächlich der Schlüssel zur Vermeidung von semantischen Sackgassen.

  2. Interface

    Das visuelle Erscheinungsbild seitenübergreifender Elemente (bspw. Schatten, Rahmen etc.) ist in der Regel überall identisch. Sie sind somit perfekte Kandidaten um als Konfigurations-Variablen deklariert zu werden. Teures Nachjustieren kann vermieden werden, indem zu Beginn des Projektes überlegt wird, für welche Elemente/Attribute eine Abstrahierung als Variable sinnvoll ist.

  3. Includes

    Wart ihr fleißig, liegen im Ordner abstracts/ (bzw. dessen Unterordnern) viele Dateien mit Abstraktionen. Um zu vermeiden, die globale _bootstrap.scss Datei (siehe nachfolgender Abschnitt) immer wieder erneut anpassen zu müssen, sobald eine neue Abstraktion erstellt worden ist, werden diese Dateien dort per Globbing (Sass Plugin) importiert. Was dazu führt, dass grundsätzlich alle– auch die im CSS nicht genutzten Abstraktionen – im generierten CSS auftauchen und die Dateigröße des kompilierten Stylesheets dadurch unnötig aufblähen.

    Wie im Abschnitt zu den Abstraktionen erwähnt enthält jede dieser Dateien eine @if Kontrollanweisung: Zeit, sie zu nutzen! Es werden nur die Variablen explixit auf true gesetzt, deren Abstraktionen auch tatsächlich im CSS genutzt werden.

    Tipp: Unabhängig davon, ob sie eingesetzt werden oder nicht: Es müssen grundsätzlich alle im Ordner abstracts/ vorhandenen Abstraktionen in der Konfigurationsdatei definiert werden, da der Compiler sich sonst über nicht definierte Variablen mokiert.

  1. /**
  2.  * $CONFIGURATION
  3.  * Section: website
  4.  */
  5.  
  6. /**
  7.  * $ACOLORS
  8.  * Variablen bezogen auf ihren Farbwert
  9.  */
  10. $nearlyWhite: #f1f1f1;
  11. ...
  12.  
  13. /**
  14.  * $COLORS
  15.  * Variablen bezogen auf ihren Verwendungszweck
  16.  */
  17. $pageBackgroundColor: $nearlyWhite !default;
  18. ...
  19.  
  20. /**
  21.  * $INTERFACE
  22.  * Rahmen, Schatten, Rundungen, Schriftgrößen, Basismaße etc.
  23.  */
  24. $borderRadius: 5px !default;
  25. ...
  26.  
  27. /**
  28.  * $INCLUDES
  29.  * Listing aller verfügbaren Abstraktionen
  30.  * Inkludiere (value => `true`) nur die Abstraktionen,
  31.  * die auch tatsächlich im Projekt genutzt werden
  32.  *
  33.  * bool true|false(Standard)
  34.  */
  35. $use-abstract-[name-der-abstraktion]: false !default;
  36. $use-abstract-ext-[name-der-abstraktion]: false !default;
  37. ...

_bootstrap.scss

Die globale _bootstrap.scss Datei (die nichts mit dem gleichnamigen CSS-Framework zu tun hat) importiert alle Dateien, die keinen unmittelbaren Bezug zu einem dezidierten Projektbereich haben. Sie ist Teil der Mastervorlage. Auch werden hier die Styles der externen Bibliotheken inklusive der _overrides.scss Datei eingebunden.

Wichtige Regel: In der Bootstrap-Datei werden keine CSS-Styles deklariert! Nur so bleibt der globale Charakter der Bootstrap-Datei erhalten.

  1. /**
  2.  * $BOOTSTRAP
  3.  * Section: global
  4.  */
  5.  
  6. // Helfer wie functions, mixins importieren
  7. @import "utilities";
  8.  
  9. // Es werden nur die Abstraktionen importiert deren Wert in
  10. // der `_website-configuration.scss` auf `true` gesetzt ist
  11. @import "abstracts/base/*";
  12.  
  13. // Abgeleitete Abstraktionen aus Drittanbieter-Frameworks
  14. // einzeln importieren. "ext-" als Datei-Prefix verwenden
  15. @import "abstracts/extensions/ext-[name-der-abstraktion]";
  16. ...
  17.  
  18. // Vendor styles importieren
  19. @import "vendor/[name-der-datei]";
  20.  
  21. // Vendor overrides Partial importieren
  22. @import "vendor/overrides/overrides";

website.scss

Hier nun kommt Dampf in den Kessel. Die website.scss ist die einzige Datei, die kompiliert und später im HTML verlinkt wird. Auch hier gilt: Vermeidet an dieser Stelle das Definieren von Styles! Diese gehören ausschließlich in die Dateien des jeweiligen Bereichsordners.

Die Reihenfolge der Importe ist relevant. In einem ersten Schritt wird die Konfiguration des Projektbereichs geladen, anschließend die _bootstrap.scss, die die globalen Funktionen und Abstraktionen sowie die Vendor-Styles einbindet und bereitstellt. Die bereichsbezogenen Partials werden zum Schluss importiert.

  1. /**
  2.  * $COMPILE
  3.  * Section: website
  4.  */
  5.  
  6. // Projektkonfiguration
  7. @import "website-configuration";
  8.  
  9. // Globaler bootstrap
  10. @import "bootstrap";
  11.  
  12. // Section styles importieren
  13. @import "sections/website/*";
  14.  
  15. // Media queries importieren
  16. @import "sections/website/queries/*";

Wie war das nochmal mit dem Ei?

Zu guter Letzt möchte ich dazu ermutigen, unterschiedliche Ansätze zur Strukturierung – damit ist auch der hier vorgestellte gemeint – immer wieder mit Blick auf die eigene Arbeitsweise und dem eigenem Arbeitsumfeld kritisch zu hinterfragen. Es gibt keinen allgemeingültigen richtigen Ansatz. Die Entscheidung für eine bestimmte Art der Organisation ist und sollte durchaus sehr subjektiv sein. Fühlt sich die gewählte Struktur für mich richtig, fühlt sie sich natürlich an? Nur wenn dies der Fall ist, wird man effektiv, weil ohne innere Widerstände, arbeiten können.

Weiterführende Links

Formulare für mobile Geräte optimieren

$
0
0
Verschiedene mobile Formularansichten übereinander gelegtHTML5

Für das input-type-Attribut sieht HTML5 viele neue Werte vor. Mit der Wahl des richtigen Wertes wird auf mobilen Geräten die passende Tastatur »getriggert«. Durch kleine Anpassungen im HTML wird die Usability von Formularen auf iPad & Co so deutlich verbessert.

Formularelemente nehmen unter allen HTML-Elementen eine besondere Rolle ein. Erst durch sie wird das Internet zum interaktiven Medium. Von daher sollten Formulare mit besonderer Sorgfalt aufgebaut werden. Erschreckend ist etwa, dass auf zahlreichen Webseiten kein label-Element verwendet wird und so eine einfache Möglichkeit ausgelassen wird, die Nutzbarkeit eines Formulars deutlich zu verbessern.

Ein kurzer Blick auf die Grundlagen

  1. <labelfor="vorname">Vorname</label>
  2. <inputtype="text"name="vorname"id="vorname">
  3. <inputtype="checkbox"name="agb"id="agb">
  4. <labelfor="agb">AGB anerkennen</label>

So sieht’s aus:

Das label ist die Beschriftung eines Formularelements und wird über die id des Formularelements (egal, ob input, select oder textarea) und dem for-Attribut im label verknüpft. Erst damit ist es Nutzern von Screenreadern möglich, ein Formular richtig zu füllen, da die Beschriftung der Felder eindeutig ist.

Nicht nur Screenreadernutzer profitieren vom korrekten Umgang mit dem label-Element. Klicken Nutzer auf die Beschriftung, dann befindet sich der Fokus im Eingabefeld. Klicken sie auf das label einer Radio- oder Checkbox, wird die Box aktiviert und bei Checkboxen beim zweiten Klick wieder deaktiviert. Bei den kleinen Radio- und Checkboxen wird über das label-Element die Klickfläche vergrößert und die Bedienbarkeit ist für alle Nutzer verbessert.

Neue Herausforderung durch SmartPhones und Tablets

Die Vergrößerung der klicksensiblen Fläche steigert die Usability der Formulare auch auf mobilen Geräten. Mit den neuen HTML5-Formular-Attributen kann die Formularbedienbarkeit auf iOS- und Android-Geräten mit wenig Aufwand zusätzlich verbessert werden.

Grundlage für die Optimierung ist die Tatsache, dass sich die Tastatur auf mobilen Geräten von den Tastaturen von Desktoprechnern und Laptops unterscheidet. Das ist für die meisten selbstverständlich, für die Optimierung eines Formulars muss man sich aber genau diese Tatsache vor Augen halten. Es sind nie alle Zeichen auf einem Blick verfügbar oder mit dem Drücken der Umschalttaste zu erreichen. Mobile Geräte bieten unterschiedliche Tastaturansichten, eine Standardansicht mit Buchstaben und den häufigsten Satzzeichen, eine weitere für Zahlen und weiteren Satz- und Sonderzeichen, eine oder mehrere Ansichten für diverse Sonderzeichen.

Bei der Optimierung steht die Wahl des richtigen type-Attributs für das input-Element im Mittelpunkt. Ziel ist immer, die richtige Tastaturansicht zu triggern und damit den Weg zum richtigen Zeichen so kurz wie möglich zu halten. Sprich: Bei jedem Formularelement gilt es, sich zu überlegen, welche Zeichen Nutzer dort eingeben werden, um dann den passenden Wert für das type-Attribut zu wählen.

type="email"

  1. <labelfor="email-adresse">E-Mail-Adresse</label>
  2. <inputtype="email"name="email-adresse"id="email-adresse">

So sieht’s aus:

Der Attributwert email sorgt dafür, dass sowohl auf iOS- als auch auf Android-Geräten die Tastatur um ein @-Zeichen ergänzt wird. Ein Wechsel zur richtigen Tastatur, bzw. die Überlegung, auf welcher Tastatur sich das @-Zeichen überhaupt befindet, ist damit hinfällig.

Tastatur mit @-Zeichen beim type-Parameter email auf dem iPad
Tastatur mit @-Zeichen beim type-Parameter email auf dem iPad

Android zeigt zusätzlich eine Taste mit der Aufschrift .com an. Hält der Nutzer die Taste einen kurzen Moment fest, erscheinen weitere Top-Level-Domains, die je nach Android-Version und Spracheinstellung des Gerätes variieren.

Tastatur mit @-Zeichen und .com-Taste beim type-Parameter email auf Android
Tastatur mit @-Zeichen und .com-Taste beim type-Parameter email auf Android

Hier profitieren nicht nur Nutzer mobiler Geräte. Auch bei neueren Browsern bewirkt type="email", dass die Eingabe vor dem Senden überprüft wird und eine falsche Eingabe das Absenden des Formulars verhindert (insofern diese Überprüfung durch den Browser nicht über das Attribut formnovalidate deaktiviert ist).

Fehlermeldung beim type-Parameter email im Google Chrome
Fehlermeldung beim type-Parameter email
im Google Chrome

Allerdings ist diese Validierung nur halbherzig, mit der Eingabe von a@b gilt die Prüfung auf eine korrekte E-Mail-Adresse als gültig. iOS selbst überprüft die Eingabe nicht.

type="tel" und type="number"

  1. <labelfor="telefon">Telefon</label>
  2. <inputtype="tel"name="telefon"id="telefon">

So sieht’s aus:

Soll in ein Feld eine Postleitzahl, eine Bestellmenge oder eine Telefonnummer eingegeben werden, bieten sich die type-Werte tel oder number an. Das bringt auf beiden mobilen Betriebssystemen die Zahlentastatur zur Ansicht.

Zahlentastatur beim type-Parameter tel auf dem iPad
Zahlentastatur beim type-Parameter tel auf dem iPad

Vor allem unter Android wird ein Zahlenblock angezeigt, der die Eingabe noch einfacher macht.

Zahlenblock beim type-Parameter tel auf Android
Zahlenblock beim type-Parameter tel auf Android

Während tel auch die Eingabe bestimmter Sonderzeichen erlaubt, können bei number ausschließlich Zahlen eingegeben werden. Dabei sind nicht nur ganze Zahlen zulässig, auch Fließkommazahlen können eingegeben werden.

Zahlenblock ohne Sonderzeichen beim type-Parameter number auf Android
Zahlenblock ohne Sonderzeichen
beim type-Parameter number
auf Android

Je nach Android-Gerät ist jedoch die Eingabe eines Kommas bzw. Punktes nicht möglich. Von daher: number sollte nur dann eingesetzt werden, wenn zu 100% sicher ist, dass eine ganze Zahl eingegeben wird, wie beispielsweise bei einer Bestellmenge. Bei einer Hausnummer, die prinzipiell noch einen Zusatz haben kann (z. B. 16a), wäre der Einsatz von number hingegen fatal.

type="url"

  1. <labelfor="domain">Domain</label>
  2. <inputtype="url"name="domain"id="domain">

So sieht’s aus:

Statt der normalen Buchstabentastatur werden bei type="url" auf iOS-Geräten neben den Buchstaben nur Zeichen angezeigt, die in einer URL erlaubt sind: Doppelpunkt, Slash, Bindestrich und Unterstrich oder die Space-Taste sind hier nicht zu finden.

Ebenfalls wird eine .com- bzw. .de-Taste angezeigt (je nach Spracheinstellung des Geräts), die auch hier beim Halten bzw. Hochwischen weitere Top-Level-Domains anzeigt.

Tastatur beim type-Parameter url auf dem iPad mit .com-Taste
Tastatur beim type-Parameter url auf dem iPad mit .com-Taste

Auf Android-Geräten triggert url leider keine spezielle Tastatur.

type="date", type="datetime", type="datetime-local", type="time" und type="month"

  1. <labelfor="datum">Datum</label>
  2. <inputtype="date"name="datum"id="datum">
  3. <labelfor="zeit">Zeit</label>
  4. <inputtype="time"name="zeit"id="zeit">

So sieht’s aus:

Anzeige eines Drehrädchen beim type-Parameter datetime auf dem iPad
Anzeige eines Drehrädchen beim
type-Parameter datetime
auf dem iPad

Eine Reihe von Zeit bzw. Datumswerten sind date, datetime, datetime-local, time und month. Diese führen auf iPad und iPhone dazu, dass keine Tastatur, sondern das Apple-typische Drehrädchen angezeigt wird.

Ein solches Bedienelement liefert einen genormten Zeitstring an den Server, der zum Beispiel so aussieht: 2013-12-15T12:45:17Z. Dieser Zeitwert erfordert eine spezielle Verarbeitung. Da jedoch Android sowie die meisten Desktop-Browser kein zufriedenstellendes Bedienelement anbieten, sollten Zeit bzw. Datumswerte für ein input-Element nur zum Einsatz kommen, wenn eine Seite ausschließlich für Apple-Geräte erstellt oder ein Fallback für die anderen Betriebssysteme angeboten wird.

type="week" und type="color"

Lediglich der Vollständigkeit halber seien hier die Werte week und color erwähnt. Ältere Android-Versionen und iOS unterstützen diese Parameter nicht, auch bei Desktop-Browsern ist keine browserübergreifende Unterstützung gegeben, von daher sind diese Werte für den Praxiseinsatz noch nicht geeignet.

autocapitalize="off"

  1. <labelfor="username">Username</label>
  2. <inputtype="text" autocapitalize="off"name= "username"id="username">

So sieht’s aus:

Eine Optimierung anderer Art ist die Unterdrückung der Umschalttaste. Standardmäßig wird (falls dies in den Einstellungen nicht deaktiviert wurde) die Umschalttaste aktiviert, sobald der Fokus im Feld ist, so dass die Eingabe mit einem Großbuchstaben beginnt. Was grundsätzlich eine gute Idee ist, muss nicht immer gewollt sein. Beispielsweise bei der Eingabe eines Usernamens, der wahrscheinlich bei vielen nicht mit einem Großbuchstaben beginnt.

Über autocapitalize="off" wird das automatische Aktivieren der Umschalttaste abgestellt. Allerdings ist autocapitalize kein Teil vom HTML5-Standard, sondern stammt von Apple, daher greift dieses Attribut nur auf iOS-Geräten.

autocorrect und spellcheck

  1. <labelfor="nutzername">Nutzername</label>
  2. <inputtype="text" autocorrect="off" spellcheck="false"name="username"id="nutzername">

So sieht’s aus:

Ähnlich wie bei der Umschalttaste verhält es sich mit der Autokorrektur. Bei der Eingabe eines Nutzernamens ist es eher hinderlich, wenn das Gerät Wortvorschläge macht. spellcheck="false" ist dabei valides HTML5 und unterdrückt die Autokorrektur auf Android-Geräten, autocorrect="off" ist von Apple und bewirkt den gleichen Effekt auf iPhone und iPad.

Browserkompatibilität

Nicht nur bei neuen input-type-Attributwerten, sondern generell beim Einsatz von neuen HTML5-Elementen müssen sich Webentwickler die Frage nach der Browserunterstützung stellen. Neue Strukturelemente wie section oder article müssen entweder mit div-Elementen umbaut werden oder beispielsweise über html5shiv»aktiviert« werden, damit diese die Darstellung im Internet Explorer 8 nicht »zerfetzen«.

Das Aktivieren neuer type-Parameter ist hingegen nicht möglich und auch nicht notwendig. Browser sind nicht dumm und können mehr, als die Standards definieren. Fehlt ein type im input-Element, oder hat type eine neuen Wert, den der Browser nicht kennt, wird ein einfaches Eingabefeld vom type="text" angezeigt. So ist bei älteren Browsern beispielsweise bei type="email" trotzdem die Eingabe einer E-Mail möglich. Neuere Browser, vor allem Nutzer mobiler Geräte, profitieren von neuen type-Parametern, da die richtige Tastatur angezeigt und das Wechseln der Tastatur überflüssig wird.

Webentwickler müssen sich allerdings im Klaren sein, dass die Wahl des richtigen type-Parameters keine Garantie für korrekte Eingaben ist. Ganz nach der alten Entwickler-Devise »All input is evil (jede Eingabe ist bösartig)«: Auch wenn bestimmte type-Werte vergeben sind, müssen alle Eingaben serverseitig auf ein richtiges Format bzw. zulässige Werte überprüft werden.

Bezüglich der Bedienbarkeit eines Formulars stellen die neuen type-Werte jedoch eine enorme Verbesserung dar! Hier ist der Einsatz von HTML5 bereits heute sinnvoll.

Weiterführende Links

Stephan Heller

Eine Extrawurst für oldIE

$
0
0
Teller mit BratwürstchenSASS für ältere IE nutzen

Die alten Internet Explorer bis Version 8 haben viele Techniken nicht implementiert, die Webworker heute gerne und oft nutzen. In solchen Fällen kann der Präprozessor SASS hilfreich sein, um den alten IE – ohne viel zusätzliche Arbeit – eine Extrawurst zu braten.

Die Nutzung moderner Techniken im Frontend ist nicht mehr ungewöhnlich. Die meisten dieser Techniken werden von älteren IE (bis inklusive Version 8) nicht unterstützt. Manche haben allerdings ein IE-spezifisches Pendant. Deshalb sind Webworker immer wieder in der Situation, oldIE (IE 8 und früher) eigene Styles zuweisen zu wollen.

Wollt ihr euch nicht nur auf Hacks verlassen, könnt ihr einen Präprozessor wie Sass für diese Zwecke nutzen. Dadurch befreit ihr gleichzeitig das CSS für die richtigen Browser von altem Ballast und Hacks. Das Prinzip ist dabei einfach.

Ich lass Dich nicht rein

Als allererstes müsst ihr verhindern, dass oldIE das gleiche Stylesheet liest wie alle modernen Browser. Denn schließlich möchtet ihr nicht ein globales CSS durch ein IE-spezifisches ergänzen, ihr möchtet zwei getrennte Welten schaffen. Dafür bindet ihr das CSS folgendermassen ein:

  1. <!-- Dieses CSS wird vom oldIE definitiv nicht gelesen -->
  2. <link rel="stylesheet" href="css/styles.css" media="all and (min-width: 0px)">
  3.  
  4. <!--[if lte IE 8]>
  5. <link rel="stylesheet" href="css/oldie.css">
  6. <![endif]-->

Zuerst verlinkt ihr styles.css mit einer Media Query, die den alten IE davon abhält, diese Datei herunterzuladen. Danach verlinkt ihr für oldIE ein spezielles CSS innerhalb eines Conditional Comment. Getrennte CSS-Dateien für IE7 und IE8 solltet ihr vermeiden, sie würden den Pflegeaufwand unnötig erhöhen. Zudem könnt ihr zwischen beiden Versionen prima mit dem Star-Plus-Hack unterscheiden. Und nicht zuletzt werden die IE7-Nutzer immer weniger, und nur der IE8 wird noch ein Weilchen als Pflegefall verbleiben.

Auf diese Weise weist ihr zwei CSS-Dateien sauber voneinander getrennt zu. Doch eigentlich wollt ihr effektiv nur an einer CSS-Datei arbeiten. Deshalb müsst ihr den nächsten Schritt tun.

Variablen

Die Unterscheidung zwischen »für oldIE« und »für richtige Browser« kann auf mehreren Wegen getroffen werden. Die gängigste Methode ist die Nutzung einer Variablen.

Ihr erstellt zwei SCSS-Dateien – styles.scss und oldie.scss –, in die ihr eure eigentlichen Sass-Dateien (die Partials) importiert. Am Anfang der beiden Dateien definiert ihr eine Variable in zwei Ausprägungen. Im Falle der oldie.scss schreibt ihr isoldIE: true; und im Falle der styles.scss schreibt ihr isoldIE: false.

Aufteilen in Portionen

Die eigentliche Arbeit geschieht dann nicht in diesen beiden eben genannten Dateien, sondern in den Partials. Dabei kann auch einmal eine spezielle oldIE-Datei importiert werden, im Grundsatz sollen aber alle Einzeldateien in die beiden zentralen Dateien importiert werden.

Variablennutzung

Die Variablen entfalten ihre Wirkung in Mixins und in einzelnen Regeln. Sie werden dabei mit @if-Bedingungen in den Code eingeflochten. Dadurch werden die betreffenden Codeteile nur ausgegeben, wenn die Bedingung zutrifft. Ein einfaches Beispiel ist ein Mixin, das oldIE einen Filter zuweist, der dem CSS3-Boxschatten recht nahe kommt:

  1. @mixin box-s($x: 1px, $y: 1px, $offset: 5px, $color: #666) {
  2. $ie-color: ie-hex-str($color);
  3.  
  4. @if $isoldIE {
  5. filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=#{$x}, OffY=#{$y}, Color='#{$ie-color}');
  6. }@else {
  7. box-shadow: $x $y $offset $color;
  8. }
  9. }

Da nun am Anfang der beiden zentralen Stylesheets die Variable $isoldIE steht, kann dementsprechend dieses Mixin abgearbeitet werden. @if $isoldIE ist gleichbedeutend mit @if $isoldIE == true, sodass der erste Teil des Mixins nur dann ausgegeben wird, wenn es über die Datei oldie.scss aufgerufen wird.

Nicht nur im Mixin

Was im Mixin funktioniert, kann natürlich auch in normalen Regeln angewendet werden. Die Syntax ist einfach zu merken und schnell geschrieben. Da insbesondere ältere IE ein fürchterliches Schriftrendering haben, könnt ihr diesen eine andere Schrift für alle Überschriften zuweisen, als allen anderen Browsern:

  1. #{headings()}{
  2. @if $isoldIE == false {
  3. font-family: $font-headline;
  4. font-weight: 400;
  5. }
  6. @if $isoldIE == true {
  7. font-family: Verdana, Helvetica, Arial, sans-serif;
  8. font-weight: normal;
  9. }
  10. }

Oder ihr schreibt eine Alternative für moderne Selektoren. Irgendwann könnt ihr diesen Teil des Codes dann entfernen, wenn der letzte IE8 endlich den Weg alles Irdischen gegangen ist:

  1. .footerlinks{
  2. // das folgende Mixin formatiert Links horizontal
  3. @include inline-list;
  4. @if $isoldIE == true {
  5. li {
  6. border-left: 1pxsolid#666;
  7. padding-left: 10px;
  8. margin-left: 10px;
  9. &:first-child{
  10. border-left: none;
  11. padding-left: 0;
  12. margin-left: 0;
  13. }
  14. }
  15. }@else {
  16. li:not(:first-child){
  17. border-left: 1pxsolid#666;
  18. padding-left: 10px;
  19. margin-left: 10px;
  20. }
  21. }
  22. }

Fazit

Mit einem Präprozessor wie Sass könnt ihr prima an einer einzelnen Codebasis arbeiten, aber zwei unterschiedliche Varianten ausgeben. So könnt ihr den Schwächen der alten IE entgegenarbeiten, ohne dass moderne Browser mit zusätzlichem Code behelligt werden müssen.

Jens Grochtdreis

Tage wie dieser

$
0
0
Francisco de Goya: »Der Schlaf der Vernunft gebiert Ungeheuer« (Ausschnitt), 1798Kolumne

Wie sieht der normale Tag eines selbstständigen Webdesigners aus? Darauf können auch wir pauschal keine Antwort geben. Klar ist nur, dass öde Routine nur selten dazugehört. Oft sind es die kleinen Tücken der Projektarbeit, die für ereignisreiche Stunden am Rechner sorgen. Heute gewährt uns Nils Pooker einen Blick in den Ablauf eines nicht ganz ernst gemeinten »Worst-Case-Arbeitstages«.

7.00 Uhr

Traum gehabt: Adobe-Entwickler stieg durchs Fenster in mein Büro, installierte etwas auf meinem Rechner und stieg hämisch lachend wieder hinaus. Schweißgebadet aufgewacht. Immerhin: heute ist Launch von Firma Meierhoff.

7.10 Uhr

Gut: Der Kaffee ist heiß, für Anrufe ist es zu früh. Schlecht: E-Mail-Eingänge überflogen.

Meierhoffs Mail um 23.18 Uhr. »am rechner? schicke pdf, muss noch rein.« Kein Anhang. Keine weitere Mail. PDF? Denke an den Adobe-Mann aus dem Albtraum.

Kunde Clausen will mein Angebot lesen. »Wir wollen das Redaktionssystem mit großem Funktionsumfang. Frage: Wie öffne ich Ihren Anhang?« Brauche sofort eine Zigarette.

7.20 Uhr

Kanzlei Trammer: »Dieses Jimdo ist uns doch zu kompliziert. Ein Mandant hat uns Typo3 empfohlen, ist das einfacher?« Ruhig bleiben.

Firma Klöbner? Wer war das noch? »Sie hatten uns 2002 eine Website erstellt. Kann man die für mobile Geräte optimieren?« Komplette Löschung? Zugang sperren? Abschalten der CSS-Datei? Markiere die Mail mit »Ist Werbung«. Erledigt.

Sieh’ an, Kunde Lüdermann schickt das Foto für die Einzelansicht des Teams. »Größer, wie gewünscht!« 400 x 230 Pixel. Spaß muss sein? Kann ich auch: Photoshop > Bildgröße > Pixelwiederholung. Online.

Im Schrank stünde noch der Panama-Rum. Nein, zu früh. Zigarette.

7.50 Uhr

Vor dem nächsten Kaffee eine letzte Mail lesen. Hach, der nette und dankbare Herr Müller, also Erfreuliches. Vermutlich eine kleine Änderung an seiner statischen Site. »Wir hätten gern Suchfunktion, Aktuellbereiche, ein Blog und mehrere Formulare.«
Mein Blick fällt auf Spiegel online. Wieder Amoklauf in den USA. Kurze Recherche. Nein, war weder ein Webdesigner noch ein Entwickler.

7.55 Uhr

Kaffee in ausreichend großer Entfernung zum Schrank getrunken. Hoffe auf Ruhe für den Launch.
Pling! Mail von Meierhoff. »pdf anbei. hochauflösend.« Endlich. Hochauflösend? PDF mit 4 MB. Denke an den Adobe-Mann. In der Hoffnung auf viele Bilder falte ich beim Öffnen des Acrobats instinktiv die Hände.
Nur Text, eingescannt und als PDF gespeichert. Abtippen? Mail schreiben?
Entscheide mich für den Schrank. Oh, wie schön ist Panama.

8.15 Uhr

Gut gelaunt zurück am Rechner.
Telefon. Anruf der Agentur von Kunde Clausen: »Könnten Sie uns aus der Vorlage einen Dummy erstellen?«
»Einen Klickdummy als HTML-Prototypen?«
»Ach, das geht mit Photoshop?«
Erkläre das genauer und denke über die Vorteile der Waffengesetze in den USA nach.

8.25 Uhr

Anruf von Meierhoffs Assistentin.
»Auf der Startseite steht noch ein Wort alleine in der letzten Zeile, das soll da weg.«
»Das ist HTML und nicht zu verhindern.«
»Natürlich! Blocksatz und Tabulator, geht sogar in Word!«
Erkläre das genauer und denke über eine Auswanderung in die USA nach.

Hole mir was zu trinken, damit die Zigarette nicht so trocken schmeckt. Die Schranktür kann auch offen bleiben.

8.55 Uhr

Telefon. Meierhoff höchstpersönlich. Ich melde mich noch einigermaßen deutlich.
»Da ist was zerschossen!«
»Hm. Welchen Browser benutzen Sie?«
»Windows!«
»Nein, das Programm, mit dem Sie ins Internet gehen. Am Bildschirmrand in der Menüleiste, ist da ein Symbol, vielleicht ein blaues ›e‹?«
»Moment. Ah, hier. Da steht ›Samsung‹.«
Genehmige mir einen sehr großen Schluck. Nach Telefonat mit dem Praktikanten, der sich das mal angesehen hat, lasse ich mich wieder zu Meierhoff durchstellen und versuche zu erklären, dass die Kombination aus sehr groß eingestellter Schrift und dem IE6 bei stark verkleinertem Browserfenster zu leichten optischen Irritationen führen kann. Erklärungsversuch scheitert. Trinke noch etwas mehr und frage nach den PDF-Inhalten als Word-Datei. Klar, haben die nicht mehr. Erwähne dann leichtsinnig den Begriff »OCR-Texterkennung«.
»OCR? Schade, unser Scanner ist leider von Epson.«

Vor dem Abtippen zwei Zigaretten und mal eine Kleinigkeit trinken. Auswanderung nach Panama wäre auch eine Option. Besser das Telefon in die Brusttasche stecken. Habe das Glas im Büro vergessen. Egal, geht auch aus der Flasche.

9.45 Uhr

Panama macht keine gute Laune mehr.
Drei Anschläge, dann schmiert Acrobat ab. Der Adobe-Mann? Hangle mich geschickt mit den Händen am Schreibtisch entlang und stoße nur zweimal gegen Möbelstücke. Blicke nach draußen, aber weit und breit niemand zu sehen. Jetzt den Rückweg antreten.

10.25 Uhr

Scheiß Turnschuhe, nicht gesehen. War dann auch keine gute Idee zu versuchen, an einem Drehstuhl hochzukraxeln, nicht zu empfehlen, dauert ewig. Bleibe jetzt sitzen und hoffe auf ausdauernde Blase. Dumpfe Töne. Augen und Ohren versuchen, die Geräuschquelle zu identifizieren. Da! Zwei Telefone auf dem Boden zwischen mir und dem Fenster? Ach nee, doch nur eines. Nicht noch einmal aufstehen, warte lieber auf E-Mails.
Klick, Acrobat öffnet sich wieder, ich weiche automatisch zurück. Jetzt behutsam tippen. Schnell geht eh nicht mehr. Entdecke noch einen großen Rest in der Flasche. Puh, Panama.

16.30 Uhr

Langsam kann ich wieder klar denken, war wohl kurz weggenickt. Zwei getippte Seiten, Tastatur scheint kaputt zu sein, Text ist kaum zu entziffern. Fünf Anrufe in Abwesenheit auf der Basisstation. Nanu, so viele Browser-Tabs? Ein Formular zur Bewerbung bei der CIA? Eine Seite mit Infos zur Auswanderung, ein Tab mit irgendeiner »Rifle Association« und ein Tab mit Google-Suche nach »Kopfschmerzen Chemtrails Adobe«? Scheiß Spam.
Blicke auf den Posteingang. Ups, Mail von Meierhoff vor zwei Stunden: »wo sind sie, pdf hat sich erledigt, bitte sofort online schalten!!!!«
Öffne das Backend des CMS. Klick. Launch.
Mail an Meierhoff: »Online. Sorry, habe zur Zeit Panama-Grippe.«

16.55 Uhr

Mail von Meierhoff: »na endlich. logo muss vier millimeter weiter nach links, habe das mit lineal nachgemessen!!! wieso sehe ich auf meinem alten laptop die runden ecken und schatten nicht, wo sind die??? assistentin hat alte www-adresse noch im google gefunden, bitte da mal schnell anrufen wg. änderung. gute besserung.«

Der Rechner lässt sich nicht gut tragen. Draußen zünde ich mir eine Zigarette an und atme tief durch. Wundervoll, diese Ruhe. Die ersten Schneeflocken, friedlich und sanft bedecken sie den winterlichen Rasen. Ich drücke auf den Garagenöffner. Da drüben, irgendwo hinter den Fahrrädern, da müsste der Vorschlaghammer liegen.

RRRING!

Wache schweißgebadet auf. Gehe ins Büro an den Rechner und öffne das Backend des CMS von Meierhoff. Klick. Launch. Schalte den Rechner wieder aus und tippe eine SMS an Meierhoff: »Site ist freigeschaltet, kann heute leider keine Mails empfangen.«

Nils Pooker

Durch die Brille des Nutzers I

$
0
0
Blick durch eine BrilleUsability Engineering: Arbeiten mit Nutzungsanforderungen

Um interaktive Systeme mit hoher Usability zu entwickeln, ist es notwendig, die Nutzungsanforderungen zu kennen und in geeignete technische Lösungen umzusetzen. Dabei ist es sehr einfach, an die richtigen Anforderungen zu gelangen: Man stellt Nutzern die richtigen Fragen und hört aufmerksam zu.

Der benutzerzentrierte Gestaltungsprozess

Usability ist definiert als »Ausmaß, in dem ein interaktives System durch bestimmte Benutzer in einem bestimmten Nutzungskontext genutzt werden kann, um festgelegte Ziele effektiv, effizient und zufriedenstellend zu erreichen« (ISO 9241-11). Hohe Usability lässt sich planen und erzielen, wenn in allen Phasen der Entwicklung des interaktiven Systems der Benutzer im Mittelpunkt steht. Man spricht dabei von einem benutzerzentrierten Gestaltungsprozess, der aus vier miteinander verbundenen Aktivitäten besteht (siehe Abbildung 1).

Benutzerzentrierter Gestaltungsprozess: Nutzungskontext verstehen und beschreiben, Nutzungsanforderungen spezifizieren, Gestaltungslösungen entwickeln, Produkt evaluieren
Abbildung 1: Benutzerzentrierter Gestaltungsprozess (nach ISO 9241-210)

Die beiden ersten Aktivitäten nach der Planung lassen sich unter dem Stichwort »benutzerzentrierte Analyse« zusammenfassen; darauf basierend erfolgt die »benutzerzentrierte Gestaltung«; den Abschluss einer Iteration bildet die »benutzerzentrierte Evaluation«.

Warum überhaupt analysieren?

Eine Websites und Web-Anwendungen kann nur dann erfolgreich sein, wenn von Beginn an klar ist, welches Problem sie eigentlich lösen soll, und wenn jede einzelne Anforderung aus der Sicht des Nutzers begründet ist. Sonst kommt es zu fehlenden oder überflüssigen Funktionen, wodurch Nutzer vergrault (und die Kosten gesteigert) werden und das Projekt scheitert. Das wurde in der Vergangenheit durch zahlreiche Beispiele bestätigt, besonders drastisch beispielsweise bei der Ablösung AltaVistas durch Google.

AltaVista war bis ins Jahr 1999 neben HotBot die bekannteste Volltext-Suchmaschine der Welt. Ende der 1990er veränderte AltaVista seine strategische Ausrichtung und entwickelte sich von einer Suchmaschine zu einem Portal mit Nachrichten, E-Mail und Einkaufsangeboten (siehe Abbildung 2). AltaVista versuchte damit, mit Yahoo! zu konkurrieren, war damit aber nahezu erfolglos. Im Suchmaschinenmarkt wurde AltaVista währenddessen ziemlich schnell von Google überholt. Das lag vor allem daran, dass Google sich konsequent auf die primären Anforderungen der Nutzer ausgerichtet hatte: Das User Interface beschränkte sich auf Wesentliche, nämlich das Suchfeld und die Anzeige der Suchergebnisse. Bei den damals noch üblichen langsamen Internet-Verbindungen brachte das den Suchmaschinennutzern erhebliche Vorteile. AltaVista wurde nach mehreren Übernahmen von Yahoo! gekauft und verlor bis zu seiner Schließung im Juli dieses Jahres mehr und mehr an Bedeutung. Google hingegen gehört seit Jahren zu den wertvollsten Marken der Welt.

Das 1999er User Interface von AltaVista und Google im Vergleich
Abbildung 2: AltaVista und Google 1999 (Quelle: archive.org)

Anforderungen konsequent aus der Perspektive der Benutzer zu berücksichtigen, ist die zentrale Grundlage erfolgreicher Projekte und kann entscheidend sein für den Erfolg eines gesamten Unternehmens. Der Ansatz der benutzerzentrierten Analyse stellt sicher, dass diese sogenannten Nutzungsanforderungen systematisch ermittelt, dokumentiert, geprüft und verwaltet werden.

Den Nutzungskontext verstehen und beschreiben

Wer die oben genannte Definition von Usability verinnerlicht hat, wird aufhorchen, wenn er Aussagen hört wie »Die Usability dieser Anwendung ist schlecht« und sich fragen: Schlecht für wen? Schlecht unter welchen Rahmenbedingungen? Oder mit den Worten eines Usability Engineers: Schlecht für welchen Nutzungskontext?

Der Nutzungskontext eines interaktiven Systems wird beschrieben durch die Benutzer, deren Aufgaben und Arbeitsmittel (Hardware, Software und Materialien) sowie die Umgebung, in der sie mit dem interaktiven System arbeiten (ISO 9241-11), siehe Abbildung 3.

Elemente des Nutzungskontexts: Benutzer, Aufgaben, Arbeitsmittel, Umgebung
Abbildung 3: Elemente des Nutzungskontexts eines interaktiven Systems

Was bedeutet das genau, beispielsweise für eine Web-Anwendung zur Erstellung von Terminumfragen wie Doodle?

  • Benutzer sind Personen, die eine Umfrage erstellen oder daran teilnehmen wollen. Zumindest der ersten Gruppe lässt sich eine gewisse IT- bzw. Online-Affinität unterstellen.
  • Ziele und Arbeitsaufgaben: Eine Umfrage erstellen und andere dazu einladen; an einer Umfrage teilnehmen; Umfrageergebnisse einsehen.
  • Arbeitsmittel sind primär ein Webbrowser und ein Gerät, auf dem dieser läuft, beispielsweise ein Notebook oder ein Smartphone. Arbeitsmittel sind aber auch ein Kalender und ein Adressbuch.
  • Über die Umgebung lässt sich am wenigsten sagen. Termine werden überall vereinbart, daher ist ein mobiler Kontext, vielleicht unter widrigen Sicht- und akustischen Bedingungen, genauso wahrscheinlich wie eine Nutzung im Büro auf einem 24-Zoll-Display.

Klingt diese Nutzungskontextbeschreibung überzeugend? Sie wurde wohlüberlegt und gewissenhaft verfasst. Aus Sicht eines Usability Engineers ist sie dennoch wertlos – sie basiert vollständig auf Annahmen und ist ohne Benutzerbeteiligung entstanden.

Bei überschaubaren Websites und Web-Anwendungen mit bekannter Aufgabenstellung, reicht es aus, die Beschreibung des Nutzungskontexts mit echten Benutzern zu diskutieren und zu validieren. Beispielsweise bei der Website des örtlichen Zahnarztes oder eben einem Online-Terminfinder. Bei komplexen interaktiven Systemen hingegen oder solchen, die Arbeitsaufgaben einer unbekannten Fachdomäne abbilden, ist es unabdingbar, Interviews mit Benutzern zu führen und zu dokumentieren. Folgende Leitfragen können dabei zur Orientierung dienen:

  • Welche Aufgaben führen Sie mit dem System durch?
  • Wie häufig fallen die einzelnen Aufgaben an? Welche führen Sie häufig durch, welche eher selten?
  • Gibt es eine bestimmte Reihenfolge, in der Sie die Aufgaben abarbeiten?
  • Sind zur Lösung von Aufgaben Dialogschritte oder Eingaben notwendig, die Sie eigentlich nicht benötigen?
  • Wo kann etwas schief gehen? Wie bemerken Sie das?
  • Arbeiten Sie mit jemandem über das System zusammen? Wie läuft die Zusammenarbeit ab?
  • Macht Ihnen die Nutzung des Systems Spaß?
  • Welche besonderen Stärken hat die derzeitige Lösung?
  • Welche besonderen Schwächen hat die derzeitige Lösung?

Das Ziel ist es, zusammen mit den beteiligten Benutzern ein gemeinsames Verständnis des Kontexts und der Aufgaben zu entwickeln und darin deren Erfordernisse zu erkennen.

Nutzungsanforderungen spezifizieren

Erfordernisse beschreiben, welches Ziel ein Benutzer erreichen will und welche Voraussetzung dafür erfüllt sein muss. Sie sind aus der Sicht des Nutzers und vollkommen systemneutral formuliert, das heißt sie geben keine technischen Details vor.

Einige Erfordernisse sind offensichtlich und ergeben sich direkt aus der Aufgabe, beispielsweise das folgende Erfordernis für das Beispiel »Online-Terminfinder«:

»Ein Teilnehmer einer Terminumfrage (Benutzer) muss wissen, welche Termine angeboten werden (Voraussetzung), um bei der Teilnahme an der Umfrage (Nutzungskontext) eine Auswahl treffen zu können (Ziel).«

Andere Erfordernisse ergeben sich erst dann, wenn der Usability Engineer genau zuhört, wenn Nutzer erzählen, was sie tun oder worauf sie achten, wenn sie ihrer Arbeitsaufgabe nachgehen, und wenn er gezielt nachfragt. Beispiele dafür könnten sein:

»Ein Ersteller einer Terminumfrage muss einsehen können, welche Personen der Einladung zwar gefolgt sind, aber noch keine Angaben gemacht haben, um explizit nachfragen zu können, ob diese kein Interesse an der Veranstaltung generell oder nur an keinem Termin Zeit haben.«

»Ein Teilnehmer einer Terminumfrage muss wissen, welche Termine welche anderen Teilnehmer angegeben haben, um bei der Teilnahme an der Umfrage die Termine angeben zu können, die bevorzugte Personen ebenfalls gewählt haben.«

Alle erkannten Erfordernisse werden in einem Bericht gesammelt, der dem nächsten Schritt zugrunde liegt, der Spezifikation der Nutzungsanforderungen.

Nutzungsanforderungen beschreiben eine erforderliche Leistung oder Aktion eines Benutzers während er eine Aufgabe an einem interaktiven System durchführt. Aus dem ersten Erfordernis des oben genannten Beispiels lassen sich zwei Nutzungsanforderungen ableiten:

»Der Nutzer muss am System erkennen können, welche Termine angeboten werden.«

»Der Nutzer muss am System die Termine auswählen können, an denen er teilnehmen will.«

Die folgenden (zusätzlichen) Nutzungsanforderungen ergeben sich aus den beiden nächsten Erfordernissen:

»Der Nutzer muss am System erkennen können, welche Personen der Einladung bereits gefolgt sind.«

»Der Nutzer muss am System die bisherigen Umfrageergebnisse detailliert einsehen können, also welcher Teilnehmer welche Termine angegeben hat.«

»Der Nutzer muss am System die bisherigen Umfrageergebnisse einsehen können, bevor er selbst an der Umfrage teilnimmt.«

Je nach Größe und Komplexität des interaktiven Systems umfasst eine Nutzungsanforderungsspezifikation eine Handvoll bis viele Hundert Nutzungsanforderungen. Aus Nutzersicht ist das System damit vollständig beschrieben. Die Phase der benutzerzentrierten Analyse ist abgeschlossen.

Was man nun damit anfängt, verrät morgen der zweite Teil dieses Artikels, der zeigt, wie ihr benutzerzentrierte Analysen in der Praxis anwenden könnt.

Literatur und Quellen

Michael Jendryschik

Durch die Brille des Nutzers II

$
0
0
Usability-Experte bespricht Wireframes einer Website mit KundinUsability Engineering: Benutzerzentrierte Analysen in der Praxis

Die benutzerzentrierte Analyse hilft dabei, Websites und Web-Anwendungen so zu gestalten, dass sie nützlich und effizient sind. Die notwendigen Informationen werden über Interviews mit den Benutzern erhoben – das kann aufwendig sein. Für gewöhnliche Websites genügt es, auf eigene Erfahrungen zurückzugreifen, diese sollten aber vernünftig erfasst und hin und wieder mit echten Nutzern abgeglichen werden.

Nutzungsanforderungen bilden die Grundlage für die Gestaltung

In den ersten beiden Phasen des benutzerzentrierten Gestaltungsprozesses (Abbildung 1) geht es darum, den Nutzungskontext zu beschreiben und Nutzungsanforderungen zu spezifizieren. In der dritten Phase werden darauf basierend Lösungen entworfen. Dabei finden im Wesentlichen zwei Aktivitäten statt: das Interaktionsdesign sowie die Gestaltung des User Interfaces.

Benutzerzentrierter Gestaltungsprozess: Nutzungskontext verstehen und beschreiben, Nutzungsanforderungen spezifizieren, Gestaltungslösungen entwickeln, Produkt evaluieren
Abbildung 1: Benutzerzentrierter Gestaltungsprozess (nach ISO 9241-210)
Das Interaktionsdesign beschreibt das Zusammenspiel zwischen den Eingaben des Nutzers und den Ausgaben des Systems, während der Nutzer mit dem System arbeitet, um seine Aufgaben zu erledigen. Das User Interface wiederum besteht nach ISO 9241-210 aus allen Bestandteilen eines interaktiven Systems, die Informationen und Steuerelemente zur Verfügung stellen, die der Benutzer benötigt, um seine Aufgaben mit dem interaktiven System zu erledigen. Das bedeutet, dass alle Elemente, die er dafür nicht benötigt, im User Interface nichts zu suchen haben.

Letztlich dreht sich auch hier wieder alles um den Benutzer und seine Aufgaben. Beides gehört zum Nutzungskontext und findet sich in den Erfordernissen und Nutzungsanforderungen wieder, die dem Designer damit klar vorgeben, was sie zu gestalten haben (und was nicht).

Auf der anderen Seite lassen Nutzungsanforderungen Designern aufgrund der Art, wie sie formuliert sind, auch viele Freiheiten. Sie beschreiben zwar, wie ein Nutzer mit einem System interagiert, implizieren aber keine Lösung. Folgende Gegenüberstellung macht den Unterschied deutlich:

»Der Nutzer muss über das System Kontakt zu einem Ansprechpartner aufnehmen können.«

»Das System muss dem Nutzer ein Kontaktformular bereitstellen, das in einem Popup-Fenster eingeblendet wird.«

Die erste Formulierung ist eine Nutzungsanforderung. Sie macht dem Designer keine Vorgaben und überlässt es ihm, die Steuerelemente und Informationen auszuwählen und anzubieten, die aus seiner Sicht die Aufgabenerfüllung bestmöglich unterstützen. Die zweite Formulierung ist eine Systemanforderung und beschreibt bereits eine konkrete Lösung, aber sicherlich nicht die beste. Im mobilen Kontext wäre vielleicht eine Telefonnummer wünschenswert, aber die konkret formulierte Anforderung bietet keinen Raum für eine derartige Idee.

Anwendbarkeit der benutzerzentrierten Analyse in der Praxis

Interviews mit Benutzern führen, den Nutzungskontext beschreiben, Erfordernisse erkennen und dokumentieren – das alles, um zu einer möglichst vollständigen Spezifikation der Nutzungsanforderungen zu gelangen? In welchen Projekten lässt sich das wirtschaftlich durchführen? Lohnt sich der Aufwand bei einer Website, über die der örtliche Zahnarzt auf sein Angebot aufmerksam machen möchte, oder über die eine Ferienwohnung präsentiert und zur Reservierung angeboten werden soll? Ist es sinnvoll, Nutzungsanforderungen zu spezifizieren, wenn es darum geht, kleine Web-Anwendungen zu entwickeln wie beispielsweise ein einfaches Tool zur Arbeitszeiterfassung oder einen Online-Terminfinder? Die Antwort lautet in allen Fällen: Ja! Man muss nur pragmatisch vorgehen.

Bei den gerade genannten Beispielen gehört vermutlich jeder Webworker selbst zur Gruppe der potenziellen Nutzer und kann daher auf Basis der eigenen Erfahrungen und Erfordernisse versuchen, den Nutzungskontext zu beschreiben. Daraus ergibt sich ein erster Satz von Nutzungsanforderungen, der allerdings noch mit Vorsicht zu genießen ist. Die Annahmen müssen validiert und gegebenenfalls korrigiert und ergänzt werden.

Der Auftraggeber eignet sich dafür im Allgemeinen nicht. Häufig gehört er selbst zu keiner (echten) Benutzergruppe des Systems oder ist fachlich vorbelastet. Ein Zahnarzt besucht die Website eines anderen Zahnarztes aus ganz anderen Gründen als Personen mit Zahnschmerzen auf der Suche nach Hilfe und einem Termin.

Auch der Blick auf vergleichbare Websites und Anwendungen ist nicht hilfreich, denn was dort zu sehen ist, sind Lösungen. In der Analyse sucht man aber nach Problemen (Arbeitsaufgaben) und den tatsächlichen Anforderungen der Nutzer. Was lässt sich beispielsweise daraus schließen, wenn auf vier von fünf analysierten Ferienwohnungen-Websites eine Anzeige des örtlichen Wetters zu sehen ist? Braucht man das? Warum? Anderes gefragt: Gibt es dafür ein Erfordernis? »Der Besucher der Website muss wissen, wie das aktuelle Wetter am Ort der Ferienwohnung ist, um« – tja, um was? Vermutlich gibt es dafür kein Erfordernis und diese Funktion ist unnötig.

Die einzige Möglichkeit, Annahmen zu validieren, bieten Interviews mit anderen (potenziellen) Benutzern. An die ist relativ einfach heranzukommen, wenn das Ziel der Website oder Web-Anwendung allgemeinverständlich ist. Vermutlich eignet sich fast jeder. Am Beispiel der Ferienwohnung-Website reichen zwei Fragen, um herauszufinden, ob jemand zur avisierten Benutzergruppe gehört oder nicht: »Machen Sie Urlaub in Ferienwohnungen? Würden Sie eine Ferienwohnung über das Internet reservieren?« Wer diese beiden Fragen mit »Ja« beantwortet, gehört dazu und eignet sich für eine Befragung (die zudem vermutlich nicht lange dauert). Häufig kommt bereits nach zwei oder drei Gesprächen nichts Neues mehr. Wenn es mehr als eine Benutzergruppe gibt, beispielsweise Ersteller von Terminumfragen und Teilnehmer an Terminumfragen, dann sind entsprechend mehr Interviews notwendig.

Auf diese Weise können Webworker die Annahmen, die sie beim ersten Entwurf der Nutzungskontextbeschreibung getroffen haben, bestätigen oder widerlegen sowie durch neue Erkenntnisse ergänzen. Als Ergebnis erhalten sie eine vollständige und validierte Nutzungskontextbeschreibung und damit

  • Informationen über die (verschiedenen) Benutzer des interaktiven Systems sowie
  • deren Ziele, Arbeitsaufgaben und Aufgabenabfolgen und somit eine Beschreibung des Zwecks des Systems;
  • für jede Nutzungsanforderung eine Begründung aus Benutzersicht in Form eines oder mehrerer Erfordernisse und dadurch Hinweise darauf, welche Funktionen unnötig komplex oder gar überflüssig sind;
  • Informationen über die Rahmenbedingungen, unter denen das System eingesetzt wird;
  • eine Grundlage für die weiteren Arbeitsschritte im Projektverlauf, vor allem in Bezug auf die Gestaltung;
  • eine Basis für Inspektionsverfahren in der Phase der benutzerzentrierten Evaluation (dabei dient die Liste der Nutzungsanforderungen als Checkliste, anhand der überprüft wird, ob das System effektiv ist, also alle Nutzungsanforderungen erfüllt);
  • eine professionelle Basis für die Angebotserstellung gegenüber den Kunden sowie – last but noch least –
  • eine Grundlage für die benutzerzentrierte Analyse bei folgenden, ähnlichen Projekten.

Und dafür lohnt es sich doch, ein wenig Zeit bei Gesprächen mit seinen Nutzern zu verbringen, oder?

Literatur und Quellen

Michael Jendryschik

Der Workflow lernt fliegen

$
0
0
das Bower Logo, ein VogelBower Package Manager

Ein neues Projekt steht an. Für die Web-Applikation wird Modernizr, jQuery, normalize.css und Handlebars sowie das jQuery Plugin lazyload benötigt. Die Komponenten sucht sich der Frontendler auf den einzelnen Webseiten oder Github zusammen und lädt die neusten Versionen in den Projektordner. Eine nach der anderen, so wurde das früher gemacht. Heute gibt es Bower, ein Open-Source-Projekt von Twitter. Und Bower macht das mit nur einem Befehl im Terminal. bower install...

Das Stichwort heißt Package Management in Verbindung mit der Workflow-Optimierung eines Frontendlers. Und vielleicht auch noch Spaß-mit-der-Konsole. Auf jeden Fall lohnt sich ein Blick auf das neue Tool, das von den internationalen Stars der Szene so eifrig angepriesen wird. Und nicht ohne Grund.

das Bower-Logo. Ein Vogel.
Das Logo von Bower

I've got the Bower

Bower? Bower ist Englisch und bedeutet Vogelkäfig oder Gartenlaube. Das Logo zeigt einen Vogel mit einem Blatt im Schnabel und soll wohl die einfache Handhabung zum Ausdruck bringen. Und relativ einfach funktioniert es auch, aber zuerst wird Bower benötigt.

Bower läuft mit node.js und dem Node Package Manager, kurz npm, sowie Git. Also muss zuerst node.js von der Homepage installiert werden und das bringt den Package Manager npm direkt mit. Über das Terminal, die Konsole, die Shell oder die Eingabeaufforderung (je nach OS) wird Bower danach installiert. Mit folgender Eingabe:

  1. npm install –g bower

npm aktiviert den Node Package Manager. Install –g bower installiert dann global, also auf dem Rechner und nicht nur in einem definierten Ordner, den Bower Package Manager.

Da Bower die angeforderten Packages ausschließlich über Github bezieht, muss vor dem ersten Einsatz unbedingt noch Git auf dem Rechner installiert werden. Achtung bei Windows, hier bei der Installation unbedingt darauf achten, dass Git auf der Windows Command Prompt, also der Eingabeaufforderung angewendet werden kann.
Soviel zu den Vorbereitungen.

Die Arbeit mit der Konsole

Bower kann auf drei verschiedene Arten eingesetzt werden: Mit einer Direktaufforderung über das Terminal, durch Aufruf der Konfigurationsdateien im Repository oder über die programmatische API.

Über die Eingabeaufforderung springt der Developer zu einem leeren Ordner. Das geht über den Befehl cd (change directory) und der Eingabe des Pfads zum Ordner. Oder in Windows viel einfacher über die Adressleiste des Explorers, mit der Eingabe cmd. Mit dem Befehl bower install jquery in der Konsole kopiert Bower dann die neuste jQuery-Version (bis dato Version 2.0.3) von Github, erzeugt im referenzierten Verzeichnis automatisch einen neuen Ordner namens »bower_components« und legt in diesem wiederum den Ordner »jquery« mit allen integrierten Dateien ab. Das sieht dann so aus:

bower install in der Konsole und der erzeugte Ordner
bower install jquery – links die Ausgabe der Konsole, rechts der erzeugte Ordner mit Inhalt

Neben dem gewünschten Package kann auch explizit eine Versionsnummer angegeben werden. Also im Fall von jQuery z. B. bower install jquery#1.10.2. Aber die Direkteingabe kann noch ein bisschen mehr. Mit bower search werden alle registrierten Packages für Bower aufgelistet und mit bower uninstall jquery lokal installierte Packages (in diesem Beispiel jQuery) wieder deinstalliert. bower update jquery aktualisiert zur neusten Version von jQuery.

Eine sehr hilfreiche Aufforderung ist bower init, mit der sich eine bower.json-Konfigurationsdatei Schritt für Schritt auf Grundlage des vorhandenen Repositorys manuell über die Konsole erstellen lässt. Der Codeblock etwas weiter unten zeigt welche Properties über bower init abgefragt werden.

Auf ein besonderes Feature, bower register für das Registrieren von eigens hergestellten Packages für Bower, gehe ich am Ende des Artikels noch einmal kurz ein, denn dazu wird zuerst eine Konfigurationsdatei gebraucht.

Die Konfiguration von Bower

Die Integration vom Bower-Package-Manager, z. B. in ein Boilerplate, läuft über die Konfiguration mit bower.json und der .bowerrc-Datei.

Alle Packages, die für ein Projekt benötigt werden, werden in einem JSON-File mit dem Dateinamen bower im Repository vorkonfiguriert. Das erspart die doch recht mühselige Einzel-Installation über die Konsole. Die bower.json-Datei setzt sich folgendermaßen zusammen:

  1. {
  2. "name" : "Mein Packagename",
  3. "version" : "Meine Packageversion, z. B. 1.0.0",
  4. "authors" : [
  5. "Autor 01 <autor01@email.de>"
  6. ],
  7. "description" : "Beschreibung des Packages",
  8. "keywords" : [
  9. "Suchbegriff 01",
  10. "Suchbegriff 02"
  11. ],
  12. "license" : "Lizenzangabe, z. B. MIT",
  13. "homepage" : "Homepage zum Package, falls vorhanden",
  14. "private" : Nur für den privaten gebrauch? true oder false,
  15. "ignore" : [
  16. "**/.*",
  17. "Datei, die nicht mitgepackt werden soll 01",
  18. "Datei, die nicht mitgepackt werden soll 02..."
  19. ],
  20. "dependencies" : {
  21. "Package, das benötigt wird 01" : "Versionsnummer",
  22. "Package, das benötigt wird 02" : "Versionsnummer",
  23. "Package, das benötigt wird 03" : "Versionsnummer",
  24. },
  25. "devDependencies" : {
  26. "Datei, die nur zur Entwicklung des Packages benötigt wird 01" : "Versionsnummer",
  27. "Datei, die nur zur Entwicklung des Packages benötigt wird 02" : "Versionsnummer",
  28. "Datei, die nur zur Entwicklung des Packages benötigt wird 03" : "Versionsnummer"
  29. }
  30. }

bower.json mit allen relevanten Properties

Diese Konfiguration kann zum einen zur Registrierung eines Packages und aller benötigten Dateien (den Dependencies) für Bower auf Github dienen, zum anderen aber auch um benötigte Packages lokal zu installieren. Das klingt jetzt etwas verwirrend, aber es ist eigentlich recht simpel. Mal angenommen der Webworker möchte sein eigenes Boilerplate erstellen. Das Boilerplate soll als Repository auf Github abgelegt werden, und jedes Mal, wenn er ein Projekt startet, lädt er dieses Boilerpate von Github herunter und alle benötigten Packages werden vor Projektbeginn wie oben beschrieben automatisiert installiert. Dazu benötigt er also eine Datei wie die oben gezeigte. Hier die Beschreibung der einzelnen Properties und ihre Funktion:

  • Unter name wird der Namen des Packages vergeben.
  • version zeigt die Versionsnummer an.
  • Mit authors werden alle Autoren des Packages in einem Array aufgelistet.
  • description beschreibt das Package, also was macht es und wofür ist es da.
  • Das Array keywords sorgt für eine bessere Auffindbarkeit durch definierte Suchbegriffe.
  • Es kann eine Lizenz für den Gebrauch des packages unter license deklariert werden.
  • Unter homepage wird eine Internetseite zum Package angegeben, wenn vorhanden.
  • private sorgt dafür, dass das Package in die offizielle Registrierung für Bower aufgenommen wird oder auch nicht.
  • Mit ignore können Dateien innerhalb des Package-Ordners deklariert werden, die nicht mit geladen werden sollen.
  • dependencies spielt eine herausragende Rolle, denn hier werden die Packages aufgeführt, die heruntergeladen werden müssen, damit das Projekt bzw. Package funktioniert.
  • Und devDependencies schließlich beinhaltet die Dateien, die nur für die Entwicklung, nicht die Anwendung bzw. Ausführung des Packages benötigt werden (das können z. B. Dokumentationen oder Logfiles sein).

Will der Developer lediglich die in der Konfigurationsdatei aufgeführten Dependencies lokal installieren, also ohne Registrierung, reicht eine Datei wie die folgende aus:

  1. {
  2. "name" : "Mein Packagename",
  3. "version" : "Meine Packageversion, z. B. 1.0.0",
  4. "main" : "Mein Pfad zur Hauptdatei des Packages",
  5. "ignore" : [
  6. "Datei, die nicht mitgepackt werden soll 01",
  7. "Datei, die nicht mitgepackt werden soll 02..."
  8. ],
  9. "dependencies" : {
  10. "Package, das benötigt wird 01" : "Versionsnummer",
  11. "Package, das benötigt wird 02" : "Versionsnummer",
  12. "Package, das benötigt wird 03" : "Versionsnummer",
  13. },
  14. "devDependencies" : {
  15. "Datei, die nur zur Entwicklung des Packages benötigt wird 01" : "Versionsnummer",
  16. "Datei, die nur zur Entwicklung des Packages benötigt wird 02" : "Versionsnummer",
  17. "Datei, die nur zur Entwicklung des Packages benötigt wird 03" : "Versionsnummer"
  18. }
  19. }

bower.json nur zur Installation

Die zweite Konfigurationsdatei im Repo neben der bower.json ist dann die .bowerrc. Diese liegt im selben Verzeichnis wie die bower.json und sorgt dafür, dass die Dependencies in einen unter directory definierten Ordner geladen werden. Diese Datei ist optional – wenn sie nicht vorhanden ist wird einfach wieder ein neuer Ordner namens bower_components erstellt. Auch in dieser Datei wird mit einem JSON-Objekt gearbeitet und das sieht so aus:

  1. {
  2. "directory" : "[Pfad zum Ordner, in dem das Package landen soll]",
  3. "json" : "[Die Konfigurationsdatei, per Default bower.json"
  4. }

.bowerrc

Um die Dateien aufzurufen genügt es, über die Konsole den Pfad zum Repository anzuwählen und den Befehl bower install einzugeben. Bower führt dann automatisch die konfigurierten Aktionen aus.

Ein eigenes Package für Bower registrieren

Die Packages, die über Bower installiert werden können, sollten vorher vom Webworker für diesen Zweck registriert werden. Somit werden sie bei den Bower components veröffentlicht, eine Auflistung von Git-Endpoints. Die Registrierung geschieht in der Datei wie oben bereits beschrieben oder über die Konsole mit folgendem Befehl:

  1. bower register <Package name> <Git-Endpoint>

Git-Endpoint steht dabei für die URL, die auf das Github-Repository des Packages verweist.

Die programmatische API

Auf die programmatische API von Bower soll an dieser Stelle nur mal kurz eingegangen werden. Sie kann sich als recht nützlich erweisen, wenn der Package Manager mit einem Task Runner wie z. B. Grunt verknüpft werden soll. Bower stellt dafür das bower.commands Objekt zur Verfügung, das folgendermaßen aufgebaut werden kann:

  1. var bower = require('bower');
  2.  
  3. bower.commands
  4. .install(paths, options)
  5. .on('end', function(data){
  6. data && console.log(data);
  7. });

Beispielsnippet für die API

bower.commands kennt vier Events, die ein Callback zulassen, nämlich log, prompt, error und end. Um die Wichtigsten zu nennen, error reagiert auf eine Fehlermeldung während der Installation und end wird nach der Fertigstellung gefeuert.

Fazit

Das war nur ein kurzer Ausflug in die Welt von Bower. Ich nutze den Package Manager seit einiger Zeit in meinen Projekten und möchte ihn nicht mehr missen. In Tateinheit mit Grunt und anderen Tools auf Basis von node.js und npm wird der tägliche Workflow extrem beschleunigt und vereinfacht. Dadurch gewinne ich mehr Zeit für das Wesentliche. Den Code.

Links zum Thema

Henry Zeitler

Zeile für Zeile

$
0
0
Zeilenweise BuntstifteSyntax-Highlighter

Wer als Webworker für Online-Magazine oder sein eigenes Blog schreibt, wird früher oder später auch Code-Beispiele bringen. Der Quelltext ließe sich schlicht mit code und pre auszeichnen. Heutzutage darf sich ein Autor aber durchaus die Mühe machen, seinen Code etwas sinnvoller zu präsentieren – zum Beispiel mit Syntax Highlighting.

Als wir hier auf webkrauts.de die ersten Artikel veröffentlicht haben, sahen die Code-Beispiele im Quellcode noch so aus:

  1. <pclass="bsp">
  2.   <code><br />
  3.   <spanstyle="color: #a00">&lt;div id="wrap"></span><br />
  4.   &nbsp;&nbsp;&nbsp;&nbsp;&lt;div id="identitaet">...&lt;/div><br />
  5.   <spanstyle="color: #a00">&nbsp;&nbsp;&nbsp;&nbsp;&lt;div id="hauptbereich"></span><br />
  6.   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div id="inhalt">...&lt;/div><br />
  7.   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div id="navigation">...&lt;/div><br />
  8.   <spanstyle="color: #a00">&nbsp;&nbsp;&nbsp;&nbsp;&lt;/div></span><br />
  9.   &nbsp;&nbsp;&nbsp;&nbsp;&lt;div id="extra">...&lt;/div><br />
  10.   &nbsp;&nbsp;&nbsp;&nbsp;&lt;div id="rechtliches">...&lt;/div><br />
  11.   <spanstyle="color: #a00">&lt;/div></span><br />
  12.   </code>
  13. </p>

Offensichtlich haben wir damals <pre> nicht genutzt, sondern die Zeilen per &nbsp; eingerückt. Wichtige Stellen wurden per <spanstyle="color: #a00"> eingefärbt (weil ein Autor Inline-Styles benutzen, aber nicht am CSS rumwerkeln durfte). Und natürlich mussten wir ein <div> als &lt;div&gt; oder zumindest &lt;div> schreiben, damit es richtig als Code dargestellt wurde. Das können wir heute belächeln oder den Kopf schütteln – aber hey, es war 2005.

Code-Beispiele auf anderen Websites

Acht Jahre später sieht die Sache schon anders aus. Sowohl Autoren als auch Leser können mehr von Code-Beispielen erwarten. Das beginnt mit einem passenden Syntax Highlighting. Dabei werden bestimmte Elemente eines Codes anders dargestellt – eben die Syntax hervorgehoben. In dem Beispiel oben sind etwa die HTML-Tags fett dargestellt, Werte für die Attribute erscheinen in rot, HTML-Entitäten in ocker. Das ist meist hilfreich, um die einzelnen Elemente einer Sprache schneller zu erfassen. Was noch möglich ist, zeigt ein Blick auf die Code-Beispiele von anderen Websites.

Syntax Highlighting mit JavaScript

Syntax Highlighting auf Smashing Magazine mit Prism
Syntax Highlighting auf Smashing Magazine mit Prism

Beim Smashing Magazine ist für das Syntax Highlighting die JavaScript-Bibliothek Prism von Lea Verou zuständig, die zum Beispiel auch A List Apart oder webplatform.org nutzen. Längere Code-Zeilen werden hier einfach umbrochen. Ohne JavaScript fällt das Highlighting weg, das Beispiel sieht dann so aus:

Das Beispiel von Smashing Magazine ohne JavaScript
Das Beispiel von Smashing Magazine ohne JavaScript

Zeilennummern

Die Website A Beginner’s Guide to HTML & CSS bietet Einsteiger-Kurse für HTML und CSS. Ein orangener Hinweis oben rechts zeigt deutlich das Thema an. Der Hinweis wird per CSS ausgeblendet, sobald ein Benutzer mit der Maus über dem Code hovert. Zusätzlich gibt es hier eine Zeilennummerierung. Das ist für Code-Beispiele recht hilfreich, weil sich der Autor bei längeren Beispielen einfach im Artikel auf eine Zeile beziehen kann.

Syntax Highlighting auf A Beginner’s Guide to HTML
Syntax Highlighting auf A Beginner’s Guide to HTML

Im Einsatz ist hier eine aufgehübschte Version von Prettify, einer weiteren JavaScript-Bibliothek. Ohne JavaScript sieht der Code so aus:

Das Beispiel von A Beginner’s Guide to HTML ohne JavaScript
Das Beispiel von A Beginner’s Guide to HTML ohne JavaScript

Kleiner Exkurs: Welches HTML-Konstrukt ist sinnvoll, um die Zeilennummern hinzuzufügen?

Am einfachsten wäre es, einfach eine Zahl an den Anfang jeder Zeile zu schreiben. Das hat den Nachteil, dass die Zahlen in jedem Fall bei Copy & Paste mitkopiert werden. Das ist wenig benutzerfreundlich, weil der Nutzer die Zeilennummern per Hand wieder entfernen müsste.

Auf jquery.com wird eine Tabelle um den Code gebaut. Eine Tabellenzelle (td) trägt alle Zeilennummern, die nächste Tabellenzelle den kompletten Code. Per Copy & Paste wird hier nur der Code kopiert. Allerdings würden einem Screenreader auch alle x Zeilennummern hintereinander vorgelesen, das kann nicht sinnvoll sein.

Die meisten Syntax Highlighter bauen eine nummerierte Liste um den Code. Damit lässt sich grundsätzlich arbeiten. Ein Copy & Paste in einen üblichen Texteditor wie Sublime Text kopiert auch hier nur den reinen Text.

Erfahrene Webworker werden sicher einen professionellen Editor bevorzugen. Bei Anfängern muss das nicht unbedingt der Fall sein. Falls jemand auf die Idee käme, sein HTML mit Word oder Open Office zu schreiben, würden bei Copy & Paste jede Mege unerwünschter Zusatzinfos kopiert. Das betrifft nicht nur die Zeilennummern, sondern auch Schriftfarben und andere Auszeichnungen.

Hervorgehobene Stellen

Auf HTML Dog wiederum gibt es zwar keine Zeilennummern, dafür sind wichtige Stellen im Code hervorgehoben.

Syntax Highlighting bei HTML Dog
Syntax Highlighting bei HTML Dog

In diesem Beispiel kommt dazu ein <em> zum Einsatz. Aus HTML5-Sicht wäre <mark> besser geeignet. Mit passendem CSS bleiben die hervorgehobenen Stellen so auch erhalten, wenn JavaScript ausgeschaltet ist:

Syntax Highlighting bei HTML Dog ohne JavaScript
Syntax Highlighting bei HTML Dog ohne JavaScript

Zu lange Zeilen

Was tun mit zu langen Codezeilen? In einem Editor gibt es keine Probleme mit zu langen Zeilen. Diese werden in der Regel automatisch sinnvoll umbrochen. In einem Artikel auf einer Webseite funktioniert das leider nicht so leicht. Genau genommen gibt es keine einzige gute Lösung. Es kommen einige Spielarten in Frage, die alle ihre Nachteile haben:

  • Ein overflow: hidden kommt nicht Frage; der komplette Code muss schließlich sichtbar sein.
  • Auf Smashing Magazine werden zu lange Zeilen per CSS mit word-wrap: break-word; umbrochen. Das sieht zunächst hübscher aus, hat aber den Nachteil, dass wichtige Elemente wie Attribute oder Eigenschaften mitten im Wort getrennt werden könnten.
  • Hier auf webkrauts.de nutzen wir overflow: auto;, was für einen Scrollbalken sorgt. Wörter werden zwar nicht irgendwo getrennt, dafür kann ein Leser nun ggf. nicht mehr alles auf einen Blick erfassen.
  • Möglich wäre, zu lange Zeilen künstlich in mehrere aufzuteilen. Aber wo genau endet eine Zeile? Bei einem fixen Layout mit Monospace-Schrift für den Code lässt sich vielleicht eine maximale Buchstabenanzahl pro Zeile festlegen. Aber bei einem responsive Design wird das nicht mehr funktionieren.

Einige Seiten wie zum Beispiel lullabot.com arbeiten mit einem Codeblock, der sich horizontal aufklappt, wenn ein Leser mit der Maus über den Block fährt. Das macht die Seite allerdings recht unruhig, und der Scrollbalken kommt trotzdem zum Einsatz.

Auf lullabot.com klappt die Code-Box bei einem Hover nach rechts aus
Auf lullabot.com klappt die Code-Box bei einem Hover nach rechts aus

Externe Dienste

Eine ganz andere Lösung wäre, die Code-Beispiele direkt auszulagern. Christian Heilmann macht das zum Beispiel in diesem Artikel, bei dem alle Beispiele direkt über jsFiddle eingebunden sind. Sieht hübsch aus und hat den klaren Vorteil, dass der Leser sofort selbst mit dem Code herumspielen könnte. Auf der anderen Seite: Sollte jsFiddle seine Dienste einmal einstellen, wären alle Beispiele weg. Das muss also jeder Autor für sich selbst abwägen. Falls der Dienst erst in ein paar Jahren webgbrechen sollte, ist es vielleicht egal, weil diese alten Artikel dann ohnehin nicht mehr auf dem aktuellen Stand der Technik wären.

Anforderungen und Wunschliste

All die Effekte und Auszeichnungen könnte ein Autor selbst in seinen Quellcode schreiben. Das bietet zwar die größtmögliche Kontrolle, ist aber nicht effektiv. Zum einen macht es viel mehr Arbeit, seine Code-Beispiele sinnvoll umzuwandeln. Zum anderen verändert sich das Web nun einmal. Ein paar Jahre später ist es vielleicht besser, seinen Code etwas anders auszuzeichnen. Und wer arbeitet daraufhin schon all seine alten Beispiele nach?

Es läuft daher auf eine Bibliothek hinaus, die den Quellcode im Hintergrund aufbereitet. Das kann auf zwei Arten passieren. Entweder wird der Code bereits auf dem Server vorbereitet oder per JavaScript im Browser umgewandelt. Soll es nicht noch dynamische Effekte geben, dürfte eine Vorbereitung auf dem Server effektiver sein: Der Webworker spart ein wenig JavaScript, der Code erscheint auch ohne JavaScript hübsch aufbereitet und lässt sich aus dem Cache des CMS bereits komplett ausliefern.

Je nach persönlichen Vorlieben kommen diese Anforderungen in Frage:

  • Die Bibliothek sollte alle benötigten Sprachen verstehen und highlighten können. Das sind für Webworker erst einmal HTML, CSS und JavaScript. Je nach Themengebiet des Autors kommen Sprachen wie XML, PHP, Ruby, Java, C++ etc. hinzu.
  • Das Tool sollte von den Machern weiterentwickelt werden. Für ein reines Highlighting reichen auch ältere Bibliotheken von 2008, aber auf Dauer will ein Autor sicherstellen, dass neuere Sprachen und Formate wie etwa SASS, LESS oder JSON auch vernünftig dargestellt werden.
  • Das Highlighting passiert ordentlich über Klassen und nicht über Inline-Styles.
  • Zeilen sollten optional nummeriert werden können. Es bietet sich an, den Code als nummerierte Liste darzustellen. Der generierte Code sollte in jedem Fall auch für Screenreader sinnvoll zu lesen sein.
  • Zeilen sollten per Klasse angesprochen werden können. Sinnvoll ist eine alternierende Klasse, um gerade und ungerade Zeilen farblich zu unterscheiden. Letzteres lässt sich bei modernen Browsern natürlich auch über den Pseudo-Selektor :nth-child() regeln.
  • Zusätzlich wäre vielleicht eine Syntax wünschenswert, mit der sich bestimmte Teile zusätzlich markieren lassen. Es müsste dann eine Syntax geben, die wahlweise per <mark> Code nochmals optisch hervorhebt oder aber <mark> als Text ausgibt, weil das HTML-Element selbst im Code-Beispiel vorkommt.
    Aber zum einen ist diese Option vielleicht etwas viel verlangt, zum anderen mögen Syntax Highlighting plus <mark> zusammen optisch zu unruhig wirken.
  • Nett wäre weiterhin die Option, eine Überschrift oder Unterzeile angeben zu können. Etwa »Listing 4: Das komplette Beispiel«. Das klappt aber auch mit einem entsprechend gestalteten Absatz vor oder nach dem Codeblock.
  • Und vorzugsweise generiert die Bibliothek validen Quellcode (siehe unten).

Mögliche Highlighter

Welcher Syntax Highlighter kommt nun in Frage? Das hängt von den eigenen Vorlieben ab: JS- oder PHP-Lösung? Unterstützte Sprachen? Vorhandene Themes? Alle Varianten sollte ein Webworker fix selbst einbauen können. In Kombination mit einem Content-Management-System macht man es sich meistens einfacher und nutzt die Bibliothek, die bereits als Modul/Plugin für das CMS vorhanden ist.

PHP

GeSHi - Generic Syntax Highlighter
Der Filter unterstützt stolze 112 Sprachen und Formate. Darunter natürlich HTML, CSS, JavaScript und PHP. Aber auch LaTeX, Perl, Python, Smarty, Ruby, Ruby on Rails, robots.txt und XML. Er bietet Zeilennummern an. Darüber hinaus lassen sich eingebaute Keywords direkt verlinken, um weitere Informationen zu erhalten. So würde etwa <span> auf december.com verlinken. Diese Seite ist in der aktuellen Form natürlich wenig hilfreich, aber die Idee ist gut.

Da der GeShi-Filter aktuell auf webkrauts.de über ein Drupal-Modul im Einsatz ist, zwei Tipps dazu:

  1. In der Grundeinstellung setzt GeShi einen <pre>-Wrapper um den Quellcode. Mit Zeilennummerierung erzeugt das ein <ol> innerhalb eines <pre>. Das ist laut Validator aber nicht erlaubt. In der Konfiguration lässt sich alternativ auch ein <div> als Wrapper oder kein Wrapper-Element einstellen – beide Optionen liefern validen Code.
  2. Damit der Filter zum Einsatz kommt, packt der Autor seinen Quellcode in einen Container. Dieser kann die Syntax <foo> ... </foo>, [foo] ... [/foo] oder [foo]] ... [[/foo]] haben. Statt »foo« wird die Sprache eingesetzt, etwa html, css, javascript oder php.
    Nutzt vorzugsweise nicht die Schreibweise <foo> ... </foo>. Das führt zu Problemen, wenn ihr mal ein <html> im Quellcode benutzen wollt, denn das feuert ja den Filter neu.

JavaScript

Prism
Der besagte Highlighter von Lea Verou, der unter anderem beim Smashing Magazin, A List Apart, WebPlatform.org und dem Mozilla Developer Network eingesetzt wird. Diese Namen reichen den meisten schon, um direkt diese Bibliothek zu wählen. Die Bibliothek kennt zunächst 21 Sprachen (darunter Markup, CoffeScript, SASS und SQL). Dabei werden auch ineinander verschachtelte Sprachen richtig ausgezeichnet (CSS in HTML, JavaScript in HTML). Wer will, kann selbst weitere Sprachen hinzufügen. Mit einem Plugin werden auch automatische Zeilennummer möglich. Unterstützt werden IE9+, Firefox, Chrome, Safari, Opera, sowie die meisten mobilen Browser.
highlight.js
Auch highlight.js hat einiges zu bieten. Es unterstützt 67 Sprachen – darunter auch JSON, SQL, XML, ActionScript, SCSS, Haml, Handlebars, Smalltalk. Dazu kommen stolze 32 Themes. Das Tool kann die Sprache automatisch ermitteln und highlighted auch verschiedene Sprachen im Code. Nach der Demo und den kurzen Doku zu urteilen, gibt es hier aber keine Zeilennummern. Außerdem fehlt eine Info zu den unterstützen Browsern.

Im Netz sind viele weitere JS-Highlighter zu finden. Zum Beispiel SyntaxHighlighter, Prettify, SHJS, Lighter oder Rainbow. Die meisten sind im Vergleich zu den beiden genannten nicht besonders gut dokumentiert, bieten deutlich weniger Funktionen und/oder wurden seit Jahren nicht aktualisiert.

Wer also auf der Suche nach einem Highlighter ist, dürfte mit einer der drei Bibliotheken – GeShi, Prism oder highlight.js – gut bedient sein.

Fazit

Vielleicht findet der ein oder andere hier die Inspiration, seine eigenen Code-Beispiele etwas aufzupeppen. Schließlich ist es nicht so schwer, eine der vorhandenen Bibliotheken einzubinden. Auch hier auf webkrauts.de können wir noch dieses oder jenes verbessern: Schriftart und -farben des Codes sehen auf anderen Seiten deutlich ansehnlicher aus. Und das Ocker ist auch nicht wirklich gut lesbar (schon gar nicht im Sinne der Barrierefreiheit). Da werden wir beizeiten nachbessern müssen.

Nicolai Schwarz

Drei unter einem Dach

$
0
0
Laptop mit TouchscreenPointer-Events für Maus, Stylus und Touchscreen

Um Interaktionen über einen Touchscreen zu berücksichtigen, müssen Entwickler oft separaten Code für Maus- und Touch-Events schreiben. Im Internet Explorer 10 wurde mit Pointer-Events ein komplett umgedachtes Modell eingeführt: Damit ist es möglich, Interaktionen über Maus, Stylus oder Touchscreen in einem Event zusammenzufassen.

Im letzjährigen Adventskalender gab es eine schnelle Einführung zu Touch-Events. Wie schon damals erwähnt, werden Touch-Events in fast allen modernen Browsern unterstützt… mit Ausnahme von Internet Explorer. Obwohl Microsoft lange Zeit auf Touch-fähigen mobilen und »Desktop«-Geräten präsent war, gab es anfangs keine Möglichkeit, Touchscreen-spezifisches JavaScript im Internet Explorer einzusetzen. Entwickler waren darauf angewiesen, auf (simulierte) Maus-Events zu reagieren.

Anstatt anderen Browsern nachzuziehen und auch Touch-Events (mit den damit verbundenen Problemen, die schon im Adventskalender-Artikel zum Thema kurz zusammengefasst wurden) einzusetzen, wurde im Internet Explorer 10 (in Windows Phone 8 und Windows 8/RT) mit Pointer-Events ein komplett umdachtes Modell eingeführt.

Vorteile von Pointer-Events im Vergleich zu Touch-Events

Touch-Events sind speziell auf Touchscreens ausgesetzt – Entwicklern müssen deshalb in vielen Fällen separaten Code für Maus- und Touch-Interaktionen schreiben.

  1. /* Pseudo-Code: zur Bearbeitung von Maus- und Finger-Bewegungen
  2.    benötigt im Touch-Event Modell separate Funktionen */
  3.  
  4. foo.addEventListener('mousemove', function(e){ ... }, false);
  5. foo.addEventListener('touchmove', function(e){ ... }, false);

Darüber hinaus müssen sich Entwickler noch mit einer Eigenheit von Touch-Events auseinandersetzen: die Koordinaten der verschiedenen Touch-Punkte sind bei Touch-Events nicht direkt im Event, sondern in separaten TouchList-Arrays untergebracht (siehe dazu die W3C Spezifikation zu TouchEvent und Touch). Im Endeffekt benötigen sie also separaten Code, um Maus- und Finger-Bewegungen in JavaScript zu bearbeiten.

  1. /* Pseudo-Code: Koordinaten in Maus- und Touch-Events */
  2.  
  3. foo.addEventListener('mousemove', function(e){
  4.     ...
  5.     /* Bei Maus-Events sind die Koordinaten
  6.        direkt im Event-Objekt vorhanden */
  7.     posX = e.clientX;
  8.     posY = e.clientY;
  9.     ...
  10. }, false);
  11.  
  12. foo.addEventListener('touchmove', function(e){
  13.     ...
  14.     /* Bei Touch-Events muss man mit
  15.        TouchList-Arrays arbeiten, selbst
  16.        wenn man nur einen einzigen Touch-Punkt
  17.        bearbeiten moechte */
  18.     posX = e.targetTouches[0].clientX;
  19.     posY = e.targetTouches[0].clientY;
  20.     ...
  21. }, false);

Pointer-Events bieten hingegen einen Abstraktionslayer, der alle möglichen Inputs (Maus, Touch, Stylus) in ein einheitliches Event-Modell unterbringt. Die neuen Events sind den traditionellen Maus-Events sehr ähnlich: pointerenter, pointerover, pointerdown, pointermove, pointerup, pointerout, pointerleave. Darüber hinaus gibt es im Pointer-Event-Modell noch einige spezielle Events – pointercancel, getpointercapture, lostpointercapture– auf die in dieser Einführung aber nicht weiter eingegangen wird.

Somit ermöglichen Pointer-Events, den Code relativ zu vereinfachen, indem Entwickler nur noch auf eine generelle Art von Events reagieren müssen:

  1. /* Pseudo-Code: zur Bearbeitung von Maus-, Finger- und Stylus-Bewegungen
  2.    brauchen im Pointer-Event Modell nur eine einzige Funktion */
  3.  
  4. foo.addEventListener('pointermove', function(e){ ... }, false);

Im Gegensatz zu Touch-Events, die ein komplett eigenes Event-Objekt haben, sind Pointer-Events an sich nur eine Erweiterung von klassischen Maus-Events. Jegliche Berührungspunkte (Finger oder Stylus auf einem Touchscreen) und Maus-Interaktionen generieren ein Event-Objekt, das alle normalen Maus-Events Properties beinhaltet (inklusive der individuellen Koordinaten-Paare). Dazu kommen weitere Properties, die den Events mehr Informationen zum Input mitliefern (siehe dazu die W3C Spezifikation zur PointerEvent interface). Somit ist es einfach, älteren Code – der speziell auf Maus-Events abgerichtet war – unmodifiziert auch für Pointer-Interaktionen einzusetzen. In den meisten Fällen reicht es aus, anstatt auf Maus-spezifische Ereignisse wie mousemove einfach den gleichen JavaScript bei pointermove auszuführen.

  1. /* Pseudo-Code: zur Bearbeitung von Maus-, Finger- und Stylus-Bewegungen
  2.    brauchen Entwickler im Pointer-Event-Modell nur eine einzige Funktion, und jeder
  3.    Pointer-Event enthält direkt die Koordinaten, genau wie bei Maus-Events */
  4.  
  5. foo.addEventListener('pointermove', function(e){
  6.  
  7.     /* "e" beinhaltet unter anderem die folgenden Properties:
  8.  
  9.         (traditionelle Maus-Events
  10.          http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-MouseEvent)
  11.         readonly attribute long             screenX;
  12.         readonly attribute long             screenY;
  13.         readonly attribute long             clientX;
  14.         readonly attribute long             clientY;
  15.         readonly attribute boolean          ctrlKey;
  16.         readonly attribute boolean          shiftKey;
  17.         readonly attribute boolean          altKey;
  18.         readonly attribute boolean          metaKey;
  19.         readonly attribute unsigned short   button;
  20.         readonly attribute EventTarget      relatedTarget;
  21.  
  22.         (Maus-Event Erweiterungen
  23.          http://www.w3.org/TR/cssom-view/#extensions-to-the-mouseevent-interface)
  24.         readonly attribute long             pageX;
  25.         readonly attribute long             pageY;
  26.         readonly attribute long             x;
  27.         readonly attribute long             y;
  28.         readonly attribute long             offsetX;
  29.         readonly attribute long             offsetY;
  30.  
  31.         (Pointer-Event-spezifische Erweiterungen
  32.          http://www.w3.org/TR/pointerevents/#pointerevent-interface)
  33.         readonly attribute long             pointerId;
  34.         readonly attribute long             width;
  35.         readonly attribute long             height;
  36.         readonly attribute float            pressure;
  37.         readonly attribute long             tiltX;
  38.         readonly attribute long             tiltY;
  39.         readonly attribute DOMString        <strong>pointerType</strong>;
  40.         readonly attribute boolean          <strong>isPrimary</strong>;
  41.     */
  42.     ...
  43.     posX = e.clientX;
  44.     posY = e.clientY;
  45.     ...
  46. }, false);

Falls eine Applikation trotzdem speziell auf verschiedene Inputs anders reagieren soll (um zum Beispiel ein Hover-Menu nur für Maus-User anzuzeigen), erlauben Pointer-Events, die Quelle/Art des Events mittels der pointerType Property abzufragen.

  1. /* Pseudo-Code: verschiedenen Code je nach pointerType ausführen */
  2. switch(e.pointerType){
  3.     case"mouse":
  4.         ...
  5.         break;
  6.     case"pen":
  7.         ...
  8.         break;
  9.     case"touch":
  10.         ...
  11.         break;
  12. }

Somit erlauben Pointer-Events einen »best of both worlds«-Ansatz: meistens ist es eigentlich egal, wie ein User mit einer Web-Applikation interagiert – ob ein Link oder Button per Maus oder Touch aktiviert wurde. Da in allen Fällen die gleichen Pointer-Events abgefeuert werden, ist es somit möglich, »Input-agnostischen« Code zu schreiben. Trotzdem können die verschiedene Input-Arten im Code differenziert werden.

»Feature detection« für Pointer-Events

Um festzustellen, ob ein Browser Pointer-Events unterstützt, reicht ein einfacher Feature-Detect:

  1. if(window.PointerEvent){
  2.     /* Browser mit Pointer-Events */
  3. }

Man beachte hier, dass Pointer-Events nicht nur für Touchscreens benutzt werden – selbst auf nicht-touch-fähigen Geräten können Pointer-Events benutzt werden, um auf traditionelle Maus/Trackpad-Inputs zu reagieren.

Pointer-Events definieren auch eine separate navigator.maxTouchPoints Property, die die (Hardware-bedingte) maximale Anzahl an Touch-spezifischen Berührungspunkte angibt. Um nun zu testen, ob der Browser auf einem Gerät mit Touch läuft, können Entwickler einen separaten Feature-Detect benutzen:

  1. if(navigator.maxTouchPoints> 0){
  2.     /* Browser auf einem Touch-fähigen Gerät */
  3. }

Grundlagen zur Bearbeitung von Pointer-Events

Wie schon bei der Abhandlung zu Touch-Events besprochen, sind Browser von Haus aus darauf ausgerichtet, existierende Webseiten so gut wie möglich auf Handys und Tablets darzustellen und benutzbar zu machen. Und da die meisten Seiten im Web immer noch auf Maus-Interaktionen ausgerichtet sind, werden selbst in Internet Explorer 10+ auch für Touchscreen-Interaktion traditionelle Maus-Events simuliert.

Beispiel 1 – Simulierte Maus-Events in Windows Phone 8 / IE10
Beispiel 1 – Simulierte Maus-Events

So ähnlich wie es auch in Chrome, Safari, Firefox und co. der Fall ist, werden bei einem »Tap« die folgenden Events abgefeuert:

mouseover > mouseenter > mousedown > mousemove > focus > mouseup > mouseout > mouseleave > click

Man beachte, dass diese Events in dieser Reihenfolge praktisch ohne Zwischenpausen abgesandt werden.

Wenn eine Webseite auf spezifische Events wie click oder mouseover reagiert, wird diese Seite in den meisten Fällen ohne jegliche Veränderung auch in IE10+ auf Touch-Geräten benutzbar sein. Es gibt aber, wie auch bei Touch-Event-fähigen Browsern, einige wohlbekannte Einschränkungen, wenn sich Entwickler nur auf Maus-Events verlassen – unter anderem, eine spürbare 300ms-Verzögerung bei Touch-Interaktionen, bevor der click Event abgesandt wird, und die Tatsache, dass Fingerbewegungen auf einem Touchscreen nicht – wie man es von einer normalen Maus gewohnt ist – mousemove Events generiert.

Pointer-Events und simulierte Maus-Events

Die Event-Reihenfolge im Touch-Events-Modell sieht folgendermaßen aus:

touchstart > [touchmove]+ > touchend > [300ms delay] > mouseover > mousemove > mousedown > (focus) > mouseup > click

Zuerst werden die Touch-spezifischen Events abgesandt. Dann, nach dem klassichen 300ms Delay, werden die simulierten Maus-Events und zuletzt der click abgefeuert.

Im Pointer-Events-Modell, hingegen, werden die Pointer- und Maus-Events folgendermaßen abgesandt:

pointerover > mouseover > pointerenter > mouseenter > pointerdown > mousedown > [pointermove > mousemove]+ > focus > pointerup > mouseup > pointerout > mouseout > pointerleave > mouseleave > [300ms delay] > click

Im IE10 (immer noch der Standard-Browser auf Windows Phone 8) sind Pointer-Events mit einem Vendor-Prefix versehen. Somit sehen die verschiedenen Events in dieser Version so aus: MSPointerOver, MSPointerEnter, MSPointerDown, MSPointerMove, MSPointerUP, MSPointerOut, MSPointerLeave. In IE11 sind die Events gemäß der W3C Spezifikation ohne Prefix implementiert.

Verkürzte Reaktionszeit bei click Events

Wie schon letztes Jahr gesehen, gibt es bei Touchscreens in der Regel eine Verzögerung von ungefähr 300ms zwischen dem Moment, in dem der Finger bei einem »Tap« den Touchscreen verlässt, und dem click Event. Um bei Touch-Events diese Verzögerung zu umgehen, müssen sich Entwickler traditionell mit extra Code auseinandersetzen, der sowohl auf touchend (der direkt vor der Verzögerung ausgeführt wird) als auch auf click reagiert, und mittels preventDefault() verhindern, dass die gleiche Funktion doppelt abläuft – einmal für den Touch-Event, und danach für die simulierten Maus-Events.

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

Im Pointer-Event-Modell ist die 300ms Verzögerung immer noch vorhanden.

Beispiel 2 – 300ms Verzögerung vor dem click Event auch in Windows Phone 8 / IE10
Beispiel 2 – 300ms Verzögerung vor dem click Event

Zwar könnte man hier einen ähnlichen Ansatz nehmen und auf pointerup und click Events hören. Einziger Haken: Bei Pointer-Events hat preventDefault weder auf die simulierten Maus-Events (die, wie gesehen, »inline« zusammen mit den verschiedenen Pointer-Events abgesandt werden), noch auf den click, einen Effekt.

Pointer-Events haben aber hier eine viel einfachere Alternative. Die Pointer-Events Spezifikation definiert eine neue CSS Property touch-action, mit der es möglich ist, dem Browser explizit mitzuteilen, welche Touchscreen-Interaktionen (und deren »Default« Bearbeitung vom Browser) zugelassen sind.

  1. touch-action: auto | none | pan-x | pan-y
  • auto: der Browser kümmert sich um alle Touch-Gesten, inklusive »double-tap to zoom« (und damit die 300ms Verzögerung).
  • none: alle Standard-Touch-Gesten sind unterdrückt.
  • pan-x und pan-y: überlässt dem Browser auschließlich horizontales oder vertikales Scrolling.

Wie auch mit preventDefault ist hier Vorsicht geboten: touch-action:none unterdrückt nicht nur unerwünschtes Verhalten wie die 300ms Verzögerung, sonder auch andere Interaktionen wie Zooming und Scrolling. Aus diesem Grund sollte diese CSS Property wirklich nur gezielt auf die nötigen Elemente (wie zum Beispiel Links und Buttons), und nicht auf die gesamte Webseite, angewandt werden

Anstatt komplexe JavaScript Routinen einzusetzen, können die 300ms recht elegant mittels einer einzige extra Zeile im CSS unterdrückt werden.

  1. button { touch-action: none; }
Beispiel 3 – touch-action:none unterdrückt 300ms Verzögerung in Windows Phone 8 / IE10
Beispiel 3 – touch-action:none unterdrückt 300ms Verzögerung

Finger-Bewegungen verfolgen

Ein weiteres Problem, das schon im letztjährigen Artikel besprochen wurde, ist die Tatsache, dass Finger-Bewegungen auf einem Touchscreen nicht direkt mittels mousemove verfolgt werden können – sobald sich der Finger mehr als nur ein paar Pixel über den Touchscreen bewegt, wird dies als eine Scroll-Geste interpretiert, und die simulierten Maus-Events werden nicht abgefeuert.

Um Finger-Bewegungen per JavaScript zu verfolgen, müssen Entwickler deshalb im Touch-Event Modell direkt auf touchmove Events reagieren, und mittels preventDefault das Scrollen im Browser unterdrücken.

Das gleiche Problem mit mousemove ist auch in Browsern mit Pointer-Events vorhanden. Als Beispiel dient hier wieder eine Canvas-basierte Spielerei:

Beispiel 4 – Canvas-Spielerei – nur Maus-orientiert; funktioniert nur teilweise auf Windows 8.1/ IE11
Beispiel 4 – Canvas-Spielerei – nur Maus-orientiert

Dieses Beispiel funktioniert einwandfrei mit der Maus. Wenn man aber auf einem Touchscreen den Finger über den Canvas bewegt, wird die Bewegung nur für ein paar Pixel verfolgt … danach interpretiert der Browser die Bewegung als Scrolling.

Als ersten Schritt sollten Entwickler echte Pointer-Events, und nicht die simulierten Maus-Events, einsetzen. Anstatt auf mousemove werden die Event-Listener also auf pointermove gesetzt.

Die nächsten Beispiele funktionieren nur in Browsern mit Pointer-Events-Unterstützung – zur Zeit also nur Internet Explorer 10+

Beispiel 5 – Canvas-Spielerei mit pointermove

Der Effekt ist leider immer noch der gleiche: selbst bei pointermove wird eine Finger-Bewegung als Scroll vom Browser abgefangen. Wie auch mit der 300ms-Verzögerung können Entwickler aber bei Pointer-Events direkt im CSS angeben, ob sich der Browser wie gewohnt um das Scrolling kümmern soll, oder ob Berührungen direkt per Scripting bearbeitet werden sollen. Somit reicht es aus, wieder eine einzige CSS-Zeile zum Beispiel hinzuzufügen:

  1. canvas { touch-action: none; }

Beispiel 6 – Canvas-Spielerei mit pointermove und touch-action:none

Dieses Beispiel funktioniert nun schon recht gut. Bewegungen werden sowohl mit dem Finger als auch mit einer Maus registriert, und von dem gleichen Code bearbeitet. Eine Tücke hat es aber noch: das Beispiel ist von Grund auf nur auf ein einziges Koordinaten-Paar ausgerichtet – wenn mehr als ein Finger auf dem Canvas ist, wird immer nur der Berührungs-Punkt, der sich zuletzt bewegt hat, von dem Script wahrgenommen.

Um genauer zu sein, kommt das Problem bei dem vorherigen Beispiel nicht nur mit mehreren Fingern auf dem Touchscreen vor – die gleiche Problematik tritt auf, wenn mehr als ein Pointer (sei es ein Finger, Stylus oder eine Maus) gleichzeitig benutzt werden. Der Einfachheit halber geht der Beispiel-Code davon aus, dass ein User diese verschiedenen Inputs nicht gleichzeitig verwenden wird.

Um nur den »ersten« Finger auf dem Touchscreen zu verfolgen, muss der Code leicht erweitert werden, um nur auf den »primären« Pointer zu reagieren.

  1. /* Pseudo-Code: Koordinaten nur für den primären Pointer erfassen */
  2.  
  3. foo.addEventListener('pointermove', function(e){
  4.     ...
  5.     if(e.isPrimary){
  6.         ...
  7.         posX = e.offsetX;
  8.         posY = e.offsetY;
  9.         ...
  10.     }
  11.     ...
  12. }, false);
Beispiel 7 – Canvas-Spielerei mit pointermove, touch-action:none und isPrimary Check; funktioniert komplett auf Windows Phone 8 / IE10
Beispiel 7 – Canvas-Spielerei mit pointermove, touch-action:none und isPrimary Check

Fazit

Im Gegensatz zu traditionellen Maus- und Touch-Events erlauben Pointer-Events, Web-Applikationen auf elegante Weise auf verschiedene Input-Methoden auszulegen, ohne spezielle »Weichen« (für Maus, Touch, Stylus, usw.) in den Code packen zu müssen.

Momentan sind diese Events leider nur in Internet Explorer 10+ vorhanden – aber Unterstützung in anderen Browsern wird voraussichtlich bald kommen (siehe die aktiven Bugs für Chromium/Blink und Firefox– obwohl es momentan noch unsicher ist, ob Webkit auch nachziehen wird). Um trotzdem schon heute das vereinfachte Pointer-Event-Modell einzusetzen, gibt es schon recht stabile Polyfills wie HandJS und Polymer's PointerEvents.

Weiterführende Links

Patrick Lauke

Over

$
0
0
Nägel und Schrauben in einem KopfWas heutzutage alles in den Head muss – und was nicht

René Descartes sagte einmal »Denn es ist nicht genug einen guten Kopf zu haben; die Hauptsache ist ihn richtig anzuwenden«. Auch wenn Descartes nicht viel mit dem Internet anfangen konnte, gilt diese Weisheit auch für Websites. Was gehört also wirklich in einen guten Kopf einer Website?

Die Ausgangslage bei typischen Meta-Tag-Angaben sah vor zehn Jahren noch recht überschaubar aus:

  1. <head>
  2.      <title>Over&lt;head&gt; | Webkrauts</title>
  3.      <metaname="keywords"content="meta-tags, meta-attribute, head, html, suchmaschinen, seo, favicon" />
  4.      <metaname="description"content="Welche Meta-Tags gehören in den Head-Bereich einer Website?" />
  5.      <linkrel="shortcut icon"href="/favicon.ico"type="image/x-icon" />
  6. </head>

Fast Forward nach 2013: Mittlerweile ist das »keywords«-Meta-Tag obsolet, es wird von keiner großen Suchmaschine mehr unterstützt, da zur Verschlagwortung der eigentliche Inhalt der Seite herangezogen wird. Bei der Description hat sich hingegen nicht viel geändert: Sie wird weiterhin von den Suchmaschinen als Beschreibung des Links genutzt. Einzig in der maximalen Länge unterscheiden sich die verschiedenen Anbieter. Hier wird eine Länge von 160 bis 200 Zeichen empfohlen.

Das Favicon

Früher genügte eine einzige Datei im ICO-Format von Windows, die ein 16×16px großes Icon enthielt, das der Browser dann bei Bookmarks zusätzlich anzeigte. Alle waren glücklich.

Heute empfiehlt es sich, ein paar Größen mehr zu unterstützen: Für die verschiedenen Systeme, Auflösungen und Funktionen werden die Seitenlängen 16, 24, 32 und 64 Pixel benötigt, die als weitere Bilder innerhalb der Favicon-Datei selbst gespeichert werden (etwa für die unten beschriebenen »Pinned Sites«).

Ein freier und guter Favicon-Generator dafür ist der X-Icon Editor. Dort kann man PNGs hochladen und sich eine ICO-Datei mit mehreren Auflösungen generieren lassen.
Moderne Browser unterstützen neben dem ICO-Format auch PNG oder GIF, allerdings macht uns hier der Internet Explorer einen Strich durch die Rechnung, der diese Formate erst ab Version 11 unterstützt. Daher empfiehlt es sich, beim ICO-Format zu bleiben.

Wird im Head-Bereich der Seite kein Metatag für die favicon.ico-Datei angegeben, wird vom Browser nach einer Datei dieses Namens im Root-Verzeichnis der Website gesucht. Diese Angabe wird also nur benötigt, wenn das Favicon an einem anderen Ort liegt.

Touch-Icons für iOS & Android

Mit dem iPhone wurde zusätzlich zum Favicon ein neues Bild-Element als Meta-Angabe hinzugefügt: Das »apple-touch-icon« mit einer Bildgröße von 57×57px. Es wird angezeigt, sobald der Benutzer den Link zu einer Website auf seinem iPhone-Homescreen speichert. Trotz des Namens haben kurz darauf Android-Handys dieses Verhalten übernommen.

  1. <linkrel="apple-touch-icon"href="/apple-touch-icon.png">

Bei diesem Icon wurde bis einschließlich iOS6 automatisch ein typischer Glanzeffekt hinzugefügt, wie er auch bei den Apple-eigenen Applikationen vorgesehen war. Wenn dies bewusst nicht gewünscht ist, muss die Icon-Datei stattdessen »apple-touch-icon-precomposed.png« benannt werden.

Im Laufe der Zeit ist durch Tablet- und Retina-Versionen der Geräte die Anzahl zunächst auf 4 quadratische Größen gewachsen: 57px, 72px, 114px und 144px, mit der Einführung von iOS7 sind bei Apple auch noch die Größen 60px, 76px, 120px und 152px hinzugekommen. Mit der Umstellung auf »Flat Design« allerorten, sollte für ein einheitliches Erscheinungsbild auf unterschiedlichen Geräten die precomposed-Variante verwendet werden. Ab iOS7 wird auch der Glanzeffekt immer weggelassen.

Um sämtlichen Varianten Rechnung zu tragen, muss der folgende Block in den Header einfügt werden:

  1. <!-- iPad, Retina, iOS ≥ 7: -->
  2. <linkrel="apple-touch-icon-precomposed" sizes="152x152"href="apple-touch-icon-152x152-precomposed.png">
  3. <!-- iPad, Retina, iOS ≤ 6: -->
  4. <linkrel="apple-touch-icon-precomposed" sizes="144x144"href="apple-touch-icon-144x144-precomposed.png">
  5. <!-- iPhone, Retina, iOS ≥ 7: -->
  6. <linkrel="apple-touch-icon-precomposed" sizes="120x120"href="apple-touch-icon-120x120-precomposed.png">
  7. <!-- iPhone, Retina,  iOS ≤ 6: -->
  8. <linkrel="apple-touch-icon-precomposed" sizes="114x114"href="apple-touch-icon-114x114-precomposed.png">
  9. <!-- iPad mini, iPad 1. und 2. Generation, iOS ≥ 7: -->
  10. <linkrel="apple-touch-icon-precomposed" sizes="76x76"href="apple-touch-icon-76x76-precomposed.png">
  11. <!-- iPad mini, iPad 1. und 2. Generation, iOS ≤ 6: -->
  12. <linkrel="apple-touch-icon-precomposed" sizes="72x72"href="apple-touch-icon-72x72-precomposed.png">
  13. <!-- Non-Retina iPhone, iPod Touch und Android 2.1+: -->
  14. <linkrel="apple-touch-icon-precomposed"href="apple-touch-icon-precomposed.png">

Sind keine Touch-Icons in der Seite enthalten, sucht zumindest iOS im Root der Website nach den Dateien in der Reihenfolge apple-touch-icon.png und apple-touch-icon-precomposed.png, ignoriert aber weitere Dateinamen mit Größenangaben. Der empfehlenswerte Artikel von Mathias Bynens geht dabei ausführlich auf die Entstehung und Entwicklung der Touch-Icons ein.

Viewport

Um eine Website auch fit für die mobilen Geräte zu machen, benötigen diese den Viewport-Meta-Tag. Diese Anweisung beschreibt, wie ein Gerät mit geringerer Bildschirmgröße – meist ein Handy – mit der Seite umgehen soll. Um eine Seite mit einer Breite von 1200px auf ein 480px breites Handy-Display zu bringen, gibt es verschiedene Ansätze: Man zoomt auf eine bestimmte Auflösung, lässt den User selber skalieren oder gibt einen bestimmten Zoom-Faktor an.

Folgendes Beispiel gehört zu einer Website, die bereits »responsive« ist, und somit mit allen Auflösungen funktioniert.

  1. <metaname="viewport"content="width=device-width, initial-scale=1">

Eine genaue Beschreibung des Viewport-Meta-Tags und den Hintergründen findet sich im Webkrauts-Archiv: Ein Blick durch den Viewport.

Funktionen für Windows 7 und 8 im Internet Explorer

Microsoft hat seinen Betriebssystemen ab Version 7 in Verbindung mit dem Internet Explorer als Standardbrowser ein paar weitere Funktionen spendiert:

Pinned Sites

Webseiten können nicht nur in den Bookmarks gespeichert, sondern auch in der Windows-Taskbar abgelegt werden. Dazu wird ein 32×32px großes Favicon benötigt, das mit einem Icon-Editor schon im favicon.ico gespeichert wurde. Um etwas mehr Einfluss auf den Link zu haben, hat Microsoft noch folgende Meta-Tags definiert:

  1. <metaname="application-name"content="Der Name der Website">
  2. <metaname="msapplication-tooltip"content="Ein kleiner Erklärungstext wie er beim Hover erscheinen soll.">

Jump Lists

In Windows 7 waren auch sogenannte »Jump Lists« möglich. Diese wurden in das Rechts-Klick-Menü eingefügt, wenn der Nutzer auf die Seite in der Taskbar klickt. Für jeden Eintrag in das Menü kann ein Meta-Tag definiert werden, der wie folgt aussieht:

  1. <metaname="msapplication-task"content="name=Zur Startseite; action-uri=./; icon-uri=logo.ico">

Für die Icons kann z.B. der oben schon erwähnte X-Icon-Editor verwendet werden.

Tiles-Infos

Unter Windows 8 kann eine Website auch im Startmenü als Kachel hinterlegt werden. Dazu werden die Farbe, die Kachel-Grafik (144×144px, einfarbig, transparent) und folgende Meta-Tags benötigt:

  1. <metaname="msapplication-TileColor"content="#D83434">
  2. <metaname="msapplication-TileImage"content="path/to/tileicon.png">

Hier empfiehlt es sich, Kontrastfarben zu setzen. Um das Aussehen der Kacheln vorab zu testen, stellt Microsoft ein Tool zur Verfügung: Build my pinned site.
Optional kann auch ein RSS-Feed eingebunden werden, dann wird die Kachel regelmäßig mit neuem Inhalt befüllt.

Eine kleine Übersicht mit noch mehr Spielereien und Beispielen von Microsoft gibt es hier: Build my pinned Site for Windows 7.

Sonstiges

In älteren Versionen des Internet Explorers kann es noch bisweilen Darstellungsprobleme auf Webseiten geben, wenn der sogenannte »Kompatibilitätsmodus« aktiviert ist. Das hat zur Folge, dass versucht wird, das Verhalten älterer Browser (z.B. des IE7 oder IE6) zu imitieren. Das führt bei standardkonformem HTML meist zu sehr unschönen Ergebnissen. Mit dieser Metatag-Angabe kann der IE dazu gezwungen werden, stets die aktuellste Version seiner Rendering-Engine einzusetzen:

  1. <metahttp-equiv="X-UA-Compatible"content="IE=edge">

Detaillierte Informationen zu weiteren Einstellungsmöglichkeiten gibt es direkt bei Microsofts Developer Network. Durch die deutlich verbesserte Unterstützung in aktuellen Versionen des Internet Explorers, verliert dieser Meta-Tag allerdings zusehend an Bedeutung.

SEO

Um die Qualität der Suchergebnisse zu verbessern, haben einige Suchmaschinen-Anbieter – allen voran Google – beschlossen, sogenannten »Duplicate Content« abzuwerten. Dieser entsteht zum Beispiel, wenn eine Webseite sowohl unter domainname.de als auch www.domainname.de erreichbar ist (Suchmaschinen werten dies als zwei unterschiedliche Adressen). Duplicate Content liegt ebenso vor, wenn der gleiche oder fast der gleiche Inhalt etwa in mehreren Kategorien einer Website (und damit unter mehreren URLs) zu finden ist.
In diesen Fällen wird den Suchmaschinen mitgeteilt, wo der Original-Text liegt, der für die eigentliche Indizierung verwendet werden soll, und ihr umgeht eine Abstrafung durch den Suchmaschinen-Betreiber:

  1. <linkrel="canonical"href="http://www.example.com/original/">

Die großen Content-Management- bzw. Blog-Systeme wie WordPress, Drupal oder Joomla setzen die Tags meist automatisch – oder es gibt Module dafür. Um sicher zu gehen sollten aber unbedingt die Einstellungen und der ausgegebene Quelltext überprüft werden. Auf statischen Seiten hingegen kann auf diesen Tag verzichtet werden, wenn dort Inhalte nicht über mehrere URLs aufrufbar sind.

DNS-Prefetching

Bevor eine Ressource auf einer Website (z.B. JavaScript, CSS, Bilder) geladen werden kann, muss der Browser erst den DNS-Eintrag auflösen. Das dauert in der Regel nur wenige Millisekunden. Lädt der Browser nun viele Inhalte von anderen Domains, etwa über ein Content-Delivery-Network oder verwendete Werbung oder Zählpixel, kann es besonders bei mobiler Internetnutzung mit hohen Latenzen zu Verzögerungen kommen. Ihr könnt allerdings den Browser anweisen, die DNS-Informationen vorab zu laden, wenn sich ein freies Zeitfenster dafür ergibt:

  1. <linkrel="dns-prefetch"href="//www.example.com">

Wird etwa der jQuery-CDN und Google Analytics im Projekt verwendet, sähe ein passender Eintrag so aus:

  1. <linkrel="dns-prefetch"href="//code.jquery.com">
  2. <linkrel="dns-prefetch"href="//google-analytics.com">

Eine ausführliche Beschreibung zu DNS-Prefetching gibt es im Mozilla Developer Network.

Weitere Meta-Tags

Generell sollte das Zeichen-Encoding einer Website bereits dem Browser vom Web-Server im HTTP-Header mitgeteilt werden, zusätzlich kann diese Einstellung als Meta-Tag mitgegeben werden. Für HTML5 wird dabei UTF-8 als Standard angenommen, so dass auf diese Auszeichnung auch verzichtet werden kann:

  1. <metacharset="utf-8">

Nach dieser grundlegenden Übersicht der aktuell geläufigsten Meta-Angaben geht es im morgigen zweiten Teil um weitere Möglichkeiten speziell für Social Media und Tracking-Dienste.

Andreas WeißFrederic Hemberger

More Over: Social Media

$
0
0
Junge hält verzweifelt die Hände vor den KopfWas heutzutage alles in den head muss – Teil II

Tagtäglich posten Millionen Nutzer etliche Links in den sozialen Netzen. Es heißt, allein auf Facebook werden alle zwanzig Minuten eine Million Links geteilt. Grund genug, die eigene Website für Social Media herzurichten. Mit Hilfe der passenden Meta-Tags.

Ging es im ersten Teil um die allgemeinen Infos, die in den head einer Seite sollten, beschäftigt sich der zweite Teil mit den Infos, die verschiedene soziale Netzwerke für die Verlinkung der Seite benötigen. Dort hat jeder Anbieter seine eigenen Vorstellungen und Ideen.

Open Graph

Der Branchenprimus Facebook hat vor einigen Jahren den »Open Graph« eingeführt, um Webseiten besser maschinenlesbar zu gestalten. Dadurch wird die Vorschau der verlinkten Seiten auf Facebook mit Inhalten und Infos angereichert, wie z.B. einer Beschreibung oder aussagekräftiger Bilder. Mittlerweile ist das Protokoll der Quasi-Standard und damit weit verbreitet – nicht nur bei Facebook.

Damit diese Daten von sozialen Netzwerken auch gelesen werden können, müssen ein paar Meta-Tags im head gesetzt werden:

  1. <meta property="og:title"content="More Over&lt;head&gt;: Social Media">
  2. <meta property="og:description"content="Welche Meta-Tags können im &lt;head&gt; für Soziale Netzwerke verwendet werden?">
  3. <meta property="og:url"content="http://webkrauts.de/artikel/2013/more-over-social-media">
  4. <meta property="og:type"content="article">
  5. <meta property="og:image"content="">

Bei »og:title« handelt es sich um die Überschrift der Seite, »og:description« beinhaltet eine kurze Zusammenfassung. Die im ersten Teil beschriebene Canonical-URL sollte im »og:url« Meta-Tag ebenfalls enthalten sein. »og:type« beschreibt hingegen die Art des verlinkten Inhalts, der entweder als Website (»website«), Buch (»book«), Produkt (»product«) oder Artikel (»article«) klassifiziert ist.

Das passende Bild zur Seite (etwa ein Screenshot, Teaser oder das eigene Logo) wird mit »og:image« hinzugefügt. Facebook gibt hier eine Mindestgröße von 600×315 Pixel vor. Das Seitenverhältnis sollte idealerweise 1.91:1 sein, da Facebook Bilder entsprechend zuschneidet. Bei anderen sozialen Netzwerken (etwa Twitter) können diese Angaben aber auch abweichen, wie im Folgenden noch zu sehen ist. Daher lässt sich mit diesem Tag auch mehr als ein Bild definieren, etwa mit verschiedenen Größen oder Motiven:

  1. <meta property="og:image"content="/beispiel1.jpg">
  2. <meta property="og:image:width"content="600">
  3. <meta property="og:image:height"content="600">
  4. <meta property="og:image"content="/beispiel2.jpg">
  5. <meta property="og:image"content="/beispiel3.jpg">
  6. <meta property="og:image:height"content="1200">

Die Größe eines Bildes wird immer jeweils nach dem Bild angegeben. Dazu nimmt man die spezifischere Auszeichnung »og:image:width«, diese bezieht sich dann auf die letzte allgemeinere Information »og:image«. Der Besucher der Seite kann sich dann das Bild in seinem sozialen Netzwerk beim Verlinken aussuchen. Ideal ist es, seitenspezifische Bilder anzugeben und nicht nur immer die gleichen allgemeinen Bilder.

Twitter Cards

Auch Twitter bietet seit Anfang 2013 die Möglichkeit, einen Link »anzureichern«. Um die sogenannten »Twitter Cards« nutzen zu können, muss die eigene Seite bei Twitter allerdings noch freigeschaltet werden. Der genaue Ablauf ist in der Twitter Developers Dokumentation beschrieben. Die Syntax einer Twitter Card sieht dabei folgendermaßen aus:

  1. <metaname="twitter:card"content="summary">
  2. <metaname="twitter:site"content="@andiweiss">
  3. <metaname="twitter:creator"content="@andiweiss">
  4. <metaname="twitter:title"content="">
  5. <metaname="twitter:description"content="">
  6. <metaname="twitter:image"content="beispiel.jpg">

Der von Twitter gewählte Aufbau sieht in einigen Punkten der »Open Graph«-Struktur sehr ähnlich. Kein Wunder, sie benötigen ja größtenteils die gleichen Informationen. Nutzt ihr die Meta-Angaben für beide Dienste, könnt ihr euch doppelte Schreibarbeit sparen. Fehlen benötigte Angaben in den Twitter-Auszeichnungen, wird automatisch nach entsprechenden »Open Graph«-Daten auf der Seite gesucht:

Twitter CardOpen GraphAnmerkungen
twitter:urlog:urlCanonical-URL
twitter:descriptionog:descriptionmax. 200 Zeichen
twitter:titleog:titlemax. 70 Zeichen
twitter:imageog:imageje nach Card-Typ

Dadurch werden nur noch ein paar zusätzliche Informationen benötigt, die noch nicht im »Open Graph« angegeben wurden:

  1. <metaname="twitter:creator"content="@andiweiss">
  2. <metaname="twitter:site"content="@webkrauts">
  3. <metaname="twitter:card"content="summary">

»twitter:creator« ist der Twitter-Account des Artikel-Autoren, »twitter:site« ist der Account des Inhabers der Seite. Mit »twitter:card« kann zwischen verschiedenen Darstellungen gewählt werden. Am interessantesten sind hier »summary« und »summary_large_image« zu nennen. Sie beinhalten den Titel, die Beschreibung, den Autor sowie ein Bild der verlinkten Seite und sind für Artikel-Zusammenfassungen gedacht.
Die anderen Möglichkeiten sind die Photo-Card, Gallery-Card, App-Card, Player-Card und die Product-Card.

Twitter bietet in seinem Developer-Bereich auch einen Validator und einen Baukasten für die benötigten Meta-Tags an.

Google+

Google und damit auch Google+ setzen hauptsächlich auf das schema.org-System, um eine Webseite maschinenlesbar zu machen. Die Anreicherung mit Metadaten findet hier allerdings im Body statt und fällt damit aus dem Rahmen dieses Artikels. Aber auch in diesem Fall kommen wieder Meta-Daten mit ins Spiel: Wenn keine schema.org-Deklarationen vorhanden sind, greift Google auch hier auf vorhandene »Open Graph«-Angaben zurück.

Pinterest

Ein anderes Soziales Netzwerk ist Pinterest. Der Reiz dabei liegt vor allem im Verlinken von Bildern auf Webseiten, die hier sehr prominent präsentiert und auch als Kopie auf der Servern von Pinterest abgelegt werden. Wer diesbezüglich Bedenken hat oder es aus Urheberrechtsgründen verhindern möchte, kann das Anpinnen seiner Bilder mit einem einfach Meta-Tag unterdrücken:

  1. <metaname="pinterest"content="nopin" description="Leider erlaubt der Seitenbesitzer kein Pinnen seiner Inhalte.">

Analytics

Ein weiteres Themengebiet sind die Analyse-Tools. Neben Google Analytics bieten auch Facebook und Pinterest die Möglichkeit, die Aufrufe der eigenen Website zu messen, wenn ihr euch über einen Meta-Tag als Besitzer der Seite verifiziert habt.

Facebook Insights

Um Informationen zu Aktivitäten rund um die eigene Seite bei Facebook zu erhalten, könnt ihr euch in Facebook Insights umschauen. Die eigene Website muss dazu mit diesen Angaben mit einem Facebook-Account verknüpft werden:

  1. <meta property="fb:admins"content="user_id">
  2. <meta property="fb:app_id"content="your_app_id">

Die User-ID und die App-ID findet ihr im Insight-Dashboard, hier helfen aber auch die Insights-Dokumentation auf den Facebook-Entwicklerseiten weiter.

Pinterest Analytics

Pinterest bietet eine sehr ähnliche Funktionalität wie Facebook an: Zuerst schaltet ihr die eigene Webseite in eurem Pinterest-Account frei, danach muss auch hier der Verifizierungs-Code in den head der Seite:

  1. <metaname="p:domain_verify"content="">

Google Analytics/Webmaster-Tools

Google Analytics und die Webmaster-Tools von Google, Bing oder Yahoo! wollen genauso verifiziert werden, bevor ihr Zugriff auf die Informationen erhaltet. Dies geschieht auch entweder über ein Meta-Tag oder über eine Datei, die im Root der Website ablegt wird. Um so viele unnötige Infos wie möglich im head-Bereich zu vermeiden, empfiehlt sich an dieser Stelle die Validierung per Datei.

Fazit

Heutzutage gibt es unzählige Möglichkeiten eine Webseite mit vielen – teilweise sehr speziellen – Informationen und Funktionen zu erweitern. Jeder Betreiber sollte sich aber sehr genau überlegen, welche Angaben sinnvoll sind und auf welche Spielereien besser verzichtet werden kann. Mit den vorgestellten Anregungen dieses Artikels lässt sich der head-Bereich der eigene Seiten nun nach individuellen Bedürfnissen optimieren.

Andreas WeißFrederic Hemberger
Viewing all 231 articles
Browse latest View live