我的浮动元素哪去了
The Guillotine 是一个 bug ,当链接 hovered 结束后,浮动元素的 bottom part 被截断。
这个效果非常像 IE/Win Unscrollable Content Bug,但是当它包含少量内容和更多的 dynamic 的时候更容易出现。
这有个小例子来阐释我们在说什么。
The Background
现在我们已经看到了 Guillotine 这个bug ,下面我们来检查一下,我们要想创建这样一个bug都应具备那些要素。
要想出现 Guillotine 必须的有的条件是:
1. 一个容器
2. 一个包含在容器内的浮动元素,并且没有 "cleared" 。
3. 在容器内的浮动元素后面,包含 non-floated 链接。
4. 一些作用到这些链接上的合适的属性 a:hover style rules 。
5.Internet Explorer ,这是显然的。
这些 non-floated 内容可能也可能没有被包含在一个块级元素之内,例如 p 或 div 。
能够引起 Guillotine 的链接可以是任何 a:hover style rules 做出的改变,包括:
- Background
- Padding
- Text Style
- Border etc.
<!-- Example Layout for a Guillotine Invoking Situation --> <div id="container"> <div id="floated"> This is the floated content. It is vulnerable to the Guillotine. </div> This is the non floated content inside the container. Guillotine invoking links should be in this content. </div>
/* Example Style Rules for a Guillotine Invoking Link */ a:hover { background: none #FFFFCC scroll repeat 0% 0%; /* and/or */ padding: 5px; /* and/or */ text-style: italic; /* and/or */ border-bottom: #0000FF 1px solid; }
The Bug
如果容器被设定了尺寸,IE会在容器内自动包含浮动元素。这严重的违背了规范,让人痛苦的是,这个浏览器就这么规定的。因此,在IE中,容器会自动伸展来包含浮动元素,这会超过 non-floated 内容的高度。
(如果你仔细看,你会发现 IE 3px text jog 。 把它留给它自己的demo去解决吧,我们先看看这个麻烦的问题。)
Guillotine 包含能够 switch off 这个 auto-enclosing 行为的链接。当给这样的链接一个 hover ,容器底部的border会 jumps up 来包含 only the non-floated content ,这是正确的元素布局。然而,当容器缩小时,浮动元素低于 non-floated 的一部分内容会被隐藏,只是在容器底边框以上的部分能看到。
在下面的 demo 中,注意,在non-floated 内容部分前两行 links 不会触发这个 bug ,并且实际上当 given a hover 后会重置 Guillotine 。在non-floated部分其他所有的 links将会触发这个 bug 。
所有在浮动元素 div 中的 link 同样会重置 Guillotine 。
可以看到,没有指定尺寸的容器,尽管通常没有实际意义,可以阻止这个 bug ,因为浮动元素不会被自动包含。但是IE就是IE,就算浮动元素没有自动包含,在有些情况下,能够触发 Guillotine 的链接也会截断浮动元素。
在页面上,浮动元素没有被任何元素 cleared ,这种情况下 Guillotine 会发生。在这个bug的变种中,浮动元素没有被容器截断而是被body截断。
Live Example | Screenshot Before Execution | Screenshot After Execution
The Fixes
当浮动元素不会被自动包含时(既父容器不具有 layout)
这并不十分高雅,但是在这个时候唯一能生效的办法就是使用一个空的 div 来 clear everything , outside and after the container 。
<!-- Example Layout to Fix the Guillotine with Markup --> <div id="container"> <div id="floated"> This is the floated content. It is vulnerable to the Guillotine. </div> This is the non floated content inside the container. Guillotine invoking links should be in this content. </div> <div style="clear: both"></div>
当浮动元素自动包含时
当浮动元素被自动包含时,应该在容器内部清楚浮动。使用一个空的div来清楚浮动是一个比较方式。
清楚浮动的div应该出现在 container div 的内部,并出现在实际的内容之后。
<!-- Example Layout to Fix the Guillotine with Markup --> <div id="container"> <div id="floated"> This is the floated content. It is vulnerable to the Guillotine. </div> This is the non floated content inside the container. Guillotine invoking links should be in this content. <div style="clear: both"></div> </div>使用没有语义的标记并不是最好的方式;毕竟,这就是为什么引入清除方法的原因。符合标准的浏览器使用 :after ,并且给容器指定高度,IE不支持 :after 。但是给容器指定尺寸确实会触发 IE Guillotine ,所以在元素本身上 "生成清除元素" 不会解决这个问题。
我们需要使用 :after 方法达到目的。幸运的是,可以使用 Holly Hack 来解决问题。
首先,在 non-floated 的内容里面增加一个块级元素,比如 p 或 div 。使用它们来包含文本是符合语义的,所以主张标准的人们不会觉得有问题。然后我们给块级元素通过 Holly hack 设置高度,这个只有在IE中会用来设置尺寸。你瞧,bug 消失了。
<!-- Example Layout with the Holly Hack applied --> <div id="container"> <div id="floated"> This is the floated content. It is vulnerable to the Guillotine. </div> <p class="hollyhacked"> This is the non floated content inside the container. Guillotine invoking links should be in this content.</p> </div>
/* Example style rules for the above fix */ #container { /* Set margins, padding, borders, colours etc. */ } /* Contain the floats using the :after method */ #container:after { content: "."; display: block; height: 0; clear: both; visibility:hidden; } /* \*/ * html #container { height: 1%; } /* */ /* End float containing rules */ #floated { /* Set margins, padding, borders, colours etc. */ float: left; /* float the block */ } /* Apply Holly Hack to the non-floated content */ /* \*/ * html .hollyhacked { height: 1%; } /* */如果到此就结束了,那就太好了,但是IE是那个永远不离开舞台的胖女人。使用 Holly hack 给 non-floated content block 设置尺寸,来排除 Guillotine ,但是会触发 IE's flawed float model plus it's own set of complications 。
然而,Guillotine的效果只有当浮动元素内容比跟在它后面的 non-floated 内容高的时候才会被注意到。因此,non-floated 内容很少出现在浮动元素的下面。这就给了我们一个机会使用 Holly hack 并且不破坏 layout 。
正如你所看到的,对于 Guillotine bug 没有完美的解决方法。
原文地址:
http://positioniseverything.net/explorer/guillotine.html
了