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

Christian Cantrell
Christian Cantrell

מבוא

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

דוגמה להחרגה של שירותי CSS בפעולה
דוגמה להחרגות של שירותי CSS

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

דוגמאות לפעולה של אזורים בשירות CSS
דוגמה לשימוש באזורים ב-CSS

אזורים של שירות CSS

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

הפעלת אזורים של CSS ב-Google Chrome

החל מגרסה 20 של Chrome (גרסה 20.0.1132.57, ליתר דיוק), אזורי CSS מופעלים דרך ממשק chrome://flags. כדי להפעיל אזורי CSS:

  1. פותחים כרטיסייה חדשה או חלון חדש ב-Chrome.
  2. מקלידים chrome://flags בסרגל המיקום.
  3. משתמשים בפונקציה חיפוש בדף (control/command + f) ומחפשים את הקטע 'תכונות ניסיוניות של פלטפורמת האינטרנט'.
  4. לוחצים על הקישור Enable.
  5. לוחצים על הלחצן הפעלה מחדש עכשיו בחלק התחתון.

למידע נוסף על הדגלים של Chrome, יש לעיין בפוסט בבלוג שלי בנושא כל המידע על הדגלים של Chrome.

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

סקירה כללית של האזורים בשירות ה-CSS

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

התוכן עובר לאזורים מוגדרים
התוכן עובר לאזורים מוגדרים

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

דוגמה לפרויקט לא בסגנון אנושי מדור קודם
דוגמה לפרויקט Unstyled Human Legacy Legacy

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

פרויקט מורשים אנושי שמציג אזור
פרויקט אנושי מדור קודם עם אזורים.

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

פרויקט דור קודם של אדם שמציג אזורים
פרויקט אדם מדור קודם שמציג אזורים

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

יצירת תהליך עבודה בעל שם

שירות ה-CSS שנדרש כדי שבלוק של טקסט יזרום בין אזורים הוא פשוט מאוד. קטע הקוד שלמטה מקצה זרימה בעלת שם שנקרא "article" ל-div עם המזהה "content", ומקצה את אותו "מאמר" בעל שם לכל רכיב עם המחלקה "אזור". התוצאה היא שהטקסט שכלול באלמנט "content" עובר באופן אוטומטי דרך כל רכיב עם המחלקה "region".

<!DOCTYPE html>
<html>
<head>
    <style>
    #content {
        { % mixin flow-into: article; % }
    }

    .region {
        { % mixin flow-from: article; % }
        box-sizing: border-box;
        position: absolute;
        width: 200px;
        height: 200px;
        padding: 10px;
    }

    #box-a {
        border: 1px solid red;
        top: 10px;
        left: 10px;
    }

    #box-b {
        border: 1px solid green;
        top: 210px;
        left: 210px;
    }

    #box-c {
        border: 1px solid blue;
        top: 410px;
        left: 410px;
    }
    </style>
</head>
<body>
    <div id="box-a" class="region"></div>
    <div id="box-b" class="region"></div>
    <div id="box-c" class="region"></div>
    <div id="content">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent eleifend dapibus felis, a consectetur nisl aliquam at. Aliquam quam augue, molestie a scelerisque nec, accumsan non metus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin cursus euismod nisi, a egestas sem rhoncus eget. Mauris non tortor arcu. Pellentesque in odio at leo volutpat consequat....
    </div>
</body>
</html>

התוצאה נראית כך:

תוצאה של הקוד שלמעלה
התוצאה של הקוד שלמעלה

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

מודל האובייקטים של CSS

מודל האובייקטים של CSS, או CSSOM, מגדיר ממשקי API של JavaScript לעבודה עם CSS. בהמשך מופיעה רשימה של ממשקי ה-API החדשים שקשורים לאזורים של CSS:

  • document.webkitGetNamedFlows(): פונקציה שמחזירה את האוסף של תהליכי העבודה בעלי שם, הזמין במסמך.
  • document.webkitGetNamedFlows().namedItem("article"): פונקציה שמחזירה הפניה לזרימה ספציפית בעלת שם. הארגומנט תואם לשם שצוין כערך של מאפייני ה-CSS flow-into ו-from-from. כדי לקבל הפניה לזרימה בעלת השם שצוינה בקטע הקוד שלמעלה, עליך להעביר את המחרוזת 'מאמר'.
  • WebKitNamedFlow: ייצוג אובייקט של נוזל בעל שם עם המאפיינים והפונקציות הבאים:
    • firstEmptyRegionIndex: ערך של מספר שלם שמפנה אל האינדקס של האזור הריק הראשון שמשויך לזרימת השם. בgetRegions() שבהמשך יש מידע על האופן שבו ניתן לגשת לאוסף אזורים.
    • name: ערך מחרוזת עם שם הזרימה.
    • overset: נכס בוליאני שהוא:
      • false כאשר התוכן של התהליך בעל השם מתאים לאזורים המשויכים
      • true כשהתוכן לא מתאים ונדרשים אזורים נוספים כדי לכלול את כל התוכן.
    • getContent(): פונקציה שמחזירה אוסף עם הפניות לצמתים שזורמים לזרימה בעלת השם.
    • getRegions(): פונקציה שמחזירה אוסף עם הפניות לאזורים ששמורים בהם התוכן של התהליך בעל השם.
    • getRegionsByContentNode(node): פונקציה שמחזירה הפניה לאזור שמכיל את הצומת שצוין. האפשרות הזו שימושית במיוחד לאיתור אזורים שמכילים דברים כמו עוגנים עם שם.
  • אירוע אחד (webkitregionoversetchange). האירוע הזה מופעל ב-WebkitNamedFlow בכל פעם שהפריסה של התוכן המשויך משתנה מסיבה כלשהי (הוספה או הסרה של תוכן, גודל הגופן, צורת האזור משתנה וכו') וגם גורם לשינוי במאפיין webkitRegionOverset של אזור. האירוע הזה שימושי להאזנה לשינויים בפריסה גסה. זהו סימן לכך שקרה משהו חשוב וייתכן שנדרשת התייחסות לפריסה, למשל: נדרשים אזורים נוספים, ייתכן שאזורים מסוימים יהיו ריקים וכו'.
  • אירוע אחד (webkitregionfragmentchange). לא יושם בזמן העריכה הזו. האירוע הזה מופעל ב-WebkitNamedFlow בכל פעם שהפריסה של התוכן המשויך משתנה מסיבה כלשהי, בדומה ל-webkitregionoversetchange, אבל בלי קשר לשינויים כלשהם בנכסים של webkitRegionOverset. האירוע הזה שימושי להאזנה לשינויי פריסה מפורטים שאינם בהכרח משפיעים על הפריסה כולה של הזרימה בעלת השם, לדוגמה: התוכן עובר מאזור אחד לאחר, אבל התוכן הכולל עדיין מתאים לכל האזורים.
  • Element.webkitRegionOverset: רכיבים הופכים לאזורים אם הוקצה להם נכס ה-CSS flow-from. לרכיבים האלה יש מאפיין webkitRegionOverset, שאם הם חלק מזרימה בעלת שם, הוא מציין אם תוכן מזרימה גולש באזור. הערכים האפשריים של webkitRegionOverset הם:
    • 'גלישה' אם יש יותר תוכן ממה שהאזור יכול להכיל.
    • "fit" (התאמה) אם התוכן מפסיק לפני סוף האזור
    • 'ריק' אם התוכן לא הגיע לאזור.

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

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

var flow = document.webkitGetNamedFlows().namedItem("article")
flow.addEventListener("webkitregionoversetchange", onLayoutUpdate);

function onLayoutUpdate(event) {
    var flow = event.target;
    
    // The content does not fit
    if (flow.overset === true) {
    addRegion();
    } else {
    regionLayoutComplete();
    }
}

function addRegion() {
    var region = document.createElement("div");
    region.style = "flow-from: article";
    document.body.appendChild(region);
}

function regionLayoutComplete() {
    // Finish up your layout.
}

הדגמות נוספות זמינות בדף 'דוגמאות של אזורים בשירות CSS'.

תבניות דפים של CSS

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

נבחן תרחיש נפוץ לדוגמה של תבניות דפי CSS. קטע הקוד הבא מציג את השימוש ב-CSS ליצירת שתי זרימות בעל שם: "article-flow" ו-"timeline-flow". בנוסף, הוא מגדיר בורר שלישי שנקרא "מאמרים משולבים" שבתוכו שני התהליכים ייכללו. אם מוסיפים רק את המאפיין overflow-style בבורר 'מאמרים משולבים', צריך לציין שהתוכן צריך להישלח אוטומטית לאורך ציר ה-x או לרוחב:

<style>
    #article {
    { % mixin flow-into: article-flow; % }
    }

    #timeline {
    { % mixin flow-into: timeline-flow; % }
    }

    #combined-articles {
    overflow-style: paged-x;
    }
</style>

לאחר הגדרת התהליכים והתנהגות הגלישה הרצויה, נוכל ליצור את תבנית הדף עצמה:

@template {
    @slot left {
    width: 35%;
    float: left;
    { % mixin flow-from: article-flow; % }
    }

    @slot time {
    width: 25%;
    float: left;
    { % mixin flow-from: timeline-flow; % }
    }

    @slot right {
    width: 35%;
    float: left;
    { % mixin flow-from: article-flow; % }
    }
}

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

דוגמה של תבניות דפים
דוגמה לתבניות דפים

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

תבניות דפי CSS הן עדיין הצעה, אבל יש לנו אב טיפוס שמשתמש ב-JavaScript "shim" (שנקרא גם polyfill) כדי לאפשר לכם להתנסות בהן עכשיו.

כדי לקבל מידע נוסף על אזורים של CSS באופן כללי, כדאי לעיין בדף 'אזורים של שירותי CSS' בכתובת html.adobe.com.

החרגות של שירותי CSS

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

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

דוגמה להחרגה של שירותי CSS בפעולה
דוגמה להחרגות של שירותי CSS

ההיפוך מתואר בצילום המסך הבא: טקסט הזורם בתוך מצולעים בעלי צורות לא סדירות:

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

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

מידע נוסף על החרגות של שירותי CSS זמין בדף'החרגות של שירותי CSS' בכתובת html.adobe.com. למידע מפורט יותר על העבודה של Adobe על הטכנולוגיה הבסיסית להחרגות של שירותי CSS, אפשר לקרוא את הפוסט בבלוג של הנס מולר, שנקרא Horizontal Box: Polygon Intersection for CSS החרגות.

המצב הנוכחי של אזורי ה-CSS והחרגות של שירותי CSS

הפעם הראשונה שהדיברתי באופן ציבורי על אזורי CSS והחרגות של CSS הייתה ב-Adobe Developer Pod ב-Google I/O 2011. באותו זמן הצגתי הדגמות בדפדפן אב-טיפוס מותאם אישית משלנו. בקבלה הייתה נלהבת במיוחד, אבל תחושת האכזבה הייתה מוחשית כשהצופים גילו שאף אחת מהאפשרויות שהצגתי לא הייתה זמינה עדיין באף אחד מהדפדפנים העיקריים.

ביקרתי שוב ב-Google I/O השנה (2012), הפעם כמציג עם עמיתי וינסנט הרדי ואלכס דנילו מ-Google (ניתן לצפות במצגת כאן). שנה אחת בלבד לאחר מכן, כ-80% מהמפרט של אזורי CSS יושם ב-WebKit, וכבר יש בו את הגרסה העדכנית ביותר של Google Chrome (חשוב לשים לב שכרגע יש להפעיל את אזורי ה-CSS דרך chrome://flags). התמיכה הראשונית באזורי CSS זמינה אפילו ב-Chrome ל-Android:

אזורים ב-Chrome ל-Android
אזורים ב-Chrome ל-Android

בנוסף, אזורי CSS והחרגות של CSS מיושמים בתצוגה המקדימה של Internet Explorer 10 ונמצאים כעת במפת הדרכים של Mozilla לשנת 2012 עבור Firefox. הגרסה הראשית הבאה של Safari אמורה לתמוך ברוב המפרט של אזורי CSS, והעדכונים הבאים צריכים לכלול את השאר.

למטה מופיע ציר זמן מפורט של ההתקדמות שלנו ביחס לאזורים של CSS ולהחרגות של שירותי CSS מאז ההצעה הראשונית שלנו לארגון W3C באפריל 2011:

התקדמות האזור וההחרגה
התקדמות לפי אזור והחרגה

סיכום

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