Obrazek w etykietce formularza vs Explorer
10 października 2006
Explorer posiada masę błędów, ale webdeveloperzy musieli nauczyć się z nimi walczyć. Jeden z nich - opisywany w poście - pozostaje niepoprawniony nawet w najnowszej wersji przeglądarki z Redmond. Chodzi o obrazek img umieszczony w elemencie label - kliknięcie na obrazek nie działa - to znaczy element formularza nie dostaje fokusu / nie jest zaznaczany.
Jednym z najpopularniejszych zastosowań obrazka jako etykietki jest wybór jednej opcji z wielu - a wizualny przekaz w postaci obrazków / ikon pomaga rozróżnić opcje. Kliknięcie na obrazek wydaje się naturalne.
Szukałem w Internecie hacków, ale nie znalazłem niczego ciekawego. Johnatan Snook proponuje skrypt podpinający zdarzenie onclick do obrazka. A fuj. Nie ma takiej potrzeby - ponieważ wynalazłem rozwiązanie w CSS.
Obrazki stosowane jako ikony obok tekstu można aplikować przez background-image, więc nie będę o nich wspominał.
Struktura
Ze względu na opisane przeze mnie wykorzystanie obrazka-etykietki, zastosuję specyficzną strukturę HTML. Jednak ogólne założenia opisanego hacka pozwolą Wam napisać swój własny kod, gdyby potrzeba było ułożyć inaczej pola formularza.
Tak więc mój HTML wygląda następująco:
<fieldset><div><label for="id-pola"><img height="wysokosc" src="sciezka" alt="" /><span><input id="id-pola" name="grupa" type="radio" /> Opis</span></label></div>…</fieldset>
Mam zwyczaj opakowywać poszczególne pola i ich etykietki w dodatkowe divy - pozwalają używać formularza nawet bez włączonych stylów - nie staje się jedną ciągłą linią tekstu i pól. Zrobicie jednak jak chcecie - wszystko co aplikuję w CSS divowi można zrobić labelowi.
Dalej mamy etykietkę, koniecznie z atrybutem for wskazującym na pole radio. W innym przypadku IE w ogóle nie powiąże tych elementów, mimo otoczenia jednego drugim!
W środku label umieściłem obrazek (czemu wysokość?) oraz w dodatkowym spanie pole oraz jego opis. Chyba nie warto wspominać o różnicy między name i id, ale gdyby jednak - id to identyfikator elementu, name zawiera zmienną używaną do przekazywania danych skryptom po stronie serwera - bądź w tym przypadku - grupujące pola radio.
Zaaplikowałem potem proste stylowanie, układające pola w formie, jakiej się spodziewamy po takim formularzu. Dodałem obramowanie dla każdego pola, aby było widać gdzie kończy się aktywny obszar.
The Hack
Po odpaleniu strony przykładowej w IE widać, że tylko kliknięcie na opis zaznacza pole. Dlatego hack na tym się opiera - spraw, aby użytkownik zawsze klikał na opis.
Skorzystałem z pozycjonowania relatywnego i umieściłem span nad obrazkiem, odwołując się do label.
fieldset label {position: relative;}fieldset label span {position: absolute;bottom: 0;}
W ten sposób pole + opis znalazły się na dole. Właściwości left / right zostawiłem w spokoju. Następnie trzeba zwiększyć pole do kliknięcia. Sposób ten składa się z paru hacków na raz.
Po pierwsze rozciągamy opis do 100% szerokości rodzica. Po drugie odsuwamy go od góry paddingiem. Po trzecie ustawiamy fałszywe tło, aby obszar aktywny powiększył się także poza same literki. Na końcu dodajemy padding dla obrazka równy jednej linii (około 1.25em). Nie krępuj się użyć innych metod na rozciągnięcie tego elementu nad obrazkiem jeśli masz inne zamiary co do końcowego efektu.
Padding górny można ustawić na sztywno, jeśli mamy do czynienia z jedną podstroną. Ja jednak postawiłem na expressions.
fieldset label img {padding-bottom: 1.25em;}fieldset label span {position: absolute;bottom: 0;width: 100%;padding-top: expression(this.parentNode.offsetHeight);background: url(fake);}
Zamiast ciągu „fake ” można użyć transparentnego GIF-a. Cały napisany dla IE CSS ukrywamy w bloku <!--[if lte IE 7]><![endif]--> a pod nim dodajemy jeszcze mały hack dla IE7 związany z hasLayout:
<!--[if IE 7]><style type="text/css">fieldset label {zoom: 1;}</style><![endif]-->
Działa cudnie. Jeśli odpalacie w IE a nie z poziomu IETab, to efekt jest identyczny (embedowany widget IE dodaje obwódkę wokoło labela). Mam nadzieję, że się workaround przyda. :)


