📜 ⬆️ ⬇️

IE bugs. Part 1. The presence or absence of hasLayout

With this post I plan to start a series of articles on IE bugs and possible fixes. The series of articles I decided to write first of all for myself, in order to somehow systematize and preserve my knowledge, but I hope that it will be useful for both beginners and experienced layout designers.

The first post I want to touch on one of the fundamental concepts when fixing IE bugs is hasLayout.

What is hasLayout?


In the IE rendering engine, each element is essentially not responsible for its location. The location of the element depends only on its position in the source code and its location in the normal stream. At the same time, all the child elements of a certain container block are located, in fact, not relative to their immediate parent, but depending on the closest ancestor who has a “layout”.

hasLayout is a proprietary IE property that determines whether the layout element has a “i.e.” how the element is located in the flow, its size, positioning, reaction to events and the impact on other elements.
')
HTML elements that have “layout” by default (hasLayout = true): <html>, <body>, <table>, <tr>, <td>, <th>, <img>, <input>, <button >, <textarea>, <select>, <fieldset>, <legend>, <hr>, <iframe>, <embed>, <object>, <applet>, <marquee>.

The hasLayout property in IE cannot be directly set, but its presence can be indirectly affected by various values ​​of some css properties. The following values ​​of the listed properties give the layout element (hasLayout = true):

To drop hasLayout, you need to specify a value other than those listed above ( for example : width: auto or float: none).

For more information on what hasLayout is, see the great article On Having Layout - the concept of hasLayout in IE / Win ( translation ).

How and why to install hasLayout


Giving hasLayout elements can fix a lot of IE bugs. Most of the bugs associated with incorrect positioning, display or measurement are related to the presence or absence of the hasLayout element.

To successfully fix these bugs, first of all you need to know if the hasLayout element is enabled. This can be verified analytically or empirically.

The first involves viewing the source code styles applied to the problem element, and scanning them for the presence of properties, triggers listed above. If, for example, an element has an explicit height (the height property has a value other than auto), then the hasLayout property is set (its value is true). If the trigger properties are not found, or they have values ​​that reset hasLayout and the element does not belong to the list of elements with “layout” by default, then the property hasLayout is not set.

The second way is to directly view the value of the element's hasLayout property using the DOM inspector in the Internet Explorer Developer Toolbar plugin.
After you install the plugin, the button will appear on the IE panel IEDevToolbarButton , clicking on it will open the plugin panel:

Iedevtoolbar
Also, you can open the panel through the View menu in IE6 ( View → Explorer Bar → IE Developer Toolbar ) or through the Tools menu in IE7 ( Tools → Toolbars → Explorer Bar → IE Developer Toolbar ).

In order to select an element for which we want to check for the presence of the hasLayout property, you need to click on the button inspect and select it with the mouse (in the same way that elements are selected in Firebug after clicking on the “Inspect” button). After that, in the “Current Style” panel all styles applied to the selected element by the browser will be shown. If among them there is no property hasLayout, the element does not have a “layout”. If among them it is and its value is -1 (true), then the hasLayout property is set, and the element has a “layout”.

After we learned how to check whether the hasLayout property is enabled, it's time to learn how to install it correctly. All the above properties-triggers one way or another will affect the display element. If, for example, we specify the element float: left; then, in addition to the effect we need (the hasLayout setting), the element will behave in accordance with the direct purpose of this property (it will be torn out of the normal flow and other elements will wrap around it). It is good if this coincides with our idea, but most often we just need to include the hasLayout element.

Therefore, we need such a property-trigger, which, ideally, does not directly affect the behavior of the element. There are few such properties, in some situations this property can be height with a value of 1% or display: inline-block, but they all have limitations. If you use height: 1%, then in the case of the explicit height of the parent block, the height of the element will naturally be calculated relative to the set value. In my opinion, the most secure can be considered the zoom property with the value set to 1 (scale 100%). But, since this property is not valid, it is best to use it in a separate style file for IE, which is connected using Conditional Comments . Everything would be fine, but this property is not supported in IE <6, so if you need support for these browsers you can use display: inline-block or height: 1% for them.

The search algorithm for bugs that can be fixed with hasLayout is as follows:
  1. Find inconsistencies in the display of a specific section of the page in IE.
  2. View a piece of HTML code of this site in order to memorize the hierarchy of elements.
  3. Find styles in CSS that apply to elements on this site.
  4. Analyze all the applied styles for the presence of trigger properties hasLayout for both the problem element and its ancestors.
  5. Alternately apply zoom: 1; for elements that have not installed hasLayout, starting from the topmost one in the HTML tree, and after each change of the CSS file, check the result in IE.

If, after carrying out all these actions, it was not possible to fix the initial bug, then it is not a matter of hasLayout :)

Examples: hasLayout positive effect


Suppose we need to arrange two blocks inside some element. One in the upper left corner and the other in the lower left corner.
The code will look something like this:
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" >
< html xmlns ="http://www.w3.org/1999/xhtml" xml:lang ="ru" >
< head >
< title > 1. position:absolute. </ title >
< meta http-equiv ="Content-Type" content ="text/html;charset=utf-8" />
< style type ="text/css" >
* {
margin:0;
padding:0;
}

.zoom {
zoom:1;
}

div.parent {
position:relative;
border:1px solid #000;
padding:20px;
margin:10px;
}

div.parent div {
position:absolute;
width:20px;
height:20px;
top:0;
left:0;
background:#0c0;
}

div.parent div.bottom {
top:auto;
bottom:0;
}
</ style >
</ head >
< body >
< div class ="parent" >
< p > Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </ p >
< div ></ div >
< div class ="bottom" ></ div >
</ div >
</ body >
</ html >

* This source code was highlighted with Source Code Highlighter .

Example 1

In normal browsers, everything is displayed as intended. Two green squares, one of which is in the upper left corner of the element with a frame, and the other in the lower left. But, in IE6, it looks like this:
Example 1
In order to correct this behavior, you need to give a “layout” to the parent element (div.parent) for this, I will add to it a specially prepared “zoom” class. After that, everything will fall into place:

Example 1 (bug fixed)

Consider the following example. Its code is:
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" >
< html xmlns ="http://www.w3.org/1999/xhtml" xml:lang ="ru" >
< head >
< title > 2. </ title >
< meta http-equiv ="Content-Type" content ="text/html;charset=utf-8" />
< style type ="text/css" >
* {
margin:0;
padding:0;
}

.zoom {
zoom:1;
}

div.parent {
border:1px solid #000;
padding:20px;
margin:10px;
}

div.parent ul {
background:#00c;
}

div.parent ul li {
border:1px solid #000;
background:#0cc;
}
</ style >
</ head >
< body >
< div class ="parent" >
< ul >
< li > </ li >
< li > </ li >
< li > </ li >
</ ul >
</ div >
</ body >
</ html >


* This source code was highlighted with Source Code Highlighter .

Example 2

In normal browsers, the list inside the block with a frame ends exactly where the last element of the list ends. In IE 6 and 7, the lower border of the list coincides with the lower border of the block with a frame (this is clearly seen from the fact that I indicated the blue background to the list):
Example 2
Again, after turning on the parent element hasLayout (div.parent), the bug disappears:

Example 2 (bug fixed)

The following example. There is some common container in which several floated elements:
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" >
< html xmlns ="http://www.w3.org/1999/xhtml" xml:lang ="ru" >
< head >
< title > 3. </ title >
< meta http-equiv ="Content-Type" content ="text/html;charset=utf-8" />
< style type ="text/css" >
* {
margin:0;
padding:0;
}

.zoom {
zoom:1;
}

div.parent {
border:2px solid #000;
margin:10px 20%;
}

div.parent div.float {
background:#cc0;
float:left;
margin:2px;
text-align:center;
width:50px;
height:50px;
line-height:50px;
}
</ style >
</ head >
< body >
< div class ="parent" >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div class ="float" > Float </ div >
< div style ="clear:both;" ></ div >
</ div >
</ body >
</ html >


* This source code was highlighted with Source Code Highlighter .

Example 3

IE is buggy again:
Example 3
After adding the zoom class for the parent diva, the bug disappears:

Example 3 (bug fixed)

In addition to fixing such bugs, including the hasLayout element is also useful for the following:

HasLayout negative effect


In addition to the positive effect, the inclusion of hasLayout can also negatively affect the display. This is most often expressed in the non-collapse of vertical margins, the appearance of unnecessary indents, the disappearance of parts of the elements, or the “jumping” of elements when the window is resized or the cursor is moved over the link.
In such cases, you must either abandon hasLayout, or, if there is no way without it, try to wrap the problematic element in another one, set the wrapping element to hasLayout, and reset it in the original wrapping element.

In addition, it is necessary to take into account that the use of hasLayout has a bad effect on performance.

Source: https://habr.com/ru/post/50175/


All Articles