Podstawowe omówienie tworzenia komponentów <button>
dostosowanych do kolorów, elastycznych i dostępnych.
W tym poście chcę podzielić się swoimi przemyśleniami na temat tego, jak utworzyć elastyczny, elastyczny i łatwo dostępny element <button>
.
Wypróbuj wersję demonstracyjną i zobacz źródło
Jeśli wolisz film, oto wersja tego posta w YouTube:
Omówienie
Element <button>
jest przeznaczony do interakcji z użytkownikiem. click
zdarzenia aktywowane przez klawiaturę, mysz, dotyk, głos i inne, z inteligentnymi regułami dotyczącymi ich czasu. Każda przeglądarka ma też pewne style domyślne, więc możesz ich używać bezpośrednio bez dostosowywania. Użyj color-scheme
, aby włączyć też jasne i ciemne przyciski udostępniane przez przeglądarkę.
Istnieją też różne typy przycisków, z których każdy jest pokazany w poprzednim embedzie Codepen. <button>
bez typu dostosuje się do typu <form>
i zmieni się na typ przesyłania.
<!-- 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">
W wyzwaniu GUI w tym miesiącu każdy z przycisków otrzyma style, które pomogą wizualnie odróżnić ich intencje. Przyciski resetowania będą miały kolory ostrzegawcze, ponieważ są to przyciski niszczące, a przyciski przesyłania będą miały tekst w niebieskim kolorze, aby były nieco bardziej wyróżnione niż zwykłe przyciski.
Przyciski mają też pseudoklasy, które służą do stylizacji za pomocą CSS. Te klasy zapewniają elementy CSS do dostosowywania wyglądu przycisku: :hover
– gdy kursor myszy znajduje się nad przyciskiem, :active
– gdy mysz lub klawiatura są naciśnięte, :focus
lub :focus-visible
– w celu pomocy w stylowaniu technologii wspomagających.
button:hover {}
button:active {}
button:focus {}
button:focus-visible {}
Znacznik
Oprócz typów przycisków podanych w specyfikacji HTML dodaliśmy przycisk z ikoną i przycisk z niestandardową klasą 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">
Następnie, w celu przetestowania, każdy przycisk jest umieszczany w formularzu. Dzięki temu mogę mieć pewność, że style są odpowiednio aktualizowane w przypadku przycisku domyślnego, który działa jak przycisk przesyłania. Zmieniam też strategię dotyczącą ikony, z wstawionego pliku SVG na zamaskowany plik SVG, aby upewnić się, że oba rozwiązania działają równie dobrze.
<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>
W tej chwili matryca kombinacji jest przytłaczająca. Typy przycisków, pseudoklasy i bycie w formularzu lub poza nim – mają do wyboru ponad 20 kombinacji przycisków. Dobrze, że CSS może nam pomóc w jasnym przedstawieniu każdego z nich.
Ułatwienia dostępu
Elementy przycisków są naturalnie dostępne, ale jest kilka typowych ulepszeń.
Przesuwanie i skupienie uwagi
Lubię grupować elementy :hover
i :focus
za pomocą pseudoselektora funkcjonalnego :is()
. Dzięki temu moje interfejsy zawsze uwzględniają
klawiaturę i technologie wspomagające osoby z niepełnosprawnością.
button:is(:hover, :focus) {
…
}
Interaktywny pierścień ostrości
Chcę animować pierścień fokusa dla użytkowników klawiatury i technologii wspomagających. W tym celu animuj kontur przycisku o 5 pikseli, ale tylko wtedy, gdy przycisk nie jest aktywny. Spowoduje to, że pierścień fokusu skurczy się do rozmiaru przycisku po jego naciśnięciu.
:where(button, input):where(:not(:active)):focus-visible {
outline-offset: 5px;
}
Zapewnienie odpowiedniego kontrastu kolorów
W przypadku jasnych i ciemnych kolorów są co najmniej 4 różne kombinacje kolorów, które wymagają uwzględnienia kontrastu kolorów: przycisk, przycisk przesyłania, przycisk resetowania i przycisk wyłączony. Tutaj używamy VisBug do sprawdzania i wyświetlania wszystkich wyników naraz:
Ukrywanie ikon przed osobami, które ich nie widzą
Podczas tworzenia przycisku ikony ikona powinna wizualnie wspierać tekst przycisku. Oznacza to też, że ikona nie jest przydatna dla osób słabowidzących. Na szczęście przeglądarka umożliwia ukrywanie elementów przed czytnikami ekranu, aby osoby z problemami ze wzrokiem nie były rozpraszane przez ozdobne przyciski.
<button>
<svg … aria-hidden="true">...</svg>
Icon Button
</button>
Style
W następnej sekcji najpierw utworzę system właściwości niestandardowych do zarządzania adaptacyjnymi stylami przycisku. Dzięki tym właściwościom niestandardowym mogę zacząć wybierać elementy i dostosowywać ich wygląd.
strategia z niestandardową właściwością dostosowaną do potrzeb
Strategia niestandardowej usługi używana w tym wyzwaniu GUI jest bardzo podobna do tej, która jest stosowana w tworzeniu schematu kolorów. W przypadku systemu z adaptacyjnymi kolorami jasnymi i ciemnymi dla każdego motywu definiowana i nazwana jest odpowiednia właściwość niestandardowa. Następnie do przechowywania bieżącej wartości motywu używana jest jedna właściwość niestandardowa, która jest przypisywana do właściwości CSS. Później można zmienić wartość tej właściwości niestandardowej na inną, a następnie zaktualizować styl przycisku.
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);
}
}
Podoba mi się to, że jasne i ciemne motywy są wyraziste i wyraźne. Przekierowanie i abstrahowanie są przenoszone do właściwości niestandardowej --_bg
, która jest teraz jedyną „reaktywnie” działającą właściwością. --_bg-light
i --_bg-dark
są statyczne. Jasny motyw jest też domyślnym motywem, a ciemny jest stosowany tylko warunkowo.
Przygotowanie do zachowania spójności projektu
Selektor współdzielony
Ten selektor służy do kierowania reklam na wszystkie typy przycisków i na początku jest nieco przytłaczający. Używany jest parametr :where()
, więc dostosowywanie przycisku nie wymaga żadnych szczególnych działań. Przyciski są często dostosowywane do alternatywnych scenariuszy, a selektor :where()
ułatwia to zadanie. Wewnątrz :where()
wybierany jest każdy typ przycisku, łącznie z przyciskiem ::file-selector-button
, którego nie można używać w komponentach :is()
ani :where()
.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"],
input[type="file"]
),
:where(input[type="file"])::file-selector-button {
…
}
Wszystkie właściwości niestandardowe będą ograniczone do tego selektora. Czas przejrzeć wszystkie usługi niestandardowe W tym przycisku jest używanych sporo właściwości niestandardowych. Opiszę po kolei całą grupę, a na końcu tej sekcji pokażę kontekst w ciemnym i zmniejszonym ruchu.
Kolor akcentu przycisku
Przyciski i ikony przesyłania idealnie nadają się do tego, aby kolorować:
--_accent-light: hsl(210 100% 40%);
--_accent-dark: hsl(210 50% 70%);
--_accent: var(--_accent-light);
Kolor tekstu przycisku
Kolory tekstu przycisków nie są białe ani czarne. Są one przyciemnione lub rozjaśnione w wersji --_accent
przy użyciu funkcji hsl()
i utrzymanej w odcieniu 210
:
--_text-light: hsl(210 10% 30%);
--_text-dark: hsl(210 5% 95%);
--_text: var(--_text-light);
Kolor tła przycisku
Tła przycisków są w tym samym stylu hsl()
, z wyjątkiem przycisków w ciemnym motywie, które są białe, dzięki czemu wyglądają jakby były blisko użytkownika lub przed innymi powierzchniami:
--_bg-light: hsl(0 0% 100%);
--_bg-dark: hsl(210 9% 31%);
--_bg: var(--_bg-light);
Tło przycisku
Ten kolor tła pozwala wyświetlać powierzchnię za innymi powierzchniami, co jest przydatne jako tło podczas wprowadzania danych z pliku:
--_input-well-light: hsl(210 16% 87%);
--_input-well-dark: hsl(204 10% 10%);
--_input-well: var(--_input-well-light);
Odstęp przycisku
Odstępy wokół tekstu na przycisku są tworzone za pomocą jednostki ch
, która jest długością względną do rozmiaru czcionki. Ma to kluczowe znaczenie, gdy duże przyciski są w stanie po prostu przesunąć w górę element font-size
i przycisk skalować się proporcjonalnie:
--_padding-inline: 1.75ch;
--_padding-block: .75ch;
Obramowanie przycisku
Promień obramowania przycisku jest przechowywany w własnej właściwości, aby dane wejściowe pliku pasowały do innych przycisków. Kolory obramowania są zgodne z ustanowionym systemem kolorów dostosowanych do potrzeb:
--_border-radius: .5ch;
--_border-light: hsl(210 14% 89%);
--_border-dark: var(--_bg-dark);
--_border: var(--_border-light);
Efekt podświetlenia przycisku
Te właściwości określają rozmiar w celu przejścia po interakcji, a kolor wyróżnienia jest zgodny z systemem kolorów dostosowujących się do warunków. W dalszej części tego artykułu opiszemy, jak te elementy współdziałają ze sobą, ale na koniec warto wspomnieć, że służą one do box-shadow
efektu:
--_highlight-size: 0;
--_highlight-light: hsl(210 10% 71% / 25%);
--_highlight-dark: hsl(210 10% 5% / 25%);
--_highlight: var(--_highlight-light);
Cień tekstu przycisku
Każdy przycisk ma styl subtelnego cienia tekstu. Dzięki temu tekst będzie znajdować się na przycisku, co poprawi jego czytelność i doda przyjemny element prezentacji.
--_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);
Ikona przycisku
Ikony mają rozmiar 2 znaków dzięki względnej długości ch
, która pomoże skalować ikonę proporcjonalnie do tekstu przycisku. Kolor ikony jest oparty na kolorze --_accent-color
, aby zapewnić kolorystykę dostosowaną do motywu.
--_icon-size: 2ch;
--_icon-color: var(--_accent);
Cień przycisku
Aby cienie prawidłowo dostosowywały się do światła i ciemności, muszą zmieniać zarówno kolor, jak i przezroczystość. Jasne cienie w motywie sprawdzają się najlepiej, gdy są subtelne i zabarwione w kierunku koloru powierzchni, na którą nakładają się. Ciemne cienie muszą być ciemniejsze i bardziej nasycone, aby mogły nakładać się na ciemniejsze kolory powierzchni.
--_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);
Dzięki dostosowywaniu kolorów i intensywności mogę stworzyć 2 głębokości cieni:
--_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%));
Aby nadać przyciskom nieco trójwymiarowego wyglądu, zastosowaliśmy cień wewnętrzny 1px
, który tworzy iluzję:
--_shadow-depth-light: 0 1px var(--_border-light);
--_shadow-depth-dark: 0 1px var(--_bg-dark);
--_shadow-depth: var(--_shadow-depth-light);
Przejścia między przyciskami
Zgodnie ze wzorcem kolorów dostosowujących tworzymy 2 właściwości statyczne, które będą przechowywać opcje systemu projektowania:
--_transition-motion-reduce: ;
--_transition-motion-ok:
box-shadow 145ms ease,
outline-offset 145ms ease
;
--_transition: var(--_transition-motion-reduce);
Wszystkie usługi razem w selektorze
: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);
}
dostosowywanie ciemnego motywu,
Wartość wzorca statycznych rekwizytów -light
i -dark
staje się jasna, gdy ustawisz rekwizyty ciemnego motywu:
@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);
}
}
Jest to nie tylko czytelne, ale też użytkownicy tych niestandardowych przycisków mogą używać pustych elementów z pewnością, że będą one odpowiednio dopasowane do preferencji użytkowników.
Adaptacje z obniżonym ruchem
Jeśli użytkownik może poruszać się po mapie, przypisz --_transition
do 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);
}
}
Kilka wspólnych stylów
Fonty przycisków i pola tekstowego muszą być ustawione na inherit
, aby pasowały do reszty czcionek na stronie. W przeciwnym razie przeglądarka nada im styl. Dotyczy to również letter-spacing
. Ustawienie wartości line-height
na 1.5
powoduje, że pole na litery ma odpowiedni rozmiar, aby zapewnić tekstowi odpowiednią ilość miejsca u góry i u dołu:
: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);
}
Przyciski stylu
Regulacja selektora
Selektor input[type="file"]
nie jest elementem przycisku w danych wejściowych, a pseudoelementem ::file-selector-button
jest, więc usunięto z listy element input[type="file"]
:
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"],
input[type="file"]
),
:where(input[type="file"])::file-selector-button {
}
Regulacja kursora i dotyku
Najpierw stylizuję kursor w stylu pointer
, aby poinformować użytkowników, że przycisk jest interaktywny. Następnie dodaję touch-action: manipulation
, aby kliknięcia nie wymagały oczekiwania i obserwowania potencjalnego podwójnego kliknięcia, co sprawia, że przyciski wydają się szybsze:
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
cursor: pointer;
touch-action: manipulation;
}
Kolory i obramowanie
Następnie dostosowuję rozmiar czcionki, kolory tła, tekstu i ramki, używając niektórych wcześniej utworzonych niestandardowych właściwości dostosowanych:
: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);
}
Cienie
Przyciski zostały wykonane za pomocą świetnych technik. text-shadow
dostosowuje się do światła i ciemności, tworząc przyjemny, subtelny tekst przycisku, który ładnie leży na tle. W przypadku box-shadow
przypisane są 3 cienie. Pierwszy, --_shadow-2
, to zwykły cień ramki.
Drugi cień to sztuczka optyczna, która sprawia, że przycisk wygląda na lekko zaokrąglony. Ostatni cień to podświetlenie najechania kursorem, które początkowo ma rozmiar 0, ale później zostanie mu nadany rozmiar i przejście, dzięki któremu będzie wyglądać tak, jakby wyrastał z przycisku.
: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);
}
Układ
Użyłem układu flexbox, a w szczególności układu inline-flex
, który pasuje do treści. Następnie wyśrodkowuję tekst oraz wyrównuję elementy podrzędne do środka w pionie i poziomie. Pomoże to w prawidłowym wyrównaniu ikon i innych elementów przycisku.
: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;
}
Odstępy
W przypadku odstępów między przyciskami użyłem atrybutu gap
, aby elementy pokrewne nie stykały się ze sobą, oraz atrybutów logicalznych, aby odstępy między przyciskami działały w przypadku wszystkich układów tekstowych.
: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);
}
UX dotykowy i myszy
Ta sekcja jest przeznaczona głównie dla użytkowników urządzeń dotykowych. Pierwsza właściwość,
user-select
,
jest przeznaczona dla wszystkich użytkowników; zapobiega ona wyróżnianiu tekstu przycisku. Jest to najbardziej widoczne na urządzeniach dotykowych, gdy użytkownik naciska i przytrzymuje przycisk, a system operacyjny wyróżnia tekst przycisku.
Ogólnie uważam, że nie jest to wygodne dla użytkowników, więc wyłączam to ustawienie, ustawiając wartość user-select
na „brak”. Kolory podświetlenia (-webkit-tap-highlight-color
) i menu kontekstowe systemu operacyjnego (-webkit-touch-callout
) to inne funkcje przycisków bardzo skoncentrowane na internecie, które nie są zgodne z ogólnymi oczekiwaniami użytkowników przycisków, dlatego też je usuwam.
: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;
}
Przejścia
Zmienna adaptacyjna --_transition
jest przypisana do właściwości transition:
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
…
transition: var(--_transition);
}
Gdy użytkownik najedzie kursorem na przycisk, ale nie naciśnie go, dostosuj rozmiar cienia podświetlenia, aby nadać mu ładny wygląd i odcień, który będzie się zwiększał od środka przycisku:
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
):where(:not(:active):hover) {
--_highlight-size: .5rem;
}
Po zaznaczeniu zwiększ odstęp obrysu od przycisku, a także nadaj mu wygląd, który wydaje się rozszerzać od środka przycisku:
:where(button, input):where(:not(:active)):focus-visible {
outline-offset: 5px;
}
Ikony
Aby obsługiwać ikony, selektor ma dodany selektor :where()
dla bezpośrednich elementów potomnych SVG lub elementów z atrybutem niestandardowym data-icon
. Rozmiar ikony jest ustawiany za pomocą właściwości niestandardowej za pomocą właściwości logicznych wstawianych i blokowych. Ustawiono kolor konturu i drop-shadow
pasujący do elementu text-shadow
. Aplikacja flex-shrink
jest ustawiona na 0
, więc ikona nigdy nie jest skompresowana. Na koniec wybieram ikony z liniami i przypisuję im te style za pomocą fill: none
i 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;
}
Dostosowywanie przycisków przesyłania
Chciałem, aby przyciski przesyłania miały nieco wyróżniający wygląd. Osiągnąłem to, zmieniając kolor tekstu przycisków na kolor akcentu:
:where(
[type="submit"],
form button:not([type],[disabled])
) {
--_text: var(--_accent);
}
Dostosowywanie przycisków resetowania
Chciałem, aby przyciski resetowania zawierały wbudowane ostrzeżenia, które ostrzegałyby użytkowników przed potencjalnie szkodliwymi działaniami. W przypadku jasnego motywu przycisk ma też więcej czerwonych akcentów niż w ciemnym. Dostosowanie polega na zmianie odpowiedniego jasnego lub ciemnego koloru podstawowego, a przycisk zaktualizuje styl:
: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%);
}
Myślę też, że kolor obrysu okna fokusu powinien pasować do czerwonego akcentu. Kolor tekstu zmienia kolor z ciemnoczerwonego na jasnoczerwony. Kolor obrysu dopasowuję do słowa kluczowego currentColor
:
:where([type="reset"]):focus-visible {
outline-color: currentColor;
}
Dostosowywanie wyłączonych przycisków
Bardzo często, gdy wyłączony przycisk ma niski kontrast kolorów, by zmniejszyć poziom aktywności wyłączonego przycisku. Testowałem każdy zestaw kolorów i upewniłem się, że spełniają wymagania. Zmieniałem wartość jasności w HSL, aż uzyskałem wynik akceptowalny w DevTools lub 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);
}
Dostosowywanie przycisków wprowadzania plików
Przycisk wyboru pliku to kontener dla elementu span i przycisku. CSS może nieco sformatować kontener pola wejściowego oraz wbudowany przycisk, ale nie element span. Kontenery mają wartość max-inline-size
, dzięki czemu nie będą większe niż to konieczne, a wartość inline-size: 100%
pozwoli im się zmniejszyć i pasować do kontenerów mniejszych niż one. Kolor tła jest ustawiony na kolor adaptacyjny, który jest ciemniejszy niż inne powierzchnie, dzięki czemu jest widoczny za przyciskiem selektora plików.
:where(input[type="file"]) {
inline-size: 100%;
max-inline-size: max-content;
background-color: var(--_input-well);
}
Przycisk selektora plików i przyciski typu danych są przeznaczone specjalnie do usuwania wszelkich stylów dostarczanych przez przeglądarkę, które nie zostały zastąpione przez inne style przycisków.
:where(input[type="button"]),
:where(input[type="file"])::file-selector-button {
appearance: none;
}
Na koniec do inline-end
przycisku dodawany jest margines, aby odsunąć tekst elementu span od przycisku, tworząc w ten sposób odstęp.
:where(input[type="file"])::file-selector-button {
margin-inline-end: var(--_padding-inline);
}
Wyjątki dotyczące ciemnego motywu
Przyciski podstawowych działań miały ciemniejsze tło, dzięki czemu tekst był bardziej kontrastowy, co nadaje im bardziej atrakcyjny wygląd.
@media (prefers-color-scheme: dark) {
:where(
[type="submit"],
[type="reset"],
[disabled],
form button:not([type="button"])
) {
--_bg: var(--_input-well);
}
}
Tworzenie wariantów
Dla zabawy i praktycznej funkcji pokażę, jak stworzyć kilka wariantów. Jeden z wariantów jest bardzo żywy, podobny do przycisków głównych. Innym wariantem jest duży. Ostatni wariant ma ikonę z gradientem.
Intensywny przycisk
Aby uzyskać taki styl przycisków, podstawowe rekwizyty zastąpiłem niebieskim kolorem. Chociaż było to szybkie i łatwe, powoduje usunięcie elementów dostosowanych do urządzenia i wygląda tak samo w motywie jasnym i ciemnym.
.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%);
}
Duży przycisk
Ten styl przycisku uzyskuje się przez modyfikację właściwości niestandardowej --_size
.
Odstępy i inne elementy przestrzeni są względne do tego rozmiaru i zmieniają się proporcjonalnie do nowego rozmiaru.
.btn-large {
--_size: 1.5rem;
}
Ikona
Ten efekt ikony nie ma nic wspólnego z naszymi stylami przycisków, ale pokazuje, jak osiągnąć ten efekt za pomocą zaledwie kilku właściwości CSS oraz jak dobrze przycisk radzi sobie z ikonami, które nie są wbudowane w formatie 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));
}
Podsumowanie
Teraz, gdy już wiesz, jak to zrobić, jak Ty to zrobisz? 🙂
Stosujmy różne podejścia i poznajmy sposoby budowania obecności w internecie.
Utwórz wersję demonstracyjną, wyślij mi linki, a ja dodam je do sekcji z remiksami społeczności.
Remiksy utworzone przez społeczność
Na razie jest tu pusto.
Zasoby
- Kod źródłowy w GitHubie