Haruskah saya memasukkan elemen input ke dalam elemen label?

606

Apakah ada praktik terbaik tentang bersarang labeldan inputelemen HTML?

cara klasik:

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

atau

<label for="myinput">My Text
   <input type="text" id="myinput" />
</label>
jpsimard-nyx
sumber
107
Salah satu kelebihan besar menempatkan bagian <input />dalam <label>, adalah bahwa Anda dapat menghilangkan fordan id: <label>My text <input /></label>dalam contoh Anda. Jauh lebih bagus!
Znarkus
16
Sementara saya setuju bahwa inputtidak semantik berada di dalam label, saya perhatikan hari ini bahwa pengembang Bootstrap tidak setuju dengan saya . Beberapa elemen, seperti kotak centang sebaris, ditata secara berbeda tergantung pada apakah bagian inputdalam atau luar.
Blazemonger
6
BTW ini adalah ide yang sangat buruk untuk dibuat <label for="id">karena saya memiliki beberapa bentuk pada halaman dan saya tidak dapat menggunakan idatribut untuk banyak widget tanpa jatuh ke dalam unique id per pageperangkap. Satu-satunya cara yang dapat diterima untuk mengakses widget adalah dengan form + widget_name.
MaxZoom
5
@MaxZoom jika Anda memiliki begitu banyak formulir berbeda di halaman Anda dengan nama bidang yang identik sehingga Anda kesulitan membuat ID unik, Anda mungkin ingin mempertimbangkan kembali desain halaman Anda sedikit, IMHO; jelas saya tidak tahu situasi Anda, tapi itu hanya bau buruk bagi saya
Ken Bellows
5
@kenbellows Ini adalah ide desainer / bisnis (bukan saya) untuk meletakkan dua formulir pencarian pada satu halaman. Praktik pengalaman pengguna terbaik dapat berubah seiring waktu tetapi HTML harus cukup fleksibel (IMHO) untuk mencakup semua skenario yang terlihat.
MaxZoom

Jawaban:

529

Dari w3: Label itu sendiri dapat diposisikan sebelum, setelah atau di sekitar kontrol terkait.

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

atau

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

atau

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

Perhatikan bahwa teknik ketiga tidak dapat digunakan saat tabel digunakan untuk tata letak, dengan label di satu sel dan bidang formulir yang terkait di sel lain.

Salah satunya valid. Saya suka menggunakan contoh pertama atau kedua, karena memberi Anda lebih banyak kontrol gaya.

tanpa judul
sumber
14
Seperti yang dijawab, semua valid tetapi dalam praktik saya sendiri, saya biasanya puas dengan contoh pertama yang diberikan di sini oleh superUtitle untuk kotak teks, textareas, dan pilih. Tetapi untuk tombol radio dan kotak centang, saya biasanya menggunakan contoh ketiga, di mana saya ingin input sebelum teks yang menyertainya dan tidak ingin jenis lebar tetap yang sama dan / atau mengambang yang digunakan oleh label dan bidang lainnya. Jadi pada formulir apa pun yang diberikan, Anda mungkin menemukan saya menggunakan kedua format ini bersama-sama.
Funka
6
Saya bertanya-tanya apakah <label for="inputbox"><input id="inputbox" type="text" /></label>lulus sesuai dengan kriteria mereka.
Matt
64
Sayang sekali Anda tidak bisa membuat sarang label di dalam tag input. Akan jauh lebih rasional secara semantik, karena label benar-benar merupakan properti dari input, jika Anda melihatnya dari sudut pandang abstrak.
Alex
9
Dokumen WCAG tertaut mencakup opsi berikut "Kontrol terkandung dalam elemen label yang berisi teks label." Saya tidak tahu apakah itu ditambahkan pada tahun-tahun sejak @Sorcy berkomentar, tetapi skenario input-in-label dianggap valid sekarang.
Alex Weitzer
6
Ada masalah dengan label di dalam input, setidaknya di chrome, ketika Anda melampirkan pengendali event klik ke label, pawang dipecat dua kali ketika label diklik. Anda dapat melakukannya dengan return false;di akhir handler, tetapi jika Anda mungkin memiliki handler lain yang perlu dieksekusi setelahnya, dan menghentikan propagasi bukanlah suatu pilihan, ini menjadi masalah.
wired_in
67

saya lebih memilih

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

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

lebih

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

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

Terutama karena itu membuat HTML lebih mudah dibaca. Dan saya benar-benar berpikir contoh pertama saya lebih mudah untuk bergaya dengan CSS, karena CSS bekerja sangat baik dengan elemen bersarang.

Tapi kurasa itu masalah selera.


Jika Anda membutuhkan lebih banyak opsi gaya, tambahkan tag rentang.

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

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

Kode masih terlihat lebih baik menurut saya.

Znarkus
sumber
3
Termasuk input di dalam label sama dengan menggunakan HTML untuk tata letak.
Emil
8
Saya suka solusi ini juga untuk kasus-kasus seperti ini: <label>Expires after <input name="exp" /> days</label>(label ada sebelum dan sesudah elemen input)
Philipp
Saya pikir contoh terakhir adalah - selain atribut untuk dan id - tidak benar-benar berbeda dari memiliki label di sebelah input dan keduanya dibungkus menjadi div, liatau apa yang tidak, kan !?
retrovertigo
1
@retrovertigo - secara fungsional? Tidak. Itu hanya mengurangi markup, dan mengurangi penggunaan istilah yang terlalu banyak. Kami tahu input firstnameharus mengikuti label firstname, tetapi browser perlu deklarasi. Ini semua masalah selera dan apa yang ANDA anggap paling baik (dan paling mudah untuk di-debug) dalam kode Anda. Saya lebih suka menggunakan bersarang sekarang, meskipun butuh beberapa saat bagi saya untuk terbiasa dengannya.
Xhynk
3
@ MPavlak - melihat sekilas dan saya menemukan panduan ini dari w3.org. w3.org/WAI/tutorials/forms/labels . Saya kemudian memeriksa w3.org/TR/WCAG20-TECHS/H44.html . Di bagian bawah (tidak jelas) dikatakan bahwa untuk mengklaim kesesuaian, Anda harus lulus kriteria pengujian, dan yang secara khusus menyatakan bahwa Anda harus menggunakan atribut for. Pada kenyataannya, ketika saya terakhir kali menguji ini di Apple Voiceover (desktop screenreaders pangsa pasar 10%, screenreaders pangsa pasar 60% mobile) label implisit tidak bekerja, jadi itu adalah faktor utama lain. Semoga itu bisa membantu!
James Westgate
39

Jika Anda memasukkan tag input ke tag label, Anda tidak perlu menggunakan atribut 'untuk'.

Yang mengatakan, saya tidak suka memasukkan tag input dalam label saya karena saya pikir mereka terpisah, tidak mengandung, entitas.

Terry
sumber
8
Untuk itu mengharuskan Anda untuk menggunakan id, yang membuat penataan tata letak sangat sulit :-(
lethalman
39

Perbedaan perilaku: mengklik di antara label dan input

Jika Anda mengklik spasi di antara label dan input, ia mengaktifkan input hanya jika label berisi input.

Ini masuk akal karena dalam hal ini spasi hanyalah karakter lain dari label.

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

Mampu mengklik antara label dan kotak berarti:

  • lebih mudah untuk mengklik
  • kurang jelas dari mana segala sesuatu dimulai dan berakhir

Contoh kotak centang Bootstrap v3.3 menggunakan input di dalam: http://getbootstrap.com/css/#forms Mungkin sebaiknya Anda mengikuti mereka. Tetapi mereka berubah pikiran dalam v4.0 https://getbootstrap.com/docs/4.0/components/forms/#checkboxes-and-radios jadi saya tidak tahu lagi apa yang bijak:

Kotak centang dan penggunaan radio dibangun untuk mendukung validasi formulir berbasis HTML dan memberikan label yang ringkas dan dapat diakses. Dengan demikian, elemen <input>s dan <label>s kita merupakan elemen yang bertentangan dengan a <input>dalam <label>. Ini sedikit lebih verbose karena Anda harus menentukan id dan atribut untuk menghubungkan <input>dan <label>.

Pertanyaan UX yang membahas hal ini secara terperinci: /ux/23552/should-the-space-between-the-checkbox-and-label-be-clickable

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
sumber
Ini bukan perbedaan spesifikasi. Beralih berfungsi untuk kedua kasus di semua browser yang sesuai.
hexalys
@hexalys Terima kasih atas laporannya. Saya sudah memperbarui jawabannya. Apakah maksud Anda browser yang sesuai harus beralih atau tidak pada kedua kasus? Jika Anda dapat menautkan ke bagian standar yang relevan yang akan luar biasa.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
1
Iya. Meskipun saya gagal memperhatikan bahwa contoh Anda menyesatkan karena ruang Anda sebenarnya bukan ruang teks . Itu salah satu margindari kotak centang. Perilaku Firefox pada contoh Anda aneh dan tampak seperti bug. A labelakan berisi spasi atau padding di sekitar konten inline sebagai dapat diklik. Tetapi mengingat bahwa model Konten label inline / konten Frase , margin input tidak boleh diklik, kecuali label Anda dibuat display: blockdalam hal ini bagian dalam label blockmenjadi dapat diklik di semua browser.
hexalys
1
Perhatikan bahwa tautan Bootstrap dalam jawabannya masuk ke dokumen untuk v3.3. The docs untuk v4.0 tampaknya menunjukkan mereka telah berubah pikiran mereka. "Checkbox dan radio menggunakan dibangun untuk validasi form berbasis HTML dukungan dan memberikan ringkas, label diakses Karena itu, kami <input> dan <label> s adalah elemen saudara sebagai lawan dari <input> dalam <label>. Ini sedikit lebih bertele-tele karena Anda harus menentukan id dan atribut untuk menghubungkan <input> dan <label> ".
Michael Krebs
2
Perbedaan perilaku ini adalah yang terbesar bagi saya. Ketika elemen bersaudara, setiap margin pada elemen mana pun mengurangi area permukaan yang dapat diklik yang akan memicu elemen input. Bersarang input di dalam label mempertahankan area maksimum yang dapat diklik, memberikan aksesibilitas maksimum bahkan untuk pengguna yang kesulitan dengan gerakan mouse atau sentuhan yang tepat. Di Bootstrap 4, nesting masih berfungsi dan masih menampilkan yang sama tanpa perlu menyesuaikan atau mengganti CSS Bootstrap apa pun.
Turun
17

Secara pribadi saya suka menyimpan label di luar, seperti pada contoh kedua Anda. Itu sebabnya atribut FOR ada di sana. Alasannya adalah saya akan sering menerapkan gaya ke label, seperti lebar, untuk mendapatkan bentuk agar terlihat bagus (singkatan di bawah):

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

Membuatnya jadi saya bisa menghindari meja dan semua sampah di formulir saya.

Bayan
sumber
3
Bukankah Anda harus meninggalkan presentasi ke CSS, daripada menggunakan <br />untuk memisahkan input?
Znarkus
1
@Narkus - ya, biasanya saya membungkusnya dalam OL / LI untuk menangani pemformatan seperti itu, ini hanya contoh singkat.
Burung beo
1
@Parrots: Itu tidak masuk akal secara semantik, imo. Dan jika Anda perlu membungkusnya, mengapa tidak membungkusnya dengan label saja?
Znarkus
1
@Parot Dengan alasan itu saya pikir semua yang ada di halaman harus masuk ke dalam / li. Dan dengan <label> <span>My text</span> <input /> </label>Anda memiliki semua opsi penataan yang Anda perlukan.
Znarkus
1
Menggunakan "untuk" memaksa Anda untuk menggunakan id, yang buruk untuk tata letak hierarkis.
lethalman
15

Lihat http://www.w3.org/TR/html401/interact/forms.html#h-17.9 untuk rekomendasi W3.

Mereka mengatakan itu bisa dilakukan dengan cara apa pun. Mereka menggambarkan dua metode sebagai eksplisit (menggunakan "untuk" dengan id elemen) dan implisit (menanamkan elemen dalam label):

Eksplisit:

Atribut for mengaitkan label dengan kontrol lain secara eksplisit: nilai atribut for harus sama dengan nilai atribut id dari elemen kontrol terkait.

Implisit:

Untuk mengaitkan label dengan kontrol lain secara implisit, elemen kontrol harus berada di dalam konten elemen LABEL. Dalam hal ini, LABEL hanya dapat berisi satu elemen kontrol.

pengguna470514
sumber
Saya baru saja menemukan bahwa yang tersirat tidak bekerja di IE .... Ada ide?
carinlynchin
11

Keduanya benar, tetapi memasukkan input ke dalam label membuatnya jauh lebih fleksibel saat menata dengan CSS.

Pertama, a <label>dibatasi di mana elemen-elemen itu dapat mengandung . Misalnya, Anda hanya dapat meletakkan teks <div>antara <input>dan label, jika <input>tidak ada di dalam <label>.

Kedua, sementara ada solusi untuk membuat gaya lebih mudah seperti membungkus teks label bagian dalam dengan rentang, beberapa gaya akan diwarisi dari elemen induk, yang dapat membuat gaya lebih rumit.

nicholaides
sumber
apalagi fleksibel? bisakah kamu menguraikan? seperti yang telah disebutkan orang lain, Anda dapat dengan mudah membungkus teks label bagian dalam dengan rentang, kecuali itu yang membuatnya jauh kurang fleksibel?
MPavlak
7

'Gotcha' terkenal menyatakan bahwa Anda tidak boleh menyertakan lebih dari satu elemen input di dalam elemen <label> dengan atribut "untuk" eksplisit, misalnya:

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

Sementara ini mungkin tergoda untuk fitur formulir di mana nilai teks khusus sekunder untuk tombol radio atau kotak centang, fungsi klik-fokus dari elemen label akan segera melempar fokus ke elemen yang idnya secara eksplisit didefinisikan dalam atribut 'untuk' nya , sehingga hampir mustahil bagi pengguna untuk mengklik ke dalam bidang teks yang ada untuk memasukkan nilai.

Secara pribadi, saya mencoba menghindari elemen label dengan input anak-anak. Tampaknya tidak semestinya bagi elemen label untuk mencakup lebih dari label itu sendiri. Jika Anda memasukkan input ke label untuk mencapai estetika tertentu, Anda harus menggunakan CSS.

Harun
sumber
4
Ini bukan "gotcha". Ini secara eksplisit bagian dari spesifikasi; label dapat berisi hingga 1 kendali di dalamnya. Anda juga mencampur gaya implisit dan eksplisit di sini - jika Anda meletakkan kontrol di dalam label, Anda tidak perlu for... dan jika Anda ingin menggunakannya for, maka memiliki kontrol di dalam label tidak masuk akal .
cao
Benar, tetapi tampaknya spesifikasi ini tidak dipahami dengan baik. Kami mengalami masalah ini dengan formulir Drupal 6 API, yang menghasilkan markup yang membuat skenario tidak seperti yang dijelaskan di atas. Ada kolega saya dan saya menggaruk-garuk kepala kami selama satu atau dua menit, jadi saya pikir saya akan mengemukakan masalah ini di sini untuk mencegah potensi kebingungan di masa depan.
Aaron
tidak perlu untuk "untuk" di label-> skenario input. satu input per label dan itu memiliki manfaat tidak harus tahu nama atau id dan Anda dapat melakukan styling css yang bagus untuk menjaga hal-hal dienkapsulasi serta memiliki fokus terjadi ketika elemen lain seperti di dalamnya diklik. lihat zipstory.com/signup untuk contoh cara bersih melakukan ini.
Jason Sebring
Terima kasih; ini menjawab pertanyaan terkait lainnya yang saya miliki, yaitu apakah berpotensi memiliki lebih dari satu input di dalam label. (Konteks: Beberapa opsi tombol radio, satu per baris, setiap entri tombol radio memiliki input teks tipe 1, 2, 3, atau mungkin lebih banyak, dengan maksud mengklik pada suatu baris yang memiliki hasil memilih tombol radio garis itu, jika tidak dipilih, dan memungkinkan pengeditan input / input pada baris itu.) Ini membiarkan pintu terbuka untuk memiliki beberapa label untuk teks non-input dalam formulir, tetapi itu menjawab pertanyaan saya tentang apakah apa yang saya pikir baik-baik saja. (Bukan.)
Christos Hayward
6

Seperti yang dikatakan kebanyakan orang, kedua cara itu memang bekerja, tetapi saya pikir hanya yang pertama yang harus. Karena semantik ketat, label tidak "mengandung" input. Menurut pendapat saya, hubungan penahanan (orang tua / anak) dalam struktur markup harus mencerminkan penahanan dalam output visual . yaitu, elemen yang mengelilingi yang lain di markup harus digambar di sekitar yang ada di browser . Menurut ini, label harus saudara input, bukan orang tuanya. Jadi opsi nomor dua adalah arbitrer dan membingungkan. Setiap orang yang telah membaca Zen Python mungkin akan setuju (Flat lebih baik daripada bersarang, Jarang lebih baik daripada padat, Seharusnya ada satu - dan lebih disukai hanya satu - cara yang jelas untuk melakukannya ...).

Karena keputusan seperti itu dari W3C dan vendor peramban utama (memungkinkan "dengan cara apa pun yang Anda sukai untuk melakukannya", alih-alih "melakukannya dengan cara yang benar") adalah bahwa web sangat kacau hari ini dan kami para pengembang harus berurusan dengan kusut. dan kode warisan yang sangat beragam.

slashCoder
sumber
5

Saya biasanya pergi dengan dua opsi pertama. Saya telah melihat skenario ketika opsi ketiga digunakan, ketika pilihan radio di mana tertanam dalam label dan css berisi sesuatu seperti

label input {
    vertical-align: bottom;
}

untuk memastikan penyelarasan vertikal yang tepat untuk radio.

Victor Ionescu
sumber
2

Mengacu pada WHATWG ( Menulis antarmuka pengguna formulir ) tidak salah untuk memasukkan bidang input di dalam label. Ini menghemat kode Anda karena foratribut dari labeltidak lagi diperlukan.

Benny Neugebauer
sumber
2

Saya lebih suka membungkus elemen di dalam saya <label>karena saya tidak harus membuat id.

Saya adalah pengembang Javascript, dan React atau Angular digunakan untuk menghasilkan komponen yang dapat digunakan kembali oleh saya atau orang lain. Maka akan mudah untuk menduplikasi id di halaman, mengarah ke sana ke perilaku aneh.

Nicolas Zozol
sumber
1

Satu hal yang perlu Anda pertimbangkan adalah interaksi kotak centang dan input radio dengan javascript.

Menggunakan struktur di bawah ini:

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

Ketika pengguna mengklik "Teks teks", fungsi controlCheckbox () akan diaktifkan sekali.

Tetapi ketika tag input diklik, fungsi controlCheckbox () dapat diaktifkan dua kali di beberapa browser lama. Itu karena kedua input dan label tag memicu onclick event yang dilampirkan pada kotak centang.

Maka Anda mungkin memiliki beberapa bug di kotak centang Status Anda.

Saya mengalami masalah ini akhir-akhir ini di IE11. Saya tidak yakin apakah peramban modern bermasalah dengan struktur ini.

Mariusz
sumber
-1

Keuntungan utama menempatkan inputbagian dalamlabel adalah efisiensi mengetik untuk manusia dan penyimpanan byte untuk komputer.

@Znarkus mengatakan dalam komentarnya kepada OP,

Salah satu kelebihan besar menempatkan bagian <input />dalam <label>, adalah bahwa Anda dapat menghilangkan fordan id: <label>My text <input /></label>dalam contoh Anda. Jauh lebih bagus!

Catatan: Dalam kode @Znarknus, efisiensi lain dimasukkan tidak secara eksplisit dinyatakan dalam komentar. type="text"juga dapat dihilangkan dan inputakan membuat kotak teks secara default.

Perbandingan penekanan tombol dan byte berdampingan [1].

31 penekanan tombol, 31 byte

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

58 penekanan tombol, 58 byte

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

Jika tidak, snippet secara visual sama dan mereka menawarkan tingkat aksesibilitas pengguna yang sama. Seorang pengguna dapat mengklik atau mengetuk label untuk menempatkan kursor di kotak teks.

[1] File teks (.txt) dibuat di Notepad pada Windows, byte dari properti Windows File Explorer

Klik ini
sumber