עיצוב כפתורי צ'קבוקס ורדיו (checkbox/radio)

עיצוב אלמנטים של HTML עשוי להיות משימה מאתגרת לעיתים, וזה משום שהפקדים (inputs) מהסוג צ'קבוקס ורדיו לא ממש טורחים לקבל את הCSS שאנחנו כותבים להם, בטח לא בכל הדפדפנים והמכשירים, וזה עוד לפני שדברנו על הסימון הפנימי של עיגול או V, שאם אנחנו רוצים לדוגמה עיגול או V בעיצוב מסויים – זה עשוי להיות כבר ממש סיוט, והרבה פעמים מפתחים יעדיפו להשתמש בפלאגין כלשהו שיעשה את העבודה עבורם, העיקר לסיים ולעבור לרכיב הבא.

אבל לא אתם….

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

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

טריק מס' 1 – שימוש בlabel

לכל פקד בטופס, בין אם שדה טקסט, רדיו, תיבת סלקט או צ'קבוקס – צריך להיות בנוסף גם אלמנט מסוג label שמשוייך אליו. בתוך הlabel נכתוב את מהות השדה – "שם פרטי", "מס' תעודת זהות" ואפילו "אני מאשר קבלת מיילים". כל אלו ועוד יהיו לא בתוך span או p או כל אלמנט אחר, אלא אך ורק בתוך label, שמשויך לשדה באמצעות המאפיין for.

איך עושים את זה?
לכל פקד (input, זוכרים?) יש ID משלו, לדוגמה firstName. ללייבל שמכיל את מהות השדה ושמו יש להוסיף את המאפיין for עם הID של השדה שאליו הוא שייך. לדוגמה:


שימו לב, כל label שקשור לשדה ומכיל מידע אודותיו צריך להיות עם for של השדה. זה כולל גם את הלייבל עם שם השדה כמו בדוגמה שלעיל, וגם לייבלים שמכילים את הודעות השגיאה. חובה להגדיר הודעות שגיאה כlabel שמשוייכים לשדות הרלוונטיים ולא כspan וכדו', שלהם אין שום קשר לשדה מבחינה לוגית, אלא אולי בנראות. כך הHTML שלנו יהיה מדויק יותר, וכן קורא המסך ידע לתאר את השדה בצורה המיטבית. בנוסף כשהלייבל מקושר לשדה, כאשר נלחץ עליו עם העכבר או האצבע (במסכי מגע) – התוצאה זהה למה שקורה כשלוחצים על השדה עצמו:
אם זה צ'קבוקס – הסימון V מתהפך,
אם זה רדיו – הוא נעשה checked,
וכן לכל הפקדים – הפוקוס עובר לשדה.

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

יש לנו label שמשויך לשדה. מה הלאה?

קודם כל, נקפיד לשים את השדה כאלמנט הקודם של הlabel. לא label ואחריו שדה וגם לא label ובתוכו שדה כמו שעושים לעיתים משום מה. בנוסף ניתן לlabel של הפקד שאותו רוצים לעצב קלאס כלשהו, כך שיהיה לנו קל להגדיר את הCSS. לדוגמה נתתי את הקלאס inputDesign לlabel של הcheckbox שאותם אני רוצה לעצב.

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

כזכור כדי להשתמש בbefore יש לתת לו קודם כל content. הcontent שנכניס תלוי באיזה V נרצה להציג כשהצ'קבוקס מסומן. אם זו תמונה – ניתן content: '' אבל אם זה אמור להיות V של פונט אייקונים (כדוגמת fontAwesome) או סתם האות V בפונט כלשהו – הרי שניתן את התו הזה כcontent. כן, גם כשהצ'קבוקס לא מסומן יהיה content שמכיל את הV, כדי לא לגרום לקפיצה בעת סימון והורדת סימון, שתנבע מעניין של גובה שורה וכו'. לא מאמינים לי – תוכלו לנסות בעצמכם :-).
בכל מקרה אני בדוגמה רוצה לעשות שימוש בV של fontAwesome, ולכן כאמור אני נותנת את הcontent של הbefore כבר עכשיו עם הcontent שנדרש ליצירת V, ואתן גם את סוג הפונט כבר עכשיו:

.inputDesign:before{
   content: '\f00c';
   font-family: fontAwesome;
}

בשלב הזה אני אמורה לראות בתחילת הlabel שלי את הסימון V של פונט-אוסום. כעת נוסיף קודם כל display מתאים כדי שנוכל לתת גובה, רוחב, padding וגובה שורה. אם רוצים את הצ'קבוקס בשורה נפרדת מהטקסט – צריך לתת display block ואם רוצים את זה ליד הטקסט, כמו ברירת המחדל של צ'קבוקסים display inline-block. אחר כך נוסיף גודל, צבעים ומסגרת, וגם נגדיר color: transparent כדי שלא יראו את הV במצב לא מסומן. במידה ואנחנו משתמשים בbackground image אין צורך לתת color: transparent, אלא לתת את הרקע הרצוי למצב לא לחוץ של הפקד.

.inputDesign:before{
   content: '\1234';
   font-family: fontAwesom;
   display: inline-block;
   border: 1px solid #000;
   background: #fff;
   height: 20px;
   width: 20px;
   color: transparent;
}

איך זה נראה? רואים את הצ'קבוקס הלא מסומן שלנו? כשאתם מוכנים – אפשר לעבור לשלב הבא:

טריק מס' 2 – הסלקטורים +, ~

עד עכשיו עיצבנו ודברנו רק על המצב הלא מסומן של הצ'קבוקס. כעת לכאורה, היה צריך לעשות שימוש בסקריפטים כדי לדעת אם הצ'קבוקס מסומן או לא, ולהתאים את הסימון המעוצב שלנו אליו. רק לכאורה. בהתאם לכלל הלא כתוב שכל מה שאפשר לבצע עם CSS אל תבצע בJS – נשתמש בסלקטור +, וטוב יותר ~.

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

כעת נתקדם עם העיצוב של הצ'קבוקס שלנו. זוכרים את ההדגשה מלמעלה, להקפיד לשים את הinput דווקא לפני הlabel? כאשר הinput נמצא לפני הlabel – הרי שהוא אחיו הגדול ואנחנו יכולים "לשאול" עליו, כשהסלקטור בסופו של דבר יהיה הlabel. למה הכוונה?

input ~ label

יפנה לlabel שלנו רק בתנאי שהinput כתוב לפניו. אבל אנחנו נשתמש עכשיו בסלקטור input:checkex ~ .inputDesign:before שמשמעותו – האלמנט הפיקטיבי before, של מי שיש לו את הקלאס inputDesign (זה הקלאס שנתנו לlabel שלנו כזכור), ויש לו אח לפניו שהוא input שהינו במצב checked – מסומן, במילים אחרות – כאן נוכל לכתוב את הCSS של הדמוי צ'קבוקס שלנו, במצב פעיל. לדוגמה:

input:checkex ~ .inputDesign:before{
color: orange;
}

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

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

לסיום – נסתיר את הצ'קבוקס שלנו

כעת אתם בטח אומרים "טוב, מה הבעיה?! מוסיפים לו display: none וגמרנו סיפור". אז זהו שלא. ניווט מקלדת עובר רק על אלמנטים שקיימים על המסך, וכשמגדירים display none לאלמנט – הוא לא קיים וניווט מקלדת ידלג עליו. גם גרסאות מסוימות של דפדפנים שונים לא מסמנות פקד עם display none מאותה סיבה, גם אם לחצו על הlabel שלו.
במקום זאת נוסיף לפקד (input) את ההגדרות הבאות:

height: 0;
width: 0;
position: absolute;
visibility: hidden;

כך הוא גם לא ייראה על המסך (visibility: hidden) וגם לא יתפוס מקום (position absolute) וליתר ביטחון גודל 0.

זה כל הסיפור, והנה דוגמה חיה:

בהצלחה רבה. אשמח לקבל הערות והארות, מה הצליח ומה לא מספיק ברור.

כתוב/כתבי תגובה