CSS学习笔记:定位

定位

利用定位,可以准确地定义元素框相对于其正常位置应该出现在哪里,或者相对于父元素、另一个元素甚至浏览器窗口本身的位置。

基本概念

定位的类型

/* 关键字值 */
position: static;
position: relative;
position: absolute;
position: fixed;
position: sticky;
  • static:元素框正常生成。块级元素生成一个矩形框,作为文档流的一部分,行内元素则会创建一个或多个行框,置于其父元素中。
  • relative:元素框相对于其原本的位置进行定位。元素仍保持其未定位前的形状,它原本所占的空间仍保留,也不会强制转换成块级框。
  • absolute:元素框从文档流中完全删除,相对于其包含块定位。元素定位后生成一个块级框,而不论它在正常流中生成何种类型的框。
  • fixed:元素框的表现类似于absolute,但是相对于视窗定位。
  • sticky:元素先按照普通文档流定位,然后相对于该元素在流中的 flow root(BFC)和 containing block(最近的块级祖先元素)定位。在所有情况下(即便被定位元素为 table 时),该元素定位均不对后续元素造成影响。当元素 B 被粘性定位时,后续元素的位置仍按照 B 未定位时的位置来确定。

包含块

之前讨论浮动的时候,对于浮动元素,其包含块定义为最近的块级祖先元素。但是对于定位则没有这么简单:

  • 初始包含块:一个视窗大小的矩形
  • 如果一个元素的position值是relative或static,包含块由最近的块级框、表单元格或行内块祖先框的内容边界构成。
  • 如果一个元素的position值是absolute,包含块设置为最近的position值不是static的祖先元素:
    • 如果这个祖先元素是块级元素,包含块就设置为该元素的内边距边界;也就是由边框界定的区域。
    • 如果这个元素是行内元素,包含块则设置为该祖先元素的内容边界
      在从左到右的语言中,包含块的上边界和左边界是第一个行框内容的上边界和左边界,包含块的下边界和右边界是最后一个框的下边界和右边界。
    • 如果没有祖先,元素的包含块定义为初始包含块

这里有一点很重要,元素可以定位到其包含块的外面。这与浮动元素使用负外边距浮动到其父元素内容区外面很类似。这也说明,包含块实际上应该是“定位上下文”。

偏移属性

以下四种定位机制:relative、absolute、fixed、sticky(除了static),使用了4个属性来描述定位元素各边相对于其包含块的偏移。我们将这4个属性成为偏移属性。

  • 应用于定位元素(非static)
  • 百分数

    • 对于top和bottom,相对于包含块的高度计算
    • 对于left和right,相对于包含块的宽度计算
  • 正值会导致向内偏移,使边界朝着包含块的中心移动

  • 负值会导致向外偏移,可以将一个元素定位到其包含块之外

除了长度和百分数,偏移属性还可以设置auto,这是默认值,auto的具体行为会根据所用的定位类型改变。

宽度和高度

设置宽度和高度

如果想为定位元素指定一个特定的宽度,显然要用width属性。类似地,利用height可以为定位元素声明特定的高度。

尽管有时设置一个元素的宽度和高度很重要,但对于定位元素来说则不一定必要:如果使用了那四个偏移属性,那么元素的高度和宽度将由这些偏移隐含确定。
假如你希望一个绝对定位元素从上到下填充其包含块的左半部分,可以使用以下值:

top:0; bottom:0; left:0; right:50%;

由于width和height的默认值都是auto,因此在这个例子中会根据偏移属性定义其宽度和高度。
这里写图片描述

限制宽度和高度

如果有必要,可以用最小最大属性来限制元素的宽度和高度:min-wdith、max-width、min-height、max-height

  • 应用于除了非替换行内元素和表元素以外的所有元素
  • 百分数:相对于包含块的宽度或高度计算
  • 属性的值不能为负

例子:

top:10%;
bottom:auto;
left:50%;
right:10%;
height:auto;
min-width:15em;

根据偏移属性,元素的宽度应该是包含块的40%,但是不能小于15em。

使用最大最小属性的一个好处是,可以相对安全地混合使用不同的单位,比如使用百分数大小的同时,再设置基于长度值的限制。

最小最大属性结合浮动元素使用时也会非常有用:比如可以允许一个浮动元素的宽度相对于其父元素的宽度,同时确保该浮动元素的宽度不小于某个值。

内容溢出和剪裁

如果一个元素内容相对于元素大小来说过大,就有可能溢出元素本身。

溢出

当内容在元素中放不下时,就可以利用overflow属性来控制这种情况。

/* 默认值。内容不会被修剪,会呈现在元素框之外 */
overflow: visible;

/* 内容会被修剪,并且其余内容不可见 */
overflow: hidden;

/* 内容会被修剪,浏览器会显示滚动条以便查看其余内容,打印机会打印溢出的内容*/
overflow: scroll;

/* 由浏览器定夺,如果内容被修剪,就会显示滚动条 */
overflow: auto;

内容剪裁

如果一个绝对定位元素的内容溢出其内容框,而且overflow设置为要求剪裁该内容,使用clip属性可以改变剪裁区域的形状。

clip: rect(1px, 10em, 3rem, 2ch)
clip: auto
  • 默认值auto表示元素的内容不应剪裁。
  • 可以相对于元素内容区定义一个剪裁形状,这不会改变内容区的形状,只会改变将显示内容的区域形状。

这是利用形状值 rect(< top>, < right>, < bottom>, < left>)实现的。
< top> 和 < bottom> 指定相对于盒子上边框边界 的偏移,< right> 和 < left> 指定了相对于盒子左边框边界 的偏移。
也就是说,不是边偏移,而是距元素左上角的距离

rect(0,20px,20px,0); //涵盖元素左上角20*20正方形的剪裁区域

rect(…)只允许长度值和auto。
但是可以设置负长度值,这会使剪裁区域延伸到元素框之外。但是尽管剪裁区向外延伸,但是延伸区内不会出现任何内容,因此也没有多大作用。
这里写图片描述

另一方面,完全可以超越下边界和右边界,这会扩展可以看到内容的区域。但是内容流并没有改变,唯一的视觉效果就是元素下面可以看到更多内容。

元素可见性

除了剪裁和溢出,还可以控制整个元素的可见性

visibility: visible | hidden | collapse 
  • visible:初始值,元素可见
  • hidden:元素不可见,但其位置还保留,元素还是会影响布局。
    这与display:none有区别,后者令元素不仅不显示,还会从文档中删除,所以对文档布局没有任何影响。
    有可能将一个hidden元素的后代元素置为visible。这会使该后代元素正常出现,尽管其祖先元素是不可见的。为此,必须显式声明后代元素为visible,因为visibility属性可以继承。
  • collapse:在表中显示使用,如果用于非表元素,collapse与hidden相同。

绝对定位

包含块和绝对定位元素

  • 元素绝对定位时,会从文档流中完全删除。然后相对于其包含块定位,其边界根据偏移属性放置。
  • 绝对定位元素可能覆盖其他元素,或者被其他元素覆盖。
  • 绝对定位元素的包含块是最近的position值不为static的祖先元素。通常选择一个元素作为绝对定位的包含块,将其position置为relative而且没有偏移。
  • 元素绝对定位时,还会为其后代元素建立一个包含块。

自动边偏移

元素绝对定位时,如果除bottom外某个任意偏移属性设置为auto,会有一种特殊的行为。
下面以top为例:

span{
  position:absolute;
  top:auto;
  left:0;
  color:red;
  background-color:blue;
}

这里写图片描述

对于left:0,元素的左边界会和包含块的左边界对齐。
但是对于auto的top,定位元素的顶端要相对于其未定位之前本来的顶端位置对齐。

如果left和right设置为auto,也适用同样的基本规则:
在这些情况下,定位元素的左或右边界与元素未定位时该边界原本的位置对齐。
我们把上个例子中的left改为auto:

span{
  position:absolute;
  top:auto;
  left:auto;
  color:red;
  background-color:blue;
}

这里写图片描述

定位元素现在就位于其本来的位置,但是由于它已经定位,它原来所占的空间已经消失,因此现在定位元素和正常流内容重叠。

但是这种自动放置只在某些情况下可行,就是对定位元素的其他尺寸没有什么限制的时候。如果确实又增加了许多限制该怎么办呢?

非替换元素的放置和大小

一般地,元素的大小和位置取决于其包含块。
考虑一个定位元素的宽度和水平放置:

left+margin-left+border-left-width+padding-left+width+padding-right+border-right-width+margin-right+right
= 包含块的width

那么所有这些属性之间有什么关系呢?

  • 如果left、width、right都设置为auto,会得到上一小节的结果:左边界置于静态位置(从左向右读的语言),width恰好包围元素
span{
  position:absolute;
  top:0;
  left:0;
  right:auto;
  color:red;
  background-color:blue;
}

这里写图片描述

此时元素的width为auto,宽度恰好足够包含内容。
而从元素右边界到包含块右边界之间的距离是right的计算值。

  • 如果左右外边距都设为auto,而left、right和width不是auto
span{
  position:absolute;
  top:0;
  left:1em;
  right:5em;
  width:10em;
  margin:0 auto;
  color:red;
  background-color:blue;
}

这里写图片描述

1.首先,left和right会设置好整个元素框的偏移位置
2.其次,左右外边距会设置为相等的值。这会让元素居中。

  • 如果外边距也不为auto呢
p{
  position:relative;
  width:30em;
}
span{
  position:absolute;
  top:0;
  left:1em;
  right:5em;
  width:10em;
  margin:0 1em 0 2em;
  color:red;
  background-color:blue;
}

现在,定位元素的总宽度是1+2+10+1+5 = 19em;而整个包含块的宽度是30em,中间还差11em,必须从某个地方弥补。

规则指出,在这种情况下,用户代理会重置right的值(从左向右读)。
这里写图片描述

可以发现。此时right被重置为了16em,这样整个元素的水平宽度就等于包含块的宽度了。

但是这种情况下如果某个外边距保持为auto,则会改变这个外边距。

span{
  position:absolute;
  top:0;
  left:1em;
  right:5em;
  width:10em;
  margin:0 auto 0 2em;
  color:red;
  background-color:blue;
}

这里写图片描述

定位元素的位置和上面的相同,但是这次是重置了右外边距为12em的结果。

同样的,如果左外边距为auto,就会重置左外边距:

span{
  position:absolute;
  top:0;
  left:1em;
  right:5em;
  width:10em;
  margin:0 1em 0 auto;
  color:red;
  background-color:blue;
}

这里写图片描述

一般地,如果只有一个属性设置为auto,就会修改这个属性来满足宽度需求,但如果没有为auto的属性,就会重置right属性。

width为auto也是同理:

span{
  position:absolute;
  top:0;
  left:1em;
  right:5em;
  width:auto;
  margin:0 1em 0 2em;
  color:red;
  background-color:blue;
}

这里写图片描述

此时,width被扩展成了必要的宽度来满足宽度的需求。

在垂直方向上,规则非常类似:

<div id = container>
  <div>元素1</div>
  <div>元素2</div>
  <div>元素3</div>
</div>  
#container{
  position:relative;
  width:30em;
  height:10em;
}
#container div{
  position:absolute;
  width:30%;
  background-color:aqua;
}
#container div:nth-child(1){
  left:0;
  top:0;
}
#container div:nth-child(2){
  left:35%;
  top:0;
  height:50%;
}
#container div:nth-child(3){
  left:70%;
  height:50%;
  bottom:0;
}

这里写图片描述

1.对于元素1,元素的高度收缩为内容的高度
2.对于元素2,未指定的属性(bottom)设置为适当的值,来弥补元素底端与包含块底端之间的距离
3.对于元素3,未指定的属性是top,所以由top弥补定位元素顶端与其包含块顶端之间的距离。

此外,外边距为auto可以得到垂直居中的效果:

#container div{
  position:absolute;
  left:0;
  top:0;
  bottom:0;
  height:5em;
  margin:auto 0;
  width:100%;
  background-color:aqua;
}

这里写图片描述

这里必须显式声明top与bottom都为0,元素才会垂直居中。因为若不显式声明top与bottom为0,它们就是auto,就会调整它们来满足垂直宽度,那么元素也不会垂直居中了。

还有两个小变化:

  • 在水平布局中,如果值为auto,right或left都可以根据其静态位置放置。但在垂直布局中,只有top可以取静态位置,bottom不可以。
  • 如果一个绝对定位元素在垂直方向上过度受限,将重置bottom
#container div{
  position:absolute;
  left:0;
  top:0;
  bottom:0;
  height:5em;
  margin:0;
  width:100%;
  background-color:aqua;
}

这里写图片描述

这种情况下会重置bottom为5em。

替换元素的放置和大小

与非替换元素基本相同,只是替换元素有固定的宽度和高度,也就是说将width和height设置为auto时,其计算值由元素的固有宽度和高度决定。

z轴上的放置

利用z-index,可以改变元素相互覆盖的顺序。

/* Keyword value */
z-index: auto;

/* <integer> values */
z-index: 0;
z-index: 3;
z-index: 289;
z-index: -1; /* 使用负值降低优先级 */

一般来说,z-index值较大的元素能覆盖z-index值较小的元素。
所有整数(包括负数)都可以作为z-index的值。如果指定了一个负z-index值,元素会移到较底层的位置。

但要注意,一旦为元素指定了一个z-index值(不是auto),该元素就会建立自己的局部层叠上下文。这意味着元素的所有后代相对于该祖先元素都有自己的叠放顺序。也就是说,后代元素不会和别的元素比较,而是在自己祖先元素的基础上和祖先元素的其他后代元素们比较。
也可以理解为,如果一个元素为后代元素建立了叠放上下文,那么该元素初始就是位于此上下文z轴的0位置上。
而z-index为auto的元素不会建立一个新的本地堆叠上下文。当前堆叠上下文中新生成的元素和父元素堆叠层级相同。

固定定位

固定定位与绝对定位很类似,只不过固定定位的包含块是视窗。固定定位时,元素会完全从文档流中去除。

相对定位

采用相对定位时,将通过使用偏移属性来移动定位元素。
但是,采用相对定位时,元素会从正常位置移走,但其原来占据的空间并不会消失。

如果一个相对定位元素过度受限会怎么样呢?

strong{
    position:relative;
    top:10px;
    bottom:20px;
}

这里指定的值要求两种完全不同的行为,top:10px要求元素向下移10px,而bottom:20px要求元素向上移20px。
CSS2.1规定,如果出现过度受限情况,一个值会重置为另一个值的相反数
因此,bottom总是等于-top,为-10px,那么上面例子中的元素最终会向下移10px。

同理,在相对定位中,right=-left(从左到右的语言)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值