Как часто вам приходится встречать или писать подобное:

<input type="text" placeholder="Имя">

Так вот, такой код считается плохой практикой. Следует понимать, что placeholder - это не label.

Давайте рассмотрим, почему так и как этого избегать:

  • Каждому элементу формы input следует прописывать label. Когда пользовательские экранные читалки добираются к полю формы, label объявляется вместе с типом поля (например, "Имя, введите текст"). Если label отсутствует, пользователи могут не понять, что именно им нужно ввести (будет прочитано "введите текст");
  • Некоторые читалки всё же используют placeholder в качестве label, но полагаться на такие кейсы не рекомендуется;
  • По умолчанию, placeholder отображается светло-серым цветом с низким контрастом. Он может быть нечитаем для людей с плохим зрением или в определенных условиях, например при ярком солнечном свете;
  • Да, можно увеличить контраст, используя псевдоэлемент ::placeholder. Но если контраст слишком насыщен, пользователи могут ошибочно принять placeholder за данные, которые были заполнены автоматически;
  • Использование и отображение <label> увеличивает целевой размер поля формы, что может быть очень полезным, особенно на сенсорных устройствах;
  • Если placeholder работает как единственный label, необходимо понимать, что он исчезает, когда пользователь вводит данные. Это усложняет процесс заполнения формы, т.к. нужно помнить про назначение данного поля в случае возврата, особенно в сложных или редко используемых формах;
  • Пользователи не смогут проверить, что они заполнили, перед отправкой формы, потому что они увидят только введённый текст и не увидят label;
  • Если браузеры автоматически заполнил поля, пользователю нужно будет вырезать и вставить автоматически заполненные значения, чтобы проверить, правильно ли браузеры заполнили поля;
  • Если placeholder не вмещается по ширине поля, он обрезается;
  • Инструменты перевода, подобные Google Translate, могут не переводить значения атрибутов полей (а placeholder - это атрибут);
  • Для UX лучше, чтобы label располагался над соответствующим текстовым полем, а не в нём.

Поэтому, лучшим решением будет писать так:

<label for="firstname">Имя</label>
<input type="text" id="firstname">