Angular IDPStrong Junior
Модулі / Розмітка й стилі / Свої контроли
🔥 0

Модуль 1 · урок 12 з 14

Свої контроли

Критерій «без зовнішніх UI-компонентних фреймворків» означає, що кнопку, поле й бейдж ти малюєш сам. Головне тут не вигляд, а стани: саме за ними видно, хто верстав.

П'ять станів, які має мати кожен інтерактивний елемент

СтанСелекторНавіщо
СпокійБазовий вигляд
Наведення:hoverПоказати, що воно клікабельне
Фокус із клавіатури:focus-visibleОбов'язково: без нього не пройти клавіатурою
Натиснення:activeТактильний відгук
Вимкнено:disabled, [aria-disabled]Показати, що зараз недоступно
.btn {
  /* скидаємо все, що браузер малює за нас */
  font: inherit;
  cursor: pointer;
  border: 1px solid var(--rule);
  border-radius: 8px;
  padding: .5rem .875rem;
  background: var(--surface-2);
  color: var(--ink);

  display: inline-flex;      /* щоб іконка й текст стали в ряд по центру */
  align-items: center;
  gap: .5rem;
}

.btn:hover { border-color: var(--ink-3); }
.btn:active { transform: translateY(1px); }

.btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.btn:disabled {
  opacity: .5;
  cursor: not-allowed;
}

.btn--primary { background: var(--accent); border-color: var(--accent); color: var(--surface); }
focus-visible проти focus

:focus спрацьовує й на клік мишею — тому колись усі писали outline: none і ламали клавіатурну навігацію. :focus-visible показує обведення лише тоді, коли фокус прийшов із клавіатури. Тому правильний набір такий: ніколи не прибирай outline глобально, а стилізуй саме :focus-visible.

Поле вводу й підпис

<div class="field">
  <label class="field__label" for="task-code">Код задачі</label>
  <input class="field__input" id="task-code" type="text"
         aria-describedby="task-code-err" aria-invalid="true">
  <p class="field__error" id="task-code-err">Такий код уже існує</p>
</div>

Три речі, які тут важливі й повторяться в модулі 6: label for прив'язаний до id поля (клік по підпису ставить курсор у поле), aria-describedby зв'язує поле з текстом помилки, aria-invalid повідомляє про стан. Це той мінімум, за який у тебе не буде питань на модулі про доступність.

Статус-бейдж

.badge {
  display: inline-flex;
  align-items: center;
  gap: .375rem;
  padding: .125rem .5rem;
  border-radius: 999px;
  font-size: .75rem;
  border: 1px solid currentColor;   /* рамка бере колір тексту — один рядок на всі варіанти */
}
.badge--done     { color: var(--ok); }
.badge--blocked  { color: var(--warn); }
.badge--progress { color: var(--accent); }

currentColor — недооцінений трюк: задаєш лише color, а рамка, іконка й текст підхоплюють його самі. Замість трьох модифікаторів по три властивості виходить три рядки.

І одразу правило з модуля 7, щоб не переробляти: статус не можна кодувати лише кольором. Поруч завжди має бути текст або іконка — інакше людина з дальтонізмом побачить три однакові бейджі.