CSS Position定位属性全面讲解

前言

CSS position属性用于指定一个元素在文档中的定位方式。top、right、bottom、left 属性(值可为CSS数值单位,正负决定其方向)则决定了该元素的最终位置。

1. static定位

position属性的默认值,指定元素使用正常的布局行为,即元素在文档常规流中当前的布局位置。此时 top、right、bottom、left 属性无效。与普通元素一样,其包含块为父元素的content-box

2. relative相对定位

基于元素原本的位置进行定位移动。此时 top、right、bottom、left 属性均基于原本的位置进行移动尺寸的计算。
特点:

  • relative定位时未设置top/bottom/left/right时,位置无变化
  • relative定位的包含块为父元素的的content-box
  • relative定位后,原位置依然占用布局空间,所以不脱离标准文档流
  • relative定位后的元素位置不影响周围其他元素的布局
  • relative定位top和bottom属性同时存在时,只有top生效;left和right属性同时存在时,只有left生效

3. absolute绝对定位

通过指定元素相对于最近的非 static 定位祖先元素的偏移,来确定元素位置。

特点:

  • absolute定位未设置top/bottom/left/right时,位置无变化
  • absolute定位的包含块为最近的position不为static的祖先元素的padding-box,若没有符合条件的祖先元素,则为根元素html标签。
  • absolute定位后,原位置不占用布局空间,所以脱离标准文档流
  • absolute定位的元素可以设置外边距(margin),且不会与其他边距合并。
  • absolute定位元素的宽度由自身内容决定,且不会超过其包含块的宽度
  • absolute定位与float同时使用时,float无效

3.1 “无依赖”的绝对定位

如果一个绝对定位元素,其没有设置任何top/bottom/left/right属性,且其祖先元素全都没有设置定位(其实有定位也无妨),那么它的位置依然还是定位前的位置。

概括起来就是:“无依赖”的绝对定位本质就是脱离文档流的相对定位

absolute是独立的CSS属性值,必须改掉“ 只要有absolute定位,其必有祖先元素relative定位,top,left必有属性值或者必须有z-index ”的错误观点!!

举例:将icon图标显示到内容content的左上角

  <div class="content">
      <div class="icon"></div>
   </div>

通常来说,很多人是这么实现的:

 .content{
     position: relative;
    }
 .icon{
     position: absolute;
     left:0;
     top:0
 }

而实际只需要一行代码即可:

 .icon{
     position: absolute;
 }

无依赖绝对定位的其他应用场景举例:

(1)input表单输入框尾部添加提示信息(用无依赖绝对定位好处是提示信息不占用空间):

在这里插入图片描述

<input type="text" name="name"> <span class="message">请输入姓名</span>
 .message{
        position: absolute;
        color:red;
        margin-left: 10px;
    }

2)模拟input输入框的placeholder效果(兼容ie9以下不支持placeholder属性的情况):

在这里插入图片描述

<label class="placeholder" for="name">请输入姓名</label>
<input type="text" id="name">
.placeholder{
    position: absolute;
     color:#cccccc;
     /*margin来调整位置*/
     margin-left: 5px;
   }

3)下拉列表定位:

在这里插入图片描述

<input placeholder="搜索" type="search" id="name">
<ul class="datalist show">
    <li>张三</li>
    <li>李四</li>
    <li>王五</li>
</ul>
    ul.datalist{
        position: absolute;
        
        /*下拉列表其他样式*/
        color: #bbbbbb;
        list-style: none;
        margin: 0;
        padding: 0;
        width: 200px;
        border-style: solid ;
        border-color: #cccccc;
        border-width: 0 1px 1px 1px;
    }
    /*下拉列表显隐切换*/
    .datalist.show{
        display: block;
    }
    .datalist.hide{
        display: none;
    }
    input{
        width: 200px;
    }

建议:在只需满足布局效果的情况下,只用absolute的无依赖定位能解决的问题就能尽量不要同时再用relative定位,这样避免了relative和absloute元素的耦合度,降低了代码维护成本

3.2 absulute与overflow

当设置了overflow属性的元素其包含absolute定位的后代元素时,只有当absolute元素的包含块(即postiton为非static的祖先元素)也是overflow元素的后代元素或就是overflow元素本身时,overflow属性才会有效,否则不会生效。

  	.relative{
        position: relative;
    }
    .absolute{
        position: absolute;

    }
    .overflow{
        overflow: hidden;
        width: 100px;
        height: 50px;
    }
<div class="relative">
    <div class="overflow">
        <!-- absolute元素溢出不会被隐藏-->
        <div class="absolute">豆腐干豆腐干豆腐干地方微软微软为</div>
    </div>
</div>


<div class="overflow">
    <div class="relative">
        <!-- absolute元素溢出会被隐藏-->
        <div class="absolute">豆腐干豆腐干豆腐干地方微软微软为</div>
    </div>
</div>

<div class="overflow absolute">
        <!-- absolute元素溢出会被裁剪-->
        <div class="absolute">豆腐干豆腐干豆腐干地方微软微软为</div>
</div>

注意事项:

overflow元素自身同时设置过transform属性时,overflow属性是否生效在各种浏览器中可能存在一定差异

3.3 absoulte的流体特性

当absolute定位的元素同时定义了对立方向的定位尺寸时(如同时设置了left和right,同时设置了bottom和top),那么该元素的宽度或者高度自适应于该元素的包含块的padding-box的宽度和高度,具体宽度和高度由具体的left/top/bottom/right值来确定

示例:
在这里插入图片描述

<div class="relative">
    <div class="absolute"></div>
</div>
  .relative{
      position: relative;
      width:200px;
      height:200px;
      background-color: red;
    }
  .absolute{
      position: absolute;
      left:10px;
      right:10px;
      top:20px;
      bottom: 20px;
      background-color: blue;


  }

此例子中,relative父元素变大变小,absulute子元素也会自适应变化,并且各边界距离relative父元素的各边界距离为其设置的四种属性值尺寸。当四种尺寸都为0时,则完全覆盖其包含块的padding-box范围。

absolutel流体特性非常经典的应用就是和margin:auto属性搭配使用实现元素相对于包含块的垂直水平居中效果

在这里插入图片描述

.relative{
     position: relative;
     width:100px;
     height:100px;
     background-color: red;
    }
 .absolute{
     position: absolute;
     background-color: blue;
     width: 20px;
     height: 20px;
     left:0;
     right:0;
     top:0;
     bottom: 0;
    margin:auto

 }

绝对定位注意事项:

如果绝对定位的祖先元素 存在使用了transform属性的元素,则其会优先成为该绝对定位元素的包含块

4. fixed固定定位

基于页面根元素html标签的位置进行定位移动。此时 top、right、bottom、left 属性均基于HTML文档(即页面窗体)进行移动尺寸的计算。

特点:

  • fixed定位时未设置top/bottom/left/right时,位置无变化
  • fixed定位的包含块为根元素html标签
  • fixed定位后,原位置不占用布局空间,所以脱离标准文档流
  • 与absolute的“无依赖”定位效果原理类似,fixed定位同样有此特性,只不过包含块改变了

fixed定位相对简单粗暴,一些经典应用场景为页面右下角的回到顶部按钮,页面的各种固定位置的图标按钮或广告,页面上居中的蒙层弹窗等

经典应用——蒙层弹窗:
蒙层弹窗是网页中常见的交互,其中黑色半透明全屏覆盖的蒙层基本上都是使用 position: fixed 定位实现的。如下图所示:
在这里插入图片描述
实现这种效果并不难,但是这种蒙层弹窗一般存在一个细节体验问题:

如果原始页面存在滚动条,蒙层弹出后,鼠标滚动的时候蒙层后面的原始页面内容依然可以被滚动(即滚动穿透),且滚动时现蒙层无法覆盖浏览器右侧的原始页面滚动条

解决方法:

如果是移动端项目,阻止 touchmove 事件的默认行为可以防止滚动;

如果是桌面端项目,可以让根元素直接 overflow:hidden。但是,Windows 操作系统下的浏览器的滚动条都是占据一定宽度的,滚动条的消失必然会导致页面的可用宽度变化,页面会产生体验更糟糕的晃动。此时可以通过使用同等宽度的透明边框border来代替消失的滚动条。以下为代码示例:

蒙层显示的同时执行下面的 JavaScript 代码:

 let widthBar = 17;
 const root = document.documentElement;
 if (typeof window.innerWidth == 'number') {
     //获取滚动条的宽度
     widthBar = window.innerWidth - root.clientWidth;
 }
 //禁止原始页面滚动
 root.style.overflow = 'hidden';
 //html根元素右边框代替消失的滚动条
 root.style.borderRight = widthBar + 'px solid transparent';

蒙层隐藏的时候执行下面的 JavaScript 代码:

 const  root = document.documentElement;
 root.style.overflow = '';
 root.style.borderRight = '';

fixed定位注意事项:

由于设置了transfom属性的元素的特有渲染特性,会导致设置了fixed定位的子元素其fixed定位失效,而变成了基于transfom元素的绝对定位现象。此时的现象可视为transform元素拥有了position:relative属性,而原fixed定位的元素设置了position:absolute属性

5. sticky粘性定位

粘性定位的元素是依赖于用户的滚动

元素先根据正常文档流进行定位(即原本应该在正常文档流的位置),然后相对它的最近滚动祖先(nearest scrolling ancestor)和 containing block (最近块级祖先 nearest block-level ancestor),包括table-related元素,基于top, right, bottom, 和 left的值进行偏移。偏移值不会影响任何其他元素的位置。

该值总是创建一个新的层叠上下文(stacking context)。注意,一个sticky元素会“固定”在离它最近的一个拥有“滚动机制”的祖先上(当该祖先的overflow 是 hidden, scroll, auto, 或 overlay时),即便这个祖先不是最近的真实可滚动祖先。

文章参考资料:张鑫旭《CSS世界》

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值