8.定位详解&层级&滤镜遮罩
定位(position)
相对定位
需求的产生
问题
1. 如何让图1中的div2移动到如图2上的位置
a) 图
i. 图1
ii. 图2
b) 思路:回忆一下哪些css命令能够影响盒子显示的位置
i. 我们很容易就想到外边距margin
劣质解决(margin)
1. 使用margin来解决。
a) 第一步:使div2往右移动100px
i. 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>相对定位</title> <style> div{font-size:20px;} .box1{width:100px;height:100px;background:red;} .box2{width:100px;height:100px;background:blue;margin-left:100px;} .box3{width:100px;height:100px;background:green;} </style> </head> <body> <div class="box1">div1</div> <div class="box2">div2</div> <div class="box3">div3</div> </body> </html> |
ii. 效果
b) 第二步:使div2再往下移动100px
i. 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>相对定位</title> <style> div{font-size:20px;} .box1{width:100px;height:100px;background:red;} .box2{width:100px;height:100px;background:blue;margin-left:100px; margin-top:100px;}
.box3{width:100px;height:100px;background:green;} </style> </head> <body> <div class="box1">div1</div> <div class="box2">div2</div> <div class="box3">div3</div> </body> </html> |
ii. 效果
iii. 小结
1. 可以看到这时div2的确跑到对应的这个位置了,但是我们发现div3却往下跑了100px像素,原因是不管是div1、div2还是div3它们都在正常文档流里面,当我们给div2加了一个上边外边距,那么它会把它下面的东西统统都往下挤,所以上面div3也就往下移动了100px。
c) 第三步:移动div3往上100px
i. 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>相对定位</title> <style> div{font-size:20px;} .box1{width:100px;height:100px;background:red;} .box2{width:100px;height:100px;background:blue;margin-left:100px; margin-top:100px;} .box3{width:100px;height:100px;background:green; margin-top:-100px;} </style> </head> <body> <div class="box1">div1</div> <div class="box2">div2</div> <div class="box3">div3</div> </body> </html> |
ii. 效果
d) 总结
i. 这种方式的确可以解决此问题,但我们可以看到,这种方式比较麻烦,这里不仅要改变div2本身,还需要改变div3,并且改变div3的外边距值时还用到了负数,那么有没有更好的解决方法呢!当然有,那就是我们下面要讲的相对位置。
特性
1. 相对位移样式 : “position:relative” 。
2. 相对定位不影响元素本身的特性。
a) 该是块就是块,该是内嵌就是内嵌。
b) 如果没有定义偏移量,对元素本身没有任何影响。
3. 不会使元素脱离文档流。
4. 相对定位是相对于元素本身在文档流中的默认位置发生偏移的。
详解
1. 详解1
a) 范例
i. 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>相对定位</title> <style> div{font-size:20px;} .box1{width:100px;height:100px;background:red;} .box2{width:100px;height:100px;background:blue;position:relative;} .box3{width:100px;height:100px;background:green;} </style> </head> <body> <div class="box1">div1</div> <div class="box2">div2</div> <div class="box3">div3</div> </body> </html> |
ii. 效果
1. 添加“position:relative”前
2. 添加“position:relative”后
3. 小结
a) 可以发现添加了相对位移后没有任何效果。
b) 既然加了相对定位元素后没有效果,那么还用它干嘛,其实添加了相对定位样式“position:relative”后,这个元素就变成了定位元素,它也就具备了定位元素的一些特性了,也就是具备了“定位元素位置控制”。
c) “定位元素位置控制”一共有四个方向的定位元素偏移量,如下:
i. top
ii. right
iii. bottom
iv. left
d) 在给四个方向的定位元素偏移量值时需要注意
i. 属性的方向与实际移动的方向是反的
1. 如“top:50px”实际上是往下移动50px,可以理解为远离top五十像素。
2. 如“left:50px”实际上是往右移动50px,可以理解为远离left五十像素。
3. 如“left:-50px”实际上是往左移动50px,可以理解为接近left五十像素。(等价于“right:50px”)
2. 详解2
a) 范例
i. 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>相对定位</title> <style> div{font-size:20px;} .box1{width:100px;height:100px;background:red;} .box2{width:100px;height:100px;background:blue; position:relative;top:50px;} .box3{width:100px;height:100px;background:green;} </style> </head> <body> <div class="box1">div1</div> <div class="box2">div2</div> <div class="box3">div3</div> </body> </html> |
ii. 效果
iii. 小结
1. 可以看出当给div2添加了相对定位样式属性“position:relative”后,这个元素就是定位元素,具有了定位元素的特性,这时就可以结合定位元素偏移属性和属性值“top:50px;”一起使用,达到效果,这里“top:50px”表示div2在原有的位置基础上再往下移动50px,如果是-50px,则在原有位置基础上向上移动50px,这里所说的“原有位置”实际上就是元素在文档流中原默认位置。
2. 另外,“top:50px”离开了“position:relative”就没有意义。
3. 详解3
a) 使用相对定位来解决上面“需求产生”下的“问题”。
i. 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>相对定位</title> <style> div{font-size:20px;} .box1{width:100px;height:100px;background:red;} .box2{width:100px;height:100px;background:blue; position:relative;left:100px;top:100px;} .box3{width:100px;height:100px;background:green;} </style> </head> <body> <div class="box1">div1</div> <div class="box2">div2</div> <div class="box3">div3</div> </body> </html> |
ii. 效果
iii. 小结
1. 可以看到解决这个问题,使用相对定位取代使用外边距要方便很多,而且只需要对需要定位的元素本身使用样式即可,不会影响到其它元素。
2. 相对定位不会使元素脱离文档流
绝对定位
特性
1. 绝对定位样式 : “position:absolute” 。
2. 会影响元素本身,使元素完全脱离文档流。
a) 即使没加偏移量时,它也已经影响到元素本身了,这与相对定位不同。
3. 使内嵌支持宽高。
4. 使块属性标签不设置宽度时,默认内容撑开宽度。
5. 绝对定位,如果有定位父级会相对于定位父级发生偏移,没有定位父级相对于整个文档发生偏移。
6. 绝对定位一般会找一个相对定位做干爹(定位父级)
详解
1. 详解1 (脱离文档流)
a) 范例
i. 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>绝对定位</title> <style> div{font-size:20px;} .box1{width:100px;height:100px;background:red;position:absolute;} .box2{width:200px;height:200px;background:blue;} .box3{width:100px;height:100px;background:green;} </style> </head> <body> <div class="box1">div1</div> <div class="box2">div2</div> <div class="box3">div3</div> </body> </html> |
ii. 效果
2. 详解2 (绝对定位相对于文档发生偏移)
a) 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>绝对定位</title> <style> body{border:2px solid #000;} .box1{width:300px;height:300px;background:red;} .box2{width:200px;height:200px;background:blue;} .box3{width:100px;height:100px;background:green; position:absolute;top:0;left:0;} </style> </head> <body> <div class="box1"> <div class="box2"> <div class="box3">div3</div> </div> </div> </body> </html> |
b) 效果
c) 效果扩展(如果将偏移量属性改成如下)
i. “top:0;left:0;”改成“right:0;bottom:0;”
ii. 效果
iii. 小结
1. 无论浏览器大小怎么改变,div3始终会在右下角显示。
3. 详解3 (绝对定位相对于定位父级发生偏移)
a) 代码
<html> <head> <meta charset="utf-8"/> <title>绝对定位</title> <style> body{border:2px solid #000;} .box1{width:300px;height:300px;background:red;position:relative;} .box2{width:200px;height:200px;background:blue;} .box3{width:100px;height:100px;background:green; position:absolute;right:0;bottom:0;} </style> </head> <body> <div class="box1"> <!-- 定位父级--> <div class="box2"> <!-- 结构父级 [唯一的] --> <div class="box3">div3</div> <!-- 绝对定位元素--> </div> </div> </body> </html> |
b) 效果
c) 小结
i. 绝对定位元素会一层一层的找它父级元素,如果找到其中某一层父级元素是定位元素(不分绝对定位和相对定位),则会跳过中间其它父级元素,直接以此定位父级为参考发生偏移。如果没找到定位父级,则会以整个文档作为参考发生偏移。
ii. 另外,绝对定位元素一层一层的找父级元素的顺序是从内往外找,一旦找到就直接作为绝对偏移的参考,且停止继续往上找。
1. 如果上例中div1和div2都使用了定位,那么div3的绝对定位会把距离它最近的div2作为定位父级。
iii. 正常情况下,如果说咱们页面中的这些元素,你只加绝对定位,而没有定位父级的话,它会随着咱们页面文档的大小发生改变,而位置跟着移动,这其实就不好控制了,我们通常会为这个绝对定位元素找个干爹(定位父级)。
固定定位
特性
1. 与绝对定位特性基本相似,相似点如下:
a) 使元素脱离文档流
b) 使块属性元素内容撑开宽度
c) 使内嵌元素支持宽高
2. 与绝对定位也有很明显的区别,区别如下(需要案例阐述):
a) 范例1 (定位固定)
i. 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>固定定位</title> <style> body{height:800px;} .box1{width:300px;height:100px;background:red; position:absolute;right:0;bottom:0;} .box2{width:200px;height:200px;background:yellow; position:fixed;right:0;bottom:0;} </style> </head> <body> <div class="box1">position:absolute;绝对定位</div> <div class="box2">position:fixed;固定定位</div> </body> </html> |
ii. 效果
b) 范例2 (不搭理父级定位)
i. 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>固定定位</title> <style> body{height:800px;} .box1{width:300px;height:100px;background:red; position:absolute;right:0;bottom:0;} .box2{width:200px;height:200px;background:yellow; position:fixed;right:0;bottom:0;} .parent{400px;height:400px;border:5px solid green; position:relative;} </style> </head> <body> <div class="box1">position:absolute;绝对定位</div> <div class="parent"> <div class="box2">position:fixed;固定定位</div> </div> </body> </html> |
ii. 效果
注意
1. 固定定位IE6不支持
a) 其实现在IE6的占有率已经相当低了,有时候可以不考虑它。
b) 一些大网站可能是结合js一起来完成兼容IE6的。
其他定位
1. position是定位属性,属性值包含如下:
a) relative (相对)
b) absolute (绝对)
c) fixed (固定)
d) static (静态/没有,默认值;使用js时可能会用到,用于取消已有定位)
e) inherit (继承,罕见使用,几乎所有元素也有此属性值,但基本不用)
定位层级
原则
1. 定位元素默认后者层级高于前者
a) 这里不分相对定位和绝对定位
范例1
a) 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>定位层级</title> <style> div{font-size:20px;} .box1{width:300px;height:100px;background:red;position:absolute;} .box2{width:200px;height:200px;background:blue;position:relative;} .box3{width:100px;height:100px;background:green;} </style> </head> <body> <div class="box1">div1</div> <div class="box2">div2</div> <div class="box3">div3</div> </body> </html> |
b) 效果
i. 没有为div2添加 相对定位“position:relative;”时
ii. 当为div2添加了相对定位“position:relative;”后
c) 小结
i. 可以看到在没有为div2添加相对定位时,div1覆盖了div2 。
ii. 当div2使用了相对定位后,div2就覆盖了div1。
z-index:[number] ; 定位层级
1. 定位元素默认都有定位层级“z-index”,且默认值都是小于1的,具体多少不清楚。
2. 一般开发中不要为每一个定位元素都添加定位层级样式“z-index”,因为都加的话,加到最后会很乱,只需要根据正常开发,开发到最后希望某个定位元素在最上面显示的话,可以单独为它添加“z-index”,一般值取1即可,“z-index”的数值越高层级越高。
范例2
1. 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>定位层级</title> <style> div{font-size:20px;} .box1{width:300px;height:100px;background:red;position:absolute;z-index:1;} .box2{width:200px;height:200px;background:blue;position:relative;} .box3{width:100px;height:100px;background:green;} </style> </head> <body> <div class="box1">div1</div> <div class="box2">div2</div> <div class="box3">div3</div> </body> </html> |
2. 效果
3. 总结
a) 根据“定位元素默认后者层级高于前者”的原则,应该div2会覆盖div1,但是我们这里为div1使用了定位层级样式属性“z-index”,使得div1覆盖了div2 。
b) 开发中不要添一个定位元素就加一个层级“z-index”,只需要在最后为某个需要显示在上层的特殊定位元素单独添加即可。
c) 定位元素默认定位层级“z-index”的值不大于1,开发中我们使用“z-index:1”来提高某个定位元素的层级就够了,当多个有冲突时可以适当的提高数值,数值越大层级越高。
练习
题目
1. 使用定位实现下面布局
答
1. 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>定位练习</title> <style> .parent{width:300px;height:300px;border:1px solid red; padding:10px;margin:90px auto;position:relative;} /* 定位父级 */ .parent a{width:100px;height:100px;line-height:100px;text-align:center; font-weight:bold;color:#fff;background:red; text-decoration:none;position:absolute;} /* 绝对定位元素 */ /* 为每一个绝对定位元素指定各自的偏移量 */ .link1{left:10px;top:10px;} .link2{right:10px;top:10px;} a.link3{left:110px;top:110px;background:blue;} .link4{left:10px;bottom:10px;} .link5{right:10px;bottom:10px;} /* "a.link3"也是一个选择符,用的相对较少而已, 它表示选中class属性值为link3的a元素, 上面如果直接使用.link3选择符的话蓝色背景不会覆盖成功,因为优先级 .link < .parent a , 而a.link(优先级) = .parent a(优先级)[注:都是一个类选择符和元素选择符搭配,所以优先级相同], 根据文档流的顺序,同级样式后者覆盖前者,所以蓝色会覆盖掉红色。 注意: a与.link之间是没有空格的。 其实同理"div#box1"也是可以的,表示选中id属性值为box1的div元素。 */ </style> </head> <body> <div class="parent"> <!-- 定位父级 --> <a class="link1">链接1</a> <!-- 绝对定位元素--> <a class="link2">链接2</a> <a class="link3">链接3</a> <a class="link4">链接4</a> <a class="link5">链接5</a> </div> </body> </html> |
2. 效果
实战(涉及到 透明度、滤镜遮罩)
题目
1. 做一个类似于优酷登录遮罩
答
第一步:分析确立技术
1. 灰色蒙版
a) 独立于文档流的,可以使用绝对定位解决。
b) 半透明的
i. 标准浏览器可以使用不透明度样式属性“opacity:数值”
1. 数值取值范围为0到1
a) 0完全透明
b) 1不透明
2. 兼容性
a) IE8以上的浏览器支持(不含IE8)
ii. IE浏览器可以使用IE私有滤镜“filter:alpha(opacity=数值)”
1. 数值的取值范围为0到100
a) 0完全透明
b) 100不透明
2. 注意
a) 开发工具IETester对IE私有滤镜支持不好
i. 测试中可以使用独立IE浏览器来测试透明度
b) IE私有滤镜一般编辑工具没有提示功能,需要靠记忆。
2. 蒙版上的框
a) 同样是独立出文档流的,同样使用绝对定位解决。
第二步:编码
1. 代码
<html> <head> <meta charset="utf-8"/> <title>实战</title> <style> body{margin:0;} body,html{height:100%;} /* 解决IE6下蒙版无法遮罩整个文档的问题 */ .floats{position:absolute;top:0;left:0;width:100%;height:100%; /* opacity:0.5可以兼容标准浏览器和IE8以上;filter:alpha(opacity=50)兼容IE浏览器各个版本 */ background:#000;opacity:0.5;filter:alpha(opacity=50);} .alert{width:400px;height:200px;background:#fff; border:2px solid yellow;position:absolute;top:50%;left:50%; margin-top:-102px;margin-left:-202px;} /* 盒子的实际大小是404*204 */ </style> </head> <body> 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容<br/> 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容<br/> 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容<br/> 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容 <div class="floats"></div> <!-- 蒙版层 --> <div class="alert"></div> <!-- 弹出框 --> </body> </html> |
第三步:效果
1. 标准浏览器
2. IE8以下浏览器
body,html{height:100%;}
1. 添加这一句是为了兼容IE6浏览器的。
2. 上面如果不添加这句,IE6下执行效果如下:
定位问题
相对定位
过程1 :普通问题产生
1. 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>定位问题</title> <style> .box1{width:500px;height:300px;background:blue;} .box2{width:300px;height:500px;background:yellow;} </style> </head> <body> <div class="box1"> <div class="box2"></div> </div> </body> </html> |
2. 效果
a) 标准浏览器
b) IE6
3. 小结
a) 标准浏览器中如果子div比父div高,那么子div会把父div冲破,里面的内容会冲出来
b) IE6下有一个特性,就是它默认父级元素一定能包含住子级元素,所以当子级元素高度大于父级元素时,子级元素会把父级元素撑开。
过程2 :处理普通问题
1. 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>定位问题</title> <style> .box1{width:500px;height:300px;background:blue; overflow:hidden;} .box2{width:300px;height:500px;background:yellow;} </style> </head> <body> <div class="box1"> <div class="box2"></div> </div> </body> </html> |
2. 效果
a) 标准浏览器
b) IE6
3. 小结
a) 通常我们解决这个问题时,给父级添加“overflow:hidden;”把子级超出的部分给截掉。
过程3:子级添加相对定位产生冲突,新问题产生。(包含解决办法)
1. 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>定位问题</title> <style> .box1{width:500px;height:300px;background:blue; overflow:hidden;} .box2{width:300px;height:500px;background:yellow; position:relative;} /* 子级添加相对定位 */ </style> </head> <body> <div class="box1"> <div class="box2"></div> </div> </body> </html> |
2. 效果
a) 标准浏览器
b) IE6
3. 小结
a) 可以看出IE6下父级元素的“overflow:hidden”包不住相对定位“position:relative;”的子级元素,而标准浏览器则可以。
4. 解决办法
a) 解决此兼容性问题其实也很简单,我们只需要再把父级元素也变成一个定位元素即可(我们可以给父级元素添加相对定位,我们上面学过,给元素添加相对定位,在不指定偏移量时不会对元素特性产生任何影响,元素该是块还是块,特性不变)。
绝对定位
过程1:定位父级宽高为偶数时,一切OK
1. 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>定位问题</title> <style> .box1{width:300px;height:300px;border:1px solid black; position:relative;} /* 定位父级 */ .box2{width:50px;height:50px;background:green; position:absolute;right:-1px;bottom:-1px;} /* 绝对定位元素 */ </style> </head> <body> <div class="box1"> <div class="box2"></div> </div> </body> </html> |
2. 效果
a) 标准浏览器
b) IE6
过程2:定位父级宽高为奇数时,问题产生
1. 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>定位问题</title> <style> .box1{width:303px;height:303px;border:1px solid black; position:relative;} /* 定位父级 */ .box2{width:50px;height:50px;background:green; position:absolute;right:-1px;bottom:-1px;} /* 绝对定位元素 */ </style> </head> <body> <div class="box1"> <div class="box2"></div> </div> </body> </html> |
2. 效果
a) 标准浏览器
b) IE6
3. 总结
a) 可以看出,当绝对定位元素的定位父级宽/高为奇数时,在标准浏览器下显示没有问题,但在IE6下偏移量“right”和“bottom”就会产生1px的误差。
b) 这个兼容性问题几乎没有解决办法,唯一的办法就是尽量规避,在开发中尽量让绝对定位的定位父级元素的宽高为偶数。
第八种清浮动(定位清浮动)
简介
1. 在前面清浮动课程中,我们已经介绍七种清浮动的方案,这里我们再介绍一种——第八种定位清浮动。
过程1:子级没有加浮动,一切OK
1. 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>定位请浮动</title> <style> .box1{border:30px solid #000;} .box2{width:300px;height:300px;background:green;} </style> </head> <body> <div class="box1"> <div class="box2"></div> </div> </body> </html> |
2. 效果
过程2:子级加了浮动,问题产生,父级包不住子级
1. 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>定位请浮动</title> <style> .box1{border:30px solid #000;} .box2{width:300px;height:300px;background:green;float:left;} </style> </head> <body> <div class="box1"> <div class="box2"></div> </div> </body> </html> |
2. 效果
过程3 :给父级加绝对定位,父级又包住了子级了
1. 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>定位请浮动</title> <style> .box1{border:30px solid #000;position:absolute;} .box2{width:300px;height:300px;background:green;float:left;} </style> </head> <body> <div class="box1"> <div class="box2"></div> </div> </body> </html> |
2. 效果
总结
1. 绝对定位和固定定位可以清浮动,相对定位不可以。
2. 我们开发中不会特意给父级添加绝对或固定定位来清浮动。通常是这样的,比如一个元素是绝对或固定定位元素,它的子元素是浮动的,我们就不需要再给它清浮动了,因为绝对或固定定位元素本身就有清浮动特性,知道这个可以省掉不必要的代码。