定位和布局
- 布局是屏幕平面上的
- 定位是垂直于屏幕的
相关盒模型
盒模型
背景范围
- 背景的范围是从哪里到哪里?
A.border的内边缘围成的区域
B.border的外边缘围成的区域
正确答案:B。验证方法,把border调整成半透明。 2. 从左边看一个div是什么样子?
- 文字在border上面,border在background上面;
- 文字 > border > background
- 一个div的分层
演示
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JS Bin</title> </head> <body> <div class="demo"> 文字内容 <div class="float"> 浮动文字 </div> <div class="childDiv"> div里面的文字 </div> </div> </body> </html> .demo{ background: rgb(120, 184, 211); width: 200px; height: 200px; border: 15px solid rgba(255,0,0,1); padding: 10px; } .childDiv{ background:#fff; height:50px; color:red; margin-top:-10px;/* 说明文字压住了div */ } .float{ float: left; background: green; height: 50px; width: 50px; color: blue; margin-right:-10px /* 文字比float高 */ /* 文字高于浮动文字 */ /* float的div高于正常div */ }复制代码
position
position
- 默认是static,待在文档流里
- relative相对定位,升起来,但是不脱离文档流
- absolute绝对定位,定位基准是祖先里的非static
- fixed固定定位,定位基准是viewpoint(问题较多)
- sticky粘滞定位
- 经验
- 如果写了absolute,一般配合一个relative
- 如果写了absolute或fixed,一定要补top和left
- sticky兼容性差,主要用于面试
static
- 默认值
- 此时,top,bottom, left, right 无效
relative
- 使用场景:
- 用作位移(用的少)
- 用于给absolute做父亲
- 相对于默认位置(static)进行位移
- 必须搭配top,bottom,left,right ,指定偏移方向和距离
- 配合z-index
- z-index:auto默认值,不会创建新的层叠上下文。
- z-index:0/1/2
- z-index:-1/-2
- 经验
- 写z-index:9999的都是小傻子
- 学会管理z-index
- 代码
<head> <style type="text/css"> .box { background: red; width: 100px; height: 100px; float: left; margin: 5px; } .two { position: relative; top: 50px; left: 50px; } </style> </head> <body> <div class="box" >One</div> <div class="box two" >Two</div> <div class="box" >Three</div> <div class="box">Four</div> </body>复制代码
将class="two"的div定位到距离它本来位置的顶部和左侧分别50px的位置。不会改变其他元素的布局,会在此元素本来位置留下空白。
absolute
- 使用场景
- 脱离原来的位置,另起一层
- 比如对话框的关闭按钮,鼠标提示
- absolute相对于祖先元素中,最近的一个定位元素定位的(position不是static,就是定位元素)
- 如果所有的祖先元素都没有以上三种定位中的其中一种定位,那么它就会相对于文档body来定位(并非相对于浏览器窗口,相对于窗口定位的是fixed)。
- 注意,absolute定位的元素会被"正常页面流"忽略,即在"正常页面流"中,该元素所占空间为零,周边元素不受影响。
- 配合z-index
- 经验
- 某些浏览器不写top/left会位置错乱
- 善用left:100%
- 善用left:50%; 加负margin
4.代码演示
- absolute
<head> <style type="text/css"> .box { background: red; width: 100px; height: 100px; float: left; margin: 5px; } .two { position: absolute; top: 50px; left: 50px; } </style> </head> <body> <div class="box" >One</div> <div class="box two" >Two</div> <div class="box" >Three</div> <div class="box">Four</div> </body>复制代码
将class="two"的div定位到距离的顶部和左侧分别50px的位置。会改变其他元素的布局,不会在此元素本来位置留下空白。
- relative+absolute
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JS Bin</title> </head> <body> <div class="container"> <div class="demo"></div> <div class="demo2"></div> <div style="height:100px;"></div> <div class="close">X</div> <button>点击 <span class=tips>提示</span> </butto> </div> </body> </html> .container{ border:1px solid red; height:300px; position:relative; } .demo{ border: 1px solid red; width:50px; height:50px; position:relative; top:10px; left:10px; z-index:1; /* 压住下面的 */ } .demo2{ background:black; width:50px; height:50px; position:relative; } .close{ border: 1px solid black; position:absolute; /* 父亲relative 子absolute,子相对于父元素top right left bottom */ top:0; right:0; } button{ position:relative; } button > span { position: absolute; border: 1px solid black; white-space:nowrap; /* 文字内容不换行 */ bottom:calc(100% + 10px); left:50%; transform: translateX(-50%); } button span{ display:none;/* 隐藏 */ } button:hover span{ display:inline-block; }复制代码
鼠标移动到点击按钮之后,出现悬浮框:
fixed
- 使用场景
- 烦人的广告
- 回到顶部按钮
- 相对于视口(viewpoint),定位几点是浏览器窗口。这会导致元素的位置不随页面滚动而变化,好像固定在网页上一样。
- 配合z-index
- 经验
- 手机上尽量不要用这个属性,有坑
- 如果container里有一些特殊的属性,就不是相对饰扣定位
sticky
sticky生效的前提是,必须搭配top、bottom、left、right这四个属性一起使用,不能省略,否则等同于relative定位,不产生"动态固定"的效果。原因是这四个属性用来定义"偏移距离",浏览器把它当作sticky的生效门槛。
它的具体规则是,当页面滚动,父元素开始脱离视口时(即部分不可见),只要与sticky元素的距离达到生效门槛,relative定位自动切换为fixed定位;等到父元素完全脱离视口时(即完全不可见),fixed定位自动切换回relative定位。
请看下面的示例代码。(注意,除了已被淘汰的 IE 以外,其他浏览器目前都支持sticky。但是,Safari 浏览器需要加上浏览器前缀-webkit-。
#toolbar { position: -webkit-sticky; /* safari 浏览器 */ position: sticky; /* 其他浏览器 */ top: 20px; }复制代码
上面代码中,页面向下滚动时,#toolbar的父元素开始脱离视口,一旦视口的顶部与#toolbar的距离小于20px(门槛值),#toolbar就自动变为fixed定位,保持与视口顶部20px的距离。页面继续向下滚动,父元素彻底离开视口(即整个父元素完全不可见),#toolbar恢复成relative定位。
- 应用:
- 导航
- 固定表头
对比
绝对定位vs相对定位
绝对定位好像把不同元素安排到了一栋楼的不同楼层(除首层,文本流放在首层),它们之间互不影响;相对定位元素在首层,与文本流一起存放,它们之间互相影响。
被设置了绝对定位的元素,在文档流中是不占据空间的,如果某元素设置了绝对定位,那么它在文档流中的位置会被删除,它浮了起来,其实设置了相对定位也会让元素浮起来,但它们的不同点在于,相对定位不会删除它本身在文档流中占据的空间,其他元素不可以占据该空间,而绝对定位则会删除掉该元素在文档流中的位置,使其完全从文档流中抽了出来,其他元素可以占据其空间,可以通过z-index来设置它们的堆叠顺序 。
层叠上下文
问题
z-index:10和z-index:5哪个高?
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>哪个高</title> </head> <body> <div class="container"> <div class="a">1层叠上下文 <div class="a2">10</div> </div> <div class="b"> <div class="b2">5</div> </div> </div> </body> </html> *{ margin:0; padding:0; box-sizing:border-box; } .container{ border:1px solid green; height:200px; position:relative } .a{ position:relative; border:1px solid red; z-index:1;/* 相同范围内可以比较 */ /* 加了a之后,10和5就不能比较了。用1和5比较 */ } .a2{ position:relative; height:50px; width:50px; background:red; z-index:10;/* 正常10>5 */ } .b2{ position:relative; height:50px; width:50px; background:blue; top:-20px; z-index:5;/* 正常10>5 */ }复制代码
答:无法比较
- 层叠上下文
- 比喻:每个层叠上下文就是一个新的小世界(作用域)。这个小世界里的z-index和外部无关。处在同一个小世界的z-index才能比较。
- 哪些可以建立层叠上下文
developer.mozilla.org/zh-CN/docs/…文档中的层叠上下文由满足以下任意一个条件的元素形成:
- 文档根元素;
- position 值为 absolute(绝对定位)或 relative(相对定位)且 z-index 值不为 auto 的元素;
- position 值为 fixed(固定定位)或 sticky(粘滞定位)的元素(沾滞定位适配所有移动设备上的浏览器,但老的桌面浏览器不支持);
- flex (flexbox) 容器的子元素,且 z-index 值不为 auto;
- grid (grid) 容器的子元素,且 z-index 值不为 auto;
- opacity 属性值小于 1 的元素(参见 the specification for opacity);
- mix-blend-mode 属性值不为 normal 的元素;
- 以下任意属性值不为 none 的元素:
transform filter perspective clip-path mask / mask-image / mask-border
- isolation 属性值为 isolate 的元素;
- -webkit-overflow-scrolling 属性值为 touch 的元素;
- will-change 值设定了任一属性而该属性在 non-initial 值时会创建层叠上下文的元素(参考这篇文章);
- contain 属性值为 layout、paint 或包含它们其中之一的合成值(比如 * * contain: strict、contain: content)的元素。
- ==要记住的是:z-index/flex/opacity/transform==*
- 负z-index与层叠上下文
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JS Bin</title> </head> <body> <div class="demo"> <div class="div2"></div> </div> </body> </html>复制代码
.demo{ background: rgba(0,255,255,0.5); width: 200px; height: 200px; padding: 10px; position: relative; z-index: 0; /*注释这行看看*/ 注释之后,红色下去了。因为position:relative且z-index:auto.不会有层叠上下文。不注释的话,有层叠上下文,z-index无效。块级子元素会在background上 } .demo > div:first-child{ height: 50px; background: #000; background: red; position: relative; z-index: -1; }复制代码
练习
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JS Bin</title> </head> <body> <div class="container"> 文字 <div class="relative"> </div> <div class="relative2"> </div> </div> </body> </html> *{ margin:0; padding:0; box-sizing:border-box; } .container{ border:1px solid black; height:200px; background:yellow; } .relative{ border:1px solid red; height:50px; background:red; position:relative; top:-10px;/* 只要不是默认定位,定位元素会跑到所有元素上面 */ z-index:1; } .relative2{ border:1px solid red; height:50px; background:green; position:relative; top:-30px;/* 只要不是默认定位,定位元素会跑到所有元素上面 */ z-index:0; }复制代码
补充
- opacity和background:rgba的a的区别
- opacity:不止包括背景色,还影响里面的其他元素
- rgba:只影响背景色
- display:none
display:none和visible:hidden都能把网页上某个元素隐藏起来。但两者有区别:
display:none ---不为被隐藏的对象保留其物理空间,即该对象在页面上彻底消失,通俗来说就是看不见也摸不到。
visible:hidden--- 使对象在网页上不可见,但该对象在网页上所占的空间没有改变,通俗来说就是看不见但摸得到。
visibility: hidden----将元素隐藏,但是在网页中该占的==位置还是占着==
display: none----将元素的显示设为无,即在网页中==不占任何的位置==。