מהו הכלי הזה?
ב-React Native, צללים אינם חוצי-פלטפורמות כברירת מחדל. ב-iOS נעשה שימוש בארבע מאפייני style נפרדים (shadowColor, shadowOffset עם width/height, shadowOpacity בטווח 0-1, ו-shadowRadius לטשטוש), אשר מתואמים לאותו צל CoreAnimation שבו משתמש box-shadow באתרי אינטרנט. מערכת ה-View המובנית של Android אינה תומכת בכלל בצורות צל שרירותיות — היא תומכת רק ב-elevation, מספר בודד שמייצר צל Material Design קבוע בהתאם למידת ה'גובה' שבו ה-view נראה מרחף.
המשמעות היא שצל שנראה נכון ב-iOS באמצעות shadowRadius/shadowOpacity לא יוצג כלל ב-Android אלא אם תגדירו גם elevation, ושני אלה לעולם לא ייראו זהים ברמת הפיקסל, מכיוון שצורת הצל של elevation אינה ניתנת להתאמה אישית כמו זו של iOS. החל מ-React Native 0.74 עם ה-New Architecture מופעל, זמין גם מאפיין style חוצה-פלטפורמות בשם boxShadow, המשתמש באותו תחביר כמו ב-CSS.
למה להשתמש בו?
- צפו בתצוגה מקדימה ויזואלית בזמן אמת תוך כדי כוונון ההיסט, הטשטוש, השקיפות והצבע — במקום לנחש ערכים ולבנות מחדש את האפליקציה כדי לבדוק.
- קבלו בבת אחת את מאפייני הצל של iOS, את ה-elevation של Android ואת מחרוזת ה-boxShadow החדשה והחוצה-פלטפורמות, כך שלא תצטרכו לחפש שלושה API שונים.
- ה-elevation הוא פקד נפרד (ולא מחושב אוטומטית מתוך הטשטוש/השקיפות) מכיוון שהמיפוי מ-elevation לצורת הצל ב-Android אינו תרגום ישיר ממאפייני הצל של iOS — הכוונה היא שתכווננו אותו ויזואלית כדי שיתאים, וכלי זה מאפשר לכם לעשות זאת זה לצד זה.
- חינם, מיידי, ומוכן להעתקה כאובייקט style בודד.
איך להשתמש
- כווננו את ההיסט X/Y, רדיוס הטשטוש, השקיפות וצבע הצל — תיבת התצוגה המקדימה מתעדכנת בזמן אמת.
- כווננו בנפרד את מספר ה-elevation עבור Android עד שהוא תואם ויזואלית לעוצמת הצל שהתכוונתם אליה.
- לחצו על 'Copy' כדי להעתיק את אובייקט ה-style המלא, כולל מאפייני iOS, ה-elevation של Android, ומחרוזת ה-boxShadow.
- הדביקו את האובייקט ב-StyleSheet של הרכיב שלכם — פזרו או מזגו אותו עם סגנונות ה-view הקיימים שלכם.
דוגמה
קלט
היסט (0, 4), טשטוש 8, שקיפות 0.25, שחור, elevation 5פלט
shadowColor: '#000000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.25, shadowRadius: 4, elevation: 5, boxShadow: '0px 4px 8px rgba(0, 0, 0, 0.25)'shadowRadius מוגדר למחצית מערך הטשטוש המוצג בתצוגה המקדימה, בהתאם לאופן שבו רדיוס הטשטוש של CSS מתקשר בפועל ל-shadowRadius של iOS.
שאלות נפוצות
מדוע הצל שלי לא מופיע ב-Android?
המאפיינים shadowColor/shadowOffset/shadowOpacity/shadowRadius מיועדים ל-iOS בלבד — הרינדור המובנה של Android פשוט מתעלם מהם. עליכם להגדיר גם את המאפיין elevation (מספר חיובי) כדי שצל יופיע ב-Android בכלל.
האם אפשר לגרום לצל ב-Android להיראות זהה לזה שב-iOS?
לא בדיוק — elevation מייצר את צורת הצל המובנית של Material Design ב-Android, שאינה ניתנת להגדרה עצמאית מבחינת צבע, כיוון ההיסט או טשטוש כפי שניתן ב-iOS. אפשר לכוונן את מספר ה-elevation כדי להשיג עוצמה דומה ויזואלית, אך התאמה מדויקת ברמת הפיקסל בין הפלטפורמות אינה אפשרית עם ה-API הקלאסיים של shadow/elevation.
מהו המאפיין boxShadow והאם אפשר להשתמש בו במקום?
boxShadow הוא מאפיין style חדש יותר, שהוא באמת חוצה-פלטפורמות (נוסף ב-React Native 0.74, זמין ב-New Architecture), המשתמש באותו תחביר מחרוזת כמו box-shadow ב-CSS ופועל באופן זהה גם ב-iOS וגם ב-Android. אם גרסת ה-React Native והארכיטקטורה של האפליקציה שלכם תומכות בכך, תוכלו להשתמש רק במאפיין הבודד הזה במקום בארבעת מאפייני ה-iOS הנפרדים בתוספת elevation — בדקו את גרסת ה-RN ואת מצב ה-New Architecture לפני שתסתמכו על כך בסביבת ייצור.
מדוע shadowRadius הוא מחצית מערך הטשטוש שהגדרתי?
התצוגה המקדימה בזמן אמת משתמשת ב-box-shadow של CSS, שבו ערך הטשטוש מתפשט למרחק כפול בקירוב לעומת shadowRadius של iOS עבור אותו מספר. הקוד שנוצר מגדיר את shadowRadius למחצית מערך הטשטוש שלכם כך שהצל שאתם רואים בתצוגה המקדימה יתאים למה ש-iOS מרנדר בפועל — אילו העתקתם את ערך הטשטוש ישירות, הצל ב-iOS היה נראה רך וגדול באופן ניכר יותר מהתצוגה המקדימה.
האם אני צריך Platform.select כדי להחיל את הסגנונות הללו?
לא — בטוח לחלוטין להניח את מאפייני ה-shadow* של iOS ואת ה-elevation של Android יחד באובייקט style אחד, בדיוק כפי שהקוד שנוצר עושה: כל פלטפורמה פשוט מתעלמת מהמאפיינים של הפלטפורמה השנייה. כדאי להוסיף Platform.select רק אם אתם רוצים עיצובי צל שונים באמת לכל פלטפורמה, לא רק כדי להימנע מאזהרות (אין כאלה).
הגדרתי elevation אבל הצל ב-Android עדיין לא מופיע — מדוע?
שתי הסיבות הנפוצות ביותר: ל-view אין backgroundColor (צל ה-elevation ב-Android מוטל מהרקע האטום של ה-view, כך שview שקוף לא מטיל דבר), או שלרכיב הורה יש overflow: 'hidden' שגוזר את הצל. תנו ל-view צבע רקע אחיד ובדקו את הגדרות ה-overflow של הרכיבים ההוריים לפני שתניחו שערך ה-elevation שגוי.