Чекбокс
Незалежний вибір: фільтр у рейці, згода на умови. Кожен стоїть сам за себе. 201 штука - і до кроку 7.38 їх малював не цей файл.
.cb - квадрат, а не коло - форма одразу каже «можна кілька»201 чекбокс: .fopt 200 у панелі фільтрів, .optin 1 у діалозі реєстрації. filter-group.css - рівень 2 - писав .fopt .cb, .optin .cb: тягнувся повз власний компонент і перефарбовував клас атома на ім'я. Тому все, що цей файл казав про квадрат, було мертве. Заміряно на HEAD по 39 кольорових екранах: 18px, рамка --line-strong і галочка, які людина бачить, належали filter-group; власні 18px, рамка й галочка checkbox.css не рендерилися ніде, на жодному з двох імен.
А галочок було дві редакції, і малювалася одна:
| Де | Галочка | Колір | Посадка | Рендерилась |
|---|---|---|---|---|
checkbox.css | надрукований ✓, 12px | --text-oninverse | top:-2 left:3, на око | ніколи |
filter-group.css | намальована: 5×9, борти 0/2/2/0, поворот 45° | --line-onaction | translate(-50%,-58%) | завжди |
Те саме сімейство, що крапка наявності на 7.35 і зірка бейджа на 7.37 - надрукований знак проти намальованої форми. Тут вони існували одночасно, і намальована перемагала за порядком файлів, а це не рішення. По суті вона й правильна: надрукований ✓ читається вголос, не має товщини штриха і сідає туди, куди його поставить шрифт, а не туди, де його хоче квадрат.
Злиття вийшло піксель у піксель. A/B проти HEAD: 108 994 елементи, 40 сторінок × 2 ширини - нуль змін на всіх 201 чекбоксі. Дефект був не в тому, що щось виглядало не так, а в тому, що система казала три речі й малювала одну.
Матриця осей, а не перелік входжень: кожен рядок це питання, на яке відповідає розмітка, і правило, за яким обирають.
| Вісь | Значення | Правило вибору |
|---|---|---|
| Контекст | фільтр · згода | У фільтрі поруч стоїть кількість, у згоді - посилання на документ. Різний вміст, той самий квадрат. |
У Група фільтра і в Форма чекауту для згоди. Правило: якщо варіанти можна поєднувати - чекбокс, якщо ні - Радіо.
Правило
Показуй кількість заздалегідь. Фільтр з нулем поруч нікого не заведе в порожній список.Антиправило
Не роби чекбокс для взаємовиключних варіантів. Квадрат обіцяє, що можна поставити два. Обіцянку, яку інтерфейс не виконує, людина запам'ятає.Три: .on тримається на класі, тому він у списку класів; :hover і :active - у списку станів. Обидві редакції квадрата стоять поруч, бо їх дві і в коді.
.fopt, 175 екземплярів у продукті), знизу згода на розсилку (.optin, один). Квадрат той самий, оголошений двічі - див. нижчеТиснуть на підпис, відповідає квадрат. :active не дістає до нащадків, тож .cb:active спрацювало б лише від прямого влучання у 18px - а це радше сама проблема цього контрола, ніж її розв'язок: мішень - увесь рядок, і палець приземляється саме на рядок. Та сама форма, яку :hover уже використовує рядком вище.
| Що | У спокої | Під пальцем |
|---|---|---|
| порожній квадрат | прозорий | #FFF9F5 |
позначений .cb.on | #FF5A00 | #E85200 |
Обидва імені контейнера, одне правило. .fopt належить filter-group.css і названий у checkbox.css тому, що саме там 175 із 176 екземплярів. Так само роблять stepper.css і stack-action.css, і з тієї самої причини: імена живуть і в замороженому сірому шарі, тож додати безпечно, а перейменувати - ні.
Атом оголошено двічі
Тут він прив'язаний до.optin - один екземпляр, згода на розсилку в діалозі реєстрації. Решта 175 - панель фільтрів, оголошена ще раз у filter-group.css, 9 правил, файл рівня 2. Один квадрат 18px, два власники, і файл рівня 1 тримає рідкісніший. Та сама форма, що й рядок чипів, який жив у link-row.css до 7.30b.А панель фільтрів не мала ні клавіатури, ні скрінрідера закрито на 7.34
Прочитано з живого DOM, бо панель будує скрипт:<label class="fopt"><span class="cb"></span> В наявності</label>. Немає <input>. На listing.html - 50 опцій фільтра і 11 досяжних елементів у всій панелі, жоден з них не чекбокс. Контрол при цьому живий: клік переводить клас cb -> cb on. Це той самий дефект, що мав .ord-tab на 7.31 і .sw на 7.32. Розділ нижче - що з цим зробив крок 7.34.-> #FFF9F5, позначений #FF5A00 -> #E85200Половина контракту була написана, і це читається гірше, ніж нічого. uivCheckboxes() уже писав aria-checked - і не писав ролі. aria-checked на елементі без ролі браузер відкидає: скрінрідеру не кажуть узагалі нічого, а файл при цьому має вигляд опрацьованого. Прочитано з дерева доступності, а не з домислу:
| Було | Стало | |
|---|---|---|
| опція фільтра | { role: "LabelText", name: "", checked: undefined } | { role: "checkbox", name: "В наявності 71", checked: false } |
| позначена опція | те саме | { role: "checkbox", name: "Optimum Nutrition 12", checked: true } |
| заголовок групи | <div>, ролі немає | { role: "button", name: "Тип протеїну", expanded: true } |
І писалось воно тільки на клік. З 34 опцій, які рендеряться вже позначеними, жодна не оголошувала цього, поки на щось не натиснуть. Тепер aria-checked ставиться на завантаженні.
| Що | Скільки | Що отримало |
|---|---|---|
.fopt + .optin | 351 на 8 екранах | role="checkbox" · tabindex="0" · aria-checked · Space |
.fgroup > .fh | 140 | role="button" · aria-expanded · Enter і Space |
.fgroup | 140 | role="group" + ім'я зі слів заголовка |
Space, а не Enter
Чекбокс відповідає на Space. Enter належить головній дії, а в мобільному шиті ця дія - «Застосувати». Тумблер на 7.32 узяв обидві клавіші, бо в його рядку більше нікому взяти Enter. Один файл, два прив'язки, і різницю робить те, біля чого стоїть контрол.Мандрівного tabindex немає, і тут сім'я розходиться з радіо
uivRadioGroups() дає групі один крок, бо радіогрупа - це одне значення. Двадцять п'ять фільтрів - це двадцять п'ять незалежних відповідей, тож кожен бере власний крок: рейка йде з 11 до 46. Це ціна того, чим панель є, а не дефект, який треба підкрутити.Заголовок групи був складанкою, яка нікому про це не сказала. Десять .fh на панель, cursor: pointer, і клік справді згортає групу. Поведінка була повна, обіцянки не було: <div> без ролі, без кроку табуляції і без aria-expanded. Сірий шар цей рух уже знає - toggleCab() і toggleLang() у тому самому файлі пишуть aria-expanded своїм тригерам. Дві складанки з трьох були названі, фільтрова - ні. Клас перемикає сірий шар, тут його тільки перечитують: дві редакції одного згортання - це рівно той дефект, який цей етап прибирає.
І закритий шит тримав 14 елементів у порядку табуляції. Знайдено тим, що крок 7.34 спочатку зробив гірше: transform: translateY(100%) зсуває панель за нижній край і лишає її видимою для всього, що не є оком. Зміряно на HEAD, 390, listing.html із закритим шитом: 14 досяжних елементів усередині - хрестик, шість чипів, чотири числові поля, «+ ще», «Скинути» і «Застосувати». Нові кроки табуляції довели це до 49. Кроки правильні, а шит був неправильний - і був таким ще до цього етапу. visibility: hidden з відкладеним переходом - та сама редакція, яку .wf-drawer уже носить у nav-drawer.css з тієї самої причини. Тепер закритих шарів із досяжним вмістом у продукті нуль: перевірено по всіх оверлеях, шухлядах і діалогах.
#fsheet і усі - visibility. За межами шита - нуль. Кольору, геометрії й типу не торкнулисьСторінка звіряє себе з файлом: 3 власних класів і 1 станів оголошено в checkbox.css. Нижче - ті, яких на цій сторінці немає ні в демо, ні в розмітці. Чужий контекст (його тут немає) не рахується: у цих селекторах компонент не є підметом, він лише стоїть усередині когось.
Робота: ВІДПОВІДЬ. Рухається: color, border-color, background. Тривалість --dur-fast (150ms), крива --ease-standard. Значення читаються через var() з tokens.css: підміна токена в браузері веде за собою кожне з них, тобто числа у файлі немає. При prefers-reduced-motion рух зникає, а стан лишається.
Прочитані з checkbox.css, не переписані руками. Колір іде лише через роль, геометрія - напряму з примітива.
| Семантичні ролі (10) | Примітиви (5) |
|---|---|
--bg-action --bg-action-pressed --bg-action-soft --bg-page --line-action --line-onaction --line-strong --ring-focus-control --text-action --text-secondary | --fs-14 --radius-4 --space-12 --space-2 --space-8 |
| – | --dur-fast --ease-standard |
Якорі: .cb .optin
2 екранів у wireframes/: content-guarantee.html, search-suggest.html
Чого бракує
- Немає невизначеного стану для «частина групи обрана»
- Немає
:focus- клавіатурою по фільтрах не пройти
Не домальовано наперед і не замовчано: етап 09 стартує з цього списку, зведеного в design/kit/docs/architecture.md.