HTML формы. Взгляд через призму семантики.

Подготовил: Евгений Рыжков Дата публикации: 06.08.2010

взгляд на html формы с точки зрения семантикиФормы верстают по разному: таблицами, блоками, списками или смешано. Но какой из этих способов будет правильным с точки зрения семантической верстки?

Таблицы?

<form action="">
<table>
<tr>
	<th><label>Имя:</label></th>
	<td><input type="text" /></td>
</tr>
<tr>
	<td colspan="2"><input type="submit" value="отправить" /></td>
</tr>
</table>
</form>

Исторически так сложилось, что изначально все версталось таблицами и формы не были тому исключением. Объясняется это просто — CSS почти не поддерживалось и верстка таблицами была единственным выходом.

Но те времена давно позади. Браузеры уже как минимум неплохо распознают почерк CSS, а значит пришло время вспоминать и о существовании других HTML тегов, которых не так уж и мало, а так же и о назначении этих самих тегов.

Таблицы, как наверное знают все, предназначены для разметки табличных данных. Формы на таблицы слабо похожи (кроме редких случаев, когда форма призвана заполнять действительно таблицу), поэтому вывод: таблицы не годятся для семантической верстки форм.

Блоки?

<form action="">
<div>
	<label>Имя:</label>
	<input type="text" />
</div>
<div>
	<input type="submit" value="отправить" />
</div>
</form>

Его аналоги — использование абзацев (тег <p>) или ненумерованный список (<ul>).

Использовать абзацы — это конечно извращение. А вот div'ы и списки не такие однозначные. В целом красивый и чистый код, с рядом плюсов:

  • гибкий код
  • минимум дополнительных тегов
  • при отключенных стилях структура формы сохранится

Такая разметка мне нравится. Но есть один недостаток — смысловой нагрузки минимум у такой разметки. Блоками (или строками списка) мы просто обозначаем, что этот блок является отдельным логической единицей. Т.е. такая разметка скорее нейтральна, чем несет какой-то смысловой посыл.

Список определений?

Список определений идеально подходит для верстки ассоциативных пар имя-значение. В форме такие связи видно прям таки требуют чтобы на них обратили внимание — это пары метки-поля форм:

<form action="">
<dl>
	<dt><label>Имя:</label></dt>
	<dd><input type="text" /></dd>
</dl>
<div><input type="submit" value="отправить" /></div>
</form>

Заметка

В пользу этого метода говорит еще и то, что некоторые CMS и движки для блогов по умолчанию уже предлагают формы такой разметки.

Добавим связи между метками и полями, с помощью атрибутов for и id. Но и это еще не все. Для полного фэншуя разберемся с мало используемыми тегами fieldset и legend. Что же об этих таинственных тегах поведают нам спецификации?

Fieldset позволяет авторам группировать тематически связанные элементы форм. Группировка помогает пользователю легче с ориентироваться в форме и облегчает навигацию визуальными и голосовыми браузерами. Правильное использование данного элемента делает формы более доступными.
Legend позволяет подписать сгруппированные поля. Это повышает доступность формы когда fieldset визуально не помечен.

Написано не двусмысленно. Но лучше проверить. Возьмем форму приличных размеров:

большая форма без fieldset

Думаю когда пользователь увидит такую форму, он нажмет на красный крестик в браузере. Посмотри на эту же форму, но уже с группировкой полей:

большая форма с группировкой fieldset

Визуально эффект очевиден, такая форма страха уже не вызывает. Для людей с ограниченными возможностями такая форма тоже будет намного более понятна и удобна: попадая в группу полей, браузер подскажет, что это за группа, плюс у пользователя есть возможность быстро перемещаться между группами полей (все эти удобные возможности сейчас больше теоретические, чем реальные, но мы сейчас не об этом). Т.е. рекомендации W3C имеют смысл и при использовании fieldset и legend формы действительно становятся более доступными.

Заметка

Есть мнение, что fieldset и legend имеют смысл только в паре. По одному эти теги бесполезны.

Все это конечно хорошо, но есть одно «но» — о наличии визуального разбиения форм на группы и подписях к ним принимает решение никак не верстальщик. Какой смысл во всех этих группировках, если дизайнер этого не нарисовал?

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

Простейшая форма тогда примет вид:

<form action="">
<fieldset>
<dl>
	<dt><label for="name">Имя:</label></dt>
	<dd><input type="text" id="name" /></dd>
</dl>
<div><input type="submit" value="отправить" /></div>
</fieldset>
</form>

Осталось разобраться как такой код нормально оформлять. Как никак дополнительные теги (dt и dd), которые нужно выстроить строками, добавляют проблем HTML кодеру. Попробуем оформить несложную форму по семантике:

форма, которую будем верстать семантически
<form action="">
<fieldset>
<dl>
	<dt><label for="name">Твое имя</label></dt>
	<dd><input type="text" id="name" /></dd>
	<dt><label for="email">Твой email</label></dt>
	<dd><input type="text" id="email" /></dd>
	<dt><label for="theme">Тема сообщения</label></dt>
	<dd>
		<select id="theme">
		<option></option>
		<option>Блaгодарность</option>
		<option>Нашел ошибку</option>
		<option>Хочу дополнить</option>
		<option>Есть идея</option>
		<option>Сотрудничество</option>
		<option>С темой не определился</option>
		</select>
	</dd>
	<dt><label for="message">Текст *</label></dt>
	<dd><textarea cols="" rows=""  id="message"></textarea></dd>
	<dt><label for="code">Защита от спама *</label></dt>
	<dd>
		<input type="text" id="code" maxlength="4"/>
		<img src="img/code.png" width="150" height="50" alt="" />
		<span id="feedbackChangeCode">сменить кратинку</span>
	</dd>
</dl>
<div class="submit">
		<input type="submit" name="send" value="отправить" />
</div>
</fieldset>
</form>
form {
	margin: 50px 0 0 100px;
	font: 14px "Trebuchet MS", "Helvetica CY", sans-serif;;
}
fieldset {
	margin: 0;
	padding: 0;
	border: none;
}
form dl {

}
form dt {
	float: left;
	clear: both;
	width: 120px;
	text-align: right;
	margin-right: 10px;
	vertical-align: top;
	position: relative;
	top: 4px;
}
form dd {
	margin-bottom: 10px;
}
form dd input {
	width: 200px;
	padding: 3px;
	border: 1px solid #6699ff;
}
* html form dd input {
	height: 25px;
}
form select {
	width: 208px;
	padding: 3px;
	border: 1px solid #6699ff;
}
* html form select {
	width: 200px;
}
form textarea {
	width: 390px;
	height: 120px;
	padding: 3px;
	border: 1px solid #6699ff;
}
form img {
	vertical-align: top;
	margin-left: 15px;
	border: 1px solid #6699ff;
}
form dd #code {
	width: 70px;
}
form .submit input {
	cursor: pointer;
	margin-left: 130px;
}
form #feedbackChangeCode {
	text-decoration: underline;
	cursor: pointer;
}
form #feedbackChangeCode:hover {
	color: #333;
}

Демо пример. Проверено в:

Выводы

Хотя разметка форм с помощью списка определений с точки зрения семантики наиболее подходит, не стоит на такой разметке зацикливаться. Часто придется применять разметку на блоках или ненумерованных списках, т.к. списки определений обладают меньшей гибкостью.

Материалы

По теме

Показать комментарии