Загрузка...

Пользовательский интерфейс в CSS

Optional Advanced только что наложил трафарет на одно фото. Этот урок — другой набор: пользовательский интерфейс. Вы меняете указатель, каретку и нативный хром виджета. Здесь не дырявят постер и не режут статью на газетные колонки.

Прямой ответ

Свойства интерфейса CSS намекают на взаимодействие. cursor выбирает форму мыши (pointer, wait, help, not-allowed…). resize позволяет тянуть угол — обычно у textarea. outline с outline-offset рисует кольцо фокуса, не занимая место в раскладке (outline из блочной модели вы уже знаете; здесь это привычка клавиатуры). user-select ограничивает случайное выделение. caret-color окрашивает мигающую каретку. appearance (и -webkit-appearance) может снять нативную «кожу», чтобы вы переоформили контрол. Фокус оставляйте видимым. Не превращайте всю страницу в невыделяемый плакат.

Почему это не маска и не колонки

Маска решает, какие пиксели одной коробки остаются видимыми. Многоколоночность дробит поток текста. Свойства UI не делают ни того ни другого. Ширина и высота остаются, пока не вмешается resize. Фильтры и mask-image по-прежнему про картинку. Вопрос здесь: «Похоже ли это на кликабельное? Можно ли печатать? Можно ли увеличить коробку? Видит ли пользователь клавиатуры, где он?»

cursor — говорите правду

cursor — обещание. pointer значит «сюда можно кликнуть». Ставьте на настоящие кнопки и ссылки. Не вешайте руку на заголовок, который ничего не делает.

Cursor map for honest controls

css
a.nav-link,
button.save {
cursor: pointer;
}

button[disabled] {
cursor: not-allowed;
}

.help-hint {
cursor: help;
}

.busy-panel {
cursor: wait;
}

default — стрелка. text — I-образный курсор над выделяемым текстом. grab / grabbing — для ручек перетаскивания. Свои url(...)-курсоры держите мелкими и всегда указывайте запасное ключевое слово. Лживый курсор хуже отсутствия: кликают слоган — и ничего.

resize — растите коробку, не макет

resize работает на коробках с overflow. Повседневный случай — поле заметок:

Resize a textarea

css
textarea.notes {
min-height: 6rem;
min-width: 16rem;
max-width: 100%;
resize: vertical;
overflow: auto;
}

Значения: none, both, horizontal, vertical. Сочетайте с overflow не visible, иначе ручка может не появиться. Не сыпьте resize: both на все карточки. min-height / max-width не дают полю сжаться или взорваться.

outline как кольцо фокуса

В блочной модели outline сидит снаружи рамки и не занимает место. В наборе UI вы оставляете это кольцо для клавиатурного фокуса — часто с :focus-visible, чтобы мышь не обводила каждый клик:

Focus outline with offset

css
button.save:focus-visible {
outline: 3px solid #2563eb;
outline-offset: 3px;
}

button.save:focus:not(:focus-visible) {
outline: none;
}

Не отправляйте глобальный *:focus { outline: none; }, пока у каждого контрола нет столь же заметной замены. outline-offset отодвигает кольцо, не сдвигая соседей. Это не border (меняет размер) и не масочное затухание подписи кнопки.

user-select — меньше случайного выделения

Выделение — возможность. Ослабляйте его только там, где двойной клик не должен красить синим — подпись панели, чип перетаскивания — не статья.

Limit selection on chrome, not prose

css
.toolbar-label {
user-select: none;
}

article.body {
user-select: text;
}

none блокирует подсветку. text — обычный читаемый режим. all выделяет весь элемент одним кликом. Префиксы (-webkit-user-select) ещё встречаются в старом WebKit. Не запрещайте копировать юридический текст, цены и сообщения об ошибках.

caret-color — цвет каретки

Каретка — мигающая полоска в поле. Подстройте её под бренд не пряча:

Caret color in a field

css
input.email,
textarea.notes {
caret-color: #0f766e;
color: #0f172a;
}

caret-color: auto следует цвету текста. caret-color: transparent «для чистоты» — ловушка. Это не color всей страницы и не mask-image на глифе.

appearance — переоденьте нативный виджет

Браузеры рисуют чекбоксы и поля поиска нативным хромом. appearance: none (плюс -webkit-appearance: none при необходимости) снимает эту кожу:

Reset appearance then restyle

css
input.search {
appearance: none;
-webkit-appearance: none;
border: 1px solid #94a3b8;
border-radius: 0.5rem;
padding: 0.5rem 0.75rem;
}

input[type="checkbox"].tick {
appearance: none;
-webkit-appearance: none;
width: 1.15rem;
height: 1.15rem;
border: 2px solid #334155;
border-radius: 0.25rem;
}

После none вы должны рамку, состояние «отмечено» и кольцо фокуса. Невидимый чекбокс — не кастомный контрол. Поддержка зависит от типа; проверяйте настоящий виджет. appearance не чинит маску и не заменяет колонки.

UI против маски, колонок и outline коробки

📊 UI vs mask vs columns vs outline

Tool Job Poor fit
cursor / resize / caret-color / appearance Interaction chrome on controls Stenciling a photo; newspaper columns
user-select Limit highlight on chrome, not articles Hiding copy people must paste
outline + :focus-visible Keyboard focus ring (no layout space) Replacing border math; fading labels with a mask
mask-image Soft holes on one element’s pixels Pointer shape; growing a textarea
Multi-column (column-*) Fragment flowing text Cursors, carets, native widget skin

Optional Advanced уже брал колонки для прозы и маски для картинок. Интерфейс — слой контролов. column-count на форме настроек или mask-image на кнопке отправки не делает форму «более UI».

Что не стоит стирать

Не снимайте все нативные подсказки. Полосы прокрутки, каретки и кольца фокуса нужны. Если контрол выключен, cursor: not-allowed плюс настоящий атрибут disabled спокойнее маски, прячущей подпись.

UI polish is not a mask or columns

css
.ok-ui {
cursor: pointer;
outline-offset: 2px;
}

.not-a-stencil {
/* don't: mask-image on the submit label to “soften” the click */
}

.not-a-newspaper {
/* don't: column-count on a login form to look advanced */
}

Край фото — вернитесь к маске. Длинная статья — к колонкам или обычному потоку блоков. «Не ощущается кликабельным» — начните с cursor и настоящего контрола, не с декоративного фильтра.

Попробуйте сами

  1. cursor: pointer на настоящую <button> и not-allowed на [disabled].
  2. textarea: resize: vertical, min-height, overflow: auto.
  3. Outline с :focus-visible и outline-offset — дойдите Tab.
  4. user-select: none только на чипе панели; статья остаётся выделяемой.
  5. Покрасьте caret-color во input. Не маскируйте поле и не ставьте column-count.

Частые ошибки

  • cursor: pointer на тексте, который не ссылка и не кнопка
  • resize: both на карточках макета и панелях навигации
  • Глобальный outline: none без замены :focus-visible
  • user-select: none на целых страницах, ценах или ошибках
  • caret-color: transparent «ради чистого вида»
  • appearance: none без рамки, состояния «отмечено» и кольца фокуса
  • Путать маску или колонки с полировкой интерфейса

Кратко

  • CSS интерфейса намекает на взаимодействие: указатель, resize, каретка, нативный хром
  • cursor должен говорить правду; resize — для полей, не для оболочки страницы
  • Держите видимым кольцо фокуса; user-select и caret-color трогайте легко
  • appearance: none только когда переоформляете виджет целиком
  • Это не трафарет маски и не газетные колонки
  • Optional Advanced дальше: 3D-трансформации (transforms-3d)

🧠 Проверьте Свои Знания

Готов к Началу

Проверьте Свои Знания

Бросьте себе вызов с помощью этой интерактивной викторины и узнайте, насколько хорошо вы понимаете тему

❓
7
Вопросы
🎯
70%
Для Прохождения
♾️
∞
Время
🔄
∞
Попытки

📝 Инструкции

  • Внимательно прочитайте каждый вопрос
  • Выберите лучший ответ на каждый вопрос
  • Вы можете пересдавать тест столько раз, сколько захотите
  • Ваш прогресс будет показан вверху