Budowa formularzy
Oryginał tego tekstu jest autorstwa Riddle. Na Licencji CC.
Standardy sieciowe i przejrzysty kod czasem stwarzają problemy z rzeczami bardzo prostymi. Jeden z nich jest dość pospolity — musimy złożyć formularz. W większości przypadków nie powinniśmy
korzystać z tabeli — formularz napisany na blokach div
bądź im podobnych elementach może być później przekształcony, tabela jest statyczna i mało efektywna.
Na początek napiszmy strukturę takiego formularza. Wykorzystamy znaczniki, które przez co niektórych webmasterów zostały już zapomniane, bądź nigdy nie używane. Fieldset
jest zestawem pól formularza, w naszym będzie tylko jeden taki zestaw.
<form action="">
<fieldset>
…</fieldset>
</form>
Fieldset
posiada domyślne dopełnienie w środku, odsuwające kontrolki od, także domyślnego, obramowania. Można wyłączyć taki wygląd przez CSS.
fieldset {
border: none;
padding: 0;
}
Następnie możemy nazwać nasz zestaw pól, bądź w tym wypadku, formularz. Służy do tego znacznik legend
. Umiejscawia się domyślnie centralnie na krawędzi fieldset
, gdybyśmy nie wyłączali obramowania byłoby to dobrze widoczne.
<form action="">
<fieldset>
<legend>Komentarz</legend>
</fieldset>
</form>
Dalej wypada zacząć dodawać pola formularza. Input
, textarea
, select
gdy potrzeba. W przypadku elementów input
warto nadać klasę określającą z jakim typem mamy do czynienia.
<input class="text" type="text" />
<input class="check" type="checkbox" />
<input class="radio" type="radio" />
Bo o ile możemy korzystając z selektorów atrybutów odnieść się do każdego z typu przez:
input[type=text], input[type=radio]
…
To starsze przeglądarki oraz Internet Explorer 6 nie zrozumieją takiego zapisu. Powinno się oddzielić style dla pól formularza, bo nie wszystkie właściwości CSS aplikują się jednakowo we wszystkich
agentach. Osobiście jestem także zwolennikiem niestylowania przycisków submit
— zwykle to przeglądarka korzystając z wyglądu kontrolek systemowych powinna się nimi zająć. O ile jeszcze
nadanie stylu „przycisku” — wypukły kawałek zakolorowanego miejsca mówi, że da się go kliknąć, to zupełnie płaski, niczym tekstowy input
jest złym rozwiązaniem.
Kolejnym elementem wartym wspomnienia, co więcej — prawie niezbędnym w przypadku pól checkbox
czy radio
— jest label
. Etykietka tekstowa
przypisana do którejś z kontrolek, aktywująca focus bądź zaznaczająca pole wyboru w tej kontrolce. Koniec z klikaniem maleńkiego kwadracika żeby zaznaczyć pole — kliknij jego opis. Tak więc wygląda
nasz formularz:
<form action="">
<fieldset>
<legend>
Komentarz</legend>
<label for="fNick">
Nick</label>
<input id="fNick" name="fNick" class="text" type="text" />
<label for="fMail">
Mail</label>
<input id="fMail" name="fMail" class="text" type="text" />
<label for="fText">
Treść</label>
<textarea id="fText" name="fText" cols="40" rows="10"></textarea>
<input id="fSave" name="fSave" class="check" type="checkbox" />
<label for="fSave">
Zapamiętaj dane</label>
<input id="fSubmit" name="fSubmit" class="submit" type="submit" value="Dodaj komentarz" />
</fieldset>
</form>
Uwaga do zapamiętania, jeśli jeszcze ktoś nie kojarzy — o ile w XHTML nie identyfikuje się już elementów za pomocą name
, tylko id
, to pola formularzy korzystają z atrybutu
name
aby przekazać skryptowi po stronie serwera wymagane zmienne i dane.
Zarówno input
(textarea
, nieużyty tutaj select
tak samo) jak i label
są elementami liniowymi,
co oznacza że pojawiają się na stronie jak tekst — jeden za drugim ciurkiem. Dlatego osoby początkujące starające się podejść drogą
standardów do formularzy często wstawiają znacznik złamania linii za każdym inputem — br
.
Rozwiązanie to nie jest optymalne. Wyglądać może i będzie znośnie, ale nie na samym wyglądzie się teraz skupiamy. Ja proponowałbym ująć każdą kontrolkę z jej opisem w div
.
Div
jako element blokowy łamie linię przed sobą i za sobą co stworzy podobny efekt rozdzielenia pól formularzy; także gdy wyłączymy style. Co więcej — gdyby nam kiedyś
znudził się wygląd takiego formularza, możemy zmienić element div
w form
na liniowy. Podejście metodą br
wymagałoby
usunięcia tych znaczników z wielu stron.
<form action="">
<fieldset>
<legend>
Komentarz</legend>
<div>
<label for="fNick">
Nick</label>
<input id="fNick" name="fNick" class="text" type="text" />
</div>
<div>
<label for="fMail">
Mail</label>
<input id="fMail" name="fMail" class="text" type="text" />
</div>
<div>
<label for="fText">
Treść</label>
<textarea id="fText" name="fText" cols="40" rows="10"></textarea>
</div>
<div>
<input id="fSave" name="fSave" class="check" type="checkbox" />
<label for="fSave">
Zapamiętaj dane</label>
</div>
<div>
<input id="fSubmit" name="fSubmit" class="submit" type="submit" value="Dodaj komentarz" />
</div>
</fieldset>
</form>
Po lekkim (tylko wygląd kontrolek, kolory oraz tekst) ostylowaniu otrzymujemy taki oto formularz. Pierwszą rzeczą rzucającą się w oczy jest brak wyrównania pól tekstowych względem siebie — sterczą nierówno za tekstem.
Należy je odepchnąć równo od opisów pól, aby stworzyły siatkę jak w przypadku tabeli. W tym przykładzie zamienimy w CSS label
na element blokowy i nadamy mu szerokość.
label {
display: block;
width: 100px;
}
Zamiast pikseli można także użyć procentów, em
ów, etc. Efekt jaki osiągnęliśmy nadal nie jest taki jakbyśmy sobie
życzyli. Label
z uwagi na blokowość wytworzył nową linię za sobą i przeniósł input
pod siebie. Więc należy zamienić input
na blok oraz ustawić pływanie w lewą stronę, tak samo jak w przypadku label
.
label {
display: block;
width: 100px;
float: left;
}
input, textarea {
display: block;
float: left;
}
Po włączeniu float
należy zadbać, aby poszczególne linijki pól formularza — złożone z div
ów — nadal rozdzielały kontrolki. Jako że wszystkie
elementy w środku div
a zostały wybite z flowu dokumentu, więc on sam stanie się prawie bezużyteczny — pusty div
nie przedstawia wartości na
stronach. Należy więc zadbać, aby zaczął się „przejmować” elementami które są w środku, nawet jeśli mają float
i wystają. Możemy także dodać od razu odstęp pionowy.
div {
overflow: hidden;
clear: both;
margin-bottom: 0.5em;
}
Dodałem także clear: both
, aby upewnić się że na pewno formularz pojawi się tak jak sobie wymarzyłem (Internet Explorer zwykle w tym miejscu się foszy). Efekt jest już lepszy. Pozostał tylko ten checkbox
, który ze względu na odwrotne położenie elementów label
i input
w kodzie został z lewej strony bez odstępu. Można to zmienić aplikując input
z klasą check
lewy margines:
input.check {
margin-left: 100px;
}
Oraz wyłączyć szerokość dla etykietki tego pola, której dodajemy też klasę:
label.check {
width: auto;
}
Podobnie robimy z samotnym przyciskiem wysyłającym komentarz:
input.check,
input.submit {
margin-left: 100px;
}
Gotowy formularz prezentuje się całkiem jak tabela — jest jednak wolny od niesemantycznych znaczników i działa sprawniej za
pomocą label
— kliknij w tekst etykietki formularza a zobaczysz jak pozytywny efekt powoduje.
Z powodu błędu obliczania odległości po zaaplikowaniu float
dla elementów, w Internet Explorerze checkbox
oraz przycisk będą odsunięte o 100px
za
bardzo w prawo. Można rozwiązać dodatkową regułą CSS naprawiającą błąd:
input.check,
input.submit {
display: inline;
}
display:inline
zostanie zignorowane, ponieważ elementy mające float
nie reagują na zmianę display
(poza none
).
Pytania? Komentarze? Napisz na forum kursu lub edytuj tę stronę.
Zmodyfikowano: 03.09.2007, 21:26