את כתיבת הפוסט שאתם קוראים עכשיו התחלתי בעבר. הבנתי שחסר קצת רקע, והתחלתי להרחיב אותו. הרקע התארך והפך לפוסט בפני עצמו.
בפוסט זה אני רוצה לסכם כמה תובנות לגבי התמודדות עם קוד ישן של IE. בסופו של דבר הידע הוא לא מדע טילים, אך השקעתי שעות רבות על מנת “לדוג” אותו ממקורות שונים. כרגיל, אני מנסה לכתוב פוסטים שאני הייתי שמח מאוד לקרוא לו היו זמינים לי כשהייתי צריך אותם.
חלק גדול ממה שאכתוב פה על Quirks Mode נכון גם ל Firefox או אופרה – אבל עד היום לא נתקלתי באף אחד שהתעסק בנושאים אלו בדפדפן שאינו IE – ולכן אדבר רק על IE.
אם אתם לא כותבים קוד שנדרש לרוץ ב IE8 או גרסאות ישנות יותר, או שאתם יכולים פשוט להגדיר את Chrome Frame [א] שיפתור לכם את הבעיות – רוב הבעיות שיוצגו פה הן כנראה לא בעיות שלכם. אלו נושאים שגרמו סבל ללא מעט אנשים.
המניע לעיסוק המחודש בנושא זה הוא השחרור הקרוב של IE10 (במסגרת Windows 8).
בסוף הפוסט כללתי פרטים גם על גרסה זו.
נתחיל בשאלה, “מדוע מייקרוסופט תומכת לאחור בדפי אינטרנט ישנים ועקומים?”.
![]() |
הערכה של ג’ון רזיג על היחס עלות / תועלת בתמיכה בדפדפנים. פילוח השוק של הדפדפנים שונה ממה שאני מכיר. מקור: http://www.manning.com/resig/resig_meapch1.pdf |
מדוע מייקרוסופט תומכת לאחור בדפי אינטרנט ישנים ועקומים?
למייקרוסופט יש מדיניות ארוכת שנים של Backward Compatibility. בזמן שמתחרים כאלו ואחרים שברו את ה Backward Compatibility (אשתמש מעתה בקיצור המשעשע BC) של המוצרים שלהם, וכך שברו את ליבותיהם של אנשי ה IT שנאלצו להתמודד עם הצרה – מייקרוסופט תמיד הייתה שם בשבילם ותמכה לאחור. אפשר לומר שBC הוא Value Proposition או אפילו ערך מרכזי של החברה. ערך זה מתורגם כמובן למעשים:
הנה כמה דוגמאות:
- Silverlight 5, טכנולוגיה שנראה שמייקרוסופט רוצה לזנוח – תיתמך עד 2021.
- Windows Vista הבעייתית תיתמך עד 2017. 5 שנים נוספות מעכשיו.
- IE8, שהמהדורה אחרונה שלו (עם Bing כ Default) שוחררה ב 2010 – ייתמך עד 2020.
- כיצד ניתן להסביר שמייקרוסופט הפסיקה לתמוך בIE6 המפורסם כבר לפני שנה?? האא… הוא שוחרר בשנת 2001.
שלא תבינו לא נכון: כמובן שיש ערך עסקי משמעותי בתמיכה לאחור. עבור רוב המשתמשים מוצרים ששוחררו לפני עשור (נאמר Office 2000) הם מספיק טובים ושדרוג הם כאב-ראש ועלויות מיותרות. העניין הוא שיש ערך כספי, לעתים רב, בשחרור גרסאות חדשות (למשל, אופיס) ואז נוצרת קשת של גרסאות שונות שזמינות בשוק – ומי שמפתח מוצר צד שלישי נאלץ להתאים את עצמו למספר גרסאות.
“העולם שלנו לא נעשה איטי יותר – להיפך”. שחרור של גרסה פעם בשלוש-ארבע שנים יצאה לה מהאופנה וברגע שמייקרוסופט מתחילה לשחרר מוצרים, למשל את IE, פעם בשנה – 10 שנות תמיכה היא תקורה משמעותית מאוד להתמודד איתה.
בשנת 2020 מייקרוסופט עתידה לתמוך ב 11 גרסאות שונות של אינטרנט אקספלורר: IE8, IE9, IE10, IE11, IE12, IE13, IE14, IE15, IE16, IE17 ו IE18 [ד]. בסוף פוסט זה תראו שכל גרסה של IE היא סיפור בפני עצמו.
כך עובדים ערכים של חברה: הם מחלחלים לכל פינה. לטוב ולרע.
מנוע הרינדור של IE6 הוסיף תמיכה תקנית ב Box Model (הוסבר בפוסט הקודם) – שינוי די משמעותי ש”שובר” דפים שעבדו ב Box Model הישן. על מנת לתמוך “גם וגם” הוא הגדיר 2 מודים:
- IE6 Standards Mode – שהציג את ה Box Model בצורה התקנית.
- Quirks Mode – שהציג את הדפים כפי שעבדו בגרסה הקודמת (IE 5.5) – ע”פ ה Box Model של IE.
הפתרון, בהפשטה מסוימת, הוא כזה: אם הדף הוא מסוג “חדש”, כלומר פועל ע”פ הסטנדרטים של W3C בכל הנוגע ל Box Model ובכלל – הוא יסומך בעזרת תוית DOCTYPE, שממוקמת בראש הדף, מעל תג ה HTML.
וכיצד הדפדפן יודע “עבור איזה דפדפן נכתב דף ה HTML שמורץ כרגע”?
– W3C הוסיפו הגדרת DTD (אימות מבנה הדף) על תג ה DOCTYPE. סימון Strict Mode מעיד על תמיכה בתקן החדש ו Loose או Transitional הם מודים “רכים” שעובדים ע”פ ההגדרות הישנות.
בניגוד להוספת ה DOCTYPE המקורי, שדף ישן לא דרש שינוי (מכיוון שאין לו Doctype) – במקרה זה אם לא מצוין DTD ההנחה היא שהדף הוא “חדש”.
מייקרוסופט, שמחויבותה לתאימות לאחור – גבוהה, החליטה להתעלם מהתקן ולהתייחס לDOCTYPE ללא DTD כדפים ישנים (כלומר Almost Standards Mode) אולם החלטתה יצרה מהומה לא קטנה שבסופה היא התקפלה והחליטה לפעול ע”פ התקן. על פניו, נראה שהגישה של מייקרוסופט הייתה עדיפה מקומית, אך לאורך זמן קיומו של תקן אחיד הוא חשוב אפילו יותר.
הצורך לחזור ולשנות את ה Markup (או קוד, אם מדובר בדף דינאמי) של דפים קיימים על מנת שיוצגו בצורה טובה היה בלתי נסבל עבור מייקרוסופט. מייקרוסופט התמודדה עם הבעיה בעזרת הצגה של תווית META חדשה (שניתן להגדיר גם ברמת פרוטוקול ה HTTP) שדורסת את ההחלטה של ה DOCTYPE לגבי המוד בו יש לרנדר את הדף. Application Servers היו יכולים בדרך זו לשתול את התגית החדשה ברמת ה HTML HEAD או ה HTTP וכך לגרום לדפים שתוכננו עבור IE7 להתרנדר ב Almost Standards Mode – כך שייראו היטב. התגית ה META נראית כך:
<meta http-equiv="X-UA-Compatible" content="IE=7" />
עוד השפעות של התאימות לאחור ב IE8 (המשפיעות גם על IE9 ו IE10)
בניגוד ל IE7, שלא שמרה על תאימות מדוייקת ל IE6 Standards Mode, החליטה מייקרוסופט החל מ IE8 (אולי בגלל תלונות של לקוחות) לשמור העתק מדוייק של הדרך בה הדפדפן הקודם רינדר את הדף. זהו ה IE7 Standards Mode שקיים ב IE8. אפילו כאשר מייקרוסופט מציגה מנוע רינדור משופר – הדפדפן יידע להציג את הדף בדיוק רב מאוד לצורה בה הדפדפן הקודם והפחות מוצלח הציג אותו.
החלטה הזו תקפה לא רק על ה Rendering Engine אלא גם על ה JavaScript Engine: באגים וחוסרי תאימות שהיו קיימים ב IE7 נשמרו במנוע הג’אווהסקריפט של IE8 (והלאה). אם הדף מרונדר ב IE7 Standards Mode, מנוע הג’אווהסקריפט החדש יפעיל את משפטי ה IF [ו] המתאימים ויתנהג בדיוק כמו שהתנהג ב IE7.
הערה: מפתחים שרוצים לדעת איזו גרסה אמיתית של IE רצה מולם נתקלים בקושי: ה BC גורם לדפדפן להתנהג בדיוק כמו דפדפן ישן יותר וזה כולל User Agent, יכולות נתמכות ואפילו מנוע ה JavaScript ש”משחזר” באגים ישנים. הדרך האמינה לדעת מול איזה גרסה של IE אתם עובדים היא לתשאל את גרסת ה JavaScript Engine. שלא תזדקקו לזה.
תוכלו למצוא כיצד רשימות אלו משתלבות באלגוריתם הבחירה בתרשים הזרימה שקישרתי למעלה.
מה עושים עם התאימות לאחור? אין ברירה. משלבים בדפדפן החדש, IE9, שני מנועי רינדור שונים: מנוע ישן (של IE8) ומנוע חדש שיתמוך בתקנים החדשים:
כל טאב ב IE9 מתרנדר או במנוע החדש או במנוע הישן – אך אף פעם לא בשניהם ביחד.
אם יש דף עם iFrames ייתכן והדף החיצוני (מה שנקרא topFrame) מרונדר במוד אחד (נאמר IE9 Standards) בעוד ה iFrame הפנימי מרונדר במוד אחר (נאמר QME). אולם, בניגוד ל IE6 עד IE8 בהם יכול היה הדפדפן לבחור עבור כל iFrame כל מוד מהרשימה הנתמכת, ב IE9 יש בחירה של מנוע הרינדור ומאותו הרגע הבחירה למוד עבור על Frame מוגבלת למודים הזמינים עבור אותו מנוע רינדור.
הבחירה במנוע הרינדור היא דיי פשוטה: בפעם הראשונה שהדפדפן מזהה סימן שמעיד טיפוס הדף (יהיה זה X-UA-Compatible ברמת ה HTTP או תג Doctype) – הוא בחור את המוד המתאים מכל הרשימה. מנוע הרינדור שיודע לצייר מוד זה הוא מנוע הרינדור ש IE ישתמש בו לשאר הדף.
ריבוי ה Rendering Engines, אם כן, משפיע רק על דפים הכוללים Frames או iFrames. במקרים אלו ה Top Frame יכתיב את מנוע הרינדור עבור ה iFrames שהוא מארח.
הנה הדגמה של התנהגות זו בפועל:
כתבתי דף פשוט בשם page.html שידמה אפליקציה עסקית (הוספתי Source Code בתחתית הפוסט [ג]). הדף מכיל מספר אלמנטים שבהם יש בעיות של תאימות לאחור:
- עיגול המצוייר ב SVG (תכונה של HTML5)
- תיבה עם צבע שהוגדר פעמיים: פעם בצורה תקנית (כתום) ופעם נוספת בצורה לא תקרנית (טורקיז).
- אזור אפור (border עבה במיוחד) שגובהו יהיה חצי מהתיבה ע”פ ה IE Box Model ושליש מהתיבה ע”פ ה W3C Box Model.
חתיכת הבדל בשביל Doctype – לא?
אתם יכולים להבחין ב Scrollbars שונים בשני המקרים שנובעים מ Defaults שונים בין המודים השונים. הבדלים אלו אמורים להתאפס בעקבות CSS Reset.
השלכה משמעותית של ההפרדה ל 2 מנועי רינדור שונים אי חוסר היכולת (בעזרת ifלהציג HTML5 באותו הדף עם תאימות מלאה לדפים ישנים מאוד (Old Quirks Mode) – שיש רבים כאלו במערכות עסקיות.
כיצד מתמודדים עם זה? מייקרוסופט הוסיפה מוד בשם (QME (Quirks Mode Emulation שתואם, במידה רבה, לתקן של W3C כיצד יש לרנדר Quirks Mode – כלומר דפים ישנים מאוד.
ה QME לא מתועד בצורה ברורה כמוד של IE9. לקח לי כמעט חודש של התעסקות בנושא עד שהבנתי שהוא קיים. מייקרוסופט לעיתים קוראת לו “Quirks Layout” (נשמע כמו מימד אחר של פונקציונליות) או Quirks within IE9 Engine – שיכול בקלות לבלבל עם ה Quirks Mode שקיים במנוע הישן. ב Dev Tools של IE10 הוא נקרא פשוט “Quirks Mode” בנוסף ל “Explorer 5 Quirks” שקיים שם. בקיצור: מבלבל. רק לאחרונה אני נתקל במונח QME בצורה יותר מפורשת וברורה.
הנה תיעוד שמציין את קיום ה QME – הייתי זקוק לו בכדי להיות בטוח שאני לא מדמיין. הסיבה שהמוד לא מפורט ברשימת ה modes של הדפדפן קשורה כנראה לכך שIE9 לא מאפשר להשתמש במוד זה ב topmost Frame – כלומר הוא מותיר להשתמש בו רק בתוך iFrames.
הנה תיאור של ההבדלים בהתנהגות של QME. גם לדפדפנים אחרים יש QME . הנה הגדרת ההתנהגות של QME ב FF.
הנה תיאור האלגוריתם בעזרתו IE9 מחשב באיזה Rendering Mode להריץ את הדף. דיי דומה ל IE8 – אך השפעותיו משמעותיות יותר.
בניגוד ל IE9 בו התמיכה ב HTML5 ו CSS3 היא דיי בסיסית, IE10 תומך בתקנים אלו בצורה דיי יפה. ניתן לומר שהוא כמעט in line ביחד עם שאר הדפדפנים בתחום זה.
ב IE10 בוצעו כמה שינויים שמשפיעים על ה BC:
ה Default Rendering Mode עבור מסמך ללא Doctype הוא QME ולא IE5.5 Quirks Mode – מקור. התנהגות זו רצויה, אך היא תגרום לדפי Quirks Mode שרצו יפה ב IE9 – לרוץ פחות יפה ב IE10.
פתרון פשוט: להוסיף תג X-UA-COMPATIBLE, ie=7 בכדי להכריח את מנוע ה rendering הישן לרוץ.
פתרון נכון: לתקן את הדפים לעבוד ב QME, לא לדחות את ההתנתקות מ IE5.5 לנצח! ההבדלים העיקריים בין Quirks Mode ל QME הם מסביב לטבלאות, Box-Model (ניתן לתקן בקלות בעזרת CSS) והדבר הכי קשה: באגים שהיו ב IE5.5, תאימותם נשמרה עד ל IE8 – אך הם תוקנו ב QME.
QME נתמך גם ב topframe, בשונה מה IE9 – אך בדומה לFF או כרום. נראה גם שהיישום של QME קרוב יותר לסטנדרט מאשר IE9 – אך קשה לומר בוודאות לפני ש IE10 ישוחרר ויהיה יותר נסיון לקהילה איתו.
ביטול התמיכה ב Conditional Comments (כגון <!–[if IE]>).
ביטויים אלו נמצאים בשימוש בכמה ספריות מודרניות כגון ie7.js ו html5shim – אך אלו ספריות של תאימות לאחור שלא יזדקקו, כנראה, ליכולת זו ב IE10. אם הקוד שלכם עושה כאלו בדיקות (נו, נו, נו!) – הזהרו.
Windows 8 מציגה שני סוגים של “סביבות עבודה”: Metro ו Desktop.
Metro הוא ברירת המחדל והעתיד. אופיס 2013 יקבל ממשק מטרו, למשל. מטרו הוא Touch Enabled ויהיה הסביבה היחידה על Windows 8 Tablet.
Desktop היא הסביבה שאנו מכירים מאז Windows 95 ועד Windows 7. סרגל משימות, תפריט “התחל” וכו’.
חווית השימוש ב IE10 בסביבת המטרו היא שונה מסביבת העבודה של ה Desktop. למשל, Plug-Ins ו ActiveX לא ירוצו בסביבת המטרו. פלאש דווקא כן. אם יש לכם דף שמכיל Plug-Ins ואתם רצים על בסביבת המטרו – הדפדפן יפנה אתכם לסביבת ה Desktop. לא בהכרח התנהגות BC מלאה, אך אני מוצא אותה סבירה. ב Tablet כנראה תהיה סתם הערת שגיאה או פשוט התעלמות.
תעשו חיים!
מקורות נוספים בנושא:
- QuirksMode – אתר מוצלח המוקדש לנושא ודן בדקויות.
- תיאור ההתנהגויות ב Quirks Mode
- עוד מקור טוב שיכול להוסיף על הנאמר כאן והמקורות הקודמים.
- ענייני CSS ותאימות לאחור בIE ישנים.
- ספר הבישול של תאימות לאחור ב IE10 (מאת msdn)
- מצב תאימות, נושא שלא כיסיתי, מוסבר בקצרה באינטרנט ישראל.
–
[א] Chrome Frame[ב], למי שלא מכיר, הוא Plug-In של גוגל ל IE שכולל את מנוע ה Rendering של Chrome ויכול, ע”פ תג Meta במסמך ה HTML – להפעיל את הדף, מעשית, בכרום[א]. התקנתו לא דורשת הרשאות Administrator והוא יכול להריץ את הגרסה האחרונה של Chrome (כלומר מנוע HTML5 מעולה) בתוך IE6 המיושן. טקטיקה מקובלת היא “לתמוך ב IE6 ו IE7 בעזרת Chrome Frame”, כלומר: להפעיל עבור משתמשי IE ישנים את כרום מאחורי הקלעים. יש לשיטה זו כמה מגבלות בכל הנוגע לתקשורת בין iFrames.
[ב] יש לבטא “קרום” ולא “ח-רום” – כפי שישראלים רבים נוהגים.
[ג]
[ד] נשמע לי קצת מופרך לתאר משהו שיקרה 8 שנים מעכשיו: עידן ועידנים. אני מניח שמשהו יקרה וזו לא תהיה התוצאה בפועל.
[ה] התקן ביקש מבעלי דפים ישנים, כגון HTML 3.2 לסמן את הדפים שלהם ב DOCTYPE מסוים (ש IE ידע להתעלם ממנו) – אך לא הייתה לבעלי הדפים מוטיבציה אמיתית לבצע סימון שכזה.
[ו] אני מניח ומקווה שהשתמשו ב Strategy Design Pattern ולא באמת במשפטי IF.
–>