TailwindCSS היא פריימוורק (או בשמה העברי: מִסְגֶּרֶת פִּתּוּחַ תָּכְנָה) של utility classes (בחיי שלא מצאתי לזה איזה מקבילה בעברית למעט קלאסי שירות או תועלת, אבל יש גבול להתעקשות על עברית 🙂 ). אם להיות יותר פרקטיים ולקצר, אז מדובר בפריימוורק של קלאסים שבו כל קלאס מייצג מאפיין בודד.
כדי לעצב אלמנט צריך לתת לו את כל הקלאסים שהוא צריך. לדוגמה:
<div class="flex items center text-4xl text-gray-800 p-4 bg-gray-50">
Tailwind מעודכנת מאוד, מתעדכנת מהר ומכילה ותומכת בהרבה מאפיינים חדשים (כמו גריד, שתכלס קצת מוזר לחשוב שב-2021 לא תהיה לזה תמיכה), שימוש ב-css variables, ולאחרונה גם שימוש ב-logical properties. הדעות לגבי Tailwind חלוקות (כמו בכל פריימוורק, תכלס): יש את אלה שחושבים שזה הדבר הכי נפלא שקרה ל-css, ויש כאלה שפחות.
בחצי שנה האחרונה אנחנו משתמשים ב-Tailwind ועדיין לא גיבשתי דעה מוצקה ונחרצת בנושא, אבל כן יש לי כמה תובנות 🙂
לפני שנתחיל – קצת חומר קריאה למי שרוצה לדעת יותר, או לשמוע דעות של אחרים:
- פוסט על מה היא Tailwindcss ואיך משתמשים בה: What is Tailwind CSS and How Can I Add it to my Website or React App?
- מדריך ל-Tailwind CSS
- למה כן?
- Six Reasons Why You Should Start Using Tailwind CSS
- In Defense of Utility-First CSS, ואפשר גם לצפות בווידאו (של 18 דקות) dotCSS 2019 – Sarah Dayan – In Defense of Utility-First CSS
- למה לא?
- Why Tailwind Isn't for Me
- CSS Frameworks, hype and dogmatism
- לא ממש לא, אבל פוסט מאוד מפורט על איך מה ולמה: A Look at Tailwind CSS (אוסיף בהערת שוליים שאם לא נתקלתם עדיין בפוסטים של Ahmad Shadeed, ממליצה בחום – יש לו פוסטים מעולים!)
אז בואו נתחיל:
הטוב
משקל
אי אפשר שלא לפתוח עם היתרון הבולט הזה. המשקל הכולל של Tailwind לפי ההצהרות שלהם הוא 8.7KB (אחרי build בפרודקשן). כמובן שזה לא באמת ריאלי ויש תמיד עוד קבצי CSS (וכמובן שיש להביא בחשבון גם את משקל ה-HTML שגדל) אבל עדיין, שימוש בקלאס flex
למשל בכל מקום שאנחנו רוצים ליישם פלקס, יכול לחסוך חזרתיות רבה בקבצי ה-CSS שלנו.
התאמה אישית
בניגוד לספריות UI אחרות כמו למשל Bootstrap, שבהן אלמנטים מגיעים מעוצבים, פה אין עיצוב בסיסי של שום אלמנט – אין לנו סט של מאפיינים שחלים על קלאס אחד ספציפי שנותן את המראה של כפתור למשל. לכן אין צורך בדריסות של CSS כדי לעצב מחדש אלמנטים. מה שכן יש זה סט של דברים מקובעים שמגיעים עם Tailwindcss כמו למשל גודל פונט, גדלים של padding
או margin
, צבעים, ועוד. את כולם אפשר לראות בתיעוד של Tailwindcss.
Tailwind מספקת גם פלטה צבעונית בסיסית שאני מניחה שמספקת את מי שלא עובד.ת מול עיצוב או מול צבעי מותג מסויים 🙂
מה שיפה ב-Tailwind הוא שאת הכל אפשר לשנות על ידי קונפיגורציה של הערכים שאנחנו רוצים. הצבעים לא מתאימים לפרויקט שלנו? אין בעיה, אפשר להוסיף סט חדש של צבעים. הגדרות גודל הפונט לא תואמות את מה שקיבלנו מהעיצוב? אין בעיה, את הכל ניתן להגדיר מחדש ולהתאים לפי העיצוב. (רוצים לדעת איך? – מוזמנות.ים לקרוא בדוקומנטציה 🙂 )
אחידות
שימוש ב-Tailwind עוזר לשמור על אחידות בקוד: לא עוד שימוש בצבעים hard-coded, לא עוד גדלי פונט שונים עם ערכים שונים בכל מקום – מעכשיו משתמשים רק בקלאסים ש-Tailwind מספקת וככה שומרים על אחידות. גם השימוש בערכים של padding
ו-margin
מעולה בעיניי. קפיצות של 2 פיקסלים כל פעם, שמירה על ערכים זוגיים, בלי לכתוב פתאום משהו עקום כמו: padding-top: 13px
.
בזכות האפשרות של ההתאמה האישית של Tailwind אפשר גם לקסטם את הפלטה הצבעונית ולשמור על הצבעוניות בפרויקט.
הרע
איפה העיצוב שלי?!
- אם בקבצי SCSS או CSS אני יכולה, על-ידי רפרוף על המאפיינים שיש לקלאס מסויים, להבין איך נראה ה-UI שלו, עם Tailwind זה בלתי אפשרי (לי בכל אופן). הרבה יותר קשה לעבור על רשימה של קלאסים בתוך HTML, במיוחד אם נמצאים שם גם קלאסים שמיועדים לעיצוב של רזולוציות שונות, מה שגורם לעומס של קלאסים.
- אם משהו בעיצוב לא עובד או יש איזה באג ויזואלי מוזר, הדיבוג של הבעיה הרבה פחות נוח מאשר דיבוג של CSS רגיל. ב-dev-tools לא נראה את כל המאפיינים של האלמנט מרוכזים, אלא מפוזרים תחת הרבה קלאסים שונים.
שמות הקלאסים
- לכל דבר יש עקומת למידה. טבעי שלא זוכרים את כל הקלאסים בע"פ ישר כשמתחילים לעבוד עם Tailwind, אבל אני עדיין מוצאת את עצמי הרבה פעמים נעזרת בדוקומנטציה כדי לדעת איזה קלאס לתת. גם אחמד שדיד מדבר בפוסט שלו (שמובא ברשימה בתחילת הפוסט) על חלק משמות של קלאסים שלא מספיק בהירים.
- קושי אחר שנתקלתי בו הוא הערכים של
padding
,margin
וגדלים:
נכון, יש יתרון בזה שהם מקובעים בכך שהם שומרים על אחידות, אבל אם העיצוב עדיין לא מדבר בשפה של Tailwind (לא שומר על קפיצות לפי ערכים שמוגדרים ב-Tailwind, או להגזים- מציין על ריווחים את הערך שלו ב-Tailwind), וצריך הרבה פעמים לעשות את ההמרה של פיקסלים ל-rem (שהיא המידה ש-Tailwind משתמשת בה) אז לא תמיד השימוש מספיק אינטואיטיבי (ואני, שלא מצליחה הרבה פעמים לעשות את החישוב בע"פ, פותחת כדרך קבע את העמוד להמרה של px ל-rem ואז בודקת איזה קלאס יתאים לי). - אחרון חביב – לא לכל דבר יש ערך מְסַפֵּק. מה זה אומר? בערך של מינימום גובה למשל יש 3 אפשרויות – מינימום 0, 100% או 100vh. ומה אם אני רוצה לתת ערך אחר? עד לא מזמן זה הצריך לבחור בין הכנסת inline-stlye (אימוג'י מקיא) לבין נתינת קלאס, ובקובץ CSS נפרד לתת עיצוב. היום הסעיף הזה אולי לא לגמרי מתאים להיות מקוטלג תחת "רע" היות ובגרסה האחרונה – JIT יש אפשרות לתת איזה ערך שרוצים לכל קלאס בצורה הזאת:
min-h-[200px]
.
רספונסיביות
בעמוד הבית של Tailwind מוכרזים קלות השימוש וההתאמה הרספונסיבית: כל מה שצריך לעשות זה להוסיף את שם המסך לפני שם הקלאס: sm:h-full md:w-48
. בגדול נשמע נפלא, בקטן אני פחות מחבבת את הדרך שלהם לרספונסיביות משתי סיבות.
הראשונה – לא מספיק שיש לנו עומס של קלאסים על ה-HTML , עכשיו מעמיסים עוד יותר ע"י הוספה של שמות המסכים. ולא רק זה, אלא שאין מקום אחד שאפשר בו לראות את המאפיינים שמיועדים לרזולוציות השונות כי מאוד קשה לסרוק קלאסים ולהבין את העיצוב (זה תכלס נכון לגבי השיטה בכלל, אבל בהקשר של רספונסיביות זה עוד יותר רלוונטי).
השנייה – mobile first (עיצוב מקטן לגדול, כאשר כל media-query
מוגדרת על ידי min-width
). נכון, נשמע לא הגיוני שזה שלילי. אז זה לא ממש, ואני ארחיב. אנחנו ב-2021 ואין ספק ש mobile-first הוא בייסיק בעיצוב וביישום שלו בדפדפן. אבל אם יש משהו שלמדתי בשנים האחרונות, זה שלא תמיד כל המאפיינים ברזולוציה הנמוכה ביותר רלוונטיים לכל הרזולוציות. למשל, במובייל אנחנו עשויים לרצות שהאלמנט שלנו יהיה flex
, אבל מרזולוציה של טאבלט למשל, לא נרצה אותו יותר flex
. עם Tailwind אנחנו נאלצים לתת את ההגדרה של פלקס ואחרי זה לדרוס אותה:
<div class="flex items center md:block ">Only in mobile I'm flex</div>
נכון, אין פה משהו חדש שלא היה בשום יישום אחר של mobile first, אבל אחרי שעובדים עם basic first – עבודה עם media query
פתוחים וסגורים – קצת קשה לחזור אחורה 🙂
חיפשתי קצת ומתברר שאני לא היחידה שהפריע לה שאין גם אפשרות של media query
סגורים, וכך מצאתי את הפוסט הזה שהוביל אותי ליישם גם אצלנו, ועל כן הסעיף הזה נחשב לחצי רע וחצי טוב, כי Tailwind מאפשרת עבודה דינמית עם ההגדרות שלה.
המכוער
המובן מאליו
לא יכולה להתעלם מהמובן מאליו: ה-HTML נהייה ממש ממש מכוער, עמוס ברשימות של קלאסים ולא קריא. כשהתחלנו לעבוד עם Tailwind צפיתי בהקלטה של ההרצאה של Sarah Dayan שבה היא מסבירה למה היא עברה לעבוד עם Tailwind. שרה מדברת בהרצאתה על העובדה שאם מחלקים את הקומפוננטות לקומפוננטות קטנות ופשוטות, אז אין צורך בהרבה קלאסים וכך אין עומס על ה-HTML. אני נוטה להסכים איתה, או עם חלק ממה שהיא אומרת.
אני מסכימה איתה לגמרי שיש לחלק כל קומפוננטה לכמה שיותר חלקי לגו שבסוף יעזרו להרכיב את המוצר הסופי, אבל יחד עם זאת, לא תמיד מדובר בכמה קלאסים בודדים.
אפשר כמובן לפתוח קובץ SCSS ולהשתמש בו בקלאסים של Tailwind בשימוש עם @apply
.
.subtitle { @apply absolute; @apply text-gray-100 font-normal; @apply md:font-bold; }
שימוש כזה הוא הגיוני מצד אחד כי ככה אנחנו שומרים על הערכים שיש לנו מבחינת גדלים, צבעים וכו', אבל מצד שני מאבדים את היתרון שנותנת Tailwind על חזרתיות של מאפיינים בקבצי CSS.
בעיניי יש מאפיינים שאין אצלם משמעות לכתיבה כזאת – כמו למשל position: absolute
– כי אין סיכוי שמישהו ישנה את ההגדרה שלהם בקונפיגורציה ולכן אותם אני לא טורחת לכתוב עם apply
, אבל את השאר – צבעים, ריווחים וכד' – כן.
אמנם הסעיף הזה נמצא תחת "מכוער", אבל אני רוצה לציין שאני כן אוהבת את האפשרות של שימוש בגדלי רזולוציות בתוך הקובץ:
.class { @apply bg-primary-light; @screen mobileOnly{ @apply p-4; } @screen desktop { @apply p-2; @apply flex flex-col; } }
דריסות
הנקודה האחרונה שאני אכתוב עליה היא דריסות (בקטע חיובי, כן?). בגדול, ייתכן שסעיף זה היה צריך להיכלל תחת "הרע", אבל זה לא ממש נכון, כי אם אני מישירה מבט לתיאור של Tailwind, היא מוגדרת כ-"A utility-first CSS framework" מה שאומר שאנחנו יכולים להתבסס עליה, אבל היא לא סותרת עבודה עם קבצי SCSS או CSS במקביל כדי להשלים את העיצוב.
אם בפרויקט שלנו יש שימוש בספרייה חיצונית, כמו ספריית UI (אנחנו למשל מתחזקים את הדיזיין סיסטם שלנו מחוץ לפרויקט), אם נרצה לשנות משהו מהמאפיינים שהעיצוב מגיע איתם בעזרת שימוש בקלאס של Tailwind זה לא יהיה אפשרי. כלומר, אם נוסיף קלאסים עם מאפיינים שאין בעיצוב שהגיע זה יהיה אפשרי, אבל אם נרצה לשנות את אחד מאלה שקיימים זה לא יהיה אפשרי, ולמה?
בהיררכיה של סדר טעינה של CSS, השכבה הראשונה שלנו היא Tailwind, שהרי היא הבסיס (utility-classes) ומעליה מגיעה השכבה הבאה וכו'. במקרה כזה, אנו נצטרך לתת עיצוב ספציפי לאלמנט שלנו בעזרת שימוש בקובץ CSS. יהיה יותר קל לראות את זה בקוד:
בדוגמה הראשונה – המאפיין של Tailwind נטען ראשון ונדרס ע"י העיצוב שמגיע יחד עם הכפתור:
HTML: <button class="design-style absolute">click me</button> css: .design-style{ position: relative; /*other stlyes*/ } .absolute{position: absolute;}
בדוגמה הבאה – העיצוב של הפרויקט נטען אחרי העיצוב שמגיע עם הכפתור ולכן הוא יתממש:
HTML: <button class="design-style app-style">click me</button> CSS: .app-style{ position: absolute; } .design-style{position: relative;/*other stlyes*/ }
לסיכום
כמו בסרט הטוב, הרע והמכוער – שבו שלושת הגיבורים יוצאים יחד בעקבות אוצר אבוד, כל אחד יודע רק חלק מהמידע עליו ולכן נגזר עליהם לחפש אותו יחד – ככה כנראה גם Tailwind: על אף מגרעותיה, יש בה גם צדדים חיוביים. עדיין לא תם הסרט שלי איתה ולכן אין לי אפשרות להגיד לכם אם Tailwind היא אוצר, או שמא יש תפנית בעלילה 🙂
תוספות
(מרץ 2022)
אני לא עוקבת בהתמדה לגבי חידושים על Tailwind אבל נתקלתי ב-2 ששווים אזכור:
- Freewind CSS – אפשרות להשתמש ב Tailwind בלי להתקין אותה. נשמע מוזר ולמה זה טוב בכלל, אבל אם דיברתי בפוסט שלי על היתרון של אחידות צבעונית ושל ערכים של גדלים – אז ככה אפשר להשתמש בערכים של Tailwind בתור משתני CSS בלי לכתוב את הכל מהתחלה, ובלי להתשמש בקלאסים בתוך ה-HTML.
- Create Tailwind CSS – color families – ממשק נוח וממש נעים ליצירת משפחה של צבעים עבור שימוש ב Tailwind.
(דצמבר 2022)
- Tailwind is a Leaky Abstraction
- סקירה מעניינת של שימוש ב tailwind לאורך שנתיים: What working with Tailwind CSS every day for 2 years looks like
כתוב ומסוכם בטוב טעם תודה רבה
תודה רבה, שמחה לשמוע 🙂
אני חושב שהיא עדיין לא ממש בשלה לפרויקטים בחברות גדולות, אבל לפרויקטים אישיים היא מדהימה.
הקושי העיקרי לדעתי הוא הדריסות שמקשה לעשות reuse בהרבה מקרים. אנחנו מאבדים הרבה מהיכולות של css כשמשלבים קלאסים שלנו ושל tailwind.
את ה mobile-first לא הייתי בכלל מזכיר כי קל לשנות את זה בהגדרות.
אחת הבעיות שלא הוזכרו היא איך לשתף קוד, הרי זה יראה אחרת בהתאם לקונפיגורציה, לגרסה ולהרחבות. לכן חנות הקומפוננטות שלהם קצת בעייתית, וזה רק יחמיר ככל שיעבור הזמן ויצאו עוד גרסאות והרחבות.
אני חושבת שהיא כן בשלה לפרויקטים גדולים, ויש לה את היתרונות שלה 🙂
לא לגמרי הבנתי את עניין שיתוף הקוד.
לא יודעת לגבי חנות הקומפוננטות כי לא השתמשתי.
לא אהבתי בכלל את tailwind,קשה מאוד לדאבג.
מסכימה לגמרי, שזה אחד החסרונות שלה