Прогресивне поліпшення

14

Від автора: У своїй статті Створення ефективної форми для пожертвувань Бред Фрост (Brad Frost) рекомендує використовувати кнопки замість перемикачів c типом radio, цитуючи твіт Люка Роблевски (Luke Wroblewski). Я не погодився, а Бред відповів, що у нього інша точка зору. Після того як до обговорення приєдналося більше людей, демо-приклад був оновлений. І в ньому вже стали використовувати radio перемикачі, але я вважаю, що можна зробити ще краще. Я збираюся продемонструвати, що простий хороший семантичний HTML + CSS можуть дати нам дуже багато.

Суть обговорення

Як можна розмітити і стилізувати ось таку форму, як представлено нижче (оригінал):

Прогресивне поліпшення

Погляньте на демо-сторінку

Основні моменти

Головною метою буде побудова форми з використанням семантичної розмітки та з урахуванням принципу прогресивного поліпшення. Відправка форми та доступ до її вмісту повинні здійснюватися без використання JavaScript.

Початкова розмітка

Оригінальний приклад (псевдокод):

  • $25
  • $50
  • $100
  • $250
  • $500

Заголовок

В оновленій версії контент заголовка генерується автоматично, щоб підлаштуватися під значення атрибута data-message у тегів label для кожного radio перемикача (я припускаю, що також було і з елементами button).

Проблема тут полягає в тому, що дані ключові теги призначені для JavaScript і недоступні (невидимі) користувачам, що використовують екранні диктори. Щоб змінити цю ситуацію необхідно використовувати активні області ARIA:

Активні області інформують користувачів, що використовують допоміжні технології, про оновлення, що відбуваються в документі, без відриву від поточних дій (Оновлення активних областей WAI-ARIA).

Також, користувачі, що використовують екранні диктори, можуть перемикатися між заголовками. Таким чином, зміна вмісту в заголовків може призвести користувачів в деяке замішання.

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

Теги fieldset

Тег fieldset повинен містити елемент legend:

Потрібно, щоб елементи fieldset і legend використовувалися разом. Елемент fieldset не може використовуватися без елемента legend і навпаки (Елементи Fieldset, legend і екранні диктори).

Першим елементом всередині елемента fieldset повинен бути елемент legend, що дає назву або опис всієї групи всередині елемента fieldset (H71: Вказівка опису для групових елементів управління формами).

Хоча це складно зробити, тому що, я повинен визнати, що, незважаючи на те, що в моєму прикладі міститься тег legend, йому встановлено властивість display:none. Все тому, що елемент legend буде зайвим для такої маленької форми. Більш того, програма читання екрану (Voice Over) буде озвучувати елемент legend після елементів label.

Оновлення: елемент legend також залишився прихованим, але зараз я застосовую атрибут aria-labelledby для елемента fieldset. І тепер він прив’язаний до заголовка.

Список

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

Кнопки

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

Атрибут @type

Заміна type=»text» type=»number» для поля «інша сума» дає нам можливість здійснювати безкоштовну валідацію на стороні клієнта (\w00t/).

Атрибут placeholder

Атрибут @placeholder – це не заміна елемента label. У нас немає тега label, пов’язаного з полем «інша сума», і я не бачу також атрибута @title (дивіться H65).

Простий хороший семантичний HTML

Використовуючи простий хороший семантичний HTML, розмітка може виглядати ось так:

$25 …
$50 …
$100 …
$250 …
$500 …

Подивіться на сторінку без CSS

Немає більше заголовка, списку немає і немає більше атрибута @data-message. Значення цього атрибута тепер є частиною контенту, який передається користувачам, що використовують екранні диктори, коли вони здійснюють навігацію по елементам управління формою.

Маючи цю базову розмітку, користувачі вже можуть здійснити вибір і відправити форму без використання JavaScript. А завдяки атрибуту type=»number» ми можемо провести валідацію тега input.

Я помістив пару input/label для «щомісячного пожертвування» у самий кінець форми, але мені подобається пропозицію Тобі Марсдена (Toby Mardsen) підняти її вгору, перед усіма варіантами.

Поліпшення

Тепер, коли у нас є функціональна форма, ми можемо пограти з нею, використовуючи CSS. Ми можемо використовувати псевдокласи :focus/:hover з додаванням селектора дочірніх елементів (+), щоб створити спливаючий ефект у вмісту елементів label, щоб змусити «маркер» (який виділяє вибір) ковзати між елементами label, щоб генерувати контент, щоб стилізувати тінь в DOM і т. д.:

/* спливаючий ефект для елемента label вибраного radio перемикача */
input:checked + label > b {
display: block;
}
/* оформлення згенерованого контенту, пов’язаного з обраним radio перемикачем, або оформлення елемента label при наведенні на нього покажчика миші */
input:checked + label:before,
label:hover:before {
font-size: 1em;
text-shadow: none;
}
/* прибираємо кнопку «spin» (дозволяє збільшувати значення) */
::-webkit-inner-spin-button {
-webkit-appearance: none;
}
/* змушуємо текст атрибута placeholder зникнути, коли поле знаходиться у фокусі */
#other-amount:focus::-webkit-input-placeholder {
opacity: 0;
transition: opacity .3s;
}
/* подивіться на стилі в тезі style демо-сторінці */

Це кінцевий результат

Додатково

З цього моменту ми будемо…

Використовувати JavaScript для управління різними «станами» елементів управління:

знімати/скидати вибір radio перемикачів, якщо користувач вибрав полі «інша сума»

очищати поле «інша сума», якщо користувач знову вибрав один з radio перемикачів

Редагувати CSS правила для забезпечення браузерною сумісності, оскільки зараз мій підхід підтверджений у рамках використання движка WebKit.

Прибрати знак валюти з CSS, щоб полегшити створення локалізації.

Замінити float inline-block, щоб при бажанні було легше відцентрувати елементи label і підлаштуватися під мов, які використовують написання справа наліво (RTL – right-to-left).