Mittwoch, 8. Dezember 2010

Ein Klick hinter die Maske

Da will man mit einem runden Bullauge mal weg vom ewigen Rechteckdesign und stellt dann fest, dass man nicht durch transparente PNGs hindurch auf Links darunter klicken kann. Und jetzt?
Ich möchte mit einem an bestimmten Stellen transparenten PNG einen Textlayer abdecken, diesen Layer aber trotzdem scrollen und Links darin mit der Maus erreichen. Das geht aber nicht, weil das PNG für die Mauserkennung nicht transparent ist. Mist.
Als Stichwort fällt mir zunächst event bubbling ein, aber Fehlanzeige. Wo nix ankommt, wird auch nix gebubbelt.
Da ich bei dem Projekt jQuery verwende, könnte ich ja den Klick auf's PNG abfangen, die Cursorposition ermitteln, dann im Textlayer an der Stelle nachsehen, ob da ein Link ist (geht das überhaupt?) und dem dann den Clickevent manuell senden. Klingt nach einem langen Weg mit vielen Stolperfallen.
Machen wir es kurz: Die tatsächliche Lösung ist so einfach wie elegant, funktioniert adhoc und, was für mich das Schlimmste ist, sie hätte mir auch selbst einfallen können. Nach langer Suche, diversen Posts von Leuten, die das Problem nicht verstanden haben (nein, z-Index hilft hier gar nicht) und diversen Stichwortmorphs fand ich diesen Beitrag: http://www.blazekwebdesign.com/bwd/2008/developer-notes/clickable-links-through-a-transparent-image-in-css/
Wir brauchen also drei Layer:
  1. die Textebene
  2. die Bildebene mit dem transparenten PNG
  3. eine durchsichtige Kopie der Textebene
Was ich nicht wusste: Der transparente Textlayer 3 bleibt klickbar! Man sieht also den Layer 1, aber man klickt den Layer 3. Einfach, genial, einfach genial. Das wird gleich ausprobiert: http://www.haarkoetter.com
So, nach der anfänglichen Begeisterung widmen wir uns nun den Problemen dieser Lösung ;O)

Link ohne mouseover

Zwar funktionieren nun die Links, sprich, beim Anklicken wird zum Ziel verzweigt, aber alle anderen Effekte bleiben unsichtbar. Der Grund ist klar, denn der reagierende Layer 3 ist ja voll transparent, aka unsichtbar. Der Rollover findet zwar statt, aber ohne uns.
Ok. Hatte ich schon erwähnt, dass ich jQuery verwende? Die Links werden mit IDs versehen, dann kann man den Event an Layer 1 weiterreichen und dort gibt es dann den sichtbaren Hover-Effekt. Falls ein Leser sich daran erfreut, hier die Lösung eines Problemes gefunden zu haben, darf er gerne das entsprechende Skript hier posten. Ansonsten liefere ich das demnächst nach, denn...wär schon schön!

Kopie des Textlayers pflegen

Mit der Kopie des Layers wird die HTML-Quelle ganz schön unübersichtlich. Und bei Änderungen muss man stets daran denken, diese zweimal vorzunehmen. Blöd. Besonders dann, wenn Text hinzugefügt wird und dadurch die Position des Original-Links und der Kopie verrutschen. Dann sind (sichtbare) Links plötzlich nicht mehr klickbar.
Die Lösung liegt nahe: die Kopie wird erst zur Laufzeit gefüllt! Mit jQuery ist das nur ein Einzeiler! Das müsste sich sogar in CM-Systemen machen lassen, wenn man diesen Aufruf nach dem Laden des Contents einfügen kann.

No script, no fun

Graceful degradation, also die Rücksichtnahme auf ältere Browser und Menschen, die ohne Javascript surfen, ist hier unschwer umzusetzen, sieht aber hässlich aus. Der sichtbare Layer muss im CSS zunächst vor dem Bild liegen (ade, du schöner Rahmeneffekt) und wird erst durch ein onload-Skript nach hinten gedrückt. Jetzt bleibt alles klickbar, aber die Optik ist im Eimer.

Screenreader

Freundlicherweise sollte das Skript nur angewendet werden, wenn kein screenreader erkannt wurde, denn sonst werden alle Texte zweimal gelesen.

Übrigens: die hier gezeigte Site verwendet meinen automatischen Index (Blogartikel) zur Navigation.