网页布局教程:边距和绝对定位
来源:本站 时间:2009/8/20 5:11:39 次数:
这篇文章继续前面发起的关于自动定位的话题,先前在描述关于自动定位的一些基本信息之后,我留下了一些可能用在布局中的方法,现在是时候讨论元素定位的改进问题了。
玩弄绝对定位元素于股掌之间
首先,回忆一下自动定位是如何触发的,设置绝对定位元素的left、top、right、bottom属性为默认的“auto”值,而不是给定长度值。当属性为“auto”值时,绝对定位元素不会参考任何定位的祖先元素,而是参照它作为静态流动元素应该放置的“static”位置。它占据着该位置,但仍保持在一个单独的层上,或许会叠加在文本流上。
一般情况下会很好,但真正这样做会使我们失去对每一个边距属性的控制,当我们需要将AP元素放置到理想位置时,我们就需要正常的利用这些属性了。如果AP元素的静态位置碰巧与我们想让其放置的位置不一致时,有一种可能的方法可以使自动定位元素发射偏移—-margin。
规则说明,margins在所有AP元素上都能工作,且不会与其它margin 折叠,这大大简化了这种状况,但是,有一个问题会导致混淆——AP元素作为内联元素时,如span和link。
在起前一篇文章曾经提到忽略了边距和补白的所有top和bottom属性,但是,AP元素会执行所有的margins和paddings,及时他们是纯粹的span和link。这是因为,AP元素会将其转换成包含块,或者更具体些—块元素。
借助于margin使AP元素向四周移动,这看起来不错,但当你参照前一篇文章中的自动定位演示页,你会有一点陌生,这是演示页:
01.
<
p
>
02.
Vestibulum lacus tellus, adipiscing in, volutpat sit amet, dictum ac.
03.
Duis euismod
04.
sapien quis tellus. Vivamus aliquam, lorem a accumsan consequat, dolor
05.
est iaculis
06.
est, nec pulvinar magna ipsum at lacus. Duis aliquam. Sed mattis.
07.
Morbi ipsum
08.
ipsum, euismod ut, scelerisque quis, faucibus et, tortor. Sed aliquam
09.
erat vel justo.
10.
Etiam lacinia, massa a ultrices pellentesque,
11.
<
a
href
=
"#"
12.
class
=
"linkparent1"
>Link text<
span
>Tooltip text</
span
></
a
>
13.
dolor ante sagittis nibh, eget interdum ante lectus nec est. Fusce
14.
rutrum faucibus
15.
mauris. Aliquam cursus nisl at diam. Lorem ipsum dolor sit amet.
16.
</
p
>
17.
id="line17"
18.
.linkparent1 {
19.
color: #a00;
20.
}
21.
.linkparent:hover span {
22.
left: auto;
23.
} /* this hover on the link changes the nested span's left value to
24.
auto */
25.
.linkparent span {
26.
position: absolute;
27.
left: -999em;
28.
border: 1px solid white;
29.
background: #446;
30.
color: white;
31.
font-weight: bold;
32.
padding: 2px 4px;
33.
text-decoration: none;
34.
} /* tooltip may be custom styled as desired */
35.
.linkparent:hover {
36.
background: url(bgfix.gif);
37.
} /* Applies 1x1 transparent bgfix.gif on hover - IE hover bug fix */
当鼠标经过“link-text”时,AP出现在窗口之中,自动定位将其放在一个内联span应该出现的位置上,即使span是绝对定位,并且是一个块元素,就浏览器而言,绝对定位的span元素像内联元素那样,同时它又是拥有诸如margin、padding和border等属性的块元素。
同时,回忆一下第二个演示页,我给span特定的定义了“display:block”属性,那样,所有非IE浏览器将span放置到新一行上,并且是从段落的左侧开始。这样,我们看到元素并无多大改变,而是对其自动定位属性产生了影响。(IE除外)
这非常有趣,但一点也不影响我们的margin实验。我只是让你认识到这一点,因为有时候,它会在你毫不知情的情况下使你困惑。
Margins初探
我们想让AP span弹出框的位置出现的第一点,更靠左一些,使其叠在父链接之上。这样看起来更酷,而且他们重叠,确保用户来回移动鼠标不会使弹出框消失。
这是同样的demo,但是其top边距向下移,right边距左移,这样就出现在父链接之前,增加以下代码:
1.
.first-offset-test span {
2.
margin-top
: .
8em
;
3.
margin-right
:
50px
;
4.
}
现在,鼠标经过链接文本时看到变化没有?弹出层较以前下移了一些。不错,但它并没有向左移!Right边距看来并未生效。让我们从不同的方向试试--用负的left边距代替正的right边距。
1.
.second-offset-test span {
2.
margin-top
: .
8em
;
3.
margin-left
:
-50px
;
4.
}
这是为什么?负left边距生效而正的right边距属性不生效?同样为什么top边距也能生效?我们需要更好的demo去探讨这个问题,下面是一个相对定位的盒子,四个绝对定位的子div借助其left、top、right、bottom属性分别位于四个角落。
注意,由于存在四舍五入错误,在一些浏览器中你会看到盒子的底部和右边有1px的间隙,到目前为止,一切正常,现在让我们添加一些边距。
在下面的示例中四个不同的测试版本中,第一个box拥有left、top边距,第二个拥有bottom、right边距。剩下的两个与前两个相同但属性值为负。
分析
你注意到这种模式没有?只有在绝对定位元素的同一侧应用margin和定位属性值时margin才生效。实际上,在你定义了绝对定位元素的left属性后,你可以定义margin-left属性,这样会生效,其它几边是一样。
你或许会问,为什么是这样?一个有着严格尺寸的绝对定位box会通过两个相邻的属性(left、top、right、bottom)与其他元素相毗邻。余下的将被忽略或偏移你定义的尺寸大小。
既然只有绝对定位盒子的两侧与其他相联系,当定义margin时,只有这两侧发生反应。其余的两侧被描述为“半拉子”,它们不触及任何东西,在不干扰盒子声明尺寸或已定义属性值的一侧的情况下,其margin属性不产生任何推拉效果。很明显,这种行为不是很好,这样,那些无关的margin将被忽略。
当静态位置是在从左到右的流中计算时,自动定位盒子看起来好像是由left和top属性来决定的。这样,在我们的演示页中,right属性不会生效,bottom也是一样。
绝对定位盒子没有尺寸时也没什么不同(仅仅用两个相邻的属性来控制),因为在那种情况下,绝对定位盒子会在垂直和水平方向上收缩以适合内容,这样是的盒子看起来好像被定义了尺寸,尺寸大小刚好与内容的大小相同。唯一的例外出现在绝对定位盒子由两个相反属性控制时。
试试半拉子
让我们看看,你设置绝对定位盒子的left和right属性为0,但不定义任何宽度。这样盒子在其最近的定位的祖先元素中伸展直到填满所有所有水平空间。现在,绝对定位盒子的两侧与另外一个元素相关,这样,margin-left和margin-right将会生效,其值无论正负都有效,查看示例
正如你所看到的那样,正值挤压盒子的两边,而负值使盒子延伸出去。
需要牢记的是:IE6决不允许用两个相反的属性值来控制盒子的尺寸,这样margin也不会生效,除非给绝对定位盒子定义尺寸。
总结
我希望讨论能消除绝对定位盒子关于margin属性的疑虑,一旦这些问题得到理解,它就不会很复杂。除了IE6的限制,希望bug越少越好。