מדריך: 12 טעויות נפוצות ב-CSS וכיצד אפשר להימנע מהן

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

אל תאמרו נואש. מדריך ה-CSS השלם (צילום: Pixabay)

מאת עדיאל גורן

CSS נחשבת שפת עיצוב קשה מכיוון שכאשר מגדירים properties על אלמנט, עשויות להיות לכך השפעות בלתי צפויות. בנוסף, CSS עלולה להיות מתסכלת מכיוון שהיא מכריחה אותך להתמודד עם ה-web באופן יסודי – יש לקחת בחשבון שימוש במכשירים שונים, דפדפנים שונים, להתחשב במשתמשים הזקוקים לנגישות וכו’.

על אף הקושי, חשוב להכיר את CSS לעומק כדי לא ליפול במלכודות שעלולות לגרום למשל לכך שה-layout ישבר לחלוטין. הנה 12 טעויות נפוצות – וכיצד אפשר להימנע מהן באמצעות עבודה תקנית עם CSS.

1. שימוש במספרים וצבעים hard-coded

דוגמה:

.icon {
  color: #f66035;
}

.button {
  color: #f66035;
}

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

:root {
    --main-color: #f66035;
}

.icon {
  color: var(--main-color);
}

.button {
  color: var(--main-color);
}

שימוש נהדר עבור משתני CSS הוא theming.

אפשר להגדיר css variable גם ב-javascript:

document.querySelector(':root').style.setProperty('--main-color', '#f66035');

מי שמשתמש ב-preprocessor SCSS יכול גם להגדיר משתנים של SCSS, אך אי אפשר לגשת אליהם ב-javascript כיוון שהם נעלמים בזמן הקומפילציה ל-CSS.

2. מרכוז של אלמנט באמצעות position absolute

דוגמה:

.parent {
  position: relative;
}

.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%)
}

אלמנט עם position absolute ממוקם בשכבה עצמאית ויוצא מהזרימה הטבעית של הדף. לכן עדיף להשתמש ב-flexbox:

.parent {
  display: flex;
  align-items: center;
  justify-content: center;
}

3. z-index גדול מאוד

בטוח שיצא לכם לראות את הקוד הבא:

.item {
  z-index: 9999999999;
}

ראשית, הערך המקסימלי של z-index הוא 2147483647, אז אין טעם לשים ערך גבוה יותר. שנית, z-index משפיע רק על אלמנטים הנמצאים באותו Stacking Context, כלומר, באותה קבוצת אלמנטים. אלמנט בקבוצה אחת לא יכול להיות מעל אלמנט בקבוצה אחרת הנמצאת גבוה יותר בציר z, גם אם יש לו z-index גבוה יותר.

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

  • אלמנט עם position שאינו static ועם z-index שלילי
  • אלמנט עם position static (אין משמעות לשים z-index על אלמנט מסוג זה)
  • אלמנט עם position שאינו static וללא z-index
  • אלמנט עם position שאינו static ועם z-index חיובי

ישנם מספר פתרונות אפשריים לניהול z-index.

4. שימוש ב-important! יתר על המידה

דוגמה:

.item {
  width: 100px !important;
  height: 100px !important;
  color: red !important;
}

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

במקום important, מוטב להעלות את ה-specificity של ה-selector המדובר, למשל:

.main .item {
  width: 100px;
  height: 100px;
  color: red;
}

כמו כן, מומלץ להשתמש ב-class-ים על פני inline style, מכיוון ש-inline style גורם לצמידות בין המבנה לעיצוב, ובנוסף הדרך היחידה לדרוס אותו היא באמצעות important.

להבנה טובה של Specificity ראו את Specifishity ונסו את Specificity Calculator.

5. הגדרה של font ללא fallback

דוגמה:

.item {
  font-family: Helvetica;
}

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

.item {
  font-family: Helvetica, Arial, sans-serif;
}

עובדה מעניינת: נכון להיום Helvetica נתמך ב-Mac ב 100% וב-windows ב 7.34%.

6. אנימציה באמצעות שינוי של top / left

דוגמה:

.parent {
  position: relative;
}

.child {
  position: absolute;
  left: 0;
  transition: left 0.3s;
}

.child-new-location {
  left: 100px;
}

הדפדפן מבצע שלושה שלבים במסגרת שינוי CSS:
א. Layout – חישוב כמה מקום כל אלמנט לוקח והיכן למקם אותו
ב. Paint – תהליך מילוי הפיקסלים על גבי שכבות
ג. Composite – תהליך ציור השכבות על גבי המסך בסדר הנכון

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

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

.parent {
  position: relative;
}

.child {
  position: absolute;
  transform: translateX(0);
  transition: transform 0.3s;
}

.child-new-location {
  transform: translateX(100px);
}

המאפיינים opacity ו-transform מפעילים רק את השלב האחרון, וניתן באמצעותם לבצע את רוב האנימציות.

שימו לב: כאשר שמים transform על אלמנט הוא הופך ל-containing block, כלומר, אם קיים אלמנט צאצא עם position fixed, הצאצא ימוקם יחסית אליו במקום יחסית ל-viewport.

7. שימוש ב-Physical Properties במקום ב-Logical Properties

רבים משתמשים ב-physical properties כגון margin-top ו-padding-left, לדוגמה:

.item {
  margin-right: 10px;
}

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

.item {
  margin-right: 10px;
}

html[dir="rtl"] .item {
  margin-right: 0;
  margin-left: 10px;
}

logical properties בא לעזרתנו כדי לחסוך לנו את ההגדרה הכפולה:

.item {
  margin-inline-end: 10px;
}

בדרך קצרה זו, ה-margin יעבוד כמצופה גם בעברית.

8. כיווץ שוליים – margin collapsing

לדוגמה, נגדיר לכל פסקה רווח של 20px מלמעלה ומלמטה:

p {
  margin: 20px 0;
}

במקרה הזה, המרחק בין הפסקאות יהיה 20px ולא 40px, כיוון שה-margin-top של פסקה אחת וה-margin-bottom של הפסקה מעליה מתאחדים והערך הגדול יותר הוא זה שנקבע (במקרה זה לשניהם אותו ערך).

כדי להתגבר על זה, אפשר להשתמש ב-gap במקום margin אם ה-parent הוא flex/grid, או לחלופין באמצעות יצירה של Block formatting context – למשל על ידי הגדרה של display: flex על ה-parent.

9. שימוש לא נכון ב-display

span {
  display: block;
}

קורה שמנסים לתקן את ה-UI באמצעות שינוי של ה-display מבלי להבין את משמעותו. מומלץ להכיר את ה-box model ואת ההבדלים בין סוגי ה-display:

 blockinlineinline-block
גורם לירידת שורהכןלאלא
האלמנט יתרחב בכיוון השורה כדי למלא את השטח הזמין של ה-parentכןלאלא
מאפייני הרוחב והגובה משפיעיםכןלאכן
padding/border/margin יגרמו לדחיפת אלמנטים אחרים מהאלמנטכןרק לרוחבכן

10. שימוש ב-Responsive Design במקום ב-Fluid Design

דוגמה:

.item {
  width: 100px;
}

@media (max-width: 600px) {
  width: 50px;
}

במקום להגדיר עבור כל breakpoint את הרוחב של האלמנט, אנחנו יכולים להשתמש ביחידות מידה רספונסיביות כגון vw / vh / fr / % ובמתודות רספונסיביות כמו min / max / clamp. למשל, את הדוגמה הקודמת אנחנו יכולים פשוט לכתוב כך:

.item {
  width: 25%;
}

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

11. הגדרת רוחב לא רספונסיבית

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

button {
  width: 60px;
}

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

12. שינוי layout בזמן טעינת תמונה

דוגמה:

img {
  max-width: 100%;
  height: auto;
}

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

כדי לטפל בבעיה ניתן להגדיר property חדש בשם aspect ratio:

img {
  width: 100%;
  aspect-ratio: 16 / 9;
}

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

כיום ה-property הזה נתמך בינתיים רק ב-chrome וב-edge. עבור דפדפנים שלא תומכים בזה, אפשר להוסיף לתגית img את width and height attributes, אשר עוזרים לדפדפן לחשב aspect ratio ולא פוגעים ברספונסיביות של התמונה מכיוון שה-CSS חזק יותר מה-attributes.

אגב, ניתן להשתמש ב-feature query – @supports כדי להגדיר rules רק עבור דפדפנים התומכים בתכונה הרצויה.

 

 

 

הכתבה בחסות Duda

Duda היא פלטפורמת SaaS לבניית אתרים שמשרתת יוזרים טכנולוגיים-מקצועיים - החל מסטודיואים לבניית אתרים ועד לחברות ענק כמו TripAdvisor, GoDaddy ו- AppFolio. מעל 14 מיליון אתרים נבנו ב- Duda, עם טראפיק של מאות מיליוני משתמשי קצה. הפלטפורמה מאפשרת לייצר אתרים רספונסיביים, עשירים בפיצ'רים מתקדמים ובאינטגרציות. בנוסף, היא מספקת White Labeling, כלים לעבודה צוותית ולניהול לקוחות, וכלים מתקדמים לקידום אתרים. בנוסף למשרדים במרכז תל אביב, לחברה משרדים בפאלו אלטו, קולורדו וברזיל. עד היום החברה גייסה $50MM, מתוכם $25MM ב-2019.


כתב אורח

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

הגב

14 תגובות על "מדריך: 12 טעויות נפוצות ב-CSS וכיצד אפשר להימנע מהן"

avatar
Photo and Image Files
 
 
 
Audio and Video Files
 
 
 
Other File Types
 
 
 

* היי, אנחנו אוהבים תגובות!
תיקונים, תגובות קוטלות וכמובן תגובות מפרגנות - בכיף.
חופש הביטוי הוא ערך עליון, אבל לא נוכל להשלים עם תגובות שכוללות הסתה, הוצאת דיבה, תגובות שכוללות מידע המפר את תנאי השימוש של Geektime, תגובות שחורגות מהטעם הטוב ותגובות שהן בניגוד לדין. תגובות כאלו יימחקו מייד.

סידור לפי:   חדש | ישן | הכי מדורגים
טרול
Guest

האמת, החכמתי, תודה

אשטנקר
Guest

“קשים” חיים של פועלי הבניין הוירטואלים פחחח

אף אחד
Guest

עדיין לא סיפרת לנו על העבודה שלך, מתבייש?

עמרי
Guest

אחת התגובות היותר שחצניות

User020485
Guest

שאני אבין, בזמנך הפנוי נכנסת לכתבה שמן הסתם לא התחום עניין שלך, קראת אותה ואז ניסית להשפיל אנשים שמרוויחים פי 2 ממך? מביך

מאור
Guest

מדריך מעולה, כן יירבו

נדב
Guest

נהדר ומעמיק, כל הכבוד!

משתמש אובונטו
Guest

אין על הטיפים הקטנים האלה שברורים גם לסתם מתכנת שנאלץ מדי פעם להתעסק עם CSS.

עידן
Guest

מאמר מעולה, למדתי לא מעט, תודה!

מתכנתת
Guest

יש פה דברים נכונים! ודברים שלא הכרתי.
חבל שלא רואים את שם המפתח כאן.
בכל מיקרה,
תודה! :)

FED
Guest

כתבה מצוינת ברמה גבוהה!

יצחק כהן
Guest

ב”ה

קצר ולעניין, תוכן איכותי ואופן כתיבה ברור

תודה

אורי
Guest

Display: grid, align-items: center
זאת הדרך הכי מהירה ליישר למרכז בשני הצירים

CSS Master
Guest

קודם כל ליישר ל 2 הצירים זה עם place-content ולא align-items.
דבר שני, עדיף עם flex כי למרכוז ב grid יש חיסרון שהילד הרחב ביותר קובע את הרוחב של כל שאר הילדים. ראה כאן: https://web.dev/centering-in-css

wpDiscuz

תגיות לכתבה: