Professionelles Arbeiten bedeutet auch, effektiv zu arbeiten. Effektivität bedeutet für Webentwickler, nicht immer das Rad neu erfinden zu wollen oder müssen. Nicolai Schwarz und Dirk Jesse zeigen Best Practices, die bei der Entwicklung eigener Seiten helfen, schneller und besser mit der Aufgabe fertig zu werden.
Vortrag auf der WebTech 2009 in Karlsruhe
2. Kommentierte Fassung
Best Practices in JavaScript und CSS
Vortrag auf der WebTech 2009 in Karlruhe
In diesem Vortrag präsentieren wir ein paar kleine Tipps und Tricks, die vielleicht noch nicht alle
Leute kennen. Oft geht es darum, die Inhalte für Screenreader oder Tastaturnutzer sinnvoll
aufzubereiten. Viele der Kapitel lassen sich recht einfach bei allen Projekten umsetzen.
Alle Links sind gesammelt auf delicious zu finden: www.delicious.com/textformer/webtech09
Wer den Vortrag gehört hat, kann ihn gerne hier kommentieren:
http://joind.in/talk/view/1120
11. Prüfen, ob die Reset-Anweisungen sinnvoll sind
:focus { outline: 0; }
unterdrückt die Outline für alle User; sowohl beim Draufklicken mit der Maus
als auch bei Nutzung der Tastatur
:active { outline: 0; }
unterdrückt die Outline beim Draufklicken mit der Maus
Nutzer mit Tastatur sehen nun aber den fokussierten Link mit Outline
12. CSS-Reset
Worum geht‘s?
Reset-Style-Sheets sind ein guter Start für das eigene Design. Dabei sollten wir die Anweisungen aber
nicht alle unreflektiert übernehmen. Das Style-Sheet von Eric Meyer setzt zum Beispiel die outline beim
focus auf Null. Designer mögen es nicht unbedingt, wenn beim Klick auf einen grafischen Link diese
Outline erscheint, die Anweisung verhindert das.
Aber die Outline ist dann hilfreich, wenn Besucher die Webseite per Tastatur navigieren. Wenn ein
Webworker vergisst, die Zustände für den :focus anzulegen und durch das Reset die outline auf Null
steht, bekommt der Tastatur-Nutzer gar keine Rückmeldung auf welchem Link der Fokus gerade steht.
Statt den :focus auf Null zu setzen, ist es besser, nur :active auf Null zu setzen. Maus-Nutzer sehen
dann keine Outline, aber Tastatur-Nutzer sehen die Outline.
17. /* Hauptnavigation 2. Level */
#hauptnavigation ul li ul li a {
border-left: 5px solid #FFF;
padding-left: 40px;
}
#hauptnavigation ul li ul li a:hover,
#hauptnavigation ul li ul li a:focus,
#hauptnavigation ul li ul li a:active {
border-left: 10px solid #FFF;
padding-left: 35px;
background: url(‘http://www.landtag.nrw.de/portal/CPMO/images/
icon_ebene2_pfeil.gif’) no-repeat 18px 2px #F4F8FB;
}
18. Border für die Navigation
Worum geht‘s?
Es gibt einige Nutzer, die ihren Browser so einstellen, dass die Farbeinstellungen von Webseiten igno-
riert werden. Es werden nur rudimentäre Farben, in diesem Beispiel schwarz, weiß und blau, genutzt.
Normale Farbänderungen bei :hover und :focus werden hier nicht mehr angezeigt.
Ein einfacher Trick sorgt dafür, dass auch Nutzer mit diesen Einstellungen :hover und :focus nutzen
können. Der Rand (border) ist hier zunächst 5px breit, bei :hover und :focus aber 10px breit. Da der
Rand die Farbe des Links annimmt, kann der Nutzer auch bei diesen Einstellungen :hover und :focus
wahrnehmen.
20. CSS für versteckte Inhalte
position:absolute;
left: -10000px;
top: auto;
width: 1px;
height: 1px;
overflow: hidden;
Für fokusierbare Elemente wie Links oder Formulare
http://webaim.org/blog/hiding-content-for-screen-readers/
21. Inhalte verstecken
Worum geht‘s?
Manchmal werden Inhalte für Screeneader auf der Webseite für sehende Nutzer versteckt. Sie werden
einfach aus dem sichtbaren Feld verschoben. Wer die Seite per Tatstatur navigiert, kommt aber den-
noch an diese Inhalte (wenn sie fokusierbar sind). Ist der Inhalt dabei nach oben verschoben, springt
die Ansicht auch ganz nach oben. Besser ist es, solche Inhalte nur nach links zu verschieben. Der Bild-
schirm bleibt dann auf derselben Höhe stehen – und springt nicht mehr wild nach oben und unten.
28. Skiplinks einblenden
Worum geht‘s?
Skiplinks für Screenreader sollten auch für Tastatur-Nutzer zumindest kurz eingeblendet werden.
Nämlich dann, wenn die Skiplinks auch den Fokus haben. Dazu am besten eine geeignete Stelle im
Design vorsehen, um die Skipinks einzublenden.
30. Skiplinks
Techniques for WCAG 2.0
G1: Adding a link at the top of each page that goes directly to the main
content area
Test Procedure
• Check that a link is the first focusable control on the Web page.
• Check that the description of the link communicates that it links to the
main content.
• Check that the link is either always visible or visible when it has keyboard
focus.
• Check that activating the link moves the focus to the main content.
• Check that after activating the link, the keyboard focus has moved to the
main content.
Expected Results
•All checks above are true.
http://www.w3.org/TR/2008/NOTE-WCAG20-TECHS-20081211/G1
34. Skiplinks & Webkit-Browser
Problem: Tastaturfocus wird nicht verschoben.
Lösung: Korrektur per JavaScript
var webkitFocusfix= {
init: function() {
var is_webkit = navigator.userAgent.toLowerCase().indexOf(‘webkit’) > -1;
var i = 0;
var skiplinks = [ ];
if (is_webkit) {
if (document.getElementsByClassName!== undefined) {
skiplinks = document.getElementsByClassName(‘skip’);
for (i=0; i<skiplinks.length; i++) {
var target= skiplinks[i].href.substr(skiplinks[i].href.indexOf(‘#’)+1);
var targetElement= document.getElementById(target);
targetElement.href= ‘#’+target;
targetElement.setAttribute(“tabindex”, “0”);
skiplinks[i].setAttribute(“onclick”,”document.getElementById(‘”+target+”’).focus();”);
} } } } };
webkitFocusfix.init();
35. Bessere Skiplinks
Worum geht‘s?
Nicht immer lässt sich für die einzublendenden Skiplinks ein geeigneter Platz finden. Insbesondere bei
grafisch anspruchsvollen Layouts kann daneben auch schwierig sein, Skiplinks gut sichtbar in Szene zu
setzen.
Eine Alternative ist daher, die Skiplinks per Overlay über dem Layout einzublenden. Auf diese Weise
kann man Größe, Form und Farbe relativ unabhängig festlegen und somit absichern, dass diese von
Nutzern auch wahrgenommen werden.
Ein weiterer Punkt betrifft den Tabfocus. Dieser sollte beim Benutzen eines Skiplinks ebenfalls dem Ziel
folgen (siehe WCAG 2.0 Testkriterien). In Webkit-Browsern (Safari, Chrome) passiert jedoch genau das
nicht. Diesem Problem kann mit etwas JavaScript begegnet werden.
37. Margin Collapsing
Beschreibung
• Betrifft Elemente im normalen Elementfluss
• Betrifft nur vertikale Randabstände
• „Der größere gewinnt …“
Unterbrechung durch:
• Containing Float Techniken: float, overflow:auto|hidden, display:table
• CSS-Eigenschaft: border
• Internet Explorer: hasLayout+ padding/border
38. Heading
20px
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam no-
numy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam
<h1>HeadingContent</h1> h1 {
<p>Paragraph content</p> margin: 0 0 20px 0;
background: #0335;
}
p{
margin: 10px 0 0 0;
background: #0335;
}
39. Heading
40px
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam no-
numy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam
<h1>HeadingContent</h1> h1 {
<div> margin: 0;
<p>Paragraph content</p> background: #335; }
</div>
div {
margin: 40px 0 25px 0;
background: #335; }
p{
margin: 10px 0 0 0; }
40. Heading
40px
10px
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam no-
numy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam
<h1>HeadingContent</h1> h1 {
<div> margin: 0;
<p>Paragraph content</p> background: #335; }
</div>
div {
margin: 40px 0 25px 0;
background: #335;
border-top: 1px solid #ccf; }
p { margin: 10px 0 0 0; }
41. Margin Collapsing
Worum geht‘s?
Das Margin Collapsing ist eine der Verhaltensweisen von CSS, mit denen insbesondere Anfänger
zunächst so ihre Schwierigkeiten haben. Vertikale Margins aufeinander folgender Elemente werden
nicht einfach addiert, sondern überlagern sich. Kurz gesagt, gilt die Regel: „Der Größere gewinnt!”.
Speziell bei verschachtelten Elementen ist der Überblick und die Ursache für ungewöhnliche Abstände
im Layout nicht immer einfach zu erkennen. Hier werden deshalb kurz einige CSS-Methoden vorgestellt,
mit denen das Margin-Collapsing unterbunden werden kann.
44. Alphatransparente Hintergründe
CSS 3: rgba()
• Moderne Browser (FF3+, Safari 4+, Opera 10+)
background-color: rgb(255,255,255); /* Fallback */
background-color: rgba(255,255,255,.3);
• Internet Explorer 6+
background-color: transparent9; /* Fallback Reset */
filter:progid:DXImageTransform.Microsoft.gradient( startColorstr=#4CFFFFFF,end
Colorstr=#4CFFFFFF);
zoom:1; /* activatehasLayout*/
45. Alphatransparenz
Worum geht‘s?
Alphatransparente Hintergründe sind immer öfter gefragt in modernen Layouts. Bisher waren diese
Effekte crossbrowser nur über alphatransparente PNG-Grafiken oder verschachtelte Elemente und der
CSS-Eigenschaft opacity möglich. Diese CSS-Lösung bedingt jedoch zusätzliche Elemente rein zu
Präsentationszwecken.
Mit der Ankunft von Opera 10 und dessen erweiterter CSS3-Unterstützung eröffnet sich mit der CSS3-
Eigenschaft rgba() eine weitere, sehr einfach anzuwendende Methode, um diesen Transparenz-Effekt
zu erzeugen. Und auch im Internet-Explorer kann mit einem kleinen Workaround ein identischer Effekt
- rein auf CSS-Basis - erzeugt werden.
Die rgba() Methode funktioniert crossbrowser und ist eine echte Alternative zum Einsatz von
PNG-Grafiken.
50. <div class=”photo right”>
<img src=”http://pix.sueddeut-
sche.de/politik/173/494508/spd80-
1258300472.jpg” width=”180”
height=”180” alt=”SPD Parteitag in
Dresden” title=”SPD Parteitag in
Dresden” border=”0”>
<p>Will seiner Partei das Den-
ken in veralteten Kategorien ab-
gewöhnen: Sigmar Gabriel, der
ebenso sprachmächtige wie schil-
lernde Vorsitzende. (<cite>Foto:
AP</cite>)</p>
</div>
51. <div>
<img />
<p>Untertitel</p>
</div>
Noch nicht ideal: Ein Screenreader würde Bild und Untertitel hier als zwei
unterschiedliche Blöcke behandeln.
<div>
<p>
<img />
<span>Untertitel</span>
</p>
</div>
Best Practice: Ein Screenreader sieht Bild und Untertitel nun als Einheit an.
55. Bilder mit Unterzeilen
Worum geht‘s?
Die derzeit beste Lösung für Bilder mit Unterzeilen steht auf Seite 51. Die Frage ist, wie einfach der
WYSIWYG-Editor eingerichtet werden kann, um diese Struktur zu erzeugen. Alternativ kann man statt
des span auch <em> oder <strong> nutzen, wenn diese Elemente einfacher per Editor handhabbar sind.
Noch besser ist vielleicht ein Zwischen-Code wie er etwa bei WordPress erzeugt wird. Bei der Ausgabe
kann dieser Code dann durch den gewünschten HTMl-Code ersetzt werden. Solch ein Filter hat Vor-
teile, wenn sich irgendwann mal ein besserer Code für Bilder mit Unterzeile ergibt. Zum Beispiel falls
in HTML5 ein eigenes Element (figure) dafür vorgesehen sein wollte. In diesem Fall müsste der Admin
nur den Ausgabe-Filter umschreiben, schon werden alle Bilder mit Unterzeile im neuen Code darge-
stellt.
59. <h1 class=””MsoNormal””>
<span>Patientensymposium Netzhautdegenerationen</span>
</h1>
<h1 class=””MsoNormal””>
<span> </span>
<span>Einblicke - Ausblicke</span>
</h1>
<p class=””MsoNormal””>
<span> </span>
</p>
<h2 class=””MsoNormal””>
<span>Moderation</span>
</h2>
Ergebnis ohne weitere Einstellungen. (die „doppelten“ Anführungszeichen sind
nicht wirklich doppelt, das liegt an der gewählten Schrift)
61. HTML Purifier
• beseitigt bösartigen Code
• fehlende End-Tags werden geschlossen
• falsch verschachtelte Elemente werden
repariert
• veraltetete Tags werden konvertiert
• CSS wird validiert
• Leere Elemente können ausgefiltert
werden
• Es lässt sich konfigurieren, welche
Elemente und Attribute erlaubt sind
• Ebenso lassen sich etwa ids festlegen,
die nicht erlaubt sind
62. HTML Purifier
Worum geht‘s?
Einige CMS und WYSIWYG-Editoren bemühen sich bereits, den Quellcode, den die Redakteure ein-
geben, beim Speichern oder bei der Ausgabe zu bereinigen. Nach meinen Tests stoßen beide recht
schnell an ihre Grenzen und können auch nur in bestimmten Grenzen konfiguriert werden.
Der beste Filter, um HTML-Code sauber auszugeben, ist für mich bisher der HTML Purifier. Er kann auch
nicht verhindern, dass Redaktere eine Zwischenüberschrift falsch auszeichnen oder eine Liste nicht als
HTML-Liste eingeben. Aber der Purifier repariert fehlerhaften Code viel besser als WYSIWYG-Editoren
oder CMS-eigene Filter.
Einfach mal testen.
64. Die Basis
<form action=”/”>
<div>
<input type=”text” />
<input type=”submit” value=”Suchen” />
</div>
</form>
XMHTL 1.0 Code - Laut Spezifikation dürfen die input-Elemente keine direkten
Kindelemente von form sein, daher das div.
http://www.webkrauts.de/2008/12/09/der-perfekte-suchschlitz/
65. Mehr Semantik
<form action=”/”>
<fieldset>
<legend>Volltextsuche</legend>
<label for=”suchbegriff”>Suchbegriff</label>
<input type=”text” id=”suchbegriff” />
<input type=”submit” value=”Suchen” />
</fieldset>
</form>
Mit etwas CSS auch:
66. Interaktiv mit Pseudoklassen
input[type=text]:focus {
border-color: #000 #444 #444 #000;
background-position: 0 0;
}
input[type=submit]:hover {
cursor: pointer;
}
input[type=submit]:focus,
input[type=submit]:active {
background: #6c0000;
}
Der Internet Explorer 6 versteht diese Anweisungen nicht!
67. Interaktiv mit JavaScript
<input type=”text” id=”suchbegriff” value=”Suchbegriff” />
myTextfeld = document.getElementById(‘suchbegriff’);
if (document.addEventListener) {
myTextfeld.addEventListener(‘focus’, textLeeren, false);
}
function textLeeren() {
myTextfeld.value = “”;
}
Leert das Suchfeld, wenn ein Nutzer reinklickt
68. Interaktiv mit JavaScript II
myTextfeld = document.getElementById(‘suchbegriff’);
if (document.addEventListener) {
myTextfeld.addEventListener(‘focus’, textLeeren, false);
myTextfeld.addEventListener(‘blur’, textFuellen, false);
}
function textLeeren() {
mySuchspeicher = myTextfeld.value;
myTextfeld.value = “”;
}
function textFuellen() {
if (myTextfeld.value == “”) {
myTextfeld.value = mySuchspeicher;
}
}
Merkt sich das Wort im Eingabefeld.
69. Das finale Suchfeld
• Markup nach Standards
• legend und label helfen in erster Linie Screenreadern, für sehende Nutzer
werden die Elemente versteckt
• Es gibt interaktive Pseudoklassen für :hover, :focus, :active
• Das Wort „Suchbegriff“ hilft dem Nutzer statt eines sichtbaren labels, die
Funktion des Feldes zu erklären
• Per JavaScript wird das Wort „Suchbegriff“ beim Klick ins Feld ausgeblendet.
• Schreibt der Nutzer ein neues Wort hinein, wird dieses beibehalten,
andernfalls schreibt JavaScript wieder „Suchbegriff“ ins Feld.
70. Ein Suchformular
Worum geht‘s?
Das steht im Grunde alles schon gut erklärt in dem Artikel von Gerrit van Aaken:
http://www.webkrauts.de/2008/12/09/der-perfekte-suchschlitz/
(Dabei auch die Kommentare beachten)
73. Standardmarkup für Formulare
Zielsetzung
• Einheitliches Markup für
alle Formularbausteine
• Visuelle Gestaltungsfreiheit
• Berücksichtigung von
Feedback-Informationen
• Unterstützung für
fixe & flexible Breiten
Grundgedanke
Formularelement und Label
bilden eine Einheit und werden
kontextabhängig formatiert.
74. Textfeld
Standardmarkup für Formulare
<div class=”type-text”>
<label for=”your-id”>your label</label>
Zielsetzung
• Einheitliches Markup name=”your-id” id=”your-id” size=”20” />
<input type=”text” für
</div>
alle Formularbausteine
• Visuelle Gestaltungsfreiheit
• Berücksichtigung von
Feedback-Informationen
• Unterstützung für
fixe & flexible Breiten
Grundgedanke
Formularelement und Label
bilden eine Einheit und werden
kontextabhängig formatiert.
75. Textfeld
Standardmarkup für Formulare
<div class=”type-text”>
<label for=”your-id”>your label</label>
Zielsetzung
• Einheitliches Markup name=”your-id” id=”your-id” size=”20” />
<input type=”text” für
</div>
alle Formularbausteine
• Visuelle Gestaltungsfreiheit Selectfeld
• <div class=”type-select”>
Berücksichtigung von
Feedback-Informationen Options</label>
<label for=”your-id”>More
<select name=”your-id” id=”your-id” size=”1”>
• Unterstützung für
fixe <option value=”0” selected=”selected” disabled=”disabled”>
& flexible Breiten
Please choose</option>
<optgrouplabel=”First options to choose from”>
Grundgedanke value=”value #1”>Option 1</option>
<option
Formularelement value=”value #2”>Option 2</option>
<option und Label
</optgroup>
bilden<optgrouplabel=”Yet more options to choose from”>
eine Einheit und werden
kontextabhängig formatiert. #3”>Option 3</option>
<option value=”value
<option value=”value #4”>Option 4</option>
<option value=”value #5”>Option 5</option>
</optgroup>
</select>
</div>
76. Textarea
Standardmarkup für Formulare
<div class=”type-text”>
<label for=”your-id”>your label</label>
Zielsetzung
• Einheitliches Markup für id=”your-id” cols=”30” rows=”7”></textarea>
<textareaname=”your-id”
</div>
alle Formularbausteine
• Visuelle Gestaltungsfreiheit
• Berücksichtigung von
Feedback-Informationen
• Unterstützung für
fixe & flexible Breiten
Grundgedanke
Formularelement und Label
bilden eine Einheit und werden
kontextabhängig formatiert.
77. Textarea
Standardmarkup für Formulare
<div class=”type-text”>
<label for=”your-id”>your label</label>
Zielsetzung
• Einheitliches Markup für id=”your-id” cols=”30” rows=”7”></textarea>
<textareaname=”your-id”
</div>
alle Formularbausteine
• Visuelle Gestaltungsfreiheit Checkboxen & Radiobuttons
• <div class=”type-check”>
Berücksichtigung von
Feedback-Informationenname=”your-id” id=”your-id” />
<input type=”checkbox”
<label for=”your-id”>Your checkbox label</label>
• Unterstützung für
</div>
fixe & flexible Breiten
<div class=”type-check”>
<input type=”radio” name=”your-id” value=”value #1” id=”your-id” />
Grundgedanke
<label for=”your-id”>Your radio-button label</label>
</div>
Formularelement und Label
bilden eine Einheit und werden
kontextabhängig formatiert.
82. Formulare effektiv gestalten
Worum geht‘s?
Je nach Platzangebot im Layout oder der Komplexität der vom Nutzer erfragten Daten haben sich
unterschiedliche Darstellungsformen als vorteilhaft erwiesen. Die Herausforderung besteht nun darin,
ein möglichst sinnvolles Basismarkup für Formulare zu entwickeln, das all diese verschiedenen
Anforderungen abdeckt. Gleichzeitig soll der Pflegeaufwand für das dazugehörige CSS möglichst gering
gehalten werden.
Im Rahmen des Vortrages stelle ich die Lösung vor, die ich im Rahmen des CSS-Frameworks YAML als
„Formularbaukasten” implementiert habe.
85. Erwarten Sie das Unerwartete
Mit JavaScript Ohne JavaScript
Tabs ohne Funktion!
<a onfocus=”blur()” onclick=”spToggleMPC(‘topbox’,1)”
href=”javascript:void(0);”>Gelesen</a>
86. Zugängliche Tabinhalte
Zielvorgaben
• Zugänglichkeit und ansprechende Präsentationder Inhalte
mit und ohne JavaScript
• Vollständige Tastatursteuerung
• Feedback für Screenreaderbeim Tabwechsel
• Synchronisation der Tabreiter(gleiche Höhen)
92. „AccessibleTabs“ für jQuery
Autor: Dirk Ginader
AccessibleTabs (jQueryPlugin)
• Projekthomepage
• Dokumentation (deutsch/ englisch)
Implementation
CSS Framework YAML, Version 3.2
• Optional mit Tab-Synchronisation
http://www.yaml.de/fileadmin/examples/
09_add-ons/accessible_tabs.html
93. Inhalte in Tab-Reitern
Worum geht‘s?
Wann sind Tabreiter wirklich zugänglich für Screenreader? Wie gestalte ich Tab-Inhalte sinnvoll, falls
JavaScript beim Nutzer deaktiviert ist? Diese Fragen werden anhand des „Accessible Tabs” Plugins von
Dirk Ginader beantwortet.