Object Oriented CSS – OOCSS

17 בOctober 2014

אין תגובות

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

_

סמנטיקה(SEMANTICS)

סמנטיקה בתחום של פיתוח front end מתייחסת  לשאלות כמו האם להשתמש בתגית header  או div , האם טקסט מסויים צריך להיות heading  או paragraph. סמנטיקה מיועדת למכונות כמו הבוטים של גוגל שסורקים את האתר ומנסים להפיק מהמבנה של העמוד מידע על התוכן שלו. למכונות אלה לא משנה איזה class אני אתן לתגית h1 או איזה ID יהיה ל div שלי.

לשם ההמחשה נסתכל על התגיות הבאות:

<div class=”heading”>Post Subject</div>
<h1 class=”blue”>Post Subject</h1>

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

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

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

<strong class=”red”>$99.9</strong>

.red{
  color:red;
}

כעט נוכל להשתמש בקלאס הזה הרבה מקומות ולשמור על גוון אחיד בכל המערכת. אבל אם כעבור חודש נרצה להחליף את הצבעים באתר מאדום לכחול? כדי ליעל את העבודה רבים ישנו רק את הצבע ב class ולא את שמו. הרי לא נרצה לעבור על כל  ה html  ולהחליף את ה class  מ red  ל .blue התוצאה תהיה הקוד הבא:

<strong class=”red”>$99.9</strong>

.red{
  color:blue;
}

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

<strong class=”special-offer-color”>$99.9</strong>

.special-offer-color {
  color:blue;
}

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

_

הפרדה בין מבנה ועיצוב

כאמור כאשר יצרו את ה CSS הכוונה הייתה לייצר הפרדה בין השפה שמתארת את תוכן העמוד(מבנה) לבין השפה שמתארת את העיצוב. הפרדה זו מאפשרת להחליף עיצוב בקלות בלי לשנות את מבנה ה-HTML  של הדף.

נחזור שוב לתגית H1 שהראתי קודם:

 <h1 style=”font-color:red”>Hello World</h1>

בתגית הזו אין הפרדה בין שפה שמתארת מבנה לעיצוב – הכל באותה התגית.

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

 <div class=”big-text-with-red-color”>Hello World </div>

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

הצורך בהפרדה בין המבנה לעיצוב אינו אומר שהשמות של הקלאסים לא יכולים לתאר את התוכן של האתר. למשל אם red הוא הצבע של ה special offer  באתר, שם הגיוני ל class יכול להיות special-offer ולא  .red השמות של הקלאסים שלנו יכולים לתאר את התוכן שהם מעצבים ולא רק את הניראות שלו.

_

OOCSS – Object Oriented CSS

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

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

הפרדה בין מבנה ו- Skin

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

כדי להפוך את קוד ה-CSS  ל -Object Orientred צריך לעשות הפרדה של קלאסים שמתארים מבנה לקלאסים שמתארים skin. כדי להסביר למה הכוונה תראו את האופן שבו כתבנו CSS עד היום:

#btn {
  width: 200px;
  height: 50px;
  padding: 10px;
  border: solid 1px #ccc;
  background: linear-gradient(#ccc, #222);
  box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px;
}

#wapper {
  width: 400px;
  overflow: hidden;
  border: solid 1px #ccc;
  background: linear-gradient(#ccc, #222);  
  box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px;
}

#widget {
  width: 500px;
  min-height: 200px;
  overflow: auto;
  border: solid 1px #ccc;
  background: linear-gradient(#ccc, #222);
  box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px;
}

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

הינה דוגמא להפרדה כזו:

.button {
  width: 200px;
  height: 50px;
}

.box {
  width: 400px;
  overflow: hidden;
}

.widget {
  width: 500px;
  min-height: 200px;
  overflow: auto;
}

.skin {
  border: solid 1px #ccc;
  background: linear-gradient(#ccc, #222);
  box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px;
}

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

הפרדה בין ה container לתוכן

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

#sidebar h3 {
  font-family: Arial, Helvetica, sans-serif;
  font-size: .8em;
  line-height: 1;
  color: #777;
  text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
}

הקוד הזה מתאר עיצוב של תגית H3  כשהיא נמצאת בתוך הsidebar. אבל אם נרצה להכיל את העיצוב הזה בדיוק לתגית שנמצאת בפוטר נקבל משהו כזה:

#sidebar h3, #footer h3 {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 2em;
  line-height: 1;
  color: #777;
  text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
}

#footer h3 {
  font-size: 1.5em;
  text-shadow: rgba(0, 0, 0, .3) 2px 2px 4px;
}

או במקרה יותר גרוע נשכפל קוד:

#sidebar h3 {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 2em;
  line-height: 1;
  color: #777;
  text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
}

#footer h3 {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 1.5em;
  line-height: 1;
  color: #777;
  text-shadow: rgba(0, 0, 0, .3) 2px 2px 4px;
}

במצב הנוכחי אנחנו משכפלים הרבה מהעיצוב שלנו שוב ושוב בלי לשים לב. אם נשתמש בגישה של OOCSS  נאלץ לתכנן יותר את ה CSS כך שנוכל לייצר הפרדה בין  אלמנטים כלליים שחוזרים על עצמם לבין כאלה שלא. קוד שמשתמש ב ID selector שהוא container לרוב לא ניתן לשימוש חוזר. אם נשתמש ב class  פשוט שלא מתייחס להיררכיה כלשהי נוכל לייצר קוד הרבה יותר מודולרי.

לדוגמא:

.medium-heading{
  font-family: Arial, Helvetica, sans-serif;
  color: #777;
  line-height: 1;
  text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
  font-size: 2em;
}

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

דוגמא לעיצוב מחדש בעזרת OOCSS

באו ניסתכל על העיצוב של ה- header הבא:

.header-inside {
  width: 980px;
  height: 260px;
  padding: 20px;
  margin: 0 auto;
  position: relative;
  overflow: hidden;
}

חלק מה properties  של אותו ה header הן יחודיות לו, אבל חלק מהן יכולות לעבור אבסטרקציה וניתנות לשימוש חוזר. דוגמא לאבסטקציה של הקלאס הזה:

.globalwidth {
  width: 980px;
  margin: 0 auto;
  position: relative;
  padding-left: 20px;
  padding-right: 20px;
  overflow: hidden;
}

.header-inside {
  padding-top: 20px;
  padding-bottom: 20px;
  height: 260px;
}

ה-CSS  של ה-class  שנקרא globalwidth  מטפל בדברים הבאים:

  • רוחב קבוע
  • מרכוז האלמנט בדף בעזרת margin:auto
  • מיקום רלטיבי כדי שהאלמנטים הבנים יוכלו להתמקם בתוך האלמנט באופן ייחסי אליו
  • Padding משני הצדדים ברוחב 20  פיקסלים
  • overflow hidden כדי לתמוך ב floats

עכשיו אפשר להשתמש בclass  שיצרנו לכל אלמנט שצריך את התכונות הללו ללא שכפול שלל קוד. מהרגע שיצרנו אתת הקלאסים האלה ה html  שלנו יכול להראות כך:

<header>
   <div class="header-inside globalwidth">
   </div>
</header>
<div class="main globalwidth">
</div>
<footer>
   <div class="footer-inside globalwidth">
   </div>
</footer>

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

הוסף תגובה
facebook linkedin twitter email

Leave a Reply

Your email address will not be published. Required fields are marked *