מבוא
האינטרנט הוא פלטפורמה חזקה מאוד לטקסט, תחום שבו ל-Adobe יש ניסיון ומומחיות רבים. לכן, כשחיפשנו ב-Adobe דרכים לקדם את האינטרנט, היה לנו ברור שהמקום להתחיל בו הוא שיפור יכולות הטקסט באינטרנט. באינטרנט, בדרך כלל מניחים שהטקסט מוצג בעמודה אחת ובכיוון אנכי. אפשר להזרים טקסט סביב גרפיקה, ואפילו לעצב טקסט בכמה עמודות באמצעות CSS, אבל עדיין קשה מאוד להשיג פריסה אמיתית כמו של מגזין באינטרנט. בעזרת אזורי CSS והחרגות CSS, חברת Adobe מובילה את המאמץ להביא את העוצמה של הוצאה לאור שולחנית לדפדפנים מודרניים. לדוגמה, בצילום המסך הבא, נעשה שימוש בהחרגות CSS כדי להזרים טקסט לאורך קווי המתאר של ההר:
במסמך שבצילום המסך שלמטה נעשה שימוש גם ב-CSS Exclusions כדי לאפשר לטקסט להקיף צורות בתמונות, וגם ב-CSS Regions כדי לעצב טקסט בעמודות ומסביב לציטוט:
אזורים של שירות CSS
לפני שנכנסים לפרטים של אזורי CSS, אני רוצה להסביר איך אפשר להפעיל אזורים ב-Google Chrome. אחרי שתפעילו את CSS Regions, תוכלו לנסות כמה מהדוגמאות שמוזכרות במאמר הזה וליצור דוגמאות משלכם.
הפעלת אזורי CSS ב-Google Chrome
החל מגרסה 20 של Chrome (גרסה 20.0.1132.57, ליתר דיוק), אזורי CSS מופעלים דרך הממשק chrome://flags. כדי להפעיל את CSS Regions, צריך לבצע את השלבים הבאים:
- פותחים כרטיסייה חדשה או חלון חדש ב-Chrome.
- מקלידים
chrome://flagsבסרגל המיקום. - משתמשים בחיפוש בדף (control/command + f) ומחפשים את הקטע "תכונות ניסיוניות של פלטפורמת האינטרנט".
- לוחצים על הקישור הפעלה.
- לוחצים על הכפתור הפעלה מחדש בתחתית המסך.
מידע נוסף על flags ב-Chrome זמין בפוסט בבלוג שלי בנושא הכול על flags ב-Chrome.
אחרי שתפעילו מחדש את הדפדפן, תוכלו להתחיל להתנסות עם אזורי CSS.
סקירה כללית של אזורי CSS
אזורי CSS מאפשרים לבלוק של טקסט עם תגי עיצוב סמנטיים לזרום באופן אוטומטי לתוך "תיבות" (כרגע רכיבים). התרשים הבא מדגים את ההפרדה בין הטקסט (הזרימה) לבין התיבות (האזורים שאליהם הטקסט זורם):
בואו נראה דוגמה לתרחיש אמיתי של שימוש באזורים ב-CSS. בנוסף לעבודה שלי כמפתח ב-Adobe, אני גם כותב מדע בדיוני. אני מפרסם לעיתים קרובות את העבודות שלי באינטרנט ברישיון Creative Commons. כדי שהן יפעלו במספר המרבי של מכשירים ודפדפנים, אני משתמש לעיתים קרובות בפורמט פשוט מאוד, כמו זה:
בעזרת CSS Regions, הצלחתי ליצור חוויה מעניינת יותר מבחינה חזותית וגם הרבה יותר פונקציונלית, כי קל יותר לנווט ונוח יותר לקרוא:
למטרות הדגמה, הוספתי את היכולת לחשוף אזורי CSS באב הטיפוס הזה. בצילום המסך הבא אפשר לראות איך האזורים מסודרים כך שהם נראים כמו עמודות שעוטפות גרפיקה וציטוט במרכז:
אתם יכולים להתנסות באב הטיפוס הזה (וגם לראות את קוד המקור) כאן. כדי לנווט, משתמשים במקשי החיצים, וכדי לחשוף אזורים, לוחצים על המקש Esc. כאן אפשר למצוא גם אבות טיפוס קודמים.
יצירת תהליך עם שם
ה-CSS שנדרש כדי שבלוק טקסט יזרום דרך אזורים הוא פשוט מאוד. קטע הקוד הבא מקצה תהליך בשם "article" לרכיב div עם המזהה "content", ומקצה את אותו תהליך בשם "article" לכל רכיב עם המחלקה "region". התוצאה היא שהטקסט שכלול ברכיב 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"): פונקציה שמחזירה הפניה לתהליך ספציפי בעל שם. הארגומנט תואם לשם שצוין כערך של מאפייני ה-CSSflow-intoו-from-from. כדי לקבל הפניה לזרימה בעלת השם שצוין בקטע הקוד שלמעלה, צריך להעביר את המחרוזת "article". -
WebKitNamedFlow: ייצוג אובייקט של גוש קרח צף עם שם, עם המאפיינים והפונקציות הבאים:-
firstEmptyRegionIndex: ערך של מספר שלם שמצביע על האינדקס של האזור הריק הראשון שמשויך לזרימה בעלת השם. כדי ללמוד איך לקבל את אוסף האזורים, אפשר לעיין בקטעgetRegions()שבהמשך. -
name: ערך מחרוזת עם שם התהליך. -
overset: מאפיין בוליאני שהוא:falseכשהתוכן של התהליך שצוין מתאים לאזורים המשויכיםtrueכשהתוכן לא מתאים ונדרשים אזורים נוספים כדי להכיל את כל התוכן.
-
getContent(): פונקציה שמחזירה אוסף עם הפניות לצמתים שזורמים לתהליך בעל השם. -
getRegions(): פונקציה שמחזירה אוסף עם הפניות לאזורים שמכילים את התוכן של הזרימה בעלת השם. -
getRegionsByContentNode(node): פונקציה שמחזירה הפניה לאזור שמכיל את הצומת שצוין. האפשרות הזו שימושית במיוחד כדי למצוא אזורים שמכילים דברים כמו עוגנים בעלי שם.
-
- אירוע אחד (
webkitregionoversetchange). האירוע הזה מופעל ב-WebkitNamedFlowבכל פעם שהפריסה של התוכן המשויך משתנה מסיבה כלשהי (תוכן נוסף או מוסר, גודל הגופן משתנה, צורת האזור משתנה וכו') וגורמת לשינוי במאפייןwebkitRegionOversetשל אזור. האירוע הזה שימושי להאזנה לשינויים גסים בפריסה. היא מציינת שמשהו חשוב קרה וייתכן שהפריסה דורשת התייחסות, למשל: נדרשים עוד אזורים, יכול להיות שחלק מהאזורים ריקים וכו'. - אירוע אחד (
webkitregionfragmentchange). לא מוטמע כרגע. האירוע הזה מופעל ב-WebkitNamedFlowבכל פעם שהפריסה של התוכן המשויך משתנה מסיבה כלשהי, בדומה ל-webkitregionoversetchange, אבל ללא קשר לשינוי כלשהו במאפייניwebkitRegionOverset. האירוע הזה שימושי להאזנה לשינויים קטנים בפריסה שלא בהכרח משפיעים על כל הפריסה של הזרימה בעלת השם, לדוגמה: התוכן עובר מאזור אחד לאחר, אבל התוכן הכולל עדיין מתאים לכל האזורים. -
Element.webkitRegionOverset: אלמנטים הופכים לאזורים כשהם מוקצים למאפיין ה-CSSflow-from. לרכיבים האלה יש מאפייןwebkitRegionOverset. אם הם חלק מרצף פעולות עם שם, המאפיין הזה מציין אם התוכן מרצף הפעולות חורג מהאזור או לא. הערכים האפשריים של webkitRegionOverset הם:- "overflow" אם יש יותר תוכן ממה שהאזור יכול להכיל
- "fit" אם התוכן נעצר לפני סוף האזור
- "empty" אם התוכן לא הגיע לאזור
אחד מהשימושים העיקריים של 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 Page Templates, שמאפשרת להגדיר את התנהגות הדפדוף באופן הצהרתי לחלוטין.
בואו נראה תרחיש שימוש נפוץ בתבניות דפים בשירותי CSS. בקטע הקוד הבא מוצג השימוש ב-CSS כדי ליצור שני תהליכים עם שמות: "article-flow" ו-"timeline-flow". בנוסף, הוא מגדיר סלקטור שלישי בשם combined-articles, שבתוכו ייכללו שני התהליכים. ההכללה הפשוטה של המאפיין overflow-style בתוך הסלקטור "combined-articles" מציינת שהתוכן צריך לעבור דפדוף אוטומטי לאורך ציר ה-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". בקטע הקוד שלמעלה, אנחנו מגדירים שלושה מיקומים, שכל אחד מהם תואם לעמודה. הטקסט מ-"article-flow" יזרום דרך העמודות בצד שמאל ובצד ימין, והטקסט מ-"timeline-flow" יאכלס את העמודה באמצע. התוצאה עשויה להיראות כך:
שימו לב שהטקסט של המאמר – הטקסט בעמודות השמאלית והימנית – הוא באנגלית, וציר הזמן במרכז הוא בגרמנית. בנוסף, המסמך מוצג בדפים אופקיים בלי צורך בקוד JavaScript. הכול נעשה באופן הצהרתי לחלוטין ב-CSS.
תבניות דפים ב-CSS הן עדיין הצעה, אבל יש לנו אב טיפוס שמשתמש ב-shim (שנקרא גם polyfill) של JavaScript כדי לאפשר לכם להתנסות בהן כבר עכשיו.
כדי לקבל מידע נוסף על אזורי CSS באופן כללי, אפשר לעיין בדף אזורי CSS ב-html.adobe.com.
החרגות של CSS
כדי להשיג פריסה אמיתית דמוית מגזין, לא מספיק להזרים טקסט דרך אזורים. אחד המרכיבים החשובים ביותר בהוצאה לאור איכותית ומעניינת מבחינה חזותית הוא היכולת לגרום לטקסט לזרום מסביב או בתוך גרפיקה וצורות לא סדירות. התכונה "החרגות CSS" מאפשרת להשיג את רמת האיכות הזו באינטרנט.
צילום המסך הבא הוא מאב טיפוס של CSS Exclusions, והוא מציג טקסט שזורם באופן דינמי סביב נתיב שתואם לקווי המתאר של תצורת סלע גדולה:
בצילום המסך הבא מוצג ההפך: טקסט שמופיע בתוך פוליגונים בצורות לא סדירות:
השלב הראשון שמאפשר להזרים טקסט מסביב לצורות שרירותיות או בתוכן הוא לפתח ולשפר את האלגוריתמים הנדרשים. Adobe עובדת כרגע על הטמעות שיתרמו ישירות ל-WebKit. אחרי שהאלגוריתמים האלה יעברו אופטימיזציה, הם יהפכו לבסיס שעליו ייבנו שאר ההחרגות של שירותי ה-CSS.
למידע נוסף על החרגות CSS, עיינו בדף החרגות CSS ב-html.adobe.com, ולעיון מפורט יותר בעבודה של Adobe על הטכנולוגיה הבסיסית של החרגות CSS, עיינו בפוסט בבלוג של הנס מולר שכותרתו Horizontal Box: Polygon Intersection for CSS Exclusions.
המצב של אזורי CSS והחרגות CSS (2012)
הפעם הראשונה שבה דיברתי על אזורי 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:
בנוסף, גם CSS Regions וגם CSS Exclusions מוטמעים בגרסת טרום-ההשקה של Internet Explorer 10, ונמצאים כרגע במפת הדרכים של Mozilla לשנת 2012 עבור Firefox. הגרסה הראשית הבאה של Safari אמורה לתמוך ברוב המפרט של CSS Regions, והעדכונים הבאים אמורים לכלול את השאר.
בהמשך מופיע ציר זמן מפורט של ההתקדמות שעשינו עם CSS Regions ו-CSS Exclusions מאז ההצעה הראשונית שלנו ל-W3C באפריל 2011:
סיכום
ל-Adobe יש ניסיון עצום בטקסט, בגופנים ובהוצאה לאור במחשב באופן כללי, באמצעות כלים כמו InDesign. למרות שהאינטרנט הוא כבר פלטפורמה חזקה מאוד לטקסט, אנחנו רוצים להשתמש בידע ובניסיון שלנו כדי לשפר עוד יותר את הצגת הטקסט. אזורי CSS והחרגות CSS מאפשרים לתוכן להישאר במבנה סמנטי, וגם מאפשרים פריסה אמיתית דמוית מגזין, ובסופו של דבר אינטרנט הרבה יותר אקספרסיבי.