Czy powinienem umieścić elementy wejściowe wewnątrz elementu etykiety?

605

Czy istnieje najlepsza praktyka dotycząca zagnieżdżania labeli inputelementów HTML?

klasyczny sposób:

<label for="myinput">My Text</label>
<input type="text" id="myinput" />

lub

<label for="myinput">My Text
   <input type="text" id="myinput" />
</label>
jpsimard-nyx
źródło
107
Jedną z największych zalet umieszczenia w <input />środku <label>jest to, że możesz pominąć fori id: <label>My text <input /></label>w swoim przykładzie. O wiele ładniej!
Znarkus,
16
Chociaż zgadzam się, że inputsemantycznie nie należy do wewnątrz label, zauważyłem dziś, że twórcy Bootstrap nie zgadzają się ze mną . Niektóre elementy, takie jak wbudowane pola wyboru, różnią się stylem w zależności od tego, czyinput są wewnątrz, czy na zewnątrz.
Blazemonger,
6
BTW to był naprawdę zły pomysł, <label for="id">ponieważ mam wiele formularzy na stronie i nie mogę użyć idatrybutu dla wielu widżetów bez wpadania w unique id per pagepułapkę. Jedynym dopuszczalnym sposobem uzyskania dostępu do widżetu jest form + widget_name.
MaxZoom,
5
@ MaxZoom, jeśli masz tyle różnych formularzy na stronie z identycznymi nazwami pól, że masz problemy z wymyśleniem unikatowych identyfikatorów, możesz ponownie rozważyć projekt strony, IMHO; oczywiście nie znam twojej sytuacji, ale to po prostu brzydko pachnie mi
Ken Bellows,
5
@kenbellows To projektant / firma (a nie mój) pomysł umieszczenia dwóch formularzy wyszukiwania na jednej stronie. Najlepsze praktyki użytkownika mogą się z czasem zmieniać, ale HTML powinien być wystarczająco elastyczny (IMHO), aby uwzględnić każdy widoczny scenariusz.
MaxZoom

Odpowiedzi:

528

Od w3: Sama etykieta może być umieszczana przed, za lub wokół powiązanej kontrolki.

<label for="lastname">Last Name</label>
<input type="text" id="lastname" />

lub

<input type="text" id="lastname" />
<label for="lastname">Last Name</label>

lub

<label>
   <input type="text" name="lastname" />
   Last Name
</label>

Należy zauważyć, że trzeciej techniki nie można użyć, gdy do układu używana jest tabela, z etykietą w jednej komórce i powiązanym polem formularza w innej komórce.

Każda z nich jest ważna. Lubię używać pierwszego lub drugiego przykładu, ponieważ daje on większą kontrolę nad stylem.

superUntitled
źródło
14
Jak odpowiedziałem, wszystkie są ważne, ale w mojej własnej praktyce zazwyczaj decyduję się na pierwszy przykład podany tutaj przez superUntitled dla pól tekstowych, obszarów tekstowych i zaznaczeń. Ale w przypadku przycisków opcji i pól wyboru zwykle używam trzeciego przykładu, w którym chcę wprowadzić dane przed towarzyszącym tekstem i nie chcę tego samego rodzaju stałej szerokości i / lub wartości zmiennoprzecinkowych, których używają pozostałe etykiety i pola. Tak więc w dowolnym formularzu możesz znaleźć mnie, używając obu tych formatów razem.
Funka
6
Zastanawiam się, czy <label for="inputbox"><input id="inputbox" type="text" /></label>zaliczenie jest zgodne z ich kryteriami.
Matt
63
Szkoda, że ​​nie można zagnieździć etykiety wewnątrz tagu wejściowego. Byłoby znacznie bardziej semantycznie racjonalne, ponieważ etykieta naprawdę jest własnością danych wejściowych, jeśli spojrzysz na nią z abstrakcyjnego punktu widzenia.
Alex
9
Połączony dokument WCAG zawiera następującą opcję „Formant jest zawarty w elemencie etykiety zawierającym tekst etykiety”. Nie wiem, czy zostało to dodane przez lata, odkąd @Sorcy skomentowało, ale scenariusz wprowadzania w etykiecie jest teraz uważany za ważny.
Alex Weitzer,
6
Wystąpił problem z wejściem wewnątrz etykiety, przynajmniej w chrome, gdy dołączasz moduł obsługi zdarzenia kliknięcia do etykiety, moduł obsługi jest uruchamiany dwukrotnie po kliknięciu etykiety. Możesz to zrobić za pomocą return false;na końcu procedury obsługi, ale jeśli masz innych procedur obsługi, które muszą zostać wykonane później, a zatrzymanie propagacji nie jest opcją, staje się to problemem.
wired_in
67

wolę

<label>
  Firstname
  <input name="firstname" />
</label>

<label>
  Lastname
  <input name="lastname" />
</label>

nad

<label for="firstname">Firstname</label>
<input name="firstname" id="firstname" />

<label for="lastname">Lastname</label>
<input name="lastname" id="lastname" />

Głównie dlatego, że sprawia, że ​​HTML jest bardziej czytelny. I tak naprawdę uważam, że mój pierwszy przykład jest łatwiej stylizować za pomocą CSS, ponieważ CSS działa bardzo dobrze z zagnieżdżonymi elementami.

Ale to chyba kwestia gustu.


Jeśli potrzebujesz więcej opcji stylizacji, dodaj znacznik zakresu.

<label>
  <span>Firstname</span>
  <input name="firstname" />
</label>

<label>
  <span>Lastname</span>
  <input name="lastname" />
</label>

Moim zdaniem kod nadal wygląda lepiej.

Znarkus
źródło
3
Uwzględnienie danych wejściowych w etykiecie jest takie samo, jak użycie HTML dla układu.
Emil,
8
Podoba mi się to rozwiązanie również w takich przypadkach: <label>Expires after <input name="exp" /> days</label>(etykieta jest przed i po elemencie wejściowym)
Philipp
Myślę, że ostatnim przykładem jest - oprócz atrybutów for i id - tak naprawdę nie różni się niczym od umieszczenia etykiety obok danych wejściowych i zawinięcia jej w div, lia co nie, prawda?
retrovertigo
1
@retrovertigo - funkcjonalnie? Nie. To po prostu zmniejsza znaczniki i ogranicza semantyczne nadużywanie terminów. Wiemy, że dane wejściowe firstnamepowinny być zgodne z etykietą firstname, ale przeglądarki potrzebują deklaracji. Wszystko zależy od gustu i tego, co Twoim zdaniem wygląda najlepiej (i jest najłatwiejsze do debugowania) w kodzie. Wolę używać teraz zagnieżdżonych, choć przyzwyczaiłem się do tego.
Xhynk
3
@MPavlak - szybkie spojrzenie i znalazłem te wskazówki z w3.org. w3.org/WAI/tutorials/forms/labels . Następnie sprawdziłem w3.org/TR/WCAG20-TECHS/H44.html . Na dole (jest to niejasne) napisane jest, że aby ubiegać się o zgodność, musisz spełnić kryteria testu, a konkretnie stwierdza, że ​​powinieneś użyć atrybutu for. W rzeczywistości, kiedy ostatnio testowałem to w Apple Voiceover (10% udział w rynku czytników ekranu na komputery stacjonarne, 60% udziałów w rynku czytników ekranu na urządzenia mobilne) niejawne etykiety nie działały, więc był to kolejny ważny czynnik. Mam nadzieję, że to pomaga!
James Westgate
39

Jeśli umieścisz tag wejściowy w tagu etykiety, nie musisz używać atrybutu „for”.

To powiedziawszy, nie lubię umieszczać tagu wejściowego w moich etykietach, ponieważ uważam, że są one osobnymi, nie zawierającymi bytów.

Terry
źródło
8
Opcja for wymaga jednak użycia identyfikatora, co sprawia, że ​​struktura układu jest bardzo trudna hierarchicznie :-(
lethalman 18.04.13
39

Różnica w zachowaniu: kliknięcie spacji między etykietą a danymi wejściowymi

Jeśli klikniesz spację między etykietą a danymi wejściowymi aktywuje dane wejściowe tylko wtedy, gdy etykieta zawiera dane wejściowe.

Ma to sens, ponieważ w tym przypadku spacja jest tylko kolejnym znakiem etykiety.

<p>Inside:</p>

<label>
  <input type="checkbox" />
  |&lt;----- Label. Click between me and the checkbox.
</label>

<p>Outside:</p>

<input type="checkbox" id="check" />
<label for="check">|&lt;----- Label. Click between me and the checkbox.</label>

Możliwość klikania między etykietą a polem oznacza, że ​​jest to:

  • łatwiej kliknąć
  • mniej jasne, gdzie wszystko się zaczyna i kończy

Przykłady pola wyboru Bootstrap v3.3 wykorzystują dane wejściowe: http://getbootstrap.com/css/#forms Mądrze może być ich przestrzeganie. Ale zmienili zdanie w wersji 4.0 https://getbootstrap.com/docs/4.0/components/forms/#checkboxes-and-radios, więc nie wiem już, co jest mądre:

Pola wyboru i radiotelefony są zbudowane tak, aby obsługiwać sprawdzanie poprawności formularzy oparte na HTML i zapewniać zwięzłe, dostępne etykiety. Jako takie, nasze <input>y i <label>y są elementy rodzeństwa, w przeciwieństwie do <input>W ciągu <label>. Jest to nieco bardziej szczegółowe, ponieważ musisz podać identyfikator i atrybuty, aby odnosić się do <input>i <label>.

Pytanie UX, które szczegółowo omawia ten punkt: /ux/23552/should-the-space-between-the-checkbox-and-label-be-clickable

Ciro Santilli
źródło
To nie jest specyfikacja. Przełącznik działa w obu przypadkach we wszystkich zgodnych przeglądarkach.
hexalys
@hexalys Dzięki za raport. Zaktualizowałem odpowiedź. Czy masz na myśli, że zgodne przeglądarki powinny przełączać się w obu przypadkach? Gdybyś mógł link do odpowiedniego standardowego fragmentu, byłoby świetnie.
Ciro Santilli 26 冠状 病 六四 事件 法轮功
1
Tak. Chociaż nie zauważyłem, że twój przykład wprowadza w błąd, ponieważ twoje miejsce nie jest tak naprawdę miejscem na tekst . To jedno marginz pól wyboru. Zachowanie Firefoksa w twoim przykładzie jest dziwne i wydaje się być błędem. A labelbędzie zawierać spacje lub wypełnienia wokół treści wstawianych jako klikalne. Ale biorąc pod uwagę, że model zawartości etykiety jest treścią wbudowaną / frazującą, margines danych wejściowych nie powinien być klikalny, chyba że twoja etykieta jest wykonana, display: blockw którym to przypadku wnętrze etykiety blockstaje się klikalne we wszystkich przeglądarkach.
hexalys
1
Zauważ, że link Bootstrap w odpowiedzi prowadzi do dokumentacji dla wersji 3.3. Dokumenty w wersji 4.0 wydają się wskazywać, że zmienili zdanie: „Pola wyboru i radia są zbudowane tak, aby obsługiwać sprawdzanie poprawności formularzy oparte na HTML i zapewniać zwięzłe, dostępne etykiety. W związku z tym nasze <input> i <label> s są elementami rodzeństwa w przeciwieństwie do <input> w <label>. Jest to nieco bardziej szczegółowe, ponieważ musisz podać id i atrybuty, aby odnosić się do <input> i <label> ".
Michael Krebs,
2
Ta różnica w zachowaniu jest dla mnie duża. Gdy elementy są rodzeństwem, dowolny margines na każdym elemencie zmniejsza obszar klikalny, który wyzwoli element wejściowy. Zagnieżdżenie danych wejściowych w etykiecie pozwala zachować maksymalny możliwy do kliknięcia obszar, zapewniając maksymalną dostępność nawet użytkownikom mającym problemy z precyzyjnymi ruchami myszy lub dotyku. W Bootstrap 4 zagnieżdżanie nadal działa i nadal wyświetla to samo bez konieczności dostosowywania lub zastępowania jakiegokolwiek CSS Bootstrap.
Turgs
17

Osobiście lubię trzymać etykietę na zewnątrz, jak w twoim drugim przykładzie. Właśnie dlatego istnieje atrybut FOR. Powodem jest to, że często stosuję style do etykiety, takie jak szerokość, aby formularz wyglądał ładnie (skrót poniżej):

<style>
label {
  width: 120px;
  margin-right: 10px;
}
</style>

<label for="myinput">My Text</label>
<input type="text" id="myinput" /><br />
<label for="myinput2">My Text2</label>
<input type="text" id="myinput2" />

Sprawia, że ​​mogę uniknąć stołów i innych śmieci w moich formularzach.

Papugi
źródło
3
Czy nie należy pozostawić prezentacji CSS, zamiast używać <br />do oddzielania danych wejściowych?
Znarkus,
1
@Znarkus - tak, zwykle owijam je w OL / LI, aby poradzić sobie z takim formatowaniem, to był tylko szybki przykład.
Papugi
1
@ Paprots: To nie ma sensu semantycznie, imo. A jeśli chcesz je owinąć, dlaczego nie po prostu owinąć je etykietą?
Znarkus,
1
@ Paprotki Z tego powodu uważam, że wszystko na stronie powinno znajdować się w ul / li. A dzięki <label> <span>My text</span> <input /> </label>tobie masz wszystkie opcje stylizacji, których (kiedykolwiek) potrzebujesz.
Znarkus,
1
Użycie „for” wymusza użycie identyfikatora, co jest złe w przypadku układów hierarchicznych.
zabójca
15

Zobacz http://www.w3.org/TR/html401/interact/forms.html#h-17.9 do zaleceń W3.

Mówią, że można to zrobić w obie strony. Opisują dwie metody jako jawne (użycie „for” z identyfikatorem elementu) i niejawne (osadzenie elementu w etykiecie):

Wyraźny:

Atrybut for jednoznacznie kojarzy etykietę z inną kontrolką: wartość atrybutu for musi być taka sama jak wartość atrybutu id powiązanego elementu kontrolnego.

Domniemany:

Aby skojarzyć etykietę z inną kontrolką w sposób niejawny, element kontrolny musi znajdować się w treści elementu LABEL. W takim przypadku ETYKIETA może zawierać tylko jeden element sterujący.

użytkownik470514
źródło
Właśnie odkryłem, że domniemane nie działa w IE ... jakieś pomysły?
carinlynchin,
11

Oba są poprawne, ale umieszczenie danych wejściowych wewnątrz etykiety sprawia, że ​​jest znacznie mniej elastyczna podczas stylizacji za pomocą CSS.

Po pierwsze, a <label>jest ograniczone, w których elementach może zawierać . Na przykład możesz wstawić <div>pomiędzy <input>tekstem a etykietą tylko, jeśli <input>nie ma go w środku<label> .

Po drugie, podczas gdy istnieją obejścia, które ułatwiają stylizację, takie jak zawijanie tekstu etykiety wewnętrznej za pomocą zakresu, niektóre style będą dziedziczone z elementów nadrzędnych, co może utrudnić stylizację.

nicholaides
źródło
znacznie mniej elastyczny? czy możesz rozwinąć? jak wspomnieli inni, możesz po prostu owinąć tekst wewnętrznej etykiety rozpiętością, chyba że to czyni go znacznie mniej elastycznym?
MPavlak
7

Znana „gotcha” nakazuje, abyś nigdy nie zawierał więcej niż jednego elementu wejściowego wewnątrz elementu <label> z wyraźnym atrybutem „for”, np .:

<label for="child-input-1">
  <input type="radio" id="child-input-1"/>
  <span> Associate the following text with the selected radio button: </span>
  <input type="text" id="child-input-2"/>
</label>

Chociaż może to kusić dla funkcji formularza, w których niestandardowa wartość tekstowa jest drugorzędna względem przycisku opcji lub pola wyboru, funkcja skupienia kliknięcia elementu etykiety natychmiast przeniesie fokus na element, którego identyfikator jest wyraźnie zdefiniowany w atrybucie „for” , co prawie uniemożliwia użytkownikowi kliknięcie zawartego pola tekstowego w celu wprowadzenia wartości.

Osobiście staram się unikać elementów etykiet z potomkami wejściowymi. Wydaje się semantycznie niewłaściwe, aby element etykiety obejmował więcej niż samą etykietę. Jeśli zagnieżdżasz dane wejściowe w etykietach, aby osiągnąć określoną estetykę, powinieneś użyć CSS.

Aaron
źródło
4
To nie jest „gotcha”. Jest to wyraźnie część specyfikacji; etykieta może zawierać do 1 kontrolki. Mieszasz tu także ukryte i jawne style - jeśli umieścisz kontrolę w etykiecie, nie potrzebujesz for... a jeśli chcesz użyć for, to kontrola w etykiecie nie ma większego sensu .
cHao
To prawda, ale wydaje się, że ta specyfikacja nie jest dobrze zrozumiana. Wystąpił ten problem z interfejsem API formularzy Drupala 6, który wygenerował znaczniki, które stworzyły scenariusz podobny do opisanego powyżej. Mój kolega i ja drapaliśmy się po głowie przez minutę lub dwie, więc pomyślałem, że rozwiążę tutaj ten problem, aby uniknąć potencjalnego zamieszania w przyszłości.
Aaron
nie ma potrzeby używania słowa „for” w scenariuszu etykiety-> wprowadzania. jedno wejście na etykietę i ma tę zaletę, że nie musi znać nazwy ani identyfikatora. Możesz zrobić fajne stylizacje css, aby zachować wszystko w sobie, a także skupić się, gdy klikniesz dowolny inny element w nim. zobacz zipstory.com/signup, na przykład czysty sposób na zrobienie tego.
Jason Sebring
Dziękuję Ci; to odpowiedziało na inne powiązane pytanie, które miałem, a mianowicie, czy ma ono zawierać więcej niż jeden wkład w obrębie etykiety. (Kontekst: kilka opcji przycisku opcji, po jednym w wierszu, każdy wpis przycisku opcji ma 1, 2, 3 lub ewentualnie więcej tekstów tekstowych, z zamiarem kliknięcia linii z wynikiem wybrania przycisku opcji tej linii, jeśli nie wybrano i pozwala na edycję danych wejściowych / wejściowych w tym wierszu.) To pozostawia otwarte drzwi do posiadania wielu etykiet dla tekstu bez danych wejściowych w formularzu, ale odpowiada na moje pytanie, czy to, co myślałem, było OK. (To nie było.)
Christos Hayward
6

Jak większość ludzi powiedziała, oba sposoby rzeczywiście działają, ale myślę, że tylko pierwszy powinien. Będąc semantycznie ścisłym, etykieta nie „zawiera” danych wejściowych. Moim zdaniem relacja przechowująca (nadrzędna / podrzędna) w strukturze znaczników powinna odzwierciedlać powstrzymywanie w wynikach wizualnych . tzn. element otaczający inny element znacznika powinien zostać narysowany wokół tego elementu w przeglądarce . Zgodnie z tym etykieta powinna być rodzeństwem danych wejściowych, a nie nadrzędnym. Zatem opcja numer dwa jest arbitralna i myląca. Każdy, kto przeczytał Zen Pythona , prawdopodobnie się zgodzi (Płaski jest lepszy niż zagnieżdżony, Rzadki jest lepszy niż gęsty, Powinien być jeden - a najlepiej tylko jeden - oczywisty sposób, aby to zrobić ...).

Z powodu takich decyzji podejmowanych przez W3C i głównych dostawców przeglądarek (zezwalając na „jakikolwiek sposób, w jaki wolisz to zrobić”, zamiast „zrób to we właściwy sposób”), Internet jest dziś tak poplątany, a my programiści mamy do czynienia z zaplątanymi i tak różnorodny starszy kod.

slashCoder
źródło
5

Zwykle wybieram dwie pierwsze opcje. Widziałem scenariusz, w którym zastosowano trzecią opcję, gdy opcje radiowe, w których osadzone były w etykietach i css, zawierały coś podobnego

label input {
    vertical-align: bottom;
}

w celu zapewnienia właściwego ustawienia pionowego radiotelefonów.

Victor Ionescu
źródło
2

Bardzo wolę zawijać elementy w sobie, <label>ponieważ nie muszę generować identyfikatorów.

Jestem programistą Javascript, a React lub Angular są używane do generowania komponentów, które mogą być ponownie wykorzystane przeze mnie lub innych. Łatwo byłoby zatem zduplikować identyfikator na stronie, prowadząc do dziwnych zachowań.

Nicolas Zozol
źródło
1

Jedną z rzeczy, które należy wziąć pod uwagę, jest interakcja pól wyboru i wejść radiowych z javascript.

Korzystanie z poniższej struktury:

<label>
  <input onclick="controlCheckbox()" type="checkbox" checked="checkboxState" />
  <span>Label text</span>
</label>

Gdy użytkownik kliknie „Tekst etykiety”, funkcja controlCheckbox () zostanie uruchomiona jeden raz.

Ale po kliknięciu znacznika wejściowego funkcja controlCheckbox () może zostać uruchomiona dwukrotnie w niektórych starszych przeglądarkach. Jest tak, ponieważ zarówno tagi wejściowe, jak i etykiety wywołują zdarzenie onclick dołączone do pola wyboru.

Wtedy możesz mieć jakieś błędy w swoim polu wyboru.

Ostatnio napotkałem ten problem na IE11. Nie jestem pewien, czy współczesne przeglądarki mają problemy z tą strukturą.

Mariusz
źródło
-1

Podstawową zaletą umieszczenia inputwewnątrzlabel jest wydajność pisania na klawiaturze dla ludzi i bajtowa pamięć dla komputerów.

@Znarkus powiedział w swoim komentarzu do OP:

Jedną z największych zalet umieszczenia w <input />środku <label>jest to, że możesz pominąć fori id: <label>My text <input /></label>w swoim przykładzie. O wiele ładniej!

Uwaga: W kodzie @Znarknus uwzględniono inną wydajność, która nie została wyraźnie określona w komentarzu. type="text"można również pominąć i inputdomyślnie wyświetla pole tekstowe.

Bezpośrednie porównanie naciśnięć klawiszy i bajtów [1].

31 klawiszy, 31 bajtów

<label>My Text<input /></label>

58 naciśnięć klawiszy, 58 bajtów

<label for="myinput">My Text</label><input id="myinput" />

W przeciwnym razie fragmenty są wizualnie równe i zapewniają ten sam poziom dostępności dla użytkowników. Użytkownik może kliknąć lub dotknąć etykiety, aby umieścić kursor w polu tekstowym.

[1] Pliki tekstowe (.txt) utworzone w Notatniku w systemie Windows, bajty z właściwości Eksploratora plików Windows

ThisClark
źródło