Формы и возвышение
Форма — это скругление углов, возвышение — тень, слой состояния — отклик на наведение и нажатие. Все три в ките — токены Material Design 3: компонент берёт ступень по своей роли и не рисует свою.
Скругления#
Шкала скруглений Material 3 — от прямого угла до пилюли. Чем крупнее и самостоятельнее поверхность, тем мягче её угол.
noneextra-smallsmallmediumlargeextra-largefull| Ступень | Радиус | Где в ките |
|---|---|---|
none |
0 | — |
extra-small |
4 | Выпадающее меню на широком экране |
small |
8 | Поле ввода, тост, блок кода |
medium |
12 | Таблица |
large |
16 | Карточка, карточка объекта, секция настроек, плитка, свёртка, панель сохранения, пустое состояние, свободный край шторки |
large-increased |
20 | — |
extra-large |
28 | Диалог, верхние углы листа меню на телефоне |
extra-large-increased |
32 | — |
full |
9999 | Кнопка, плашка, чип, ход в шапке, пункт дерева разделов, номер страницы, счётчик, тумблер |
Токен ступени — --md-sys-shape-corner-<ступень>. Прежние --radius-sm, --radius-md и --radius-lg — псевдонимы extra-small, small и medium.
Множитель радиуса#
Поле Радиус в оформлении умножает все ступени, кроме none и full: пилюля остаётся пилюлей при любом множителе. Допустимы значения от 0,5 до 2, всё остальное заменяется единицей. Посетитель хранит множитель в cookie оформления рядом с темой и акцентом.
ТокеныТемы.БезопасныйМножитель()src/Классы/оформление/ТокеныТемы.os
Пропускает множитель плотности или радиуса в диапазоне [0.5; 2]. Параметры: Значение - Произвольный - множитель из профиля или cookie. Возвращаемое значение: Число - множитель либо 1 для значения вне диапазона.
Возвышение#
Возвышение — высота поверхности над страницей. Тень Material собрана из двух слоёв: ключевого, резкого, и рассеянного.
level0level1level2level3level4level5| Уровень | Где в ките |
|---|---|
level0 |
Всё в потоке страницы без своей поверхности |
level1 |
Карточка, плитка, свёртка (с кольцом), основная кнопка на наведении, лист меню на телефоне |
level2 |
Шапка после прокрутки, выпадающее меню (с кольцом), панель сохранения, карточка-ссылка на наведении (с кольцом) |
level3 |
Диалог |
level4, level5 |
Свободны: для перетаскиваемого и плавающего |
Токен уровня — --md-sys-elevation-level<N>. Прежние --shadow-sm, --shadow-md и --shadow-lg — псевдонимы уровней 1, 2 и 3.
Кольцо#
Тень на тёмном фоне почти не видна, поэтому у поверхностей кита есть контур — кольцо: обводка 1 px цветом outline-variant на 60 %, нарисованная тенью без размытия. Кольцо не двигает вёрстку и идёт по скруглению поверхности.
| Токен | Значение | Где в ките |
|---|---|---|
--elevation-ring |
кольцо | Секция настроек — залитая, без тени |
--elevation-ring-level1 |
кольцо и level1 |
Карточка, карточка объекта, плитка, свёртка |
--elevation-ring-level2 |
кольцо и level2 |
Выпадающее меню, карточка-ссылка на наведении |
Таблицу обводит рамка outline-variant в полную силу, шапку страницы отчёркивает линия того же цвета — в обеих темах.
Глубину в Material даёт прежде всего ступень поверхности: карточка светлее или темнее фона ещё до тени. В тёмной теме тень почти не видна, и поверхность остаётся главной подсказкой — см. поверхности.
Уровень 1 — карточка в потоке страницы
Источники
Три подключённых репозитория.
HTML = Набор.Карточка().Отрисовать(Новый Структура("Заголовок, Тело",
"Источники", "<p>Три подключённых репозитория.</p>"));Уровень 1 и 2 — плитка-ссылка приподнимается на наведении
HTML = Набор.Плитка().Отрисовать(Новый Структура("Значение, Подпись, Адрес",
"18", "проектов", "/проекты"));Слои состояний#
Наведение, фокус и нажатие в Material — не новый цвет, а слой. Поверх заливки ложится цвет её же содержимого с небольшой прозрачностью. Поэтому состояние одинаково читается на любой заливке и в любой теме.
| Состояние | Токен Material | Токен кита |
|---|---|---|
| Наведение | --md-sys-state-hover-state-layer-opacity 0.08 |
--state-hover 8% |
| Фокус | --md-sys-state-focus-state-layer-opacity 0.1 |
--state-focus 10% |
| Нажатие | --md-sys-state-pressed-state-layer-opacity 0.1 |
--state-pressed 10% |
| Перетаскивание | --md-sys-state-dragged-state-layer-opacity 0.16 |
--state-dragged 16% |
| Недоступно, заливка | — | --state-disabled-container 12% |
| Недоступно, содержимое | — | --state-disabled-content 38% |
Токены кита — те же доли процентами: в таком виде их принимает color-mix().
Наведите указатель на кнопки — слой ложится на каждую своим цветом.
Слой состояния на заливке, обводке и тексте
HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Вариант", "Основная", "основная"))
+ Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Вариант", "Вторичная", "вторичная"))
+ Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Вариант", "Ссылка", "ссылка"))
+ Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Заблокирована", "Недоступна", Истина));Как устроен слой#
Компонент объявляет две локальные переменные: заливку --_bg и цвет содержимого --_fg. Третья, --_state, — плотность слоя: ноль в покое, --state-hover на наведении. Фон считается одной формулой, общей для всех компонентов:
background-color: color-mix(in srgb, var(--_fg) var(--_state), var(--_bg));
Вариант кнопки меняет только пару --_bg и --_fg, правила состояний у всех одни. Прозрачная заливка (кнопка-текст, пункт меню) получает слой тем же путём. Недоступный элемент подменяет пару: заливка — on-surface на 12%, содержимое — on-surface на 38%.
Своему компоненту в листе инсталляции хватит того же приёма:
.report-chip {
--_bg: var(--md-sys-color-surface-container-low);
--_fg: var(--md-sys-color-on-surface);
--_state: 0%;
color: var(--_fg);
background-color: color-mix(in srgb, var(--_fg) var(--_state), var(--_bg));
border-radius: var(--md-sys-shape-corner-small);
transition: background-color var(--motion-fast) var(--motion-ease);
}
.report-chip:hover { --_state: var(--state-hover); }
.report-chip:focus-visible { --_state: var(--state-focus); }
.report-chip:active { --_state: var(--state-pressed); }
Переменные с подчёркиванием — входы правил состояния внутри одного компонента, а не токены темы. Снаружи их не читайте.
Гайдлайны#
Код
HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Вариант", "Отмена", "вторичная"))
+ Набор.Кнопка().Отрисовать("Сохранить");Код
HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Вариант", "Отмена", "вторичная"))
+ "<button class=""button"" type=""button"" style=""border-radius:3px"">Сохранить</button>";Источники
Три подключённых репозитория.
Код
HTML = Набор.Карточка().Отрисовать(Новый Структура("Заголовок, Тело",
"Источники", "<p>Три подключённых репозитория.</p>"));Источники
Три подключённых репозитория.
Код
HTML = "<section class=""card"" style=""box-shadow:var(--md-sys-elevation-level5)"">"
+ "<h2 class=""card__title"">Источники</h2>"
+ "<div class=""card__body""><p>Три подключённых репозитория.</p></div></section>";Код
HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Заблокирована", "Опубликовать", Истина));Код
HTML = "<button class=""button"" type=""button"" disabled style=""--_bg:var(--md-sys-color-primary);"
+ "--_fg:var(--md-sys-color-on-primary);opacity:.6"">Опубликовать</button>";Доступность#
- Фокус с клавиатуры — обводка 3 пикселя цветом
secondaryс зазором 2 пикселя. Своего скругления у обводки нет: она идёт по форме элемента, и пилюля остаётся пилюлей. - Слой фокуса (10%) дополняет обводку, а не заменяет её.
- Недоступное содержимое на 38% контраст не держит — так задумано в Material: элемент, с которым ничего нельзя сделать, читать не обязательно. Причину недоступности пишите текстом рядом.