Компонент · рівень 2

Пагінація

Кінець довгого списку: «Показати ще» і номери сторінок під ним. Найменший компонент системи - 9 оголошень - і один із чотирьох файлів, де жодне число не написане рукою. Дійшов до цього не одразу: три кроки поспіль звідси виносили те, що вже сказала кнопка.

рівень 2design/system/components/pagination.css70 рядків7 селекторів11 оголошень12 екранів22 контроли
Анатомія

Розмітка звідси - та сама, що на listing.html.

1Стовпчик .pgnav - flex-direction: column, по центру, крок 16. Це вся розкладка компонента, і вона однакова на телефоні й на десктопі: нічого не перебудовується
2«Показати ще» - btn--outline і більше нічого. Клас .loadmore не має жодного правила у всій системі: він тільки гачок для скрипта
3Номери - btn--outline btn--icon btn--s, коробка 40 з фінішу. До кроку 6.7 тут стояв ::after, який розтягував квадрат 34 до цілі 44; тепер ціль це сама коробка
4Поточна .on - залита помаранчевим, текст білий. Єдине, що цей файл справді малює
5Стрілка - той самий контрол зі знаком › і aria-label. Без ярлика читач з екрана почув би саму лапку

Дві навігації, а не одна. Кнопка догортає список на місці, номери переносять на сторінку. Обидві потрібні: перша для того, хто гортає, друга для того, хто хоче повернутись на третю сторінку завтра, - і друга ж потрібна пошуковику.

Третє оголошення виявилось фінішевим
/* було */ .pages a.on, .pages button.on { background: var(--bg-action); color: var(--text-onaction); border-color: var(--line-action) } /* button.css:503 */ .btn--outline.btn--icon.on { border-color: var(--line-action) }
Заміряно в браузеріЗначення
класи елемента пагінатораbtn--outline btn--icon btn--s on
специфічність .pages a.on(0,2,1)
специфічність .btn--outline.btn--icon.on(0,3,0) - виграє завжди
де перемагав цей рядок0 із 10 заміряних
колір межі до і післяrgb(255, 90, 0) · rgb(255, 90, 0)

Значення збігалось, тож нічого не рухнулось - але межа була оголошена двічі, і найгірше не це. У button.css над тим рядком стояло написане речення: «пагінатор тримає власний .on і цього правила не читає». Читає, і саме ним малюється. Хибним було не оголошення, а запис про нього.

Антиправило

Не пиши в коментарі, що правило когось не стосується, доки не спитав браузер. Мертве оголошення коштує рядка. Неправдивий коментар коштує наступного кроку, який на нього спирається.

Що лишилось тут - справді своє: заливка і чорнило на ній. «Увімкнено» на контурній кнопці означає кольорову межу; на пагінаторі - залитий квадрат, бо це не перемикач, який ви ставите, а місце, де ви стоїте. Одне ім'я класу, два значення; перейменування записане в button.css і йде кроком 6.

Посилання чи кнопка - за тим, що станеться
ДеТегЧому
каталог, 4 екрани<a href="?page=2">змінюється адреса: сторінку можна відкрити в новій вкладці, зберегти, надіслати
відгуки, product-reviews<button type="button">перегортається список усередині сторінки, адреса не змінюється - посилання нікуди б не вело

Тому селектор і написаний парою: .pages a.on, .pages button.on. Це не про запас - обидві половини живі, 18 посилань і 4 кнопки.

Правило

Тег обирає наслідок, а не вигляд. Веде на адресу - посилання. Змінює те, що вже на екрані, - кнопка. Виглядають однаково, і це нормально: однаковими їх робить фініш, а не тег.
Три кроки, які винесли звідси все зайве
КрокЩо пішлоКуди
6.3«Показати ще», оголошена тричі, і ховер пагінатора, написаний двічіу фініш btn--outline: межа, колір і ховер там уже були
6.7коробка 34, межа 1px, гарнітура, перехід і ::after, що дотягував ціль до 44у button.css. Коробка стала 40, і псевдоелемент став непотрібним: ціль тепер сама коробка
7.77колір межі поточної сторінкиу button.css:503, де він і малювався весь цей час

Файл почав з двадцяти з гаком оголошень і закінчив дев'ятьма. З них шість - розкладка (стовпчик, вирівнювання, два кроки, відступ, ряд), два - заливка поточної сторінки, і жодного числа, написаного рукою: усі шість відступів беруться зі шкали. Таких файлів у системі чотири з 73.

Стани
1 2 3
наведіть і натисніть Tab: ховер, натиск і кільце фокуса приходять із фінішу, а не звідси
СтанЩо робитьЗвідки
спокійконтурний квадрат 40, цифра всерединіbutton.css, фініш btn--outline btn--icon btn--s
поточназалито --bg-action, текст --text-oninverseцей файл - єдине, що він малює
межа поточної--line-actionbutton.css, з 7.77
наведеннямежа бере акцентфініш
фокускільце --ring-focus-controlфініш, :focus-visible
остання сторінкастрілка «далі» вимкнена: блідий знак, курсор «не можна», натиск не проходитьbutton.css, вимкнений стан + pointer-events звідси
«Показати ще» вантажитьaria-busy: коробка не рухається, змінюється лише написцей файл - курсор; напис із мікрокопі
кінець спискукнопки немає, замість неї нотатка; номери лишаютьсяempty-state.css, .loadnote
Остання сторінка · четверта з чотирьох
порівняйте зі стрілкою в «Анатомії» вище: там вона натискається, тут ні. Знак блідне до --mark-disabled, курсор стає «не можна», а pointer-events знімає натиск - і жодного нового оголошення вигляду це не коштувало. Вимкнений стан лежав у button.css з кроку 7.61 і чекав на розмітку, яка його попросить
«Показати ще» · три моменти одного контрола
Це всі товари категорії
спокій, вантажить, кінець. Коробка не рухається між першим і другим - aria-busy не чіпає ні розмір, ні фініш, змінюється тільки напис, бо контрол, який змінює розмір під пальцем, зсуває список під ним. «Завантажуємо…» - канон зводу мікрокопі, а не нове слово
Кінець списку - це не вимкнена кнопка. Мертвий контрол запрошує натиснути й нічого не відповідає. Тут кнопка зникає зовсім, а на її місце стає .loadnote з empty-state.css - атом, який уже існує саме для рядка тексту під списком. Номери сторінок під нею лишаються робочими, і це єдине прочитання, яке слухається правила «ніколи глухий кут»: список закінчився, навігація ні
Чому <span>, а не <a> без href. Посилання без адреси все одно лишається в дереві читача посиланням, і його все одно оголосять як ціль. Тут цілі немає взагалі, тож і елемент не вдає, що вона є. aria-disabled - це те, що чує читач з екрана; pointer-events - те, що відчуває палець. Потрібні обидва: перше без другого лишає натиск робочим, друге без першого мовчить
Правило і антиправило

Правило

Кнопка каже, скільки лишилось. «Показати ще 24 (з 84)» - людина бачить і крок, і кінець. Це та сама чесність, що й лічильники в рейці фільтрів: натискають упевнено, коли видно, що буде далі.

Антиправило

Не роби нескінченну стрічку без номерів. На третій сторінці нема куди повернутись, нема що надіслати і нема що проіндексувати. Догортування - зручність, номери - адреса; прибирати треба не друге.
Холостий контроль

Сторінка звіряє себе з файлом: 5 власних класів і 3 стани. Крок 8.15 додав два класи (.loadmore нарешті з правилом, .loadnote позиченим у empty-state.css) і два стани.

Токени

Прочитані з pagination.css: 2 семантичні ролі і 3 примітиви.

Семантичні ролі (2)Примітиви (3)
--bg-action --text-onaction--space-8 --space-16 --space-24

Повз шкалу нічого. Разом із badge.css, counter.css і overlay.css це один із чотирьох компонентів системи, у якому немає жодного числа, написаного рукою.

A/B

Три проходи по 40 екранах на чотирьох ширинах: HEAD, HEAD ще раз і робоче дерево. Нульовий прохід 0, різниця 0, 215 452 елементи з кожного боку.

Плюс окремий замір межі поточної сторінки на двох екранах: rgb(255, 90, 0) з обох боків. Значення збігалось до видалення - його тут і не мало б бути видно.

Немає в коді -> етап 09

Чого бракує

  • Розрив у довгому списку - показані номери 1-4, а сторінок 84 / 24 = чотири. При більшому каталозі потрібне «1 2 3 … 12», і такого стану немає
  • Перейменування .on - один клас на два значення: «увімкнено» на перемикачі й «ви тут» на пагінаторі. Крок 6, після етапу 09
  • .loadmore майже без правил - крок 8.15 дав йому одне, і те про курсор під час aria-busy. Вигляд і далі цілком btn--outline, і це правильно; але клас, у якого одне оголошення, все ще кандидат на те, щоб бути атрибутом, а не класом. Крок 6

Не домальовано наперед і не замовчано: етап 09 стартує з цього списку, зведеного в design/kit/docs/architecture.md.