定位和布局
- 布局是屏幕平面上的
- 定位是垂直于屏幕的
相关盒模型
盒模型
背景范围
- 背景的范围是从哪里到哪里?
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----将元素的显示设为无,即在网页中==不占任何的位置==。