近年来前端工程师已经可以通过不同的 CSS 布局技巧制作出很复杂的布局. 其中有些技巧有很长的历史(比如: floats), 也有一些是近几年才被青睐的(比如 flexbox).
在这篇文章中, 我们会更加细致地探索一些鲜为人知的关于 CSS positioning 定位的事情.
在我们开始学习这些事情前, 让我们快速浏览当然也是很必要地看一下可用的定位类型.
CSS 中的定位类型一览
position 这个 CSS 属性允许我们指定元素的定位类型.
CSS 定位选项
static 是此属性的默认值. 这时候, 我们称那个元素没有被定位. 为了定位它, 我们需要改变预定义的类型. 为了改变预定义类型, 我们将 position 的属性值设置为下面中的一个:
- relative
- absolute
- fixed
- sticky
只有设置了之后, 我们才能使用 offset 参数来为我们的元素指定我们想要的位置:
- top
- right
- bottom
- left
这些属性的初始值是关键字 "auto"
我们需要记住一点, 当一个元素的 position 被设置为 absolute 或者 fixed, 我们称之为一个绝对定位元素. 同样, 注意一个被定位的元素可以用 z-index 属性来指定他的堆叠顺序.
CSS 定位类型的主要差别
现在, 让我们简单的讨论下这些定位类型之间的三个关键差别:
一个 - 绝对定位的元素是完全脱离正常流的. 邻近的兄弟节点元素会占据它的位子.
一个相对或者粘性定位的元素保留他们的位置. 邻近的元素不会占据这个元素保留的空间. 然而, 这个元素的偏移量 (offsets) 不会占据空间. 他们完全忽略其他的元素, 因此这可能会与其他元素相互重叠.
一个绝对 (fixed) 定位的元素 (记住: fixed 是 absolute 定位的一个子类) 经常相对于视图的定位(除了一个有 transform 属性的父元素, 最新版本的桌面浏览器都支持这种行为).
一个粘性的定位元素是相对于最近的可滑动的父元素(比如: overflow:auto). 如果没有这种父元素, 它就相对于视图定位.
在接下来的事例中, 我们将探索这些类型的定位是如何运行的:
看一下 Pen 定位概述 by George (@georgemarts) 在 CodePen 上.
注意: 粘性定位类型依然被认为是实验性的技术, 并且浏览器支持有限. 当然, 如果你想要, 你可以将方法加入不支持的浏览器. 鉴于他有限的支持, 我们在接下来的文章中不会提到这个属性.
绝对定位类型的定位元素
我相信你们中许多人已经知道绝对定位是如何实现的了. 然而这个定位类型是需要技巧的并且容易迷惑新手设计者.
因为这个原因, 我决定将此列入鲜为人知的概念列表之中(包括相应的实例), 涵盖在这片文章之中.
因此, 一个定位类型被设置成绝对定位的元素是相对于它最近的父元素. 当然, 这仅仅在定位类型不是'staic'的情况下有效. 考虑到这一点, 如果元素没有任何定位的父元素, 那么它是相对于视图定位.
为了解释这种行为, 看下面的在线实例:
看一下 Pen 绝对定位类型的定位元素 by George (@georgemarts) 在 CodePen 上.
在这个实例中, 我们给绿盒子一个初始的绝对定位类型, 设置他的偏移量 (offsets) 为 bottom:0 和 left:0. 此外, 我们不需要给直接父元素 (红盒子) 一个特定的定位类型.
然而, 我们相对定位父元素(比如: 一个 class 为 jumbotron 的元素). 只要我们改变他父元素的定位类型, 注意绿盒子的定位是如何改变的.
绝对定位的元素无视了 float 这个属性
如果一个元素是浮动左或右, 而且我们将此定位类型设置为'absolute' 或者'fixed' , 那么 float 的属性就会被设置为'none' . 另一方面, 如果我们将定位类型设置成 relative, 那么元素依然包含浮动的属性.
看一个相关的例子:
看一下 Pen 绝对定位的元素无视了 float 这个属性 by George (@georgemarts) 在 CodePen 上.
在这个例子中, 我们将两个不同的元素定义为 float:right. 注意当红盒子变成了绝对定位的元素, 这就无视了 float 属性, 然而相对定位的绿盒子保留了他 float 的值.
内联元素如果被设置为绝对定位, 那么他会表现出块级元素的特征
一个内联元素, 如果他的 position 设置为 absolute 或者 fixed, 那么它就有块级元素的属性. 这张表总结什么类型的元素被转换成块级元素.
这里有一个例子:
看一下 Pen 内联元素如果被设置为绝对定位, 那么他会表现出块级元素的特征 by George (@georgemarts) 在 CodePen 上.
在这个例子中, 我们定义两个不同元素. 第一个 (比如: 绿盒子) 为块级元素 (比如: div). 第二个(比如: 红盒子) 为内联元素(如 span). 注意只有绿盒子有显示.
红盒暂时没有出现, 因为我们给它的 width 和 height 的这两个属性, 这属性只能用于块级元素和内联元素. 外加, 这是一个空元素(不包含任何子元素比如文本节点). 译者 ps: 不知道是不是这里写错了 宽高属性只能用于块级元素, 用在内联元素上, 不会有效果
记住如果我们设置定位的类型是 absolute 或者 fixed, 元素会呈现出块级元素的特性.
外边距 (margins) 不会在绝对定位的元素上合并
默认情况下, 当两个垂直外边距互相接触, 他们之间的间距会取得两个之间比较大的外边距. 这种行为可以理解为外边距合并.
就像在一个浮动的元素上的外边距一样, 一个绝对定位元素的外边距不会和其他外边距合并.
思考下下面的例子:
看一下 Pen 外边距 (margins) 不会在绝对定位的元素上合并 by George (@georgemarts) 在 CodePen 上.
在这个例子中个, 最初的元素的外边距等于 20px. 此外, 他的 top 外边距和父元素的 top 外边距重叠了, 这也是 20px. 正如你所见, 只有当我们绝对定位元素, 这个 top 外边距才不会和父元素的相关外边距重叠.
但是, 我们该如何防止外边距合并? 当然, 我们需要放些东西放去分开他们.
比如说, 举个例子, 有一点内边距或者边框 (我们可以把这条规则用于父元素或者子元素). 另一个选择是添加 clearfix 类(在我的例子中) 到父元素之中.
用 px 和百分比定位元素
你用过百分比而不是 px 来定义定位元素的偏移量 (offsets) 吗? 如果答案是是的, 你可能会发现坐标值的计算和你选择的 CSS 单位是不一样的(比如 px 或者百分比).
这看上去有点迷惑, 是吧? 因此让我看下规范中关于声明为百分比的偏移量.
偏移量是包含框的宽度 (对于 left 或者 right) 或者高度 (对于 top 和 bottom) 的百分比. 对于黏着定位的元素, 偏移量是底部的宽度 (对于 left 或者 right) 或者高度 (对于 top 和 bottom) 的百分比. 负值也是允许的.
也就是说, 只要我们定义偏移量为百分比, 目标元素的定位就依赖于父元素的宽 (对于左右的偏移量) 和高(对于上下的偏移量).
注意: 你也已经许知道, transform 属性 (伴随着不同的 translate 方法) 也可以让我们改变元素的位置. 但是, 请记住如果我们使用百分比作为 CSS 单位, 那么元素会相对于他的尺寸定位并且不是相对于父元素尺寸定位 (和偏移量(offsets) 不一样).
来源: http://www.jianshu.com/p/9715cd46b37a