Чи слід вводити вхідні елементи всередині елемента мітки?


605

Чи є найкраща практика щодо вкладання labelта inputелементів HTML?

класичний спосіб:

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

або

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

107
Один з великих плюсів введення <input />всередину <label>, це те, що ви можете опускати forі id: <label>My text <input /></label>у своєму прикладі. Настільки приємніше!
Znarkus

16
Хоча я погоджуюся, що inputсемантично не належить до а label, я помітив сьогодні, що розробники Bootstrap не згодні зі мною . Деякі елементи, такі як вбудовані прапорці, inputвикладені по- різному в залежності від того, знаходиться всередині чи зовні.
Blazemonger

6
BTW це було дуже поганою ідеєю створити, <label for="id">оскільки у мене є кілька форм на сторінці, і я не можу використовувати idатрибут для багатьох віджетів, не потрапляючи в unique id per pageпастку. Єдиний прийнятний спосіб отримати доступ до віджета - за допомогою form + widget_name.
MaxZoom

5
@MaxZoom, якщо на вашій сторінці стільки різних форм з однаковими іменами полів, що у вас виникають проблеми зі створенням унікальних ідентифікаторів, ви, можливо, захочете трохи переглянути свій дизайн сторінки, IMHO; Очевидно, я не знаю вашої ситуації, але це мені просто пахне
Кен Беллоуз

5
@kenbellows Дизайнерська / бізнес (не моя) ідея розмістити дві форми пошуку на одній сторінці. Найкращі практики користувацького досвіду можуть змінюватися з часом, але HTML повинен бути досить гнучким (IMHO) для покриття будь-якого видимого сценарію.
MaxZoom

Відповіді:


528

Від w3: Сама мітка може бути розміщена до, після або навколо пов'язаного елемента управління.

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

або

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

або

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

Зауважте, що третю техніку не можна використовувати, коли використовується таблиця для компонування, з міткою в одній комірці та пов'язаним з нею полем форми в іншій комірці.

Або один дійсний. Мені подобається використовувати або перший, або другий приклад, оскільки це дає більше контролю над стилем.


14
Як я відповів, всі дійсні, але в моїй власній практиці я, як правило, зупиняюся на першому прикладі, поданому сюди superUntitled для текстових полів, текстових областей та вибору. Але для радіо кнопок і прапорців я зазвичай використовую третій приклад, де я хочу ввести текст, що додається до супровідного тексту, і не хочу того ж типу фіксованої ширини та / або плаваючого, який використовують інші мітки та поля. Тож у будь-якій одній формі ви можете знайти мене, використовуючи обидва ці формати разом.
Funka

6
Цікаво, чи <label for="inputbox"><input id="inputbox" type="text" /></label>пропуск за їх критеріями.
Метт

63
Шкода, що ви не можете вкласти мітку всередині тегу введення. Було б набагато більш семантично раціональним, оскільки мітка дійсно є властивістю вхідних даних, якщо ви бачите її з абстрактної точки зору.
Алекс

9
Зв'язаний документ WCAG включає наступний параметр "Керування міститься в елементі мітки, який містить текст мітки." Я не знаю, чи це було додано в роки з моменту коментування @Sorcy, але сценарій введення етикетки вважається дійсним зараз.
Алекс Вайцер

6
Виникає проблема із введенням всередині мітки, принаймні хромованої, коли ви прикріплюєте обробник подій клацання до мітки, обробник двічі звільняється при натисканні на мітку. Ви можете отримати це за допомогою return false;в кінці обробника, але якщо у вас, можливо, є інші обробники, які потрібно виконати після цього, і зупинити поширення не є можливим, це стає проблемою.
wired_in

67

я віддаю перевагу

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

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

над

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

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

Головним чином, це робить HTML більш читабельним. І я фактично думаю, що мій перший приклад легше стилізувати з CSS, оскільки CSS дуже добре працює з вкладеними елементами.

Але я думаю, це питання смаку.


Якщо вам потрібно більше варіантів стилізації, додайте тег "span".

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

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

На мій погляд, код все ще виглядає краще.


3
Включення вводу всередині мітки таке ж, як використання HTML для компонування.
Еміль

8
Мені подобається це рішення також і для таких випадків: <label>Expires after <input name="exp" /> days</label>(мітка є до та після вхідного елемента)
Philipp

Я думаю , що останній приклад - до того ж для атрибутів і ідентифікатор - на насправді не відрізняється від будь-якого має мітку поряд з входом і обидва обгорнуті в div, liабо те , що немає, це!?
ретровертиго

1
@retrovertigo - функціонально? Ні. Це просто зменшує розмітку та зменшує смислове перевиконання термінів. Ми знаємо, що вхід firstnameповинен відповідати мітці firstname, але браузерам потрібна декларація. Це все питання смаку і те, що ви вважаєте, що найкраще (і найлегше налагодити) у своєму коді. Я вважаю за краще використовувати вкладені зараз, хоча мені знадобилося певний час.
Xhynk

3
@MPavlak - швидкий погляд, і я знайшов це керівництво від w3.org. w3.org/WAI/tutorials/forms/labels . Потім я перевірив w3.org/TR/WCAG20-TECHS/H44.html . Внизу (це незрозуміло) йдеться про те, що для того, щоб заявити про відповідність, потрібно пройти критерії тестування, а конкретно зазначено, що слід використовувати атрибут. Насправді, коли я востаннє тестував це в Apple Voiceover (10% ринкової частки екранізаторів екрану, 60% ринкової частки екранізаторів мобільних), неявні ярлики не працювали, тому це було ще одним головним фактором. Сподіваюся, що це допомагає!
Джеймс Вестгейт

39

Якщо ви включите тег введення в тег мітки, вам не потрібно використовувати атрибут "для".

З цього приводу я не люблю включати тег введення в свої мітки, тому що я думаю, що вони є окремими, не містять сутності.


8
Тим не менш, потрібно використовувати ідентифікатор, що робить структурування макета ієрархічно дуже важким :-(
летальний

39

Різниця в поведінці: клацання в просторі між міткою та введенням

Якщо натиснути пробіл між міткою та входом, він активує вхід, лише якщо мітка містить введення.

Це має сенс, оскільки в цьому випадку простір - це лише інший символ етикетки.

<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>

Можливість натискати між міткою та полем означає, що це:

  • простіше натиснути
  • менш зрозуміло, де все починається і закінчується

У прикладах bootstrap v3.3 використовуйте введення всередині: http://getbootstrap.com/css/#forms Ви можете дотримуватися їх. Але вони передумали в v4.0 https://getbootstrap.com/docs/4.0/components/forms/#checkboxes-and-radios, тому я вже не знаю, що мудрого:

Використовувані прапорці та радіостанції створені для підтримки перевірки форм на основі HTML та надання стислих, доступних міток. Таким чином , наші <input>s і <label>s є родинні елементи , на відміну від в <input>межах <label>. Це трохи більше багатослівним , як ви повинні вказати ідентифікатор і атрибути співвідносити <input>і <label>.

Питання щодо UX, яке детально обговорює цей момент: /ux/23552/should-the-space-bet between-the-checkbox-and-label-be- clickable


Це не специфічна різниця. Перемикач працює в обох випадках у всіх сумісних браузерах.
hexalys

@hexalys Дякуємо за звіт. Я оновив відповідь. Ви маєте на увазі, що сумісні веб-переглядачі повинні змінювати чи ні в обох випадках? Якби ви могли зв'язати з відповідним стандартним проходом , який був би дивним.
Чіро Сантіллі郝海东冠状病六四事件法轮功

1
Так. Хоча я не помітив, що ваш приклад вводить в оману, оскільки ваш простір насправді не є текстовим простором . Це marginпрапорець. Поведінка Firefox на вашому прикладі властива і здається помилкою. A labelміститиме пробіли або прокладки навколо вбудованого вмісту, як натискання. Але з огляду на те, що модель вмісту мітки є вбудованим / фразовим вмістом, поле введення не повинно бути доступним для натискання, якщо тільки ваш ярлик зроблений, і display: blockв такому випадку всередину мітки не blockможна натискати у всіх браузерах.
hexalys

1
Зауважте, що посилання Bootstrap у відповіді йде на документи для v3.3. У документи для v4.0 , здається, вказують , що вони змінили свою думку :. «Прапорці та радіо використовувати побудовані для валідації форм підтримки HTML на основі і представляти короткі, доступні ярлики Таким чином , наш <вхід> s і <мітка> s є двійників елементи , на відміну від <вхід> в <знак>. Це трохи більше багатослівним , як ви повинні вказати ідентифікатор і атрибути зв'язати <введення "і" мітка> ».
Майкл Кребс

2
Ця різниця в поведінці для мене велика. Коли елементи є побратимами, будь-який запас будь-якого елемента зменшує площу поверхні, що можна натискати, що запустить вхідний елемент. Введення введення всередині етикетки зберігає максимальну площину, що можна натискати, надаючи максимальну доступність навіть тим користувачам, які борються з точними рухами миші та дотику. У Bootstrap 4 вкладення все ще працює і все ще відображається тим самим, не потребуючи коригування або перестановки будь-якого CSS Bootstrap.
Турги

17

Особисто мені подобається тримати етикетку зовні, як у вашому другому прикладі. Тому атрибут FOR є. Тому я часто застосовую стилі до мітки, як ширина, щоб форма виглядала красиво (скорочено нижче):

<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" />

Робить так, щоб я міг уникати таблиць і всього цього мотлоху у своїх формах.


3
Чи не слід залишати презентацію CSS, замість того, щоб використовувати <br />для розділення входів?
Znarkus

1
@ Znarkus - так, зазвичай я обертаю їх в OL / LI, щоб вирішити таке форматування, це був лише короткий приклад скорочення.
Папуги

1
@Parrots: Семантично це не має великого сенсу, imo. А якщо вам потрібно їх обернути, чому б просто не обернути їх етикеткою?
Znarkus

1
@Parrots З цим міркуванням я думаю, що все на сторінці має проходити всередині ul / li. А у <label> <span>My text</span> <input /> </label>вас є всі варіанти стилізації, які вам (коли-небудь) знадобляться.
Znarkus

1
Використання "для" змушує використовувати ідентифікатор, що погано для ієрархічних макетів.
летальний

15

Див. Http://www.w3.org/TR/html401/interact/forms.html#h-17.9 для рекомендацій W3.

Кажуть, це можна зробити будь-яким способом. Вони описують два методи як явні (використовуючи "для" з ідентифікатором елемента) та неявні (вбудовуючи елемент у мітку):

явна:

Атрибут for асоціює мітку з іншим елементом управління: значення атрибута має бути таким же, як значення атрибута id асоційованого елемента управління.

неявні:

Щоб неявно пов'язати мітку з іншим елементом управління, елемент керування повинен міститись у вмісті елемента LABEL. В цьому випадку мітка може містити тільки один елемент управління.


Я щойно виявив, що неявна не працює в IE ... багато ідей?
carinlynchin

11

Обидва є правильними, але введення інформації всередині етикетки робить її набагато менш гнучкою під час стилізації за допомогою CSS.

По-перше, a <label>обмежується в тому, які елементи він може містити . Наприклад, ви можете ставити <div>між <input>текстом та текстом мітки лише у тому випадку, якщо значення знака <input>не знаходиться всередині <label>.

По-друге, хоча існують обхідні шляхи для полегшення стилізації, як, наприклад, загортання внутрішнього тексту мітки прольотом, деякі стилі будуть успадковані від батьківських елементів, що може ускладнити стилізацію.


набагато менш гнучким? чи можете ви докладно? як уже згадували інші, ви можете просто обернути внутрішній текст мітки прольотом, хіба що це робить його набагато менш гнучким?
МПавлак

7

Помітний "gotcha" наказує, що ви ніколи не повинні включати більше одного вхідного елемента всередині елемента <label> з явним атрибутом "for", наприклад:

<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>

Хоча це може бути привабливим для функцій форми, в яких спеціальне текстове значення є вторинним для перемикача або прапорець, функціональна функція фокусування клацання елемента мітки негайно кине фокус на елемент, ідентифікатор якого чітко визначений в атрибуті "для" , завдяки чому користувач майже не може натиснути на текстове поле, що міститься, щоб ввести значення.

Особисто я намагаюся уникати елементів етикетки із введеннями дітей. Здається, що семантично неправильно елемент мітки містити більше, ніж сам ярлик. Якщо ви вкладаєте вкладиші в мітки, щоб досягти певної естетичності, вам слід використовувати CSS.


4
Це не "готча". Це явно входить в специфікацію; мітка може містити до 1 елемента управління. Ви також змішанням приховані і явні стилі тут - якщо поставити контроль всередині етикетки, вам не потрібно for... і якщо ви хочете використовувати for, то маючи контроль всередині етикетки не має особливого сенсу .
cHao

Щоправда, але, здавалося б, ця специфікація недостатньо зрозуміла. Ми зіткнулися з цією проблемою з Drupal 6 в форм API, який генерував код, створений сценарій не в відміну від описаного вище. У мене був мій колега, і я чухав голову хвилину-дві, тож я подумав, що я видам цю проблему, щоб уникнути потенційної плутанини в майбутньому.
Aaron

немає необхідності "для" в сценарії введення міток> введення. один вхід на етикетку, і це має перевагу в тому, що не потрібно знати ім’я чи ідентифікатор, і ви можете зробити гарний стиль css, щоб зберегти інкапсульовані речі, а також зробити фокус, коли натиснути будь-який інший елемент, такий як. см zipstory.com/signup, наприклад чистий спосіб зробити це.
Джейсон Себрінг

Дякую; це відповіло на інше відповідне запитання, яке у мене виникло, а саме: чи має воно потенційно більше одного вводу всередині мітки. (Контекст: Кілька варіантів перемикання, по одному на рядок, кожен запис перемикача має 1, 2, 3 або, можливо, більше входів тексту типу, з наміром натиснути на рядок, що має результат вибору перемикача цієї лінії, якщо знято, і дозволяє редагувати входу / входів на цій лінії.) це залишає двері відкритими , щоб мати декілька етикеток для не вводити тексту в формі, але він відповів на моє запитання про те , що я подумав було ОК. (Не було.)
Крістос Хейвард

6

Як сказала більшість людей, обидва способи дійсно працюють, але я думаю, що тільки перший повинен. Будучи семантично суворим, мітка не "містить" введення. На мій погляд, стримування (батько / дитина) відносини в структурі розмітки повинні відображати локалізації в візуальному виході . тобто елемент, що оточує інший в розмітці, повинен бути намальований навколо цього в браузері . У відповідності з цим, мітка повинна бути спорідненою на вхід, а не його батьки. Отже варіант номер два довільний і заплутаний. Кожен, хто прочитав дзен Python , напевно, погодиться (Flat краще, ніж вкладений, Sparse краще, ніж щільний. Там повинен бути один - і бажано лише один - очевидний спосіб зробити це ...).

Через такі рішення від W3C та великих постачальників веб-переглядачів (дозволяючи "в будь-який спосіб ви вважаєте за краще зробити це", а не "робити це правильно"), це те, що Інтернет сьогодні так заплутаний, і нам розробникам доводиться мати справу з заплутаними. і такий різноманітний спадковий код.


5

Я зазвичай йду з першими двома варіантами. Я бачив сценарій, коли був використаний третій варіант, коли вибір радіо, де вбудований в мітках і CSS містив щось на кшталт

label input {
    vertical-align: bottom;
}

для того, щоб забезпечити правильне вертикальне вирівнювання для радіостанцій.



2

Я дуже вважаю за краще загортати елементи всередині себе, <label>тому що мені не потрібно генерувати ідентифікатори.

Я розробник Javascript, і Реагувати або Кутові використовуються для створення компонентів , які можуть бути повторно використані мною або іншими. Тоді було б легко дублювати ідентифікатор на сторінці, що веде до дивної поведінки.


1

Одне, що вам потрібно врахувати, - це взаємодія прапорців і радіо входів з javascript.

Використовуючи структуру нижче:

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

Коли користувач натисне "Текст мітки", функція controlCheckbox () буде запущена один раз.

Але при натисканні на тег введення функція controlCheckbox () може бути запущена двічі у деяких старих браузерах. Це тому, що і теги вводу, і мітки викликають події onclick, приєднані до прапорця.

Тоді у вашому прапорець-станції можуть виникнути помилки.

Я нещодавно зіткнувся з цим питанням на IE11. Я не впевнений, що якщо сучасні браузери мають проблеми з цією структурою.


-1

Основною перевагою розміщення inputвсередині labelє введення ефективності для людей та зберігання байтів для комп'ютерів.

@Znarkus сказав у коментарі до ОП,

Один з великих плюсів введення <input />всередину <label>, це те, що ви можете опускати forі id: <label>My text <input /></label>у своєму прикладі. Настільки приємніше!

Примітка. У коді @Znarknus інша ефективність була включена, явно не вказана в коментарі. type="text"також може бути пропущено, і inputза замовчуванням буде показано текстове поле

Побічне порівняння натискань клавіш і байтів [1].

31 натискання клавіш, 31 байт

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

58 натискань клавіш, 58 байт

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

В іншому випадку, фрагменти візуально рівні, і вони пропонують один і той же рівень користувача доступності. Користувач може натиснути або торкнутись мітки, щоб розмістити курсор у текстовому полі.

[1] Текстові файли (.txt), створені в Блокноті в Windows, байти із властивостей Windows File Explorer

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.