פריסה

הפודקאסט של CSS – 009: פריסה

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

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

פריסה: היסטוריה קצרה

בימים הראשונים של האינטרנט, הם יותר מורכבים ממסמך פשוט בפורמט של <table>. בסוף שנות ה-90 של המאה ה-20 היה קל יותר להפריד בין HTML לסגנונות חזותיים, כשדפדפנים השתמשו רבים ב-CSS. שירות CSS מאפשר למפתחים לשנות לחלוטין את המראה והתחושה של אתר, בלי לגעת ב-HTML. היכולת החדשה הזאת הניבה פרויקטים, כמו The CSS Zen Garden, שמטרתה להדגים את הכוח של שירות CSS כדי לעודד מפתחים נוספים ללמוד אותו.

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

ציר זמן שמראה את התפתחויות ה-CSS לאורך השנים, החל מ-1996 ועד 2021

פריסה: ההווה והעתיד

שירותי CSS מודרניים כוללים כלי פריסה חזקים במיוחד. יש לנו מערכות ייעודיות לפריסה, ואנחנו עומדים לבחון את מה שעומד לרשותנו, לפני שנעמיק עוד יותר במודולים Flexbox ו-Grid במודולים הבאים.

הסבר על המאפיין display

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

.my-element {
  display: inline;
}

אלמנטים מוטבעים פועלים כמו מילים במשפט. הם יושבים זה לצד זה בכיוון השורה. רכיבים כמו <span> ו-<strong>, שמשמשים בדרך כלל לסגנון של קטעי טקסט שמכילים רכיבים כמו <p> (פסקה), מוטבעות כברירת מחדל. הן גם שומרות על הרווח הלבן שמסביב.

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

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

.my-element {
    display: block;
}

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

.my-element {
    display: flex;
}

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

רשת גמישה וגמישה

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

גמיש

.my-element {
    display: flex;
}

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

פריטים יישארו באותו ציר ולא יגלשו כשייגמר להם המקום. במקום זאת, הם ינסו ללחוץ אחד את השני על אותו הקו. אפשר לשנות את ההתנהגות הזו באמצעות המאפיינים align-items, justify-content ו-flex-wrap.

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

.my-element div {
    flex: 1 0 auto;
}

הנכס flex הוא קיצור של flex-grow, flex-shrink ו-flex-basis. אפשר להרחיב את הדוגמה שלמעלה כך:

.my-element div {
 flex-grow: 1;
 flex-shrink: 0;
 flex-basis: auto;
}

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

תצוגת רשת

.my-element {
    display: grid;
}

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

תצוגת רשת מאפשרת לכתוב כללי פריסה ברכיב שיש לו display: grid, ומציג כמה פרימיטיביים חדשים לעיצוב פריסה, כמו הפונקציות repeat() ו-minmax(). יחידת רשת שימושית אחת היא היחידה fr, שהיא חלק מהשטח שנותר, אפשר ליצור רשתות מסורתיות של 12 עמודות, עם פער בין כל פריט, עם 3 מאפייני CSS:

.my-element {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 1rem;
}

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

.my-element :first-child {
  grid-row: 1/3;
  grid-column: 1/4;
}

המאפיינים grid-row ו-grid-column מורים לרכיב הראשון ברשת להתפרס אל תחילת העמודה הרביעית, מהעמודה הראשונה, ואז span עד לשורה השלישית, משורה הראשונה.

פריסת זרימה

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

בלוק פנימי

חשוב לזכור שאלמנטים שמקיפים את הרכיבים לא מכבדים את השוליים והמרווח הפנימיים ברכיב המוטבע? עם inline-block אתה יכול לגרום לזה.

p span {
    display: inline-block;
}

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

p span {
    margin-top: 0.5rem;
}

צף

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

img {
    float: left;
    margin-right: 1em;
}

המאפיין float מורה לרכיב להיות 'float' לכיוון שצוין. התמונה בדוגמה הזו מורה לתמונה לצוף שמאלה, שמאפשר לרכיבים אחים "לעטוף" מסביבו. אפשר להורות לרכיב לצף את left, right או inherit.

פריסת עמודות

אם יש לכם רשימה ארוכה מאוד של רכיבים, כמו רשימה של כל מדינות העולם, התוצאה עלולה להיות הרבה גלילה ובזבוז זמן למשתמש. הוא עלול גם ליצור רווחים לבנים מיותרים בדף. באמצעות מרובה-עמודות ב-CSS, אפשר לפצל את זה לכמה עמודות כדי לעזור בפתרון שתי הבעיות האלה.

<h1>All countries</h1>
<ul class="countries">
  <li>Argentina</li>
  <li>Aland Islands</li>
  <li>Albania</li>
  <li>Algeria</li>
  <li>American Samoa</li>
  <li>Andorra</li>
  …
</ul>
.countries {
    column-count: 2;
    column-gap: 1em;
}

הרשימה הארוכה הזו תפוצל אוטומטית לשתי עמודות ותוסיף פער בין שתי העמודות.

.countries {
    width: 100%;
    column-width: 260px;
    column-gap: 1em;
}

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

מיקום

לבסוף, סקירה כללית של מנגנוני הפריסה היא מיקום. המאפיין position משנה את אופן הפעולה של אלמנט בזרימה הרגילה של המסמך, ואיך הוא קשור לאלמנטים אחרים. האפשרויות הזמינות הן relative, absolute, fixed ו-sticky. ערך ברירת המחדל הוא static.

.my-element {
  position: relative;
  top: 10px;
}

הרכיב הזה נדחף ב-10 פיקסלים למטה על סמך המיקום הנוכחי שלו במסמך כי הוא ממוקם ביחס לעצמו. הוספה של position: relative לרכיב הופכת אותו לבלוק שמכיל את כל רכיבי הצאצא עם position: absolute. המשמעות היא שהצאצא של הרכיב ימוקם עכשיו מחדש לאלמנט המסוים הזה, במקום ההורה היחסי העליון, כשחל עליו מיקום מוחלט.

.my-element {
  position: relative;
  width: 100px;
  height: 100px;
}

.another-element {
    position: absolute;
    bottom: 0;
    right: 0;
    width: 50px;
    height: 50px;
}

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

  1. אפשר למקם את הרכיב הזה בכל מקום שרוצים, באמצעות top, right, bottom ו-left בהורה היחסי הקרוב ביותר שלו.
  2. כל התוכן שמסביב לאלמנט מוחלט מבצע זרימה חוזרת כדי למלא את השטח הנותר שהושאר על ידי אותו רכיב.

רכיב עם הערך position של fixed מתנהג באופן דומה ל-absolute, כשההורה שלו הוא רכיב השורש <html>. רכיבי מיקום קבוע נשארים מעוגנים בפינה השמאלית העליונה על סמך הערכים top, right, bottom ו-left שהגדרתם.

אפשר ליצור מודעות מעוגנות את ההיבטים הקבועים של fixed ואת ההיבטים הצפויים יותר של זרימת המסמכים של relative בעזרת sticky. עם הערך הזה, כשאזור התצוגה גולל מעבר לרכיב, היא נשארת מוצמדת לערכים top, right, bottom ו-left שהגדרת.

סיכום

יש הרבה אפשרויות בחירה וגמישות בפריסה של CSS. כדי להתעמק יותר ביכולות של Flexbox ו-Grid של CSS, ממשיכים למודולים הבאים.

בדיקת ההבנה

בחינת הידע שלכם לגבי פריסה

אילו 2 פעולות הנכס display עושה?

הפונקציה קובעת את הערך inline או block או none.
למנוע הפריסה צריך לדעת אם התיבה הזו ברוחב מלא או לא, והאם צריך להוסיף אותה לשורה חדשה.
קובעת את המסגרת לפריסת הרשת.
אפשר להגדיר במאפיין 'תצוגה' את האפשרות 'רשת', אבל אין לו קשר למסגרת הפריסה.
המדיניות הזו קובעת איך הילדים צריכים להתנהג.
התוכניות Flexbox והרשת מספקות דעות ותכונות חדשות לילדים.
המדיניות קובעת אם התיבה צריכה לגלול.
זה הנכס overflow.

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

display: grid
הרשת יכולה להכיל מספר פסקאות לעמודות, אבל העמודות האלה יהיו עמודות משלהן ולא זורמות זו אחרי זו.
column-count
הפסקאות יעברו מהסוף של עמודה אחת לתחילת העמודה הבאה, כמו שעושים במגזין או בעיתון.
display: flex
אם אתם גמישים אפשר ליצור כמה פסקאות לעמודות, אבל העמודות האלה יהיו עמודות משלהן, ולא תצטרכו לעבור מפסקה אחת לאחרת.
float
כדאי לנסות שוב.

מה זה אומר אם בלוק לא תקין?

הוא תקוע בצד הנהר.
ההקשר הוא שירות CSS כאן, לא גיאוגרפיה.
הוא קיבל ערך מיקום של top או left.
שימוש במאפיינים האלה בלבד לא ימשוך תיבה כלשהי.
הוא כבר לא ממוקם על סמך מיקומי האחים שלו.
לדוגמה, תיבה עם position: absolute ממוקמת עכשיו עם קואורדינטות x ו-y על סמך הבלוק שמכיל את הקובץ, ולא על סמך הסדר שלו עם רכיבים אחים אחרים.

האם הילדים משולבים כברירת מחדל ב-Flexbox וב-Grid?

נכון
צריך להצטרף אליה עם flex-wrap: wrap או עם repeat(auto-fit, 30ch).
לא נכון
ל-Flexbox ול-Grid יש תכונות אריזה מיוחדות שצריכים סגנונות נוספים כדי להחיל אותן.