定位(确定元素的位置)
相对定位(position:relative)
我们以前学过几种布局方式
浮动 从左往右依次排列
正常布局 从上往下依次排
display:inline-block 看上去水平排列,本质上还是文本,有解析空格和垂直对齐的问题
这些能解决掉布局的很多问题,但是对于某些特殊情况
ul{
border: 2px solid pink;
}
li{
width: 100px;
height: 100px;
background-color: skyblue;
margin: 10px;
}
<ul>
<li>1</li>
<li>2</li>
<li>大哥</li>
<li>4</li>
<li>5</li>
</ul>
li{ float: left; }
ol{ overflow:hidden;}
/*现在如果我想让第三个盒子大哥上去一点或者下去一点,这个就属于页面的微调*/
relative开发中的作用
对元素进行微调
定位就是确立元素的位置,我现在问一个问题,你们的显示器和手机在哪里?
其实你们回答问题,都有定位这个概念.
如果我知道你们的手机在口袋里,我就只要知道你口袋在哪里就可以了.
我知道你们电脑在桌子上,我就只要知道你们的桌子在哪里就可以了.
这里确立东西的位置必须有在…地方,在我们前端有个专业术语叫参照物.
参照物:世间万物都可以作为参照物,这里我们的参照物必须是页面中的一个元素.
1.参照物(灯塔):用来确定物体位置的基点
2.根据参照物,描述位置偏移量
现在我们这个大哥盒子在这里,我要让他参照谁去进行移动.
我们去描述参照物的时候有个特殊的参照物叫参照自己当前的位置去进行移动.
假如说我现在让你往前走400米远,往左走200米去买杯咖啡.
你就是参照自己当前位置,去确立自己最终的位置
li.move{
position: relative;
/*这就是相对定位,参照自己去进行定位.此时大哥盒子变成了一个可以移动的盒子.
我们打开游览器,发现这时候盒子没有移动,为什么呢?
这时候相当于手刹放下来了,档挂好,就准备踩油门了.
此时这个盒子只是准备移动了,变成了可以移动的盒子,我们还要告诉它往哪里去移动.
这时候就要跟大家讲一个前端平面直角坐标系的概念*/
}
<li class="move">大哥</li>
前端平面直角坐标系
左上为顶点 水平向右x+ 竖直向下Y+ 左上顶点
我们这里用left,top去表示
li.move{
position: relative;
top:10px;
/*此时向下移动了10px,这怎么理解*/
}
top:10px;表示从上往下平移10px,距离原来位置的上边10px;
如果此时我想让它朝右边去移动我们写上面?
li.move{
position: relative;
left:20px;
}
left:20px;表示左往右平移20px;距离原来位置右边20px;
现在我想让盒子往上移动去贴着大盒子怎么办
li.move{
position: relative;
top: -10px;
/*本来top正值表示距离上边多少像素去平移.
现在top负值就表示距离下边多少像素去平移,也就是从上往下去平移负数像素.等于往上去移动
所以left和top的值可正可负,负数就为相反方向.
如果我们这里写了一个top值,再写一个top值会不会叠加呢?*/
}
li.move{
position: relative;
top: -10px;
top: 10px;
/*样式会相互覆盖.
我们这写top负值感觉很难去计算呢?还有没有别的值呢?
我们可以去写bootom正值.*/
}
li.move{
position: relative;
bottom:10px;
/*表示距离下边10px,这时候如果我们同时写上下呢?*/
}
方向的优先级
li.move{
position: relative;
bottom:10px;
top: 10px;
/*这时候向下去平移了10px,这会不会是覆盖问题呢?
我们换个方向去看看?结果都一样
如果我们同时写左右呢?*/
}
li.move{
position: relative;
left:20px;
right: 20px;
/*此时也依然只向右去进行平移了,left和right同时书写时左边为尊
top和right同时书写上边为尊*/
}
如果多个偏移量,以左上为尊,我们的读写的顺序也是这样.
我们现在继续研究一个比较有意思的东西,如果我向下平移300px呢?
li.move{
position: relative;
top: 300px;
/*此时盒子看不到了?这是为什么?
因为我们之前为了解决高度塌陷为父元素设置了overflow:hidden;
所以我们得换个方式去清除浮动*/
}
.clearfix:after{
content: "";
display: block;
clear: both;
}
<ul class="clearfix"><ul>
/*此时我们再来看我们的大哥盒子.
这个盒子移动到下面去了,为什么这个第2个盒子和第4个盒子中间没盒子还有这么多空白.
这里就相当于灵魂出窍,这个盒子还保留着原来的位置,大哥就是大哥.*/
相对移动的时候,本质上,其余元素都不会发现这个盒子移动了,只是这个盒子表现在页面的位置发生了改变.
我们可以看到他的灵魂跑到下面去了,但是他的肉体还在原来的地方.
换句话说,相对定位不会影响其他元素布局
我们去把li做下调整
li{
float: left;
display: inline;
/*为什么没有变成文本元素呢?
因为float:left会强制转换为块元素,我们把float注释.
我们可以看到我们选中上面一块内容的时候下面的大哥盒子也被选中了
这里我们相当于能摸到他的肉体骨架.
我们再去把display:inline注释,float解锁,顺便给大哥盒子变个颜色*/
}
li{
float: left;
width: 100px;
height: 100px;
background-color: skyblue;
margin: 10px;
}
.green{
background-color: green;
}
li.move{
margin: 0 -40px;
}
<li class="move green">大哥</li>
/*这时候正常情况下盒子是不是后写的覆盖先写的盒子.
如果我们使用相对定位去移动盒子呢?*/
li.move{
position: relative;
left: 40px;
}
/*这时候大哥盒子定位过去了,就把我们的浮动盒子给盖住了.
虽然不会影响布局,但是相对定位盒子层级提高.*/
相对定位层级提高,定位的层级高于浮动的层级
我们再去看看文本元素
li{ dispay:inline;}
li.move{
position: relative;
left: 30px;
}
/*定位盒子依旧盖住了文本inline元素
所以定位层级是比文本层级还要高*/
浮动 === 文本 ====>定位 相当于定位是一个最高的层级
绝对定位(position:absolute)
前面叫你去买杯咖啡,你得需要知道自己的位置在哪.
现在我要去见我的好朋友,假如我的好朋友在巴黎.
他总不可能告诉我,小云同学你先下楼打个车向前多少米向右多少米.
他可是在巴黎.所以这时候你就不能相对于自己的位置去移动.
因为你的位置和目标位置可能八竿子打不着.
众所周知巴黎城市有个埃菲尔铁塔,无论你在哪都能看到这个最高建筑.
他就可以说他在埃菲尔铁塔左边100米,右边200米.
我们下了飞机就可以先找到这个埃菲尔铁塔,然后根据它去进行移动从而找到我的朋友.
或者像古时候渔民出海打渔的时候,傍晚归来的时候要根据灯塔来找寻回家的方向.
所以我们要给出绝对的位置来安放物体,
绝对定位的位置参照物坐标:标志性建筑物
请先去参照物的位置,然后从这个位置出发,找到目标位置.
我们所有的元素只要找到这个标准性的参照物,然后根据这个参照物去进行移动就行了.
和你自身为参照物完全不同,我们只需找到一个绝对不变的参照物就行.
我们去修改一下代码.
ul{
width: 600px;
height: 600px;
margin: 100px auto 0;
border: 2px solid pink;
}
li.box{
width: 100px;
height: 100px;
background-color: pink;
}
li.move{
width: 100px;
height: 100px;
background-color: skyblue;
}
<ul>
<li class="small">小弟</li>
<li class="move">大哥</li>
</ul>
现在我想让我们的大哥盒子移动到距离这个大盒子向右100px,向下100px怎么办?
谁是参照物,是不是这个最大的盒子是我们的参照物,是不是先让我们的大盒子成为参照物.
ul{ position: relative;}
/*成为参照物,不会对外布局发生影响.
接下来我们去给大哥盒子加上绝对定位.*/
li.move{ position: absolute;}
/*这时候参照我们的大盒子进行移动,原来的位置就不不需要存在在那里.
只需在我们参照起点就可以了,从原来的层级其实已经飘起来了.
就像我们在埃菲尔铁塔一样.这里相当于给目标元素一个起始位置,此时我们就可以设置偏移量了*/
li{
position: absolute;
top: 100px;
left: 100px;
}
/*此时这个li盒子依据大盒子左上顶点去进行位置偏移*/
绝对定位的写法特点
父相子绝,
父亲设置相对定位,子元素设置绝对定位相对于父亲去移动自身的位置.
绝对定位的参照物特点
**有定位属性的最近的祖先(父级/父级的父级/父级的父级的父级)元素,**参照物必须包含目标元素
有定位属性就代表position:relative/position(有这其中一个,才能被子元素所参照)
就近法则,如果所有父级元素都没有定位属性,就会参照游览器)
到外面会找到body ===> html ==> 游览器视口
这时候如果我们有定位属性的父级是谁?是不是我们的ul.这时候如果把ul这个定位注释的话
ul{/* position: relative;*/ }
/*这时候就根据游览器视口的左上角进行*/
这时候我们去改改大哥这个盒子的偏移
ul{
position: relative;
}
li.move{
position: absolute;
top: 0;/*此时是不是在最上方*/
left: 0;
/*此时是不是在最左边
如果我们想让这个盒子贴着右边呢?或者贴着下面呢?*/
}
li.move{
position: absolute;
right: 0;
bottom: 0;
top: 0;
left: 0;/*同时都写就左上为尊*/
}
我们这里还可以去写百分比
li.move{
position: absolute;
left: 0%;
}
/*盒子的左上角.
那我们去写100%在哪呢?*/
li.move{
position: absolute;
left: 100%;
/*这移动的距离为盒子的宽高*/
}
偏移量相对于参照物的高度和宽度进行计算(包含padding不包含border)来进行计算的
包含border边框吗?
ul{ border: 40px solid pink; }/*不包含*/
包含padding内边距吗?
ul{padding: 50px;}
li.move{
position:absolute;
left:0;
top:0;
}
/*包含内边距,这里会出现在左上角这里有个知识
如果我们加了绝对定位不给值*/
li.move{position: absolute;}
/*会出现在内容区的起始点.*/
只写position:absolute;他会出现在内容区第一个盒子所在的位置,
如果加上偏移量就以padding-box来计算位置.
**绝对定位会脱离文档流 **,我们去盒子后面写上一段文字
<ul>
<li>大哥</li>
我要忘了你的样子
</ul>
li{ position:absolute}
/*此时文字就到这个盒子的下面去了,盒子已经完全脱离文档了.飘起来了.
我们浮动脱离文档流文字至少还能感受到.*/
**同级绝对定位盒子叠加,后写的在上面,绝对元素不保留位置 **
.bro1{
width: 200px;
height: 200px;
background-color: skyblue;
}
.bro2{
width: 300px;
height: 200px;
background-color: lightgreen;
}
.bro3{
width: 400px;
height:200px;
background-color: pink;
}
/*依次给这三个盒子添加绝对定位position:absolute.
可以看到的是添加了绝对定位的盒子会原地向上去飘.
在后面的块级元素或行内元素都感受不到他的存在了.
当我们给.bro2和.bro3添加绝对定位的时候,可以发现越后面绝对定位的元素.反而会在最上面*/
<ul>
<li class="bro1">大哥</li>
<li class="bro2">小弟1</li>
<li class="bro3">小弟2</li>
</ul>
块级化:将元素强行转化为块级元素,它具有块元素的所有性质,但是不具有父元素宽度100%的特性,而是由里面的元素撑开的,这是定位的包裹性;
浮动也具有包裹性
但是相对定位不具有包裹性和块状性,
li{
display: inline;
}
/*此时无法将li转换为行内元素*/
.bro1{
position: absolute;
width: 200px;
height: 200px;
background-color: skyblue;
}
.bro2{
position: absolute;
width: 300px;
height: 200px;
background-color: lightgreen;
}
.bro3{
position: absolute;
width: 400px;
height:200px;
background-color: pink;
}
<ul>
<li class="bro1">大哥</li>
<li class="bro2">小弟1</li>
<li class="bro3">小弟2</li>
</ul>
3.绝对定位会让浮动失效
li{ float:left;}
/*此时给这个li浮动,如果这个li设置了绝对定位,这个浮动就没用.*/
静态定位(static)
static,无特殊定位,它是html元素默认的定位方式.
即我们不设定元素的position属性时默认的position值就是static,它遵循正常的文档流对象.
该定位方式下,top,right,bottom,left,z-index等属性是无效的。
固定定位(position:fixed)
我们又叫它牛皮糖,扫地阿姨搞半天都刮不下来,无论怎么搞它就在那里.
我们网页上也有这样的牛皮糖.就好像粘在你的屏幕上一样.怎么动它就在那里.
这与绝对定位的工作方式完全相同,只有一个主要区别:
绝对定位的固定元素是相对于HTML元素或其最近的定位祖先.
而固定定位的固定元素则是相对于浏览器视口本身。
body{
height: 2000px;
}
span{
position: fixed;
right: 0;
bottom: 0;
width: 100px;
height: 100px;
background-color: skyblue;
}
<span>是兄弟就来砍我</span>
/*固定定位参照绝对定位理解,同样有块状化,脱离文档流等等特点.
就是除了参照物的不同其他几乎相同.*/
七层层叠结构
背景
最底层的东西,背景就好像你给墙涂上油漆贴上墙纸,最后去挂画的时候,你见过把画挂在墙纸里面的吗?
==> 块级元素(block)层级 ==> float浮动层 == 文本(inline/inline-block)层级 ==> position定位层级
定位层级就如何一个图钉去钉在某些元素上面一样.
这里只有5层层叠结构,这里position层级因为有z-index的参与而变得不同,
同样是定位层级,后写的元素同样会盖住先写的元素,
如果我们想修改元素的覆盖关系的时候,我们需要去修改HTML结构.
但是如果有一叠钞票,一张叠着一张的,我们这时想要放在下面的第二张钞票的时候,第二张钞票就凸显出来.怎么办呢?
那就必须比第一张高,怎么比第一张高.
我们就需要动态的去调整层级关系.Z-index控制定位元素谁高谁低的操作.
z-index
属性值并不是在任何元素上都有效果。它仅在定位元素(定义了
position
属性,且属性值为非static
值的元素)上有效果。判断元素在
Z轴
上的堆叠顺序,不仅仅是直接比较两个元素的z-index
值的大小,这个堆叠顺序实际由元素的层叠上下文、层叠等级共同决定。z-index默认为0(auto),
可以大于等于0的整数 数值越大越层级越高,只在定位元素内生效
也是可以写小于0的负整数,层级是最低的.
ul{
width: 600px;
height: 600px;
margin: 100px auto 0;
border: 2px solid pink;
}
.bro1{
height: 200px;
background-color: skyblue;
}
.bro2{
margin-top:-100px;
height: 200px;
background-color: lightgreen;
}
.bro3{
margin-top:-100px;
height:200px;
background-color: pink;
}
<ul>
<li class="bro1">1</li>
<li class="bro2">2</li>
<li class="bro3">3</li>
</ul>
/*此时2的一部分在1的下面,3的一部分在2的下面.像不像叠着的钞票?
如果我们想让我们鼠标悬浮在哪个元素哪个元素就露出来*/
li:hover{position:relative;}
/*鼠标放上去的时候元素层级变高了
但是如果这些元素全部都写上了position:relative呢?*/
li{position:relative;}
/*就不能控制元素显示的高低了.
我们就可以去使用z-index*/
li:hover{z-index: 1;}
/*当鼠标悬浮在上面的时候.层级就发生改变
此时我们写上z-index为0,元素显示不会发生改变,说明默认确实是0*/
假如我们z-index写上负数呢?
li:hover{z-index: -1;}
/*当我们鼠标放到元素上就会被其它元素盖住*/
或者你可以自己去修改元素的z-index
.bro2{
z-index:1;
}
/*此时这个类名为bro2的盒子就会盖在3的上面.因为其他元素默认的z-index为0.*/
如果我们手动去控制, 必须是同一父元素的定位子元素的层级
七层层级
z-idnex为负数==> 背景 ==> 块级元素(block)层级 ==> float浮动层 ==> 文本(inline/inline-block)层级 ==> z-index为0/auto ==> z-index为正
定位水平居中盒子的两种方法.
ul{
position: relative;
width: 600px;
height: 600px;
margin: 100px auto 0;
border: 2px solid pink;
}
li{
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;/*只设置绝对定位不给偏移量,左右两边的auto会暂时失效*/
width: 200px;
height: 200px;
background-color: pink;
}
/*position的方向值全部设置为0,说明小盒子完全能够分配大盒子的空间.
小盒子知道了大盒子上下左右的空间.
相当于四只手用弹簧拉它,拉力都是一样的.
会在小盒子比大盒子大失效,先margin在定位,定位最后执行*/
<ul>
<li></li>
</ul>
ul{
position: relative;
width: 600px;
height: 600px;
margin: 100px auto 0;
border: 2px solid pink;
}
li{
position: absolute;
top: 50%;
left: 50%;/*先将盒子的左上角推到大盒子的中心点*/
margin-top: -100px;/*最后平移margin的负值将元素正中心点对准盒子正中心点,实现上 下垂直居中*/
margin-left: -100px;
width: 200px;
height: 200px;
background-color: pink;
}
伪类
hover选择器左侧必须有选择器,右侧的选择器可以设置也可以不设置
当鼠标放在左侧选择器选中的元素的时候代码才会生效
hover右侧的选择器只能时选择兄弟元素或是子元素(包括兄弟元素的子元素)
hover右边选择器
中间什么都不加(空格) 控制后代元素;
>控制子代元素
‘+’控制就近元素 ;
‘~’ 控制同级元素(兄弟元素);
伪类单纯的只有左侧选择器表示自身发生改变
<div class="wrap"></div>
.wrap{
width: 200px;
height: 200px;
background-color: pink;
}
.wrap:hover{
background-color: green;
}
/*此时表示当我们触摸到这个类名为.wrap的div盒子的时候背景颜色由原来的粉色变成绿色*/
此时上面只有左边有选择器 我们还可以在:hover右边去添加选择器
<div class="wrap">
<div class="con1"></div>
</div>
.wrap{
width: 200px;
height: 200px;
background-color: pink;
}
.wrap >.con1{
width: 100px;
height: 100px;
background-color: blue;
}
.wrap:hover > .con1{
background-color: green;
}
/*此时这段代码的含义从左往右依次去读.
当我鼠标触摸到这个类名为wrap的元素的时候 让他下面子元素类名为con1的元素变绿
这右边写关系选择器 也可以写空格 表现后代元素
这后面的选择器也可以是 + ~ 表示的是选中下面的兄弟元素,例子如下.*/
<div class="bro1"></div>
<div class="bro2"></div>
.bro1{
width: 200px;
height: 200px;
background-color: pink;
}
.bro2{
width: 200px;
height: 200px;
background-color: green;
}
.bro1:hover ~.bro2{
background-color: blue;
}
/*这里表示的是当我们触摸到类名为.bro1的元素让后面的类名为bro2的兄弟元素变蓝*/
其实我们的作业显示样式的隐藏与切换,大致是这样的思路
<div class="wrap">
<div class="con1"></div>
</div>
.wrap{
position: relative;
width: 400px;
height: 400px;
background-color: pink;
}
.wrap >.con1{
display: none;
position: absolute;
top: 0;
left: 100%;
width: 300px;
height: 300px;
background-color: blue;
}
.wrap:hover > .con1{
display: block;
}
/*首先是两个父子元素.通过父相子绝的定位方式.将我们的子元素移动到父元素的左外侧
然后给子元素display:none让游览器不渲染展示.那什么时候展示呢?
当你鼠标移入类名为wrap的元素的时候,让下面的类名为con1的子元素display:block显示出来.