Уже многие годы HTML-формы являются непременным атрибутом сайтов. Самые распространённые из них — авторизация и регистрация. И пусть в последнее время всё чаще встречается эмуляция с помощью JavaScript — пользователь вводит данные и нажимает кнопку, потом скрипт всё собирает и отсылается на сервер — мы всё равно называем это формами.
Как мы знаем, в процессе той же регистрации юзеру порой приходится заполнять множество полей. Для удобства, иногда применяются скрытые поля, которые активируются при активации определённого элемента — обычно чекбокс (флажок) или радиокнопка.
Чтобы Вы лучше представляли, вот картинка с примером:
Исторически такие вещи делались на JavaScript. И, надо сказать, в массе своей делаются так до сих пор.
Но мы уже давно живём в эпоху CSS 3. Ещё в CSS 2 существовал паттерн +, который означает селектор сестринских элементов. Например, запись p+div предписывает применять правило только для элементов div, которые располагаются сразу после тега p (не внутри, а за ним). Например, для такой конструкции правило выполнится:
<p>Параграф</p> <div>Контейнер</div>
А для такой — нет:
<p>Параграф</p> <h5>Заголовок</h5> <div>Контейнер</div>
В третьей редакции появился паттерн ~ (тильда, кнопка обычно располагается над клавишей Tab, активируется при нажатии с Shift). Запись: p~div означает любые элементы div, которые расположены после тега p. В примере HTML-кода выше, стили применятся в обоих случаях.
Это были базовые понятия, чтобы мы смогли начать думать в правильном направлении.
Итак. Пусть у нас есть такая заготовка формы:
Чтобы сразу не нагружать пользователя, мы скрываем часть элементов. Первое — это ненужное пока поле Другое, где пользователь сможет текстом указать источник информации о сайте. Второе — текстовая область, в которую пользователь, при желании, сможет вписать вопрос автору сайта.
Как уже говорил, в классическом случае подобное решается с помощью JavaScript или одной из многочисленных библиотек, например, jQuery. А можно ли как-то исхитриться и сделать подобное лишь на CSS? Ответ однозначный, да!
Только нужно условиться, что достигнуть подобного можно соответствующей вёрсткой: блок со скрываемым содержимом должен находиться на том же уровне вложенности, что и чекбокс/радио, причём, располагаться после. Это очень важно. JavaScript подобных ограничений не имеет. Однако мне сложно представить, когда в этом случае может понадобиться иное расположение блоков кода.
Возможно, любознательный читатель спросит: «неужели нельзя подняться “выше” по коду и оттуда спуститься к нужному элементу?» Да, нельзя. Селекторы CSS такое не предоставляют. И это, в общем, логично: возможность свободного перемещения по «дереву» приведёт к рекурсивным вычислениям, возрастанию сложности реализации и уменьшению прогнозирования отображения сайтов. На данный момент линейчато-ступенчатая структура позволяет спускаться по иерархии сверху (от корня, элемент body) вниз и перемещаться слева направо между соседними элементами. В принципе, этого достаточно для 99,99% ситуаций. Для остального есть JS.
Чтобы можно было «достучаться» с помощью селекторов CSS, нужна такая конструкция:
<input type="checkbox"> <div>Скрытый блок, выводится при активном флажке</div>
Это наша заготовка. По хорошему, лучше такие конструкции оборачивать в собственный контейнер, чтобы избежать возможных проблем с оставшейся частью формы. Поэтому будем придерживаться такой схемы:
- Для элемента, который при активации должен показывать дополнительное содержимое, делаем свой контейнер. Для этих целей у нас будет задействоваться класс .checked
- Флажки и радиокнопки сопровождаются текстом. Поместить их в label нельзя — тогда придётся туда же пихать и скрытое содержимое, что при клике на нём вызовет сброс флажка. Но способ есть: связываем label с флажком/радио посредством атрибута for
- После закрывающего тега элемента label помещаем контейнер с классом .toggle
Эти шаги не только принесут нам немного удобства при вёрстке, но и уберегут от возможных ошибок, как это может быть при использовании «голого» div.
Сам код получается таким:
<form action="">
<h3>Откуда Вы узнали о нашем сайте?</h3>
<div><input type="radio" id="whence1" name="whence" value="Из поиска"> <label for="whence1">Из поиска</label></div>
<div><input type="radio" id="whence2" name="whence" value="Рассылка"> <label for="whence2">Рассылка</label></div>
<div class="checked">
<input type="radio" id="whence3" name="whence" value="Другое"> <label for="whence3">Другое</label>
<div class="toggle">
Укажите точно:<br>
<input type="text" name="whence_text" value="">
</div>
</div>
<p><hr></p>
<div class="checked">
<input type="checkbox" id="question" name="question" value="1"> <label for="question">Хочу задать вопрос…</label>
<div class="toggle">
Ваш вопрос:<br>
<textarea name="question_text"></textarea>
</div>
</div>
</form>
Чтобы всё заработало, добавим совсем немного CSS-магии (если код вставляется в CSS-файл, теги style не нужны):
<style type="text/css">
/* изначально все активируемые поля спрятаны */
.checked .toggle {
display:none;
}
/* для скрытых блоков указываем, что когда инпуты с типом checkbox/radio активны (выбраны), блок показывается */
.checked input[type=radio]:checked ~ .toggle,
.checked input[type=checkbox]:checked ~ .toggle
{
display:block;
}
</style>
И это всё, никакого JS) Главное, не нарушать вложенность.
днём интернета
шоколадкой для работы мозга
коробочкой ароматного чая для бодрости
продлением хостинга на +1 месяц
Я считаю, что совершенно не важно, из каких элементов создан код, главное, чтобы пользователю было удобно!
Андрей, здравствуйте.
К сожалению, мы не живём в мире, где всё бесконечно. Встречаются владельцы сайтов, которые ради небольшой фичи готовы использовать плагин, подгружающий ворох JavaScript библиотек. Самолично видел сайты, где по 2-3 версии только jQuery подключается.
Допустим, владелец совсем не разбирается в веб-программировании — это совершенно нормально. Имеет ли он право, чтобы обеспечить работу устаревшего плагина, подключить старую версию? Ну да, вполне. Но и пользователи имеют право игнорировать такой сайт.
Если есть очень лёгкий способ сделать что-то, используя лишь html/css, почему им не воспользоваться? Зачем качать плагины, которые тащут совместимость с пачкой костылей вплоть до IE 6? Удобство-удобством, но отрицать, что голый CSS + несложная вёрстка под него понятнее, чем jQuery, даже с парой строк кода, вряд ли кто будет.