Donnerstag, 28. Januar 2010

Software is hard - Firebug Tutorial

Software is hard ScreenshotSenSEO basierte bisher auf dem Code einer YSlow 1.x Version. An vielen Stellen habe ich bis heute nicht verstanden, was der Code von Yahoo! eigentlich tut und warum er so und nicht anders entwicklet wurde. Auf die Dauer wollte ich mich damit nicht abfinden. Dank dieses Tutorials zur Entwicklung von Firebug-Extensions im Blog von Jan "Honza" Odvarko war es mir möglich, den gesamten SenSEO-Code an einem Abend komplett zu überarbeiten. Das Ergebnis ist verständlicher, aufgeräumter und strukturierter. Ich erhoffe mir von dem Refactoring, dass die Extension dadurch in Zukunft stabiler und schneller läuft. Da ich nun von der ersten bis zur letzten Code-Zeile genau was, was diese tut, sollten auch eventuell nötige Updates auf neue Firebug-Versionen kein Problem mehr darstellen. Bevor ich die neue Version veröffentlichen kann, ist allerdings noch etwas Massage nötig.

Montag, 25. Januar 2010

Semantic Checker mit WAI-ARIA-Support

In der Version 0.7.0 unterstützt die Firefox-Extension Semantic Checker nun auch WAI-ARIA. Neben allen role-Attributen werden auch States und Properties (alle aria-* Attribute) ausgewertet. Damit sind alle geplanten Features für Semantic Checker implementiert. Mit der aktuellen Version habe ich einen Screenshot vom neuen Bestandskunden-Shop gemacht.

BK-Shop-Analyse mit Semantic Checker

Mittwoch, 20. Januar 2010

PNG-Transparenz für den IE6 ohne HTC

Ich nehme eine aktuelle Zusammenstellung von Performance-Problemen des IE6 im Zusammenspiel mit der HTC-Technologie zum Anlass, eine Alternative für PNG-Transparenz im IE6 ohne den Einsatz von HTC vorzustellen. Grund für die Entwicklung war die Konfrontation mit einigen der im Artikel genannten Probleme bei der Umsetzung eines unserer letzten Projekte.

Abgesehen vom Erzeugen des Namespace UNOUNO.ie kann diese Lösung nativ ohne zusätzliches JavaScript eingesetzt werden. Wie bei der ursprünglichen HTC-Lösung werden lediglich Elemente mit der Klasse alphapng mit PNG-Transparenz versehen. Der Code muss am Ende der Seite vor dem schließenden body-Tag eingebunden werden. Weiterhin sollte im Stylesheet über einen Conditional-Comment oder über den * html Selektor die Regel .alphapng a { z-index: 999; } angegeben werden, um die Funktion von Links sicherzustellen.

// init ie Namespace

UNOUNO.namespace('ie');

// place path to blank 1x1 pixel here

UNOUNO.ie.getPixel = function() {

// Pfad zu einem 1x1-Pixel transparenten Gif

return '/modules/frontend-elements/img/pnghack/transparent.gif';

};

// sets proprietary filter for alpha transparenz

UNOUNO.ie.setFilter = function(src) {

return 'progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src="' + src + '")';

};

UNOUNO.ie.fixPng = function(element, width, height) {

// fix "normal" Images and Inputs

if (/IMG|INPUT/.test(element.nodeName)) {

if (element.src) {

if (/.*\.png([?].*)?$/i.test(element.src)) { // make sure it is png image

var source = element.src;

element.style.filter = UNOUNO.ie.setFilter(source);
element.src = UNOUNO.ie.getPixel();

if (width) {

element.style.width = width + 'px';

}

if (height) {

element.style.height = height + 'px';

}

var position = element.currentStyle.position;

if (position != 'absolute' && position != 'relative') {

// this may cause layout bugs

element.style.position = 'relative';

}

}

}

}

// fix elements with png as background

var bgSrc = element.currentStyle.backgroundImage || element.style.backgroundImage;

if ((bgSrc + element.src).indexOf(UNOUNO.ie.getPixel()) == -1) {

var bgPNG = bgSrc.match(/^url[("']+(.*\.png[^\)"']*)[\)"']+[^\)]*$/i);

if (bgPNG) {

var source = bgPNG[1];

element.style.backgroundImage = 'url("' + UNOUNO.ie.getPixel() + '")';

element.style.filter = UNOUNO.ie.setFilter(source);

}

}

};

UNOUNO.ie.getElementsByClassName = function(clsName) {

var retVal = new Array();
var elements = document.getElementsByTagName("*");

for (var i = 0;i < elements.length;i++){

if (elements[i].className.indexOf(" ") >= 0){

var classes = elements[i].className.split(" ");

for (var j = 0;j < classes.length;j++){

if (classes[j] == clsName)

retVal.push(elements[i]);

}

}

else if (elements[i].className == clsName) {

retVal.push(elements[i]);

}

}

return retVal;

}

UNOUNO.ie.initFixPng = function(element) {

var pngElements = UNOUNO.ie.getElementsByClassName('alphapng');

for (var i = 0; i < pngElements.length; i++) {

UNOUNO.ie.fixPng(pngElements[i]);

}

};

UNOUNO.ie.initFixPng();

Es gibt für diese Lösung Einschränkungen. So werden keine sich wiederholenden (gekachelten) oder in irgend einer Weise positionierten Hintergrundbilder berücksichtig. Die neuste Version des TwinHelix IE PNG Fix verspricht dafür zwar eine Lösung, allerdings verrät ein Blick in den (im Alpha-Stadium befindlichen) Quellcode, das da jede Menge Voodoo passiert, dessen Konsequenzen sich für komplexe Layout-Szenarien, mal ganz abgesehen von den geschilderten Problemen mit HTC, nur sehr schwer abschätzen lassen.

Dienstag, 19. Januar 2010

Neue Bestandskunden-Shops online

In den letzten Monaten haben wir die 1&1 Bestandskunden-Shops redesigned und auf eine neue technische Basis gestellt. Dabei wurde die Gelegenheit genutzt um neue Ansätze und Technologien in dieses Redesign zu integrieren. Das Ergebnis sind Webseiten, die modernste Frontend-Anforderungen erfüllen. Anhand von Screenshots möchte ich zeigen, welche Anforderungen das sind und wie sich diese auf die Qualität der Seiten auswirken.

Vereinheitlichte Elemente
Nahezu konsequent wurden für diese neuen Shops einheitliche Elemente verwendet, die sich lediglich in Hintergrundbildern und wenigen anderen Details unterscheiden. Dies ermöglicht den Einsatz von XSLT-Templates, welche mit wenigen Parametern immer gleiches Markup erzeugen. Das CSS für das Layout ist dabei denkbar schlank, da diese einheitlichen Elemente natürlich auch mit einheitlichen CSS-Regeln gestylt werden können.



Die Verwendung der XSLT-Templates, Scripte und Styles erstrecken sich modular über verschiedene Shops in unterschiedlichen Sprachen. Dabei wurde auf einen konsequenten Einsatz von UTF-8 geachtet.

Validierung und wenig Inline-Code
Sämtliche Seiten und Stylesheets validieren gegen die Regeln des W3C. Bei der Entwicklung wurde weiterhin darauf geachtet, möglichst wenige Inline-Styles und Inline-Events zu verwenden.


W3C Markup Validation Service


Firefox-Extension Inline Code Finder

Semantisches Markup und Accessibility
Für die Elemente der Seite wurde semantisch sinnvolles Markup gewählt. Weiterhin wurde auf eine durchgängige Headline-Hierarchie geachtet. Da die Shops JavaScript voraussetzten und massiv von AJAX Gebrauch machen, werden interaktive Zustände über WAI-ARIA-Attribute kommuniziert. Dies alles stellt eine größtmögliche Zugänglichkeit sicher. Die nachfolgenden Screenshots zeigen die Seite in unterschiedlichen Darstellungen - darunter eine kontrastreiche Darstellung, eine Darstellung auf einem Mobilgerät und die Ansicht des Markups ohne Stylesheets.


Wenige Probleme werden von der Firefox Accessibility Extension gefunden


Eine kontrastreiche Darstellung mit Hilfe der Firefox Accessibility Extension


Mobile Ansicht der Seite


Ansicht ohne Styles mit der Web Developer Extension


Headline-Hierarchie, wie sie von Screenreader genutz wird (Web Developer Extension)

Optimierte Ladezeiten
Eine weitere Maßnahme war die Optimierung der Ladezeiten der Seiten. Der nächste Screenshot zeigt eine Analyse mit der Firefox-Extension YSlow - bis auf wenige Kriterien zeigt die Analyse beste Bewertungen.



Interaktive Elemente
Als JavaScript-Framework wird qooxdoo genutzt. Neben DOM-Manipulationen und Event-Listening wurden damit auch komplexe Interaktions-Elemente wie Lightboxen oder Auto-Vervollständigungen umgesetzt.

Blog abonnieren

RSS 2.0 Feed

Suche

Kalender

Zurück Januar '10 Vorwärts
Mo Di Mi Do Fr Sa So
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 21 22 23 24
26 27 29 30 31

Verwaltung des Blogs

Blogroll

Projects/Web

vCard

  • Nico Steiner
  • www.nicosteiner.de
  • Karlsruhe/Germany
  • Senior Frontend-Developer at 1&1