דרכים לעבודה עם אייקונים

משך זמן קריאה: 10 דקות

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

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

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

קצת היסטוריה

נתחיל עם מתאבן נחמד: אתר שמוקדש לנושא האייקונים בהקשר של מחשבים ואינטרנט.
ולמנה העיקרית: בגדול, אפשר לומר שכדי לשלב אייקונים באתר, בעבר הלא רחוק השתמשו בעיקר בתמונות – jpeg או gif – על png לא היה מה לדבר כי אקספלורר לא היה חבר שלו. כל תמונה נמשכת לבדה דרך תגית image, או דרך ה-css בעזרת background-image. כל שיטה והיתרונות והחסרונות שלה.

 

png sprite illustration

ואז הגיע ה-sprite

החסרון הגדול ביותר בשימוש בתגיות image מרובות ו/או שימוש בהרבה תמונות רקע הוא קריאות HTTP מרובות. אמנם עכשיו עם פרוטוקל HTTP2 יש שינוי בנושא, אבל עדיין השאיפה שלנו היא לכמה שפחות קריאות. אבל אני מחזירה אתכם כמה שנים אחורה, אי שם בסביבות שנת 2007 (אם כי ל-A list apart יש פוסט מ 2004 שמדבר על מהו-sprite ואיך משתמשים בו): אנחנו עדיין עם הפרוטוקול הישן ומנסים לחסוך קריאות לשרת, ולכן החל השימוש ב-sprite. קשה לי להאמין שמישהו מכם לא שמע על זה ולא יודע מה זה, אבל למען הסדר הטוב ניתן לקרוא הסבר על מה, איך ולמה פה, ואם מישהו מעוניין במקורות ההיסטוריים של ה-sprite, אפשר לקרוא בוויקיפדיה. כמובן, צצו גם כלים אוטומטיים שיוצרים ספרייט שמקלים על תחזוקת הקובץ.

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

  • חוסר דינאמיות – לאלמנט שמקבל את תמונת הרקע של ה-sprite אנחנו מגדירים רוחב וגובה קבועים. מה יקרה אם נרצה שהגודל ישתנה ברזולוציות שונות? אמנם נכון, יש שיטות ליצור ספרייט דינאמי (אפילו כתבתי על זה פוסט אי שם בשנת 2015) אבל זה לא פשוט, זה מצריך הרבה חישובים, והגרוע מכל – מצריך חישובים מחדש אם משנים את הגובה או את הרוחב של ה-sprite.
  • פיקסול – בסופו של יום, ה-sprite הוא תמונה – קובץ png (בדר"כ) – עם גודל, רוחב והגדרה של רזולוציית מסך. כשהגיחו לעולם מסכי הרטינה, האייקונים שהוצגו ע"י שימוש ב-sprite התפקסלו. ואז צצו פתרונות ביניים לטעינת של קובץ נוסף למסכי רטינה, אבל ראשית זה רק "האק", ושנית, מדובר על תחזוקה כפולה של קבצים, לא פתרון אופטימאלי בכלל.

 

אילוסטרציה של פונט-אייקון

בואו של הפונט-אייקון

קשה לי לומר אם פונט אייקון הגיע במקביל לשימוש ב-svg, לפניו, או אחריו, אבל בינינו – זה לא לגמרי משנה, אני לא כותבת פה ערך של ויקיפדיה 😉 . למי שלא מכיר, ממליצה לקרוא  מהו פונט אייקון. בקצרה, פונט אייקון כשמו כן הוא, פונט שנטען עם העמוד שלנו, ומציג במקום אותיות – אייקונים. כל אייקון מיוצג ע"י סט של ספרות ואותיות וניתן להשתמש בו בקלות. יש הרבה סטים של פונט-אייקון, ואחד המוּכּרים ביותר הינו Font Awesome, שיצא בגרסתו הראשונה בשנת 2012.

מצרפת דוגמת קוד שמתקבל ביצירת פונט דרך icomoon להטמעה של הפונט:

/* =========== CSS: =========== */
@font-face {
font-family: 'icomoon';
src: url('fonts/icomoon.eot');
/*and all other formats...*/
font-weight: normal;
font-style: normal;
}

[class^="icon-"], [class*=" icon-"] {
/* use !important to prevent issues with browser extensions that change fonts */
font-family: 'icomoon' !important;
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;


letter-spacing: 0;
-webkit-font-feature-settings: "liga";
-moz-font-feature-settings: "liga=1";
-moz-font-feature-settings: "liga";
-ms-font-feature-settings: "liga" 1;
font-feature-settings: "liga";
-webkit-font-variant-ligatures: discretionary-ligatures;
font-variant-ligatures: discretionary-ligatures;

/* Better Font Rendering */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

.icon-drag:before {
content: "\e922";
color: #00ff0c;
}

/* =========== HTML: =========== */
<span class="icon-drag"></span>

מה טוב בפונט אייקון?

טעון שיפור:

  • אנימציה מוגבלת – זהה לאנימציה על טקסט (שינוי צבע, מיקום, סיבוב וכדו')
  • לא באמת נגיש
  • כמו כל פונט, הוא לא מתרנדר אותו הדבר בכל הדפדפנים ומצריך איפוס של anti-alias
  • יש חשש שפתאום במקום האייקון שלנו יופיע ריבוע חסר פשר או חלילה, אייקון שבכלל לא רצינו (מוזמנים לראות דוגמה ופירוט בפוסט: Seriously, Don’t Use Icon Fonts)
  • כשהעמוד עולה, אם יש עיכוב בטעינת הפונט, האייקונים לא יופיעו, וכשהם יופיעו תתכן קפיצה קלה בעמוד.

 

איך משיגים פונט-אייקון?

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

 

אם מכינים לבד – חשוב לדעת…

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

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

 

אייקון על גריד של 16 לעומת גריד של 10
ניתן לראות בבירור שגריד 16 לא התאים לאייקון שלי

 

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

 

אייקונים על גריד 32 יותר טוב מ 16

 

בשביל מה כל העבודה הזאת בכלל?

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

 

השוואה של מראה של פונט-אייקון וגודל פונט
הסיבה שהפונט נראה טוב בגודל פונט 16px היא ש-16 הוא חצי של 32

 

שורה התחתונה:
אם יוצרים מערכת חדשה של פונט אייקון המבוססת על אייקונים שאנחנו יצרנו (או המעצבים שאיתם אנחנו עובדים) יש לקחת בחשבון כמה דברים חשובים כדי שהאייקונים ייראו טוב:

  • עבודה מסודרת ב-illustrator תקל על ההכנה
  • נוח יותר אם כל האייקונים יושבים על אותו grid-system  כמו למשל פה
  • עדיף שהאייקון יהיה בגודל של הפונט בו הוא אמור להיות באתר או בכפולות שלו.
    אייקון בגריד של 16*16 יראה באופן מיטבי בגודל פונט של 16 פיקסלים וב-32. בין לבין ייתכנו קצת מריחות, בעיקר ברזולוציות נמוכות ובאייקונים עם קווים ישרים בודדים.
  • אם האייקון לא ממלא את הגריד מקצה לקצה – יש להקפיד על רווח זהה למעלה ולמטה.

 

איור של SVG

חזרתו של ה-svg

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

במאמר מוסגר בהקשר של שימוש ב-svg:
האתר key cdn פרסם פוסט שבו יותר מ 15 מומחים שיתפו את העצה שלהם לשיפור הביצועים לשנת 2018Stefan Judis כותב ככה:

One old practice immediately coming to mind is image spriting. The http/2 adoption today is pretty good, and as thanks to multiplexing several HTTP connections can share one TCP connection, the cost of latency decreases whereas assets can be adequately cached. Say finally goodbye to huge images sprites!

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

מה טוב באייקוני svg?

  • קובץ וקטורי – אין פיקסולים, אין מריחות בתצוגה בשום גודל
  • נגיש – ניתן לקרוא על הנגשת svg בכלל, ועל הנגשת אייקונים ב svg
  • צבעוני – ואפשר לשלוט על הצבעים שבו בעזרת css
  • אנימציה – מאפשר אנימציות שונות גם ע"י css וגם js.

 

עד כאן נשמע אחלה, אז מה הבעיה?

בניגוד לפונט אייקון השימוש ב-svg מתחלק בגדול ל-2 אפשרויות הטמעה:

הראשונה: inline – הכנסה של קוד ה-svg בתוך ה-html שלנו (או עם include בשימוש עם php)

השניה: svg sprite
בשונה מ- sprite של png, זה של svg מתנהג קצת אחרת. מה שקורה, על קצה המזלג, זה שיש לנו svg אחד שבו יש אוסף של אייקונים. כל אחד מהם עטוף ב-<symbol>, ויש לו ID משלו. כשנפתח את הקובץ בדפדפן, לא נראה כלום כי כל האייקונים מוגדרים כלא נראים. כל פעם שנצטרך את אחד האייקונים נקרא לו דרך ה HTML בשימוש עם <use>.
מצרפת דוגמת קוד אבל להסבר מעמיק יותר ממליצה מאוד לקרוא את הפוסט המצויין של CHRIS COYIER.

/* =========== HTML: =========== */

<svg aria-hidden="true" style="position: absolute; width: 0; height: 0; overflow: hidden;" 
version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<symbol id="icon-add" viewBox="0 0 32 32">
   <title>add</title>
   <path d="M18.667 30.667v-12h12c0.8..."></path>
</symbol>
<symbol id="icon-alert" viewBox="0 0 27 32">
   <title>alert</title>
   <path d="M13.714 32c-2.286 0.229-4.343..."></path>
</symbol>
</defs>
</svg>

<span><svg class="icon icon-drag"><use xlink:href="#icon-add"></use></svg></span>
/* =========== CSS: =========== */
.icon {
display: inline-block;
width: 1em;
height: 1em;
stroke-width: 0;
stroke: currentColor;
fill: currentColor;
}


.icon-drag{
width: 0.7em;
}

ואם זה לא מורכב מספיק, אז גם הטעינה שלו מתחלקת ל-2 אפשרויות:

  • שילוב של ה-svg sprite בראש/תחתית העמוד
  • טעינה של קובץ svg חיצוני

היה נדמה לי שדי כיסיתי את כל האופציות אבל אז נתקלתי בעוד פוסט בעניין של המרת svg ל-data-uri ושימוש בו דרך background-image. מודה – לא התנסיתי בזה, אבל בחמישי האחרון התפרסמה ההרצאה של לאה ורו מ-YGLF-קייב, ושם היא עושה שימוש מאוד מורחב ב: background-image: url('data:image/svg+xml);

מה טעון שיפור?

  • הכנסה של ה-svg  לתוך ה-html שלנו, בין אם זה inline או sprite, מנפחת את הקוד שלנו, מאטה את זמן הטעינה, ולא נכנסת ל-cache.
  • שילוב הרבה אייקונים של svg כ-data-image מכבידים על קובץ ה-css שלנו.
  • טעינה של קובץ נפרד של svg sprite מתאפשרת רק אם הוא נמצא על אותו דומיין. מה שאומר שזה לא רלוונטי לכל מי שמשתמש ב-CDN. לקריאה מורחבת בפוסט של css tricks.
  • שוב – 2 הערות ביניים:
    • ניתן להשתמש בטעינה של קובץ משרת שונה בשימוש עם ajax אבל זה לא תמיד אידיאלי
    • אקספלורר לא תומך בקובץ חיצוני ומצריך שימוש בפוליפיל

מרגישים מתוסכלים? גם אני. אבל אם זה מנחם אתכם – אנחנו לא לבד בסיפור הזה. בהקשר של svg מול פונט אייקון נכתבו כמה וכמה פוסטים. ל-css tricks יש פוסט שמשווה בין שניהם. עוד שני פוסטים בנושא החביבים עלי במיוחד הם הפוסט של cloud4: Seriously, Don’t Use Icon Fonts, והפוסט שנכתב בתגובה: Seriously, use icon fonts

 

נוסף בתאריך 06.08.2018
נתקלתי במאמר ב 2 חלקים (חלק ראשון, חלק שני) שמתאר את תהליך העבודה בכל אחת מהשיטות שפירטתי למעלה דרך כלי שנקרא Nucleo. החידוש שיש באפשרויות שם הוא יצירת sprite-svg, לא רק באופן בו אני דיברתי עליו בפוסט, אלא זהה ל png-sprite. מעניין לקרוא על זה, במיוחד שחיפשתי כלי שמייצר את זה ולא מצאתי עד לרגע שנתקלתי בפוסט של Sebastiano Guerriero. מבטיחה לעדכן עוד על השימוש בו.

 

לסיכום

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

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

כתיבת תגובה

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