Базовый обзор того, как создавать адаптивные к цвету, отзывчивые и доступные компоненты <button>
.
В этом посте я хочу поделиться своими мыслями о том, как создать адаптивный к цвету, отзывчивый и доступный элемент <button>
. Попробуйте демо и просмотрите исходный код
Если вы предпочитаете видео, вот версия этого поста на YouTube:
Обзор
Элемент <button>
создан для взаимодействия с пользователем. Событие click
срабатывает при нажатии клавиатуры, мыши, прикосновении, голосе и т. д., с умными правилами относительно его времени . Он также поставляется с некоторыми стилями по умолчанию в каждом браузере, поэтому вы можете использовать их напрямую без какой-либо настройки. Используйте color-scheme
чтобы выбрать светлые и темные кнопки браузера.
Существуют также различные типы кнопок , каждая из которых показана на предыдущей вставке Codepen. <button>
без типа адаптируется к нахождению внутри <form>
, меняясь на тип submit.
<!-- buttons -->
<button></button>
<button type="submit"></button>
<button type="button"></button>
<button type="reset"></button>
<!-- button state -->
<button disabled></button>
<!-- input buttons -->
<input type="button" />
<input type="file">
В конкурсе GUI Challenge в этом месяце каждая кнопка получит стили, помогающие визуально различать их назначение. Кнопки сброса будут иметь предупреждающие цвета, поскольку они разрушительны, а кнопки отправки будут выделены синим текстом, поэтому они будут выглядеть немного более рекламными, чем обычные кнопки.

Кнопки также имеют псевдоклассы для CSS, которые можно использовать для стилизации. Эти классы предоставляют CSS-хуки для настройки ощущения от кнопки: :hover
, когда мышь находится над кнопкой, :active
, когда нажимается мышь или клавиатура, и :focus
или :focus-visible
для помощи в стилизации вспомогательных технологий.
button:hover {}
button:active {}
button:focus {}
button:focus-visible {}

Разметка
В дополнение к типам кнопок, предусмотренным спецификацией HTML, я добавил кнопку со значком и кнопку с пользовательским классом btn-custom
.
<button>Default</button>
<input type="button" value="<input>"/>
<button>
<svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true">
<path d="..." />
</svg>
Icon
</button>
<button type="submit">Submit</button>
<button type="button">Type Button</button>
<button type="reset">Reset</button>
<button disabled>Disabled</button>
<button class="btn-custom">Custom</button>
<input type="file">
Затем для тестирования каждая кнопка помещается внутрь формы. Таким образом, я могу гарантировать, что стили будут обновлены соответствующим образом для кнопки по умолчанию, которая ведет себя как кнопка отправки. Я также переключаю стратегию значков со встроенного SVG на замаскированный SVG, чтобы оба работали одинаково хорошо.
<form>
<button>Default</button>
<input type="button" value="<input>"/>
<button>Icon <span data-icon="cloud"></span></button>
<button type="submit">Submit</button>
<button type="button">Type Button</button>
<button type="reset">Reset</button>
<button disabled>Disabled</button>
<button class="btn-custom btn-large" type="button">Large Custom</button>
<input type="file">
</form>
На данный момент матрица комбинаций довольно обширна. Существует более 20 комбинаций кнопок между типами кнопок, псевдоклассами и нахождением в форме или вне формы. Хорошо, что CSS может помочь нам четко сформулировать каждый из них!
Доступность
Кнопочные элементы естественно доступны, но есть несколько общих улучшений.
Наведите курсор и сфокусируйтесь вместе
Мне нравится группировать :hover
и :focus
вместе с функциональным псевдоселектором :is()
. Это помогает гарантировать, что мои интерфейсы всегда учитывают стили клавиатуры и вспомогательных технологий.
button:is(:hover, :focus) {
…
}
Интерактивное кольцо фокусировки.
Мне нравится анимировать кольцо фокусировки для пользователей клавиатуры и вспомогательных технологий. Я добиваюсь этого, анимируя контур на расстоянии 5 пикселей от кнопки, но только тогда, когда кнопка неактивна. Это создает эффект, заставляющий кольцо фокусировки сжиматься до размера кнопки при нажатии.
:where(button, input):where(:not(:active)):focus-visible {
outline-offset: 5px;
}
Обеспечение передачи цветового контраста
Существует как минимум четыре различных цветовых сочетания светлого и темного цвета, требующие учета цветового контраста: кнопка, кнопка отправки, кнопка сброса и отключенная кнопка. VisBug используется здесь для проверки и отображения всех результатов одновременно:
Скрытие значков от людей, которые не видят
При создании кнопки со значком значок должен обеспечивать визуальную поддержку текста кнопки. Это также означает, что значок не представляет ценности для людей с потерей зрения. К счастью, браузер предоставляет возможность скрывать элементы от технологии чтения с экрана, поэтому людей с потерей зрения не беспокоят декоративные изображения кнопок:
<button>
<svg … aria-hidden="true">...</svg>
Icon Button
</button>

Стили
В следующем разделе я сначала создам систему настраиваемых свойств для управления адаптивными стилями кнопки. С помощью этих пользовательских свойств я могу начать выбирать элементы и настраивать их внешний вид.
Адаптивная стратегия настраиваемых свойств
Стратегия пользовательских свойств, используемая в этом вызове GUI, очень похожа на ту, которая используется при построении цветовой схемы . Для адаптивной системы светлых и темных цветов для каждой темы определяется пользовательское свойство, которому присваивается соответствующее имя. Затем используется одно настраиваемое свойство для хранения текущего значения темы и присваивается свойству CSS. Позже одно настраиваемое свойство можно обновить, присвоив ему другое значение, а затем обновив стиль кнопки.
button {
--_bg-light: white;
--_bg-dark: black;
--_bg: var(--_bg-light);
background-color: var(--_bg);
}
@media (prefers-color-scheme: dark) {
button {
--_bg: var(--_bg-dark);
}
}
Что мне нравится, так это то, что светлые и темные темы декларативны и ясны. Косвенность и абстракция выгружаются в пользовательское свойство --_bg
, которое теперь является единственным «реактивным» свойством; --_bg-light
и --_bg-dark
являются статическими. Также ясно, что светлая тема является темой по умолчанию, а темная применяется только условно.
Подготовка к единообразию дизайна
Общий селектор
Следующий селектор используется для выбора всех типов кнопок и поначалу кажется немного сложным. :where()
используется, поэтому настройка кнопки не требует каких-либо особенностей. Кнопки часто адаптируются для альтернативных сценариев, а селектор :where()
упрощает задачу. Внутри :where()
выбирается каждый тип кнопки, включая кнопку ::file-selector-button
, которую нельзя использовать внутри :is()
или :where()
.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"],
input[type="file"]
),
:where(input[type="file"])::file-selector-button {
…
}
Все пользовательские свойства будут ограничены этим селектором. Пришло время просмотреть все пользовательские свойства! В этой кнопке используется довольно много пользовательских свойств. По ходу дела я буду описывать каждую группу, а в конце раздела поделюсь темными контекстами и контекстами с ограниченным движением.
Акцентный цвет кнопки
Кнопки и значки отправки — отличное место для ярких цветов:
--_accent-light: hsl(210 100% 40%);
--_accent-dark: hsl(210 50% 70%);
--_accent: var(--_accent-light);
Цвет текста кнопки
Цвета текста кнопок не белые и не черные, это затемненные или осветленные версии --_accent
, использующие hsl()
и придерживающиеся оттенка 210
:
--_text-light: hsl(210 10% 30%);
--_text-dark: hsl(210 5% 95%);
--_text: var(--_text-light);
Цвет фона кнопки
Фон кнопок соответствует тому же шаблону hsl()
, за исключением кнопок светлой темы — они окрашены в белый цвет, поэтому на их поверхности они появляются близко к пользователю или перед другими поверхностями:
--_bg-light: hsl(0 0% 100%);
--_bg-dark: hsl(210 9% 31%);
--_bg: var(--_bg-light);
Фон кнопки хорошо
Этот цвет фона предназначен для того, чтобы поверхность отображалась позади других поверхностей, что полезно для фона ввода файла:
--_input-well-light: hsl(210 16% 87%);
--_input-well-dark: hsl(204 10% 10%);
--_input-well: var(--_input-well-light);
Заполнение кнопок
Расстояние вокруг текста в кнопке определяется с помощью единицы измерения ch
— относительной длины к размеру шрифта. Это становится критически важным, когда большие кнопки могут просто пропорционально увеличивать font-size
и масштаб кнопок:
--_padding-inline: 1.75ch;
--_padding-block: .75ch;
Граница кнопки
Радиус границы кнопки сохраняется в пользовательском свойстве, поэтому входные данные файла могут соответствовать другим кнопкам. Цвета границ соответствуют установленной адаптивной цветовой системе:
--_border-radius: .5ch;
--_border-light: hsl(210 14% 89%);
--_border-dark: var(--_bg-dark);
--_border: var(--_border-light);
Эффект выделения кнопки при наведении
Эти свойства устанавливают свойство размера для перехода при взаимодействии, а цвет выделения соответствует адаптивной цветовой системе. Мы расскажем, как они взаимодействуют позже в этом посте, но в конечном итоге они используются для эффекта box-shadow
:
--_highlight-size: 0;
--_highlight-light: hsl(210 10% 71% / 25%);
--_highlight-dark: hsl(210 10% 5% / 25%);
--_highlight: var(--_highlight-light);
Тень текста кнопки
Каждая кнопка имеет тонкий стиль тени текста. Это помогает тексту располагаться поверх кнопки, улучшая читаемость и добавляя приятный внешний вид.
--_ink-shadow-light: 0 1px 0 var(--_border-light);
--_ink-shadow-dark: 0 1px 0 hsl(210 11% 15%);
--_ink-shadow: var(--_ink-shadow-light);
Значок кнопки
Иконки имеют размер в два символа благодаря единице относительной длины ch
, что помогает масштабировать значок пропорционально тексту кнопки. Цвет значка основан на --_accent-color
для адаптивного цвета внутри темы.
--_icon-size: 2ch;
--_icon-color: var(--_accent);
Тень кнопки
Чтобы тени правильно адаптировались к свету и темноте, им необходимо изменить свой цвет и непрозрачность. Светлые тени лучше всего подходят, когда они неяркие и окрашены в цвет поверхности, на которую накладываются. Тени темной темы должны быть темнее и насыщеннее, чтобы они могли перекрывать более темные цвета поверхности.
--_shadow-color-light: 220 3% 15%;
--_shadow-color-dark: 220 40% 2%;
--_shadow-color: var(--_shadow-color-light);
--_shadow-strength-light: 1%;
--_shadow-strength-dark: 25%;
--_shadow-strength: var(--_shadow-strength-light);
С помощью адаптивных цветов и интенсивности я могу собрать тени двух глубин:
--_shadow-1: 0 1px 2px -1px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 9%));
--_shadow-2:
0 3px 5px -2px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 3%)),
0 7px 14px -5px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 5%));
Кроме того, чтобы придать кнопкам немного трехмерный вид, иллюзию создает тень 1px
:
--_shadow-depth-light: 0 1px var(--_border-light);
--_shadow-depth-dark: 0 1px var(--_bg-dark);
--_shadow-depth: var(--_shadow-depth-light);
Переходы кнопок
Следуя шаблону адаптивных цветов, я создаю два статических свойства для хранения параметров системы дизайна:
--_transition-motion-reduce: ;
--_transition-motion-ok:
box-shadow 145ms ease,
outline-offset 145ms ease
;
--_transition: var(--_transition-motion-reduce);
Все свойства вместе в селекторе
:where( button, input[type="button"], input[type="submit"], input[type="reset"], input[type="file"] ), :where(input[type="file"])::file-selector-button { --_accent-light: hsl(210 100% 40%); --_accent-dark: hsl(210 50% 70%); --_accent: var(--_accent-light);--_text-light: hsl(210 10% 30%); --_text-dark: hsl(210 5% 95%); --_text: var(--_text-light);
--_bg-light: hsl(0 0% 100%); --_bg-dark: hsl(210 9% 31%); --_bg: var(--_bg-light);
--_input-well-light: hsl(210 16% 87%); --_input-well-dark: hsl(204 10% 10%); --_input-well: var(--_input-well-light);
--_padding-inline: 1.75ch; --_padding-block: .75ch;
--_border-radius: .5ch; --_border-light: hsl(210 14% 89%); --_border-dark: var(--_bg-dark); --_border: var(--_border-light);
--_highlight-size: 0; --_highlight-light: hsl(210 10% 71% / 25%); --_highlight-dark: hsl(210 10% 5% / 25%); --_highlight: var(--_highlight-light);
--_ink-shadow-light: 0 1px 0 hsl(210 14% 89%); --_ink-shadow-dark: 0 1px 0 hsl(210 11% 15%); --_ink-shadow: var(--_ink-shadow-light);
--_icon-size: 2ch; --_icon-color-light: var(--_accent-light); --_icon-color-dark: var(--_accent-dark); --_icon-color: var(--accent, var(--_icon-color-light));
--_shadow-color-light: 220 3% 15%; --_shadow-color-dark: 220 40% 2%; --_shadow-color: var(--_shadow-color-light); --_shadow-strength-light: 1%; --_shadow-strength-dark: 25%; --_shadow-strength: var(--_shadow-strength-light); --_shadow-1: 0 1px 2px -1px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 9%)); --_shadow-2: 0 3px 5px -2px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 3%)), 0 7px 14px -5px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 5%)) ;
--_shadow-depth-light: hsl(210 14% 89%); --_shadow-depth-dark: var(--_bg-dark); --_shadow-depth: var(--_shadow-depth-light);
--_transition-motion-reduce: ; --_transition-motion-ok: box-shadow 145ms ease, outline-offset 145ms ease ; --_transition: var(--_transition-motion-reduce); }
Адаптации темной темы
Значение шаблона статических реквизитов -light
и -dark
становится ясным, когда установлены реквизиты темной темы:
@media (prefers-color-scheme: dark) {
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"],
input[type="file"]
),
:where(input[type="file"])::file-selector-button {
--_bg: var(--_bg-dark);
--_text: var(--_text-dark);
--_border: var(--_border-dark);
--_accent: var(--_accent-dark);
--_highlight: var(--_highlight-dark);
--_input-well: var(--_input-well-dark);
--_ink-shadow: var(--_ink-shadow-dark);
--_shadow-depth: var(--_shadow-depth-dark);
--_shadow-color: var(--_shadow-color-dark);
--_shadow-strength: var(--_shadow-strength-dark);
}
}
Это не только хорошо читается, но и потребители этих пользовательских кнопок могут использовать голые реквизиты с уверенностью, что они адаптируются соответствующим образом к предпочтениям пользователя.
Сниженная адаптация к движению
Если для этого посетителя движение нормально, назначьте --_transition
для var(--_transition-motion-ok)
:
@media (prefers-reduced-motion: no-preference) {
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"],
input[type="file"]
),
:where(input[type="file"])::file-selector-button {
--_transition: var(--_transition-motion-ok);
}
}
Несколько общих стилей
Для кнопок и полей ввода необходимо настроить inherit
шрифтов, чтобы они соответствовали остальным шрифтам страницы; в противном случае они будут стилизованы браузером. Это также относится к letter-spacing
. Установка line-height
на 1.5
устанавливает размер почтового ящика, чтобы оставить тексту немного места сверху и снизу:
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"],
input[type="file"]
),
:where(input[type="file"])::file-selector-button {
/* …CSS variables */
font: inherit;
letter-spacing: inherit;
line-height: 1.5;
border-radius: var(--_border-radius);
}
Стилизация кнопок
Регулировка селектора
Селектор input[type="file"]
не является частью кнопки ввода, а псевдоэлемент ::file-selector-button
, поэтому я удалил input[type="file"]
из списка:
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"],
input[type="file"]
),
:where(input[type="file"])::file-selector-button {
}
Регулировка курсора и сенсорного управления
Сначала я присваиваю курсору стиль pointer
, который помогает кнопке указать пользователям мыши, что она интерактивна. Затем я добавляю touch-action: manipulation
чтобы при нажатии не нужно было ждать, и наблюдаю за потенциальным двойным щелчком, благодаря чему кнопки начинают работать быстрее:
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
cursor: pointer;
touch-action: manipulation;
}
Цвета и границы
Затем я настраиваю размер шрифта, фон, текст и цвета границ, используя некоторые из адаптивных пользовательских свойств, установленных ранее:
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
…
font-size: var(--_size, 1rem);
font-weight: 700;
background: var(--_bg);
color: var(--_text);
border: 2px solid var(--_border);
}
Тени
К кнопкам применено несколько замечательных техник. text-shadow
адаптируется к свету и темноте, создавая приятный тонкий вид текста кнопки, красиво расположенного поверх фона. Для box-shadow
назначены три тени. Первый, --_shadow-2
, представляет собой обычную тень блока. Вторая тень — это обман зрения, из-за которого кнопка кажется немного скошенной. Последняя тень предназначена для выделения при наведении, первоначально ее размер равен 0, но позже ей будет присвоен размер и изменен переход, поэтому кажется, что она растет от кнопки.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
…
box-shadow:
var(--_shadow-2),
var(--_shadow-depth),
0 0 0 var(--_highlight-size) var(--_highlight)
;
text-shadow: var(--_ink-shadow);
}
Макет
Я присвоил кнопке макет flexbox , в частности inline-flex
макет, который соответствует ее содержимому. Затем я центрирую текст и выравниваю дочерние элементы по центру по вертикали и горизонтали. Это поможет значкам и другим элементам кнопок выровняться правильно.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
…
display: inline-flex;
justify-content: center;
align-items: center;
text-align: center;
}
Расстояние
Для расстояния между кнопками я использовал gap
, чтобы братья и сестры не касались друг друга, и логические свойства для заполнения, чтобы расстояние между кнопками работало для всех текстовых макетов.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
…
gap: 1ch;
padding-block: var(--_padding-block);
padding-inline: var(--_padding-inline);
}
Сенсорный интерфейс и мышь
Следующий раздел в основном предназначен для пользователей сенсорных устройств на мобильных устройствах. Первое свойство user-select
предназначено для всех пользователей; он предотвращает выделение текста в тексте кнопки. Это особенно заметно на сенсорных устройствах, когда кнопка нажата и удерживается, а операционная система выделяет текст кнопки.
Обычно я обнаружил, что это не тот пользовательский интерфейс с кнопками во встроенных приложениях, поэтому я отключаю его, устанавливая для параметра user-select
значение none. Цвета выделения касания ( -webkit-tap-highlight-color
) и контекстные меню операционной системы ( -webkit-touch-callout
) — это другие веб-ориентированные функции кнопок, которые не соответствуют общим ожиданиям пользователей кнопок, поэтому я удаляю их как хорошо.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
…
user-select: none;
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
}
Переходы
Адаптивная переменная --_transition
присваивается свойству перехода :
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
…
transition: var(--_transition);
}
При наведении курсора мыши, пока пользователь не нажимает активно, отрегулируйте размер теневого выделения, чтобы придать ему приятный вид фокуса, который кажется растущим изнутри кнопки:
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
):where(:not(:active):hover) {
--_highlight-size: .5rem;
}
После фокусировки увеличьте смещение контура фокуса от кнопки, также придав ему красивый вид фокуса, который кажется растущим изнутри кнопки:
:where(button, input):where(:not(:active)):focus-visible {
outline-offset: 5px;
}
Иконки
Для обработки значков в селектор добавлен селектор :where()
для прямых дочерних элементов SVG или элементов с настраиваемым атрибутом data-icon
. Размер значка задается с помощью настраиваемого свойства с использованием встроенных и блочных логических свойств. Устанавливается цвет обводки, а также drop-shadow
соответствующая text-shadow
. flex-shrink
установлено значение 0
поэтому значок никогда не сжимается. Наконец, я выбираю значки с линиями и назначаю здесь эти стили с fill: none
, round
концами линий и соединениями линий:
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
) > :where(svg, [data-icon]) {
block-size: var(--_icon-size);
inline-size: var(--_icon-size);
stroke: var(--_icon-color);
filter: drop-shadow(var(--_ink-shadow));
flex-shrink: 0;
fill: none;
stroke-linecap: round;
stroke-linejoin: round;
}
Настройка кнопок отправки
Я хотел, чтобы кнопки отправки имели слегка продвинутый вид, и добился этого, сделав цвет текста кнопок акцентным цветом:
:where(
[type="submit"],
form button:not([type],[disabled])
) {
--_text: var(--_accent);
}
Настройте кнопки сброса
Я хотел, чтобы кнопки сброса имели встроенные предупреждающие знаки, предупреждающие пользователей об их потенциально деструктивном поведении. Я также решил оформить кнопку светлой темы с большим количеством красных акцентов, чем темную тему. Настройка осуществляется путем изменения соответствующего светлого или темного основного цвета, и кнопка обновит стиль:
:where([type="reset"]) {
--_border-light: hsl(0 100% 83%);
--_highlight-light: hsl(0 100% 89% / 20%);
--_text-light: hsl(0 80% 50%);
--_text-dark: hsl(0 100% 89%);
}
Я также подумал, что было бы неплохо, чтобы цвет контура фокуса соответствовал красному акценту. Цвет текста меняется от темно-красного к светло-красному. Я делаю цвет контура соответствующим этому ключевому слову currentColor
:
:where([type="reset"]):focus-visible {
outline-color: currentColor;
}
Настроить отключенные кнопки
Слишком часто отключенные кнопки имеют плохой цветовой контраст при попытке подчинить отключенную кнопку, поэтому она кажется менее активной. Я протестировал каждый набор цветов и убедился, что они прошли проверку, изменяя значение яркости HSL до тех пор, пока оценка не пройдет в DevTools или VisBug.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
)[disabled] {
--_bg: none;
--_text-light: hsl(210 7% 40%);
--_text-dark: hsl(210 11% 71%);
cursor: not-allowed;
box-shadow: var(--_shadow-1);
}
Настройка кнопок ввода файлов
Кнопка ввода файла представляет собой контейнер для диапазона и кнопки. CSS может немного стилизовать входной контейнер, а также вложенную кнопку, но не диапазон. Контейнеру задается max-inline-size
, поэтому он не станет больше, чем нужно, а inline-size: 100%
позволит себе сжиматься и помещать контейнеры меньшего размера, чем он есть. Цвет фона установлен на адаптивный цвет, который темнее, чем у других поверхностей, поэтому он выглядит за кнопкой выбора файла.
:where(input[type="file"]) {
inline-size: 100%;
max-inline-size: max-content;
background-color: var(--_input-well);
}
Кнопка выбора файла и кнопки типа ввода имеют особый appearance: none
чтобы удалить любые стили, предоставленные браузером, которые не были перезаписаны другими стилями кнопок.
:where(input[type="button"]),
:where(input[type="file"])::file-selector-button {
appearance: none;
}
Наконец, к inline-end
кнопки добавляется поле, чтобы отодвинуть текст диапазона от кнопки, создавая некоторое пространство.
:where(input[type="file"])::file-selector-button {
margin-inline-end: var(--_padding-inline);
}
Особые исключения темной темы
Я придал основным кнопкам действий более темный фон для более контрастного текста, придав им более рекламный вид.
@media (prefers-color-scheme: dark) {
:where(
[type="submit"],
[type="reset"],
[disabled],
form button:not([type="button"])
) {
--_bg: var(--_input-well);
}
}
Создание вариантов
Ради развлечения и потому, что это практично, я решил показать, как создать несколько вариантов. Один вариант очень яркий, похожий на то, как часто выглядят основные кнопки. Другой вариант — крупный. Последний вариант имеет значок с градиентной заливкой.
Яркая кнопка
Чтобы добиться такого стиля кнопки, я перезаписал базовые реквизиты синими цветами. Хотя это было быстро и легко, адаптивные реквизиты удалены и выглядят одинаково как в светлой, так и в темной темах.
.btn-custom {
--_bg: linear-gradient(hsl(228 94% 67%), hsl(228 81% 59%));
--_border: hsl(228 89% 63%);
--_text: hsl(228 89% 100%);
--_ink-shadow: 0 1px 0 hsl(228 57% 50%);
--_highlight: hsl(228 94% 67% / 20%);
}
Большая кнопка
Этот стиль кнопки достигается путем изменения пользовательского свойства --_size
. Отступы и другие элементы пространства относятся к этому размеру и масштабируются пропорционально новому размеру.
.btn-large {
--_size: 1.5rem;
}
Кнопка со значком
Этот эффект значка не имеет ничего общего с нашими стилями кнопок, но он показывает, как добиться этого с помощью всего лишь нескольких свойств CSS и насколько хорошо кнопка обрабатывает значки, которые не являются встроенными SVG.
[data-icon="cloud"] {
--icon-cloud: url("https://api.iconify.design/mdi:apple-icloud.svg") center / contain no-repeat;
-webkit-mask: var(--icon-cloud);
mask: var(--icon-cloud);
background: linear-gradient(to bottom, var(--_accent-dark), var(--_accent-light));
}
Заключение
Теперь, когда вы знаете, как я это сделал, как бы вы‽ 🙂
Давайте разнообразим наши подходы и изучим все способы разработки в Интернете.
Создайте демо, пришлите мне ссылку в Твиттере , и я добавлю ее в раздел ремиксов сообщества ниже!
Ремиксы сообщества
Здесь пока смотреть нечего.
Ресурсы
- Исходный код на Github