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

Порожній стан

Екран, на якому нічого немає, і екран, на якому щось зламалось. Принцип 2 у найчистішому вигляді: у порожнечі мусить бути рівно один очевидний наступний крок. Три коробки під трьома іменами, і цей крок нарешті виміряв, чим вони відрізняються насправді.

рівень 2design/system/components/empty-state.css189 рядків29 екранів
Анатомія

Розмітка звідси - та сама, що на listing-empty.html. До 7.73 круглий портрет робила саме секція навколо - правило читало section[aria-label="Результати"], тобто речення інтерфейсу, вжите як селектор. Тепер це каже .empty .ei:has(img): ілюстрація, у якій є зображення. Секція лишається в демо, бо вона є в справжній розмітці, але оформлення вона більше не тримає - перейменуйте ярлик, і нічого не станеться.

За вашими фільтрами нічого не знайдено
Спробуйте прибрати частину фільтрів або оберіть ціль - підберемо безпечний набір.

.hint - рядок ПІД дією, доданий на 8.30 з coach-session-empty.html, єдиного порожнього стану в продукті, якому є що сказати після кнопки. Це не другий .es: .es каже, ЩО за стан, і стоїть над дією; .hint каже, що буде далі, і стоїть під нею - і вони ніколи не бувають найгучнішими обидва. Найтихіше чорнило і рунґ під тілом: 11.5 -> --fs-12, маргін 14 -> --space-12.

1Значок - .ei. У Результати це коло 126px, у Помилка - 118; портрет обрізаний по обличчю (object-position: center 12%) і змішаний з тлом множенням, щоб не було білого квадрата
2Заголовок - .et, 18/900. Каже, ЩО сталось, і не вибачається
3Пояснення - .es, 14, вторинний колір. Каже, що робити
4Виходи - .eact. Перший акцентний, решта контурні. Порожнеча без виходу це глухий кут, а принцип 2 вимагає рівно однієї головної дії
5Рамка - пунктир --line-strong. Пунктир каже «тут МАЄ бути вміст», суцільна казала б «це блок»
Три імені, одна ідея
📦
Ще немає замовлень
Оберіть ціль або перегляньте каталог - почніть із товарів для вашого завдання.
Клієнти зі списку підтягуються автоматично - можна вибрати збереженого.
⚠️
Не вдалося завантажити кабінет
Не змогли отримати ваші дані. Перевірте з'єднання та спробуйте ще раз - ваші замовлення й бонуси нікуди не зникли.

Завантажуємо товари…

емодзі в розмітці - сирі: .ei тут має font-size: 0, а знак ставить uivIcons(), той самий, що на екрані
.empty.emptybox.errbox
екземплярів63 .emptybox + 1 .mini (перераховано 8.15)1
деlisting-empty, listing-error, product-erroraccount-emptyaccount-error
відступ у файлі40 / 2446 / 24, не малюється48 / 24
рамка у структурі1px dashed --line-strong 7.62 було написано 1.5те самете саме
рамка на екраніпунктир --line-strongсуцільна --line-hairсуцільна --line-danger-soft
значокпортрет 126/118іконка 34, акцентіконка 34, небезпека

Пунктир виживає тільки в першої. Структура дає всім трьом однакову рамку, а кольоровий блок дві з них перефарбовує в суцільні. Це не помилка сама по собі - у коробки помилки й має бути своя рамка, - але сказано це в двох місцях, і читання структури дає відповідь, якої браузер не вживає.

Три відступи на одну ідею: 40, 46, 48. По одному читачеві в кожного, більшості немає, тож це рішення про значення, а не право вигадати. Так само, як два сірих для заголовків таблиць на 7.46.

18 оголошень, які не виграють ніде

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

ОголошенняЗбігівХто бере
.emptybox padding x46.emptybox.mini (4) + інлайн у розмітці (2)
.emptybox margin-top, border-radius x46.emptybox.mini
.emptybox .et font-size + margin x46.emptybox.mini .et
.emptybox .es font-size, margin-bottom6.emptybox.mini .es
.emptybox .ei font-size4.emptybox.mini .ei
.empty .ei font-size6обидва section[aria-label=…] .empty .ei

І жодне не видалено. Двічі перевірено, двічі відмовлено

.emptybox без .mini існує в сірому шарі: wireframes/coach-home-empty.html (тричі) і wireframes/account-addresses-empty.html. Кольорового близнюка немає - це та сама половина, що чекає, як .tband на 7.44 і .led-empty на 7.48.

.empty .ei{ font-size: --fs-30 } це запасний шлях, а не залишок. У кольорі всі три .empty стоять усередині двох секцій, які роблять зі значка коло з font-size: 0. Але в сірому шарі сім коробок .empty стоять ПОЗА цими секціями, і значок у них - емодзі, який це правило й розміряє. Той самий клас, що .pl-hw .pl-ic:empty, відкликаний на 7.46.

Два ведмеді, які поїхали з файлу

Файл звався «порожній стан» і тримав дві речі, які порожнім станом не є.

КласЕкземплярівБатькоХто ставитьПоїхав у
.uiv-bear9SECTION.seotextdesign/_nav.js:823seo-text.css
.uiv-bearwrap3.truststripdesign/_nav.js:997trust-strip.css

Перший стоїть у дірці, яку йому лишає власне правило SEO-блока: padding-right: 310px від 760 і вище. Дірка була в одному файлі, а ведмідь - в іншому. Другий - обгортка, що обрізає ведмедя по нижньому краю панелі довіри; її другу половину, .uiv-trustbear, trust-strip.css тримав від самого початку.

Жоден з двох класів не оголошено більше ніде в системі, тож переїзд не може зрушити каскад. Перевірено A/B у три проходи на 40 екранах і чотирьох ширинах: нульовий прохід 0, різниця 0. Це переїзд, а не рішення.

Стани
СтанЩо робитьЧому так
порожньопунктирна рамка, портрет, заголовок, пояснення, виходипорожнеча не є помилкою людини, тому тон рівний і ведмідь заспокоює, а не докоряє
помилката сама будова, рамка й тло --line-danger-soft / --bg-danger-softєдина відмінність - колір і слова. Будова та сама навмисно: людині не треба вчити другий макет у гірший момент
.miniменші відступи, 16px заголовок, 24px значоккоробка всередині картки кабінету, а не на цілий екран
завантаження.loadnote - рядок під скелетономскелетон показує форму, рядок називає, чого чекають. Три екрани
наведеннянемає в коробкиціль - кнопки всередині, у них свої стани. Підсвітити коробку означало б пообіцяти клік, якого немає
Коли вживати

.empty - на цілий екран результатів: лістинг, пошук, ціль. .emptybox.mini - усередині картки кабінету. .errbox - коли дані не прийшли, а не коли їх немає.

Порожньо і зламалось - різні речі, і плутати їх не можна. «Нічого не знайдено» це результат вибору людини, і виходи звідти ведуть уперед (зняти фільтр, обрати ціль). «Не вдалося завантажити» це наша поломка, і вихід звідти один - спробувати ще раз.

І тренерський потік плутав їх у чотирьох редакціях - крок 8.39

Правило вище було написане на 7.28 і жоден екран тренера його не читав. .errbox носив один екран у всьому продукті - account-error, - а п'ять екранів помилки тренерського потоку малювали власну коробку. Токен --line-danger-soft мав рівно одне вживання в системі: ту єдину коробку.

коробкаграньрадіуспадінггліф
.err · coach-client-error1px solid --line-strong1440/2232px --mark-disabled
.cerr · coach-home-error1.5px dashed --line-strong1644/26кільце 60px, --text-secondary
.ord-err · order-error, orders-error1px --line-hair1444/24немає
.empty · coach-clients-errorне своя коробка взагалі - ілюстрована плашка «тут поки нічого», яку носить каталог
.errbox1px --line-danger-soft--radius-1248/24--text-danger, 34

Жодна з чотирьох не несла ролі небезпеки

Не «інший відтінок червоного» - червоного не було зовсім. Плаский сірий, а на coach-client-error гліф попередження стояв на --mark-disabled, тобто чорнилі для того, що вимкнено. Це первинна аудиторія й найгірша хвилина її сценарію, і саме там продукт мовчав про те, що сталося.

Плюс те, що ці екрани домальовували руками: .err-btns .btn{ padding: 13px 24px } - розмір поверх btn--s, той самий, що пішов на 8.30 з .cs-empty .btn; .ord-empty і .ord-err в одному селекторі, тобто одна плашка на дві протилежні роботи; і p.lead на двох екранах клієнтів - це .es під іншим ім'ям, з мірою 42ch на одному й 46ch на другому.

А міри в цієї коробки не було, і саме тому обидва екрани її виростили

.emptybox .es обмежена 440, .errbox .es - 420, а в .empty .es межі не було зовсім: на 1280 рядок ішов у ширину того, що його тримає. Заміряно: 660px на coach-clients-empty, 726 на listing-error, 818 на coach-client-empty, 982 на product-error - до ста знаків у рядок. Одна декларація, 440 (число, яке сусідня коробка вже несе), рухає рівно один елемент на кожному з чотирьох екранів і нічого на телефоні.

Двом екранам додано гліф ⚠️, який несуть усі інші коробки помилки: коробка, якій компонент фарбує --text-danger, - це коробка, що його чекає. Це рішення про вигляд, не замір, і воно оборотне одним словом у розмітці. Заодно воно тримає правило 8.15 чесним: .errbox немає в селекторі :first-child, бо після цього кроку немає жодної коробки помилки без гліфа, а селектор, що не покриває нічого, - це той самий шум, що й порожній виняток.

Правило і антиправило

Правило

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

Антиправило

Не вибачайся і не жартуй. Ведмідь тут заспокоює, а не розважає; текст називає стан і наступний крок. Принцип 4 діє і тоді, коли показувати нічого.
Обмеження

Правила вживання, які називають саме цей компонент: U5. Автор правил один, і це architecture.html, розділ I; тут - витяг.

Один порожній стан на екран - але .emptybox це порожнеча блока, і їх буває три на одному екрані (account-empty). Плутати два класи не можна: .empty каже «екран порожній», .emptybox - «порожня ця картка».

Широкий значок

.ei--wide - той самий значок порожнього стану, але коли всередині нього малюнок, а не гліф: малюнок читається меншим за той самий розмір, тож коробка росте до 126.

🗂
Тут поки порожньо
Холостий контроль

Сторінка звіряє себе з файлом: 9 власних класів і 4 стани оголошено в empty-state.css. Нижче - ті, яких на цій сторінці немає ні в демо, ні в розмітці.

ПОВЕДІНКА НА ШИРИНІ - етап 10, крок 4

Від якого порогу: жодного. Порожній стан плинний і має свою міру рядка; єдине, що етап 10 йому дав, - --container-text замість двох рукописних ch. Раунд молекул не додав нічого.
Токени

Прочитані з empty-state.css: 10 семантичних ролей і 19 примітивів.

Семантичні ролі (11)Примітиви (20)
--bg-danger-soft --bg-surface --line-danger-soft --line-hair --line-strong --text-action --text-body --text-danger --text-muted --text-primary --text-secondary--font-display --fs-12 --fs-14 --fs-16 --fs-18 --fs-20 --fs-24 --fs-30 --fw-black --fw-semibold --lh-airy --radius-12 --radius-circle --size-34 --space-4 --space-8 --space-12 --space-16 --space-24 --space-40

Сім чисел стоять повз шкалу: 1.5px (рамка, тричі), 46px і 48px (відступи), 118px і 126px (кола), 420px і 440px (ширина пояснення). Два останні - одна й та сама межа читабельного рядка, написана двічі з різницею у 20 пікселів.

Знахідка більша за компонент: 1.5px не існує закрито 7.62

Усі три коробки просять border: 1.5px. Заміряно при DPR 1, 2 і 3: використане значення скрізь 1px, тоді як 2px лишається 2px. Chrome округлює товщину рамки вниз до цілого CSS-пікселя.

У системі 24 файли пишуть 1.5px, і два з них носять коментар, який пояснює вибір: checkbox.css - «1.5px rather than 1px», radio.css - «1.5px changing shade is legible under a mouse pointer». Різниці, яку код вважає, що робить, у Chrome немає.

Чому це не виправлено тут

Правильна відповідь не «написати 1px», а вирішити: 1 чи 2. Автори хотіли більше за одиницю, і одиниця - це те, що вони й отримали. Це рішення про значення на 24 файли, тож воно йде в етап 09 цілим питанням, а не розмінюється по одному файлу. Заміряно тільки в Chrome; Safari і Firefox треба перевірити окремо.
Розмітка
<section aria-label="Результати"> <div class="empty"> <div class="ei ei--wide"><img src="visuals/mascot-face-reassure.png" alt=""></div> <div class="et">За вашими фільтрами нічого не знайдено</div> <div class="es">Спробуйте прибрати частину фільтрів…</div> <div class="eact">…акцентна кнопка + контурні…</div> </div> </section>

aria-label секції несе оформлення, і це слабке місце. Два правила файлу чіпляються за section[aria-label="Результати"] і section[aria-label="Помилка"], тобто за український текст усередині атрибута доступності. Перейменують ярлик - і портрет розсиплеться на емодзі. Той самий клас питання, що обличчя бейджа, яке design/_nav.js виводить з української назви регуляркою.

Де вживається

Якорі: .empty .emptybox .errbox .loadnote

Заміряно на 7.28 в браузері на 360, 390, 720 і 1280 по тодішніх 40 кольорових екранах: 3 + 3 + 1 коробки на п'яти екранах, плюс .loadnote на трьох екранах завантаження. Мертвих селекторів: 0 з 26.

Перезаміряно 16.08.2026 по 88 кольорових екранах: tools/inventory.mjs --screens дає 19 екранів - 14 до кроку 8.39 і 5, що зайшли ним. Числа селекторів, правил і оголошень у шапці зняті кроком 5 із двох джерельних таблиць стилів до розколу, а не з цього файлу, тому вони звідти прибрані, а не переписані: замінити число, метод якого не відтворюється, значить видати здогад за замір.

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

Чого бракує

  • Рішення про відступ. 40, 46 і 48 на одну ідею; 46 не малюється взагалі. Одне число, сказане вголос як «змінна -> значення -> чому»
  • Рішення про 1.5px на 24 файли системи закрито на 7.62: файлів було 23, оголошень 33, і код каже 1px
  • Інлайн-стилі в кольоровому шарі: design/account-empty.html несе style="padding:20px 14px" на коробці й margin-top:0 на заголовку. Прийшли з сірого шару, який заморожений, тож знімати їх односторонньо не можна - інакше два шари розійдуться розміткою
  • Оформлення на aria-label - два правила тримаються за український рядок в атрибуті доступності
  • Немає порожнього стану для кошика й для обраного в кольорі - у сірому шарі вони є

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