CSS学习笔记:定位

    xiaoxiao2021-09-17  57

    定位

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

    基本概念

    定位的类型

    /* 关键字值 */ 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(从左到右的语言)。

    转载请注明原文地址: https://ju.6miu.com/read-677663.html

    最新回复(0)