בניית רכיב לחצן

סקירה כללית בסיסית של תהליך היצירה של רכיבי <button> מותאמים לצבעים, רספונסיביים ונגישים.

בפוסט הזה אני רוצה לשתף את הטיפים שלי ליצירת רכיב <button> רספונסיבי, נגיש ומתאים לצבע. לנסות את הדגמה ולעיין במקור

העיצוב של הלחצנים מתבצע באמצעות המקלדת והעכבר בעיצובים כהים או בהירים.

אם אתם מעדיפים סרטון, הנה גרסה של הפוסט הזה ב-YouTube:

סקירה כללית

תמיכה בדפדפנים

  • Chrome:‏ 1.
  • Edge:‏ 12.
  • Firefox: 1.
  • Safari:‏ 1.

מקור

הרכיב <button> מיועד לאינטראקציה של המשתמשים. טריגרים של אירוע click מהמקלדת, מהעכבר, ממגע, מקול ועוד, עם כללים חכמים לגבי התזמון. בנוסף, בכל דפדפן יש כמה סגנונות שמוגדרים כברירת מחדל, כך שאפשר להשתמש בהם ישירות בלי לבצע התאמה אישית. אפשר להשתמש ב-color-scheme כדי לבחור גם בלחצנים בהירים וגם בלחצנים כהים שסופקו על ידי הדפדפן.

יש גם סוגים שונים של לחצנים, שכל אחד מהם מוצג בהטמעה הקודמת של Codepen. <button> ללא סוג יתאים ל-<form> וישתנה לסוג השליחה.

<!-- 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 של החודש, לכל לחצן יהיה סגנון שיעזור להבדיל באופן חזותי בין המטרות שלו. לחצני איפוס יהיו בצבעי אזהרה כי הם משמידים את הנתונים, ולחצני שליחה יהיו עם טקסט כחול כדי להבליט אותם מעט יותר מלחצנים רגילים.

תצוגה מקדימה של הקבוצה הסופית של כל סוגי הלחצנים, שמוצגת בטופס ולא בצורה, עם תוספות נחמדות ללחצני סמלים ולחצנים מותאמים אישית.
תצוגה מקדימה של הקבוצה הסופית של כל סוגי הלחצנים, שמוצגים בטופס ולא בטופס, עם תוספות נחמדות ללחצני סמלים וללחצנים מותאמים אישית

ללחצנים יש גם מחלקות מדומה שבהן שירות CSS יכול להשתמש לעיצוב. המחלקות האלה מספקות קטעי הוק (hooks) ל-CSS להתאמה אישית של תחושת הלחצן: :hover לשימוש בעכבר מעל הלחצן, :active כשהעכבר או המקלדת לוחצים, וגם :focus או :focus-visible לעזרה בעיצוב טכנולוגיה מסייעת.

button:hover {}
button:active {}
button:focus {}
button:focus-visible {}
תצוגה מקדימה של הקבוצה הסופית של כל סוגי הלחצנים בעיצוב הכהה.
תצוגה מקדימה של הקבוצה הסופית של כל סוגי הלחצנים בעיצוב כהה

Markup

בנוסף לסוגים של לחצנים שסופקו במפרט 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) {
 

}
כדאי לנסות הדגמה!

טבעת מיקוד אינטראקטיבית

אני אוהב ליצור אנימציה של טבעת המיקוד למשתמשים במקלדת ובטכנולוגיה מסייעת. כדי לעשות זאת, אני יוצר אנימציה של קווי המתאר שמרחיקים אותם מהלחצן ב-5px, אבל רק כשהלחצן לא פעיל. כך נוצר אפקט שבו טבעת המיקוד מתכווצת בחזרה לגודל הלחצן כשלוחצים עליו.

:where(button, input):where(:not(:active)):focus-visible {
 
outline-offset: 5px;
}

איך מוודאים שניגודיות הצבעים עומדת בדרישות

יש לפחות ארבעה שילובי צבעים שונים בין כהה לבהיר שצריך להביא בחשבון את ניגודיות הצבעים שלהם: לחצן, לחצן שליחה, לחצן איפוס ולחצן מושבת. כאן נעשה שימוש ב-VisBug כדי לבדוק את כל הציונים שלהם ולהציג אותם בבת אחת:

הסתרת סמלים מאנשים שלא יכולים לראות

כשיוצרים לחצן, הסמל צריך לתמוך באופן חזותי בטקסט של הלחצן. כלומר, הסמל לא חשוב גם למישהו עם אובדן ראייה. למרבה המזל, הדפדפן מספק דרך להסתיר פריטים מהטכנולוגיה של קורא המסך, כך שלאנשים עם אובדן ראייה לא יוטרפו תמונות של לחצנים לקישוט:

<button>
 
<svgaria-hidden="true">...</svg>
  Icon Button
</button>
כלי הפיתוח של Chrome שמוצג בו עץ הנגישות של הלחצן. העץ מתעלם מתמונת הלחצן כי הערך של aria-hidden מוגדר כ-true.
כלי הפיתוח ל-Chrome שמוצג בו עץ הנגישות של הלחצן. המערכת מתעלמת מתמונת הלחצן כי האפשרות aria-hidden מוגדרת כ-true

סגנונות

בקטע הבא, קודם אגדיר מערכת נכסים מותאמת אישית לניהול הסגנונות המותאמים של הלחצן. בעזרת המאפיינים המותאמים אישית האלה, אפשר להתחיל לבחור רכיבים ולהתאים אישית את המראה שלהם.

אסטרטגיה דינמית של מאפיין מותאם אישית

אסטרטגיית המאפיין המותאם אישית שנעשה בו שימוש באתגר 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%));

בנוסף, כדי לתת ללחצנים מראה קצת תלת-ממדי, הוספת box-shadow‏ 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);
 
}
}

לא רק שהטקסט קל לקריאה, אלא גם צרכני הלחצנים המותאמים אישית יכולים להשתמש בנכסי ה-props האלה בידיעה שהם יתאימו בהתאם להעדפות של המשתמשים.

התאמות לתנועה מופחתת

אם המשתמש הזה בסדר עם התנועה, מקצים את --_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 כ'ללא'. צבעי הדגשה בהקשה (-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 מוקצה לנכס 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);
}

צילום מסך שבו מוצגים לחצנים אחרי החלת הסגנונות הקודמים.

התאמה אישית של לחצני קלט של קבצים

לחצן הקלט של הקובץ הוא מאגר של span ושל לחצן. 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 של הלחצן כדי לדחוף את הטקסט של ה-span מהלחצן, וכך ליצור מקום.

: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;
}

לחצן גדול מופיע לצד הלחצן בהתאמה אישית, והוא גדול פי 150 בערך.

לחצן הסמל

לאפקט הסמל הזה אין שום קשר לסגנונות הלחצנים שלנו, אבל הוא מראה איך להשיג אותו באמצעות כמה מאפייני 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));
}

לחצן עם סמל מוצג בעיצובים בהירים כהים.

סיכום

עכשיו, אחרי שסיפרתי לך איך עשיתי את זה, איך היית עושה את זה? 🙂

בואו לגוון את הגישות שלנו ונלמד את כל הדרכים לבניית אתרים באינטרנט.

אתם יכולים ליצור גרסת דמו, לשלוח לי קישורים בטוויטר ואוסיף אותה לקטע 'רמיקסים של הקהילה' שבהמשך.

רמיקסים של הקהילה

אין כאן שום דבר עדיין לראות.

משאבים