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

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

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

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

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

סקירה כללית

תמיכה בדפדפן

  • Chrome: 1.
  • קצה: 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) {
  
}
כדאי לנסות הדגמה!

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

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

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

שמירה על ניגודיות צבעים חולפת

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

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

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

<button>
  <svg … aria-hidden="true">...</svg>
  Icon Button
</button>
כלי הפיתוח ל-Chrome שמוצגים בהם עץ הנגישות של הלחצן. העץ מתעלם מתמונת הלחצן כי הוא מוסתר כ-true.
כלי הפיתוח ל-Chrome שמוצגים בהם עץ הנגישות של הלחצן. העץ מתעלם מתמונת הלחצן כי הוא מוגדר כ-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%));

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

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

: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. מרווחי זמן ורכיבי רווח אחרים ביחס לגודל הזה, מאפשרים התאמה לעומס (scaling) באופן יחסי עם הגודל החדש.

.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));
}

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

סיכום

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

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

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

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

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

משאבים