Концепцията hasLayout използвана в Internet Explorer за Windows

от Fuedo - Уеб дизайн енциклопедия

Направо към: навигация, търсене

Версия: Rev. 7 2006–10–19
Последна промяна: 2006–10–19
Оригинална статия: http://www.satzansatz.de/cssd/onhavinglayout.html
Едитори:

  1. Holly Bergevin
  2. Ingo Chao
  3. Bruno Fassino
  4. John Gallant
  5. Georg Sørtun
  6. Philippe Wittenbergh

Оригинално заглавие на статията: On having layout
Дискутираите статията: http://dean.edwards.name/weblog/2005/06/layout/
Преведено и публикувано cъгласно условията на Creative Commons

Съдържание

Въведение

Много от безсмислиците при изрисуването на страницата в Internet Explorer могат да бъдат избегнати като се зададе "layout" на страницата. Джон Галант и Холи Бергевин класифицират тези безсмислици, като "пространствени бъгове", като се има впредвид, че те много често могат да бъдат решени ако се зададе width или height. Това довежда до въпроса: Защо "layout" може да променя изрисуването и зависимостта между блоковете. Хубав въпрос, но труден отговор. В тази статия авторите се фокусират върху някои аспекти на този сложен проблем. За повече информация и примери погледнете дискусията.

hasLayout - Дефиниция

"Layout" е IE/Win специфична концепция която определя, как елементите се изрисуват и ограждат съдържанието си, как взаимодейства с останалите елементи, а също така и как реагират на определени събития предизвикани от приложение или потребител.

Това качество може да бъде активирано от някой CSS свойства. Някой HTML елементи имат "layout" по подразбиране.

Microsoft решават, че елементите трябва да придобиват "свойство" (в смисъл на обектно-ориентирано програмиране) който те наричат hasLayout, чиято стойност е true когато тази концепция за изрисуване е в сила.

Номенклатура

Казваме, че елемент "придобива лейаут" или "има лейаут" когато свойството hasLayout е равно на true за съответният елемент. "Елемент с лейаут" може да бъде всеки елемент, който има лейаут по подразбиране или му е бил даден такъв със задаването на съответните CSS свойства.

В "не-лейаутните" елементи, hasLayout не е true, което значи че div без зададен размер може да бъде елемент без лейаут.

Задаване или прилагане на "лейаут" на елемент който няма по подразбиране, изисква прилагането на CSS свойство което да предизвиква задаването на hasLayout=true за въпросният елемент. За повече информация погледни Елементи имащи лейаут по подразбиране и Свойства. Няма друг начин да се премахне лейаут ( да зададем hasLayout = false), освен ако не премахнем CSS свойствата които са задали hasLayout = true на първо място.

Проблемите с които се занимавахме

hasLayout проблемът обхваща дизайнерите (и кодерите) с всякакъв опит. Лейаутът има необикновен и непредвидим ефект върху визията на елементите, както за самите тях така и за техните под елементи.

Последствията за елемент който има или няма лейаут могат да включват:

  1. Много известни IE бъгове
  2. Блоковете, третиращи основни свойства по различен начин
  3. Изчезващ margin между елемент родител и неговите деца.
  4. Различни проблеми с конструкцията на списъци
  5. Различия в позиционирането на фоновите изображения
  6. Разлика между браузърите при използване на скриптове

Горният списък е кратък и непълен. Тази статия цели по-подробно да опише проблем с който се сблъскваме при прилагането на лейаут, или неговата липса.

От къде идва лейаутът

За разлика от стандартните свойства, или даже специфични за браузърите CSS свойства, лейаут не се присвоява директно с CSS. С други думи, няма свойство "layout". Някои елементи автоматично имат лейаут и той незабележимо се добавя, когато са използвани определени CSS декларации.

Елементи с лейаут по подразбиране

Следващите елемент имат лейаут по подразбиране.

  • <html>, <body>
  • <table>, <tr>, <th>, <td>
  • <img>
  • <hr>
  • <input>, <button>, <select>, <textarea>, <fieldset>, <legend>
  • <iframe>, <embed>, <object>, <applet>
  • <marquee>

Свойства даващи лейаут

Следните CSS свойство/стойност двойки ще дадът лейаут на даден елемент ако се приложат върху него:

position: absolute

Отнася се за съдържащият блок, и точно там могат да се появят проблеми;

float: left|right

Float елементите предизвикват доста проблеми, точно заради лейаут;

display: inline-block

Понякога се използва като фикс, когато имаме инлайн елемент който се нуждае от лейаут. Прилагането на лейаут е вероятно единственият ефект на това свойство. Поведението на inline-block може да бъде постигнато в IE, но доста независимо IE/Win: inline-block и hasLayout.

width: всяка стойност различна от 'auto'

Това често се е използва като фикс, още по-често когато hasLayout обърква нещата.

height: всяка стойност различна от 'auto'

height: 1% се използва във Holly Hack.

zoom: всяка друга стойност освен 'normal' (MSDN)

Собственост на Microsoft, не се валидира zoom: 1 може да се използва при дебъгване.

writing-mode: tb-rl (MSDN)

Собственост на Microsoft, не се валидира.


В IE7, overflow също предизвиква появата на лейаут:

overflow: hidden|scroll|auto

Това свойство не предизвиква лейаут в предишните версии, освен ако не е бил допълнително създаден от друго свойство.

overflow-x|-y: hidden|scroll|auto

Като част от CSS3 бокс модела, overflow-x|-y нямат широко приложение в другите браузъри. Не дават лейаут в по-старите версии на IE

И нови hasLayout актьори се появиха на сцената в IE7. Докато hasLayout съществува, min/max свойствата действат подобно width и height, и ефектът от fixed и absolute позициониране изглежда идентичен.

position: fixed
./.

min-width: всяка стойност

Дори и стойността 0 ще даде лейаут.

position: fixed
max-width: всяка стойност различна от 'none'
./.

min-height: Всяка стойност

Дори и стойността 0 задава haslayout=true

max-height: всяка стойност различна от 'none'
./.


Резултатите се основават на проучване с IE Developer Toolbar и предварителни тестове.

Бележки за инлайн елементите

За инлайн елементите(инлайн по подразбиране като span, или след задаване на display: inline)

  • width и height дават лейаут в IE 5.x и IE6 или по нови версии само в quirks mode. В IE6, когато браузъра е в " standards-compliance mode" инлайн елементите ще игнорират width и height свойствата, и задаването им няма да зададе лейаут на елемента.
  • zoom винаги дава лейаут, но не се поддържа от IE5.0

Елементите имащи едновременно hasLayout=true и display:inline, имат поведение подобно на това посочено от стандартите за inline-block: следват хоризонталното течение като думи в параграф, чувствителни са към vertical-align. Веднага след като инлайн елементът получи лейаут, започва да се държи като inline-block, и това обяснява, защо в IE/Win, инлайн елементите могат да съдържат блокови елементи с по-малко проблеми отколкото в други браузъри, където display:inline остава инлайн.

Рестартиране на hasLayout

Връщането на определени CSS свойства към тяхната стойност по подразбиране, ще върне hasLayout в неговата начална стойност, ако няма други свойства даващи лейаут:

  • width, height (на 'auto')
  • max-width, max-height (на 'none') (в IE 7)
  • position (на 'static')
  • float (на 'none')
  • overflow (на 'visible') (на IE 7)
  • zoom (на 'normal')
  • writing-mode (от 'tb-rl' на 'lr-tb')

Авторите трябва да внимават с рестартирането на тези свойства. Да вземем система за навигация: Промяната на hasLayout, било то нарочно или не, може да има непредвидими последици в изрисуването на страницата(или IE6 нестабилност на програмата, когато е рестартиран динамично в комбинация с position: relative)

Нещата обаче стоят по различен начин при display свойствата: докато 'inline-block' задава haslayout = true, стойността няма да бъде върната на false при последваща промяна на елемента от 'inline-block' в 'block' или 'inline'. Сравнено със zoom, което по същия начин може да рестартира hasLayout, комбинацията inline-block/block изглежда като сложен хак без видими предимства.

Задаването на свойствата min-width, min-height на тяхната стойност по подразбиране '0' също дава лейаут, но IE 7 приема за тях невалидната стойност 'auto', което рестартира hasLayout.

Скрипт свойства на hasLayout

Избрахме да се обръщаме към hasLayout като "скрипт свойство" в желанието си да го различим от CSS свойствата с които сме свикнали да работим.

Няма начин да зададем стойност или да рестартираме свойството hasLayout директно.

HasLayout свойството може да се използва за да се провери дали даден елемент има лейаут:
Ако, например, елементът има "eid" за id, то тогава ако просто напишем в адрес бара на IE5.5+ javascript: alert(eid.currentStyle.hasLayout) показва състоянието му.

IE Developer Toolbar ни позволява да да се разглежда и променя CSS-а за определен елемент в процеса на работа; когато hasLayout е true неговата стойност е "-1". Чрез директна промяна на CSS-a на съответният елемент, можем да зададем "zoom(css)" на "1" което ще даде лейаут на елемента.

Друго нещо което трябва да се вземе под влияние е как лейаута се отразява на скриптовете. Свойствата clientWidth/clientHeight винаги връщат стойност нула ако нямат лейаут. Това може да е объркващо за неопитни програмисти и е различно от поведението на Mozilla. Можем да използваме този факт за да определим лейаута за IE5.0: Ако стойността на clientWidth е нула то тогава елементът няма лейаут.

CSS хакове

Следните хакове за задаване на лейаут са тествани в IE6 и по-долни версии. Бъдещи версии на IE може да имат различно поведение. Ще пренапишем това когато нова версия се появи публично.

Джон Галант и Холи Бергевин публикуват Holly hack(свещенният хак) през 2003:

  /* \*/ 
   * html .gainlayout { height: 1%; } 
  /* */ 
  • Дава лейаут в IE5+ на всеки елемент, с изключение на инлаин елементите в IE6 в Standards мод
  • Работи добре, освен в редки случаи когато height:0 или 1px са по стабилни
  • Несъвместим е с overflow: hidden, с изключение за IE6 в Standards мод (където height: 1% се конвертира в height: auto, освен когато родителят няма зададена височина.)


Също така можем да използваме underscore hack:

  .gainlayout { _height: 0; } 



Също така можем да използваме и по сигурните, от гледна точка на бъдещите версии на IE, условни коментари:

  <!--[if lte IE 6]> 
    <style> 
      .gainlayout { height: 1px; } 
    </style> 
  <![endif]--> 



Използването на външна стилова таблица, за всякакви IE-Win персонални нужди, извикана от условен коментар, също е сигурно и елегантно решение:

  <link rel="stylesheet" href="allbrowsers.css" type="text/css" /> 
  
  <!--[if lte IE 6]> 
    <link rel="stylesheet" href="iefix.css" type="text/css" /> 
  <![endif]--> 



Ние предпочитаме height: 0 и 1px — height трябва да се използва винаги, освен ако не е в конфликт с (overflow: hidden). Колкото до стойността, ние предпочитаме да избягваме 1%, тъй като може(в много редки случаи) да предизвика проблеми.


Height не може да се използва за инлайн елементи в Standard мод. В тези случаи можем да използваме display: inline-block или zoom: 1.


Виждали сме и отчаяни опити на "holy" хака да даде лейаут на елементи имащи float, или елементи които вече имат width. Запомнете, целта на тези хакове не е да зададат височина на елемента, а да зададат hasLayout = True.


Не давай лейаут на всички елементи: * {_height: 1px;}. Задаването на лейаут на всички елементи не е решение, то променя цялото изрисуване на страницата.

Управление на хаковете

Браузърите се променят, и ние трябва да признаем, че в зависимост от бъговете които са оправени в IE7 и по-горни версии, неизбежно хаковете за IE6 може да повредят презентацията на страницата в по-нови версии, или пък по новите браузъри със същият лейаут бъг може да не ни доставят възможност за филтриране като * html. В този смисъл използването на, zoom може да бъде препоръчително.

  <!--[if lt IE 7]><style> 
    /* style for IE 6 + IE5.5 + IE5.0 */ 
    .gainlayout { height: 0; } 
  </style><![endif]--> 
  
  <!--[if IE 7]><style> 
    .gainlayout { zoom: 1;} 
    /* or whatever we might need tomorrow */ 
  </style><![endif]--> 

  • zoom: 1; дава лейаут в IE5.5+ на всеки елемент включително и на инлайн елементите, но няма ефект при IE5.0
  • Няма известни странични ефекти(инлайн елементите се държат като inline-block)
  • Ако се изисква валидация, zoom: 1; трябва да се скрие с условни коментари.


Тъй като "сигурност в бъдещето" е противоречие в термините, ние препоръчваме уеб дизайнерите да "играят на сигурно" и да прегледат за хакове, било те направени по желание или не, и да ги използват в условни коментари за съответната версия на браузъра за който са предназначени.

Кратка бележка за IE Mac

IE Mac и IE за Windows са две съвсем различни животни, живеещи в различни части на зоологическата градина. Всеки има различен рендъринг енджин, и IE Mac не знае нищо за "hasLayout" поведението. IE Mac рендъринг енджина е по скоро в съответствие със стандартите, със свойството height имащо поведението на height, както трябва и да бъде. Хакове и други работи около "hasLayout" проблемът, ще имат по скоро определящ ефект за IE Mac, и трябва да бъдат скривани от този браузър. Повече за IE Mac проблемите може да бъде открито на IE Mac, бъгове и странности.

MSDN документация

В MSDN има много малко написано за hasLayour свойството, а още по-малко е обяснено как присъствието на лейаут повлиява на поведението на IE.

Назад в IE4, близо всеки елемент имаше един вид лейаут, с изключение на инлайн елементите, които не са абсолютно позициониране и нямат зададени размери (MSDN). В тази ранна лейаут концепция, имаше лейаут свойства като border, margin, padding, които могат да бъдат приложени на инлайн елементи. С други думи, за даден елемент "да има лейаут" е друг термин за да се каже: "може да има тези свойства".

MSDN още говори за "лейаут свойства", но значението е променено, те не се звързват със елементи имащи лейаут. В IE5.5, hasLayout свойството беше въведено, повече или по малко вътрешен флаг.

В IE5.5, документацията за MSHTML Editing Platform (която предлага възможност за редактиране, оразмеряване, и провлачване на лейаут елементи чрез <body contenteditable=true>) повдига три аспекта свързани с присъствието на лейаут:

Ако лейаут елемент има съдържание, лейаута на съдържанието се определя от границите на правоъгълника му. Да има лейаут обикновено значи, че елементът е правоъгален. Вътрешно, да има лейаут значи, че елементът е отговорен за изрисуването на неговото собствено съдържание.

(Editing Platform)

Работата свързана с hasLayout не беше документирана до Август 2005, когато, като резултат на The Web Standards Project и Microsoft, Markus Mielke отвори вратите за дискусия:

Най-общо, елементите в DHTML енджина на IE не отговарят сами за подреждането си. Div или p елемент може да са в кода и да излизат извън нормалното течение на документа, но тяхното съдържание се подрежда спрямо най-близкия родител с лейаут(най-често body). Тези елементи се уповават на родителя с лейаут да изчислят всички необходими мерки(начална точка, и т.н.).

(HasLayout Overview)

Интерпретации

Нашата интерпретация е опит да обясним какво става в познати случаи и трябва да служи като водач в не напълно познати случаи. Опитът, да се разгадае функционирането на черна кутия само по звука който издава като и зададем няколко тестови примера, е обречен на неуспех. Въпросът "Защо?" не може да бъде отговорен. Трябва да се опитаме да разберем цялата схема по която работи hasLayout модела, и как въздейства върху изрисуването на страницата. Извън това, могат да бъдат развити указания(и това ще бъдат само указания, не абсолютно решение).

Можем да го разглеждаме като малък прозорец. Съдържанието на лейаут елемент ще бъде напълно независимо от всичко извън границите на елемента, и съдържанието на елемента не може да повлияе на нищо извън границите му.

hasLayout свойството е един вид флаг: когато е зададено, елементът има това "качество" лейаут, което включва специални способности, както за себе си така и за децата си.

Тази голяма независимост на лейаут елементите е вероятно причината да са по-стабилни, и да карат някой бъгове да изчезват. Цената за това може да бъде отклонение от стандартите, и бъдещи(в по горни версии на IE) проблеми.

Моделът на MS за уеб страниците, може да бъде разгледан, като изграден от малки несвързани разкази, докато моделът на W3C е една цяла история, блокове от информация които са свързани помежду си.

Преглед на последиците

Clear плюс float и разширяване на блока до събиране на съдържанието

Флоутнатите елементи(флоутнат елемент е този на който е зададено свойството float) са автоматично обградени от лейаут елементите. Това е една от причините повечето начинаещи с техните страници построени в IE и гледани в по-добре поддържащи стандартите браузари, където флоутовете излизат от контейнера.

Противоположното поведение: какво ако искаме флоатнат елемент да стои извън контейнера на обграждащият го елемент. За демонстрация на проблемите с които може да се сблъскате в подобни ситуации погледнете нашата дискусия:

В IE флоут винаги ще бъде обграден от неговият контейнер(ако той има лейаут). Другите елементи може да се съобразяват с лейаут контейнера, но не и със самият флоут.

Това, и свойството на IE6, контейнера да се разширява до събиране на съдържание с каквато и да е дължина(extend-to-fit), може да се смятат като резултат от "определен от обграждащият правоъгълник" правило.

Дори още по-лошо: clear няма никакъв ефект върху флоутнат елемент намиращ се извън изчистеният контейнер. Лейаути базиращи се на този бъг в IE не могат да бъдат разглеждани нормално в съвместими със стандартите браузъри без цялостно преправяне.

IE свойството лейаут елемент да обгражда флоутнати елементи, което е неизбежно, може да бъде достигнато в други браузъри: виж секцията "Подобно на CSS спецификацията" за идеи свързани с ограждащите флоутове.

Елементи близо до float

Когато блоков елемент, следва float елемент, трябва - като блок - да игнорира флоута, но съдържанието му трябва да следва самият флоут: текстът в блоков елемент близо до флоутнат елмент трябва да тече вдясно от флоута, и тогава(ако текстът е по-дълъг от флоута) трябва да продължи под него. Ако, обаче, блоковият елемент има лейаут, да кажем, че по някаква причина сме задали ширина(width) на блоковият елемент поради някаква си причина, тогава целият елемент е разместен спрямо флоута, сякаш самият той е флоутнат, и така текстът не следва дясната граница на флоутнатият елемент.

Ширина зададена в проценти за блоков елемент в IE5 се изчислява на базата на разполагаемото пространство от страната на флоута, а в IE6 на базата на пълната ширина на бащиният елемент. Така че в IE6 width: 100% резултира в нещо което не се събира от страната на флоута, с всичките проблеми които това "не-вмъкване" може да предизвика.

Тестове за hasLayout блокове в съседство с float блокове:

Подобно на това, относително позициониран елемент близо до флоут, трябва да отстои в съответствие с зададената стойност(left: 0; ще постави елементът над предходният ляво флоутнат блок). В IE6, отстоянието left: стойност; започва от десният ръб на марджина на флоута предизиквайки хоризонтално разместване по цялата външна ширина на флоута(възможно решение е да се използва margin-left, но пък трябва да се има впредвид погрешната интерпретация на процентите)

[Лейаут блокове с относително позициониране съседни на флоутнат елемент]

Съгласно спецификациите, флоутнат елемент се вплита в следващите го кутии. Това не може да бъде постигнато с двуизмерни правоъгълници които не се пресичат.

Ако авторът използва неадекватността на IE, тогава идва въпросът как да накараме кутиите в браузърите следващи стандартите да изглеждат като като тези лейаут кутии които се отдръпват за да нарпавят място за предхождащ флоут. Даваме възможности за изграждането на нов контекст за форматиране на кутиите близо до флоут в секцията Прилики с CSS спецификацията

Ако нпосетим за пореден път списъка с бъговете в IE:
Tри пиксела отместване на текста
ще забележим, че кутия с лейаут следваща флоут няма да бъде засегната от гореспоменатото 3px отместване, защото странната 3px обвивка на флоута която отмества текста не влияе върху съдържанието на лейаут елемента, а премества целия лейаут елемент с 3px. Като щит лейаута предпазва съдържанието, но самият той е избутан.

Списъци

Списъците са засегнати от лейаут приложен или на списъците(ol, ul) или на елементите им (li). Различните версии на IE реагират по различен начин. Най-очевидния ефект е на списъчните маркери (когато списъците са напълно променени с CSS няма проблеми със списъчните маркери). Маркерите най-вероятно са създадени с добавянето на някакъв вътрешен елемент който е някак си закачен за списъка и изглеждат доста нестабилни. За съжаление тъй като са вътрешни, няма начин да ги достигнем за да поправим тяхното странно поведение.

Най очевидните проблеми са:

  • Лейаут приложен на списък, кара маркерите да изчезнат или да бъде позициониран различно/ грешно.

Понякога проблема може да се реши с промяна на margin на списъчните елементи. Това изглежда като резултат от факта, че лейаут елементите изрязват вътрешните елементи излизащи извън границите.

Друг проблем е, че(в с номерираните списъци) всеки елемент с лейаут изглежда има собствен брояч. Да кажем че имаме списък с 5 елемента където само третият има лейаут. Ще видим това:
1... 2... 1... 4... 5...

Освен това когато списъчен елемент с лейаут се разпростира на повече от един ред, маркерът е вертикално подравнен с най-долният ред(а не с най-горният, както се очаква).

Някой от тези проблеми не могат да бъдат поправени, затова когато желаете маркерите да се виждат е по-добре да избягвате задаването на лейаут на списъците и на техните елементи. ако е необходимо задаването на размери, по-добре да бъдат приложени на други елементи: например width може да бъде приложена на външен обвиващ елемент, а височина, на съдържанието на всеки списъчен елемент.

Дрог често срещан проблем със списъците в IE се среща когато съдържанието на li е линк с display: block. При тези условия разстоянието между елементите не е игнорирано и обикновено резултира в допълнителен ред между тях. Един от начините да се избегне това, е като се зададе лейаут на блоковият линк. Това също има предимството, че прави цялата правоъгълна повърхност на линка възможна за кликане.

Таблици

Таблицата винаги има лейаут, винаги се държи като обект със зададена ширина. В IE6, table-layout: fixed, е обикновено еквивалент на таблица с ширина 100%, с всички проблеми които това може да предизвика(грешни изчисления). Като бележка, можем да отбележим няколко неща по ситуацията в IE5.5 и “quirks mode” IE6

Релативно позиционирани елементи

Да отбележим това, че position: relative не дава лейаут, което води до някой проблеми при изрисуването на страницата, повечето от които свързани с изчезването или разместването на съдържанието. Нередности могат да бъдат срещнати когато страницата е презаредена, промяна на размера на прозореца и скролиране, маркиране. С това свойство, IE премества елемента, но изглежда забравя да пренарисува неговите лейаут под елементи( тъй като лейаут елементи биха изпратили правилно съобщение за прерисуване).

Горепосочените са описания на проблема. Като обеца на ухото, никога не позиционирайте елемент относително без да му зададете лейаут. В добавка може да проверим дали родителят се нуждае от лейаут или position: relative също, това става съществено когато има забъркани и флоутове в цялата схема.

Абсолютно позиционирани елементи:
Обвиващ блок, какъв обвиващ блок?

Много важно е да разберете CSS концепцията за съдържащият блок, което отговаря на въпросът къде да бъде поставен абсолютно позиционираният(а.п.) елемент: да дефинираме отстоянието от началото , и да дефинираме дължината с помощта на която се изчисляват процентите.

За а.п. елементи, съдържащият блок е установен спрямо най-близкия си позициониран родител. Ако няма такъв родител, се използва блокът на html.

Обикновено, задаваме такъв съдържащ блок чрез position: relative. Това означава, че можем да поставяме а.п. елементи, където си искаме в страницата без значение от позицията им в html кода, което може да бъде много полезно за нуждите на достъпността да поставят съдържанието най-отпред, или да направи живота по-лесен в много сложни страници.

Тези дизайн идеи са поставени под въпрос от IE: началната позиция на а.п. елемент се изчислява коректно само ако съдържащият блок има лейаут, и ширината на а.п. елемент изчислена в проценти може да бъде изчислена спрямо грешен родител. Тук IE5 и IE6 имат различно поведение, но и двата браузъра имат проблеми. IЕ7b2 се държи по-стабилно, но все още има грешно поведение в определени случаи. Когато е възможно, опитайте да се придържате към случаи където съдържащият блок има лейаут и е родител на а.п. елемент(т.е. да няма други елементи между съдържащият блок и а.п. елемент)

Да кажем, че родител без лейаут е позициониран относително - принудени сме да зададем лейаут за да може зададената начална позиция да бъде интерпретирана коректно.

Да кажем че непозициониран родител трябва да има размери, и дизайнът лежи на ширини зададени в проценти - можем да забравим за тази идея заради липса на поддръжка от браузъра:

Филтър

Microsoft свойството filter се прилага само на лейаут елементи. Някой от тях разтягат границите на обекта. И показват техни собствени недостатъци(flaws)

Промяна на позицията на изрисувани елементи

Когато всички елементи са изрисувани, IE препозиционира съдържащият лейаут блок когато :hover промяна настъпи(например промяна на фона на линк). Понякога елементите са преместени на нова позиция, защото в моментът на поставяне на мишката върху линка, всички ширини и позицията на свързаните елементи са известни на IE. Малко е вероятно това да се случи при първо зареждане, когато ширината все още е неопределена поради "способността" на IE за разширяване на блока до събиране на съдържанието. Това може да резултира в подскачане при :hover.

  1. Jump on :hover (подскачане при :hover)
  2. quirky percentages: the reflow (Грешни проценти - пренареждането)

Тези свързани с проблема на пренареждането грешки в IE създават проблеми в страниците с променлива ширина, където много често се използват проценти при задаването padding и margin.

Начална позиция на фона

hasLayout засяга също и началната позиция на фона(background). Например, съгласно CSS спефикиацията background-position: 0 0 трява да започва от ръба на пълнежа(padding) на елемента. В IE/Win започва от рамката(border) когато hasLayout = false, и от пълнежа когато hasLayout=true:

Деформиране на margin

hasLayout засяга деформацията на margin между елемент и неговите под елементи. Съгласно спецификацията margin-top на елемент без зададен padding-top и border-top трябва да се слее с margin-top зададен на първият му под елемент(първият елемент трябва да не е излязъл от нормалният поток на страницата т.е. float:none;).

В IE/Win това никога не се случва ако обгръщащият елемент има лейаут: изглежда лейаута предпазва марджините на под елементите да излизат от кутията. Също така, когато hasLayout=true, било на контейнера или на детето, други грешни Margin сметки се появяват:

Блокови линкове

hasLayout засяга активната област(областта върху която може да се клика с мишката) на линковете на които е зададен display:block;, или са превърнати в блокови елементи по друг начин. Обикновено, когато hasLayout=false, активна е само частта покрита от текста. Когато hasLayout=true, целият блок е активен. Същото важи за всеки блоков елемент със закачен onclick/onmouseover събитиен манипулатор.

Вътрешна навигация чрез клавиатурата - истинска одисея

Докато използвате табулация за браузване из страница и кликнете на вътрешен линк(линк който сочи към друга секция на същата страница), следващото натискане на табулацията няма да продължи на следващият линк в секцията в която ни е отвел предния:

Табулацията ще отведе - най-често грешно - потребителя към първият линк в най-близкият лейаут наследник(ако този лейаут елемент е изграден от table, div, span и някой други елементи).

Свиване и обвиване

Някои свойства приложени на елементи с width: auto предизвикват изчисляването на тяхната ширина с алгоритъма на "свиване и обвиване". Пример за такива свойства са float: left|right, position: absolute|fixed, display: table|table-cell|inline-block|inline-table

Това работи в IE, разбира се в съответствие с поддръжката на съответните свойства. Но когато елемент който трябва да се свие и обвие съдържанието си, съдържа блоков елемент с лейаут, тогава в повечето случаи, детето се разширява до пълната ширина, независимо от съдържанието си, и заличава ефектът на свиване при родителя.

Пример:
Флоутната вертикална навигация UL се разширява на 100% вместо да се разшири спрямо съдържанието си, защото за линковете е зададен CSS a {display: block; zoom: 1;} който пък трябва да реши проблемът с празното място(бъг в IE) и да направи цялата област на линка кликаема.

Този ефект на свиване остава в сила само ако лейаут детето има зададена ширина, или има ефект на свиване на самия себе си (например има зададен float)

Орязване от ръба

В най-общият случай, когато кутия съдържа по сложни структури, като изпъкнало съдържание, "hasLayout" на този контейнер е често необходим за да се избегнат проблеми при изрисуването.

Вмъкнати кутии които са изместени навън от контейнера(с използване на отрицателни стойности за margin например) са орязани.

Отрязаната част може да бъде възстановена като се даде лейаут на изпъкналата кутия; същто така position: relative е необходимо в IE6. IE7 има по-добро поведение в тези ситуации и затова свойството position: relative не е необходимо.

Купчината, нареждането на слоевете и лейаута.

Изглежда има два начина за подреждане на слоевете в IE/Win:

И двата модела, въпреки че са несъпоставими, съществуват в IE. Правило което трябва да се запомни: Докато изчиствате от грешки, не пропускайте да проверите и двамата заподозрени. Често виждаме подобни проблеми в падащи менюта или подобни сложни менюта, където подреждането на слоевете, позиционирането и float могат да доведат разнообразни катастрофи, и решаването на проблемът може да включва използването на z-index позициониран лейаут, но това варира, така че внимавайте.

Contenteditable - Пълен провал

Атрибутът contenteditable=true, зададен на HTML таг като <body contenteditable=true> позволява да променяме съдържанието, да провлачваме и оразмеряваме елемента и неговите деца. Опитайте това с li в подредена листа.

За да може да променяме елементите, "contenteditable" и "hasLayout" предлагат два различни начина за подреждане на слоевете за тези елементи за които hasLayout=true

Платформата за редактиране наследява лейаут концепцията, доказателство може да се види, че contenteditable е причината за лейаут недоразуменията.

[Повече за contenteditable]

Прилики с CSS спецификацията

Провалят ли се страниците направени в IE в останалите браузъри? Не е необходимо да оставяте това да се случва! Всеки добър браузър може да управлява IE направените страници чудесно ако го попитаме учтиво - и му подадем валиедн CSS

Използвайки слабите прилики намерени между hasLayout и новият блок форматинг контекст можем да възпроизведем ефектът на hasLayout за ограничаването на float и за поведението на елементите близо до флоутнат елемент в браузърите следващи стандартите.

  1. Обратен инженеринг
  2. Симулации

Quirks мод

Моля погледнете quirks мод секцията за повече информация.

Лейаут - Заключение

Лейаут концепцията като цяло не може да се сравни с никоя основна CSS концепция от визуалният модел съдържащи, float, position и т.н....

Това довежда до специфични за IE/Win нарушения на CSS спецификацията дължащи се на присъствието или отсъствието на лейаут на елементите на страница.

hasLayout - част от друг енджин?

Обектният модел в IE изглежда е хибрид между докмуентен модел и традионният аппликейшън модел. Споменавам това тъй като е важно да се разбере как IE изрисува страниците. Преминаването от документен модел към апликейшън модел е да се даде лейаут на елементът.

(Dean Edwards)


Понякога е невъзможно да се даде обяснение на някакво поведение: това е просто защото зависим от статусът на hasLayout, един от два енджина се използва, всеки от които има собствени бъгове.

Абсурдът на бъговете

Софтуер бъговете са резултатът на човешки грешки и липса на пълнота и логика през процеса на създаването. Това е основен човешки недостатък, за който лекарство все още не е намерено.

Всеки опит да се коригира несполучлив софтуер, без пренаписването му от начало, ще доведе до повече и по-комплексни грешки резултат от гореспоменатите човешки недостатъци.

Всеки софтуер който основава функционирането си на друг софтуер - включително и операционна система(разбира се), ще се основава и на неговите недостатъци. Така се получава каскада от грешки, от всички включени парчета софтуер, което прави дори мисълта за напълно безгрешен софтуер напълно абсурдна.

(Molly ‚the cat‛)

Лични инструменти