באגים נפוצים ב-IE6

שייך לקטגוריות CSS, HTML, JavaScript, דפדפנים

דפדפן Interner Explorer בגרסה 6 היה שיפור עצום מבחינת תמיכה בתקנים מאז ימי 5 הזוהרים (ואף מילה על 5.5). ה-CSS התחיל להתנהג בצורה תקנית בעזרת DOCTYPE מתאים וגם ה-dom התחיל להיות תואם להגדרות W3C.

עם זאת, הרבה פעמים אנו נתקלים בבאגים מרגיזים שיכולים לעכב את העבודה שלנו כדי למצוא workarounds. מה לעשות ש-IE7 ו-Firefox עדיין לא השתלטו על השוק, ו-IE6 תופס נתח לא קטן, ואנחנו כמתכנתי web צריכים להתאים את האתרים שלנו לכל הדפדפנים הנפוצים.

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

#1 : ערכי margin כפולים ב-float

לכל אלמנט שחל עליו float כלשהו, ערכי ה-margin שיחולו עליו יוכפלו. אין הסבר הגיוני לזה.

דוגמה:

<div style="float:left;margin-left:100px;">IE6 doubles the margin and renders margin-left with 200px</div>

באג margin כפול ב-float

פתרון:

הצורה הכי אלגנטית לפתור את הבאג הזה היא לתת מאפיין display:inline לאלמנט בעל ה-float. הגדרת ה-float בכל מקרה משכתבת את ה-display ל-block. זה פותר את הבעיה, ולא מונע מהאלמנט להמשיך לתפקד כמו block.

#2 : תזוזה של פיקסל כאשר רוחב/גובה אי זוגיים

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

<div style="width:199px;height:99px;position:relative;border:1px solid #000;">
	<div style="width:100px;position:absolute;background-color:red;right:0;bottom:0;"></div>
</div>
באג ריווח של פיקסל אחדניתן לראות כי יש רווח של פיקסל מימין
ומלמטה

פתרון:

לבאג זה לא מצאתי ממש פתרון קסם, אך בעזרת ה-underscore hack ניתן למשוך את האלמנט למיקום הנכון שלו:

<div style="width:199px;height:99px;position:relative;border:1px solid #000;">
	<div style="width:100px;position:absolute;background-color:red;right:0;bottom:0;_margin-bottom:-1px;_margin-right:-1px;"></div>
</div>

#3 : תמונות וצבעי רקע נחתכים

את מי שלא מכיר דרכי פתרון, הבאג הזה יכול להוציא מהכלים. קצת הסבר כללי – ב-css של IE יש מאפיין readonly שנקרא hasLayout. לאלמנט "יש" layout אם באחד המאפיינים הבאים יש ערך שונה מברירת המחדל: width, height, float, zoom, או אחד מהמאפיינים הבאים: display:inline-block, position:absolute, writing-mode:tb-rl.

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

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

ul li {
	background-image:url('image.gif');
	zoom:1;
}

#4 : opacity, טקסט ו-ClearType (גם ב-IE7)

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

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

פתרון:

צבע רקע כלשהו לאלמנט המכיל פותר את הבאג.

#5 : תיבת select עולה על אלמנטים

ללא התחשבות ב-z-index, תיבות בחירה ב-IE6 עולות על כל אלמנט (כמעט).

אם יש לי תפריט שנפתח במעבר עכבר, ומתחת לאיזור בו אמור להפתח התפריט יש select, התיבה תופיע מעל אותו אלמנט.

פתרון:

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

> html
<iframe id="hider-iframe" style="display:none" frameborder="0" scrolling="no"></iframe>

> css
#hider-iframe {
	position:absolute;
	filter:alpha(opacity=0);
}

> js
function ShowMenu() {
	HiderIframeShow(menuElement);
	menuElement.style.display="";
}
function HiderIframeShow(clone) {
	var hiderIframe=document.getElementById("hider-iframe");
	hiderIframe.style.top=clone.style.top;
	hiderIframe.style.left=clone.style.left;
	hiderIframe.style.width=clone.offsetWidth+"px";
	hiderIframe.style.height=clone.offsetHeight+"px";
	hiderIframe.style.display="";
}
אם משתמשים בספריית prototype, הפונקציה Position.clone תעתיק את המיקום המדוייק.

מאפייני ה-top/left מועתקים מערכי האלמנט, בהנחה שגם ה-iframe וגם האלמנט בעלי position:absolute ויושבים תחת אותו offsetParent (הא הראשון בעל position:absolute/relative או ה-body). אם לא כך הדבר – יש להשתמש במנגנון המחשב מיקום מדוייק של האלמנט.

#6 : צבעים של PNG שקוף משתנים

נתקלתי לאחרונה בתופעה מוזרה: כאשר משתמשים ב-AlphaImageLoader filter של IE6 להצגת תמונות PNG עם שקיפות, התמונות התמונות מוצגות כהות יותר ממה שהן במקור. כן, IE6 ממש משנה ערכי RGB על התמונה.

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

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

TweakPNG. לאחר ההפעלה של התוכנה פותחים את קובץ ה-PNG, מוחקים את ה-Chunk בשם gAMA, ושומרים.

(מיותר לציין, Firefox ו-IE7, בעזרת תגית img או background-image, עומדים בגבורה במשימה ומציגים צבעים נכונים מראש).

underscore hack

בהתקלות בכל באג נוסף שמצריך טיפול מיוחד רק ב-IE6 אפשר להשתמש ב-underscore hack: כל מאפיין css שיוצמד לו מקף תחתון לפני שמו – יוחל רק ב-IE6.

.className {
	background-color:red;
	_background-color:blue;
}

בכל דפדפן מלבד IE6 נראה צבע אדום, אך IE6 כן יתייחס ל-_background-color כמאפיין חוקי, ולכן צבע הרקע יהיה כחול.

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

מידע נוסף

מידע נוסף ניתן למצוא בקישור באגים ב-CSS של IE6.


קטגוריות

חיפוש

עיקבו אחרי (אקספרימנטלי!)

10 תגובות

כתיבת תגובה

13.01.07 בשעה 14:03
יאיר

ה underscore hack הוא hack שאינו מומלץ, מכיוון שהוא אינו CSS תיקני, ויגרור אחריו error.
אני ממליץ להשתמש ב holy hack, של
html *

1
14.03.07 בשעה 9:29
חסוי

מושקע!

2
05.04.07 בשעה 10:20
WeBuster

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

אחלה מאמר.
אביתר.

3
20.04.07 בשעה 11:26
אלכס

יש גם דרך להציג קבצי PNG עם שקיפות בIE6

http://www.twinhelix.com/css/iepngfix/

4
20.04.07 בשעה 11:29
שוב אלכס

(שכמובן עושה גם שימוש ב -AlphaImageLoader filter)

5
17.06.07 בשעה 23:15
אסף

החכמתי!
תודה רבה וכל הכבוד!

6
08.09.07 בשעה 13:21
עופר וישניא
(אתר)

לגבי 1, זה לא מדויק. ה-margin הכפול נוצר רק כאשר האלמנט הוא floated לאותו כיוון שיש לו margin. זה לא יקרא אם האלמנט מוצף שמאלה וה-margin הוא מימין, מלמעלה, או מלמטה.

גם ה-underscore hack וגם ה-holy hack הם פתרונות ממש לא אלגנטיים. אני בד"כ יוצר קובץ נפרד בשם ie6hacks.css וטוען אותו עם
conditional comments כך שההגדרות IE6 הנקודתיות נטענות רק בדפדפן הזה ודורסות את ההגדרות הסטנדרטיות. ככה אפשר לוודא שIE7 גם לא יתפוס חלק מהם.

לגבי PNG,פתרון יותר אלגנטי הוא להוסיף לאותו קובץ IE6hacks קלאס בשם PNG, עם behavior שמצביע ל-HTC הזה

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

7
08.09.07 בשעה 13:25
עופר וישניא
(אתר)

ארג, הלינקים לא עבדו.
* טוען אותו עם conditional comments:
http://www.quirksmode.org/css/condcom.html

קובץ HTC חביב להפעלת alphaImageLoader:
http://webfx.eae.net/dhtml/pngbehavior/pngbehavior.html

ובלי קשר, בשדה של תמונה כתוב 32*32 אבל בפועל קיים מקום רק ל24*26 פיקסלים..

הכצעקתה? :)

8
08.09.07 בשעה 13:55
אלעד
עופר וישניא אמר/ה:
לגבי 1, זה לא מדויק. ה-margin הכפול נוצר רק כאשר האלמנט הוא floated לאותו כיוון שיש לו margin. זה לא יקרא אם האלמנט מוצף שמאלה וה-margin הוא מימין, מלמעלה, או מלמטה.

צודק.

עופר וישניא אמר/ה:
גם ה-underscore hack וגם ה-holy hack הם פתרונות ממש לא אלגנטיים. אני בד"כ יוצר קובץ נפרד בשם ie6hacks.css וטוען אותו עם conditional comments כך שההגדרות IE6 הנקודתיות נטענות רק בדפדפן הזה ודורסות את ההגדרות הסטנדרטיות. ככה אפשר לוודא שIE7 גם לא יתפוס חלק מהם.

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

עופר וישניא אמר/ה:
לגבי PNG,פתרון יותר אלגנטי הוא להוסיף לאותו קובץ IE6hacks קלאס בשם PNG, עם behavior שמצביע ל-HTC הזה

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

לא הצעתי פיתרון ל-PNG אלא לצבע שלו. שים לב שגם ה-HTC משתמש ב-AlphaImageLoader.

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

9
24.04.08 בשעה 20:26
n0nick
(אתר)

באיחור: אחלה מאמר, שימושי מאוד (גם בעידן IE7 שלא צבר פופולריות).

בנוגע לבעיה #4, פתרון אחר שמצאתי הוא החלת display: block-inline על האלמנט.
ואל תשאלו אותי מה זה בדיוק block-inline.

10

כתיבת תגובה

תגיות מותרות לשימוש בתוכן
XHTML: אפשר להשתמש בתגים הללו: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre>