【前端Talkking】CSS系列——CSS深刻理解之absolute定位

1. 写在前面

本篇将要介绍的绝对定位absolute属性和此前介绍的CSS系列——CSS深刻理解之float浮动有着几分的类似性,能够认为二者是兄弟关系,都具备“包裹性”、“高度塌陷”、“块状化”的特性,它们在不少场合均可以互相替代。不少人可能有这样的疑问:一个属性名是“position”,一个属性名是“float”,从名字看起来,它们八竿子都打不着啊,怎么仍是兄弟关系呢?要说position: absoluteposition: relative是兄弟关系还能理解,要说和float是兄弟关系我就纳闷!!!呵呵~~~~,别急,这就是写做本文的目的。javascript

2. absolute的特性

在介绍absolute以前,有如下公共CSS代码:css

/* CSS代码 */
.father{
    border: 2px solid deeppink;
    width: 200px;
}
.son {
    position: absolute;
    font-size: 0;
    border: 2px solid blue;
    padding: 5px;
}
.father img {
    width: 128px;
}
复制代码

2.1 包裹性

而后有如下html代码:html

<div class="father">
    <!--son1与son的惟一区别是son1的position设置为static-->
    <div class="son1">
        <img src="../../lib/img/mm1.png">
    </div>
</div>
<br/>
<br/>

<div class="father">
    <div class="son">
        <img src="../../lib/img/mm1.png">
    </div>
</div>
复制代码

最终显示的效果以下图所示:前端

在本例中,son1与son的惟一区别是son1的position设置为static.father元素的宽度设置为200pximg元素是一个128px宽度的图片,则此时绝对定位元素宽度表现为"包裹性",其宽度也就是里面图片的宽度128px。java

因为绝对定位元素宽度表现为"包裹性",所以,下面的CSS写法就是多余的:segmentfault

.wrap{
    display: inline-block;// 没有必要
    position: absolute;
}
复制代码

2.2 高度塌陷

基于上图,父元素div的高度并无被子元素撑开(粉色区域),这种效果能够称为"高度塌陷"。致使高度塌陷的缘由是由于浮动元素脱离了正常的文档流,则div.father认为其没有子元素,因此产生了高度塌陷。浏览器

若是在.father元素增长子元素,以下:微信

<!--HTML代码-->
<div class="father">
    <div class="son">
        <img src="../../lib/img/mm1.png">
    </div>
    美女1,美女2,美女3,美女4,美女5
</div>
复制代码

则在浏览器中的效果以下:app

从图中明显看出文字被图片遮盖了,这一点和float不一样。由于,float元素自己仍处于文档流中,文字会环绕着float元素,不会被遮蔽,而设置了absolute的图片元素出现了层级关系,已经脱离了正常的文档流了,从父元素的视点看,图片已经彻底消失不见了,所以从最左边开始显示文字,而absolute的层级高,因此图片遮盖了文字。布局

2.3 块状化

块状化的意思是,一旦元素position的属性为absolute或者fixed,则其display计算值就是block或者table。能够复制如下代码到浏览器控制台中:

var span = document.createElement('span')
document.body.appendChild(span)
console.log('1.' + window.getComputedStyle(span).display)
// 设置元素绝对定位
span.style.position = 'absolute'
console.log('2.' + window.getComputedStyle(span).display)
document.getElementById("aa").style.display = "block"
复制代码

则在浏览器控制台中的结果以下:

1.inline
2.block
复制代码

2.4 小结

对于上面对absolute的介绍,对比float属性,是否是应该理解他们是兄弟关系呢?若是你非得不这样认为能够,只要你明白absolute的特性便可。绝大多数前端开发人员应该都懂,可是若是本文只是介绍上面的知识点,就太对不起你们的期待了!下面将要介绍absolute的流体与相对特性才是本文的重点。

3. absolute流体与相对特性

3.1 absolute的相对特性

在介绍absolute的相对特性以前,先抛出如下问题: 若是一个元素的定位属性设置成了:position: absolute后,没有设置left/top/right/bottom,而且其祖先元素所有都是非定位元素,请问它将在哪里显示?

包括我本身,在深刻了解absolute的特性以前,认为该元素是在浏览器窗口的左上方显示,其实这是对absolute绝对定位属性错误的认识。所以,不少人在使用absolute定位属性的时候,一定先要设置父元素position: relative,同时设置绝对定位元素的left/top/right/bottom,甚至还要设置绝对定位元素层级z-index实际上,该元素仍是在当前的位置。咱们拿下面的这个例子验证:

<!--HTML代码-->
<div class="father">
    <div class="pa box"></div>
</div>
复制代码
/* CSS代码 */
.father{
    border: 2px solid deeppink;
    width: 100px;
    height: 100px;
}
.pa{
    position: absolute;
}
.box{
    background-color: #cdcdcd;
    width: 50px;
    height: 50px;
}
复制代码

以下图所示,.box元素仍是在当前的位置显示,而不是在浏览器窗口的左上方显示:

在京东商城首页,有这样的一个效果:

image-20180502200432543

而后咱们打开调试窗口,查看html和css代码以下:

image-20180502200712645

这里css代码中的top:0;left:0彻底是多余的代码,能够省略不写。由于,不设置left/top/right/bottom的绝对定位元素仍是在当前的位置,只是脱离了正常的文档流了。

实际上,absolute是一个相对比较独立的CSS属性,它的样式和行为表现不依赖其余的CSS属性就能够完成。所以,若是元素设置了定位属性为absolute绝对定位,而且没有设置left/top/right/bottom,那么能够将这种定位属性称为“无依赖绝对定位”,其本质就是"相对定位",特色仅仅是脱离文档流,不占据任何CSS流的尺寸空间了。

无依赖绝对定位在实际开发中很是有用,下面举几个比较经常使用的例子。

1)各种图标定位

咱们以慕课网首页上的课程列表举例:

WX20180502-205632@2x

<div>
    <div class="box"></div>
    <i>Hot</i>
</div>
复制代码

核心CSS代码以下所示:

WX20180502-205758@2x

彻底不须要借助top/right/bottom/leftposition: relative的帮助就能够搞定小图标的布局啦。相比使用position:relativeright/top的布局方式,这种布局方式的优势是:

  • 维护成本低。若是后面想删除这个图片,只须要将图标对应的html和css代码删除掉就能够了,不会影响其余的元素
  • 健壮性高。若是图片变大或者文字变长,咱们不须要修改小图标的css代码,仍然定位效果良好。

再举一个在实际开发中用的比较多的一个例子,以下图所示,在一段文字的前面有一个图标:

这种布局方式一样能够借助无依赖定位的实现,而且代码简单高效,代码以下所示:

<div class="email-wrapper">
    <i class="icon-email"></i>
    <span class="icon-msg">请输入您的邮箱:</span>
</div>
复制代码
.email-wrapper{
    display: inline-block;
    height: 20px;
    padding-left: 20px;
    /*font-size: 0;*/
}
.icon-email{
    position: absolute;
    margin-left: -20px;
    width: 20px;
    height: 20px;
    background: url("../../lib/img/email.png") center center no-repeat;
    background-size: contain;
}
.icon-msg{
    display: inline-block;
    line-height: 20px;
    vertical-align: top;
}
复制代码

2)校验提示错误

在实际开发中,咱们有不少表单校验,当校验不经过的时候,会有一些错误提示给用户,以下图所示:

一般,错误提示能够放到input框的下面,可是当出现错误提示的时候,下面的内容会总体下移,当错误提示消失的时候,下面的内容又会总体上移,用户体验很差。还有一种作法是放到input框的右侧显示,可是在默认状态下部容器设置了水平居中, 宽度不大,若是再出现错误提示信息,就会出现容器的宽度不够的问题。此时,咱们一样能够借助:"无依赖定位",直接给错误提示信息增长一个CSS类,以下所示:

.msg-error{
	position: absolute;
	margin-left: 10px;
}
复制代码

不管将input框的宽度变大或者变小,提示信息都会跟着input框。相比使用position:relativeright/top的布局方式,这种方法代码量更少、容错性更高、维护成本更低。

关于无依赖绝对定位的应用还有不少,这里就不一一介绍了,有兴趣的同窗能够参看张鑫旭老师的《CSS世界》。

3.2 absolute的流体特性

只有absolute遇到left/top/right/bottom属性的时候,absolute元素才真正变成绝对定位元素。若是用户给absolute至少指定了left/right中的一个,则水平方向的相对特性丢失,垂直方向上继续保持相对特性;若是用户给absolute至少指定了top/bottom中的一个,则保持水平方向上的相对特性,垂直方向上的相对特性丢失。例如:

<div class='box'></div>
.box{
    position: absolute;
    right: 0;
}
复制代码

此时,元素水平方向相对特性丢失,具备了绝对定位特性,而垂直方向的定位依然保持了相对特性。

以上面的这个例子举例,当只有left或者right属性的时候,因为包裹性,此时div的宽度是0。可是,若是同时设置left:0;right:0的时候,宽度表现为"格式化宽度",宽度自适应于.box包含快的content-box,换句话说,若是包含快的conent-box宽度发生变化,则.box的宽度也会跟着一块儿变。举个例子:

<div class='box'></div>
.box{
    position: absolute;
    right: 0;
    left: 0;
    top: 0;
    bottom: 0;
}
复制代码

若是.box的包含块是根元素,则上面的代码可让.box元素正好彻底覆盖浏览器的可视窗口,同时,若是改变浏览器窗口的大小,.box的大小会随着浏览器的大小自动变化。所以,对于设置了对立定位属性的绝对定位属性,不管设置padding仍是margin,其占据的空间一直不变,变化的就是content-box,这就是典型的流体表现特性。流体特性的具体用法在后面会介绍到。

4. absolute与其余属性

CSS中的不少属性须要和其余的属性一块儿使用的时候会发生意向不到的效果。下面将介绍absolute与其余CSS一块儿使用产生的效果。

4.1 absolute与text-align

利用text-align能够控制绝对定位元素的位置,实现主窗口右侧的"返回顶部"以及"反馈"等布局的效果。效果图以下:

WX20180502-210045@2x

核心代码以下:

<!--HTML代码-->
<div class="alignright">
    <span class="follow">
        <img src="../../lib/img/message.png">
        <img src="../../lib/img/top.png">
    </span>
</div>
复制代码
/* CSS代码 */
.alignright{
    overflow: hidden;
    text-align: right;
}
.alignright:before{
    content: "\2002"
}
.follow{
    position: fixed;
    bottom: 100px;
    z-index: 1;
}
.follow img{
    display: block;
    margin: 10px;
    width: 20px;
    height: 20px;
    background-size: contain;
}
复制代码

在本例中,利用:before伪元素,在其前面插入一个空格(\2002),而后设置text-aligin: right,则空格对齐主结构的右侧边缘,后面的固定定位元素(同绝对定位元素)因为"无依赖定位"特性,左边缘正好就是主结构的右边缘,天然就跑到主结构的外面显示了。这种布局在实际开发中用处很是大,好比说下图中某宝的楼层导航效果均可以使用这种方式实现。

4.2 absolute与clip

在实际开发过程当中,不少时候咱们为了更好的SEO和无障碍识别,都会将页面中的一些元素隐藏,例如隐藏下面代码中的本网站名字这几个字:

/* CSS代码 */
<a href="#" class="logo">
	<h1>本网站名字</h1>
</a>
复制代码

为了隐藏上面的文字,有如下几种方案能够供咱们选择:

  • 使用display:none或者visibility:hidden。缺点:屏幕阅读设备会忽略这些文字;
  • 使用text-align缩进。缺点:若是缩进过大到屏幕以外,屏幕阅读设备也是不会读取的;
  • 使用color: transparent。原生IE8浏览器器并不支持,而且仍是可以选中文本。

借助absolute和clip(关于clip用法不熟悉的同窗能够本身百度下,很简单)这两个属性,可以同时知足视觉上隐藏和屏幕阅读设备可以读取的要求,核心代码以下:

/* CSS代码 */
h1{
    position: absolute;
    clip: rect(0 0 0 0);
}
复制代码

4.3 absolute之margin:auto居中

在实际工做开发中,可能咱们用的最多的是下面的方式来实现元素的水平垂直居中效果,核心代码以下:

/* CSS代码 */
.box{
    width: 20px;
    height: 20px;
    position: absolute;
    left: 50%;
    right: 50%;
    margin-left: -10px;
    margin-right: -10px;
}
复制代码

此方法有一个不足之处就是须要提早知道元素的尺寸,不然没法控制margin负值的大小。

若是不知道元素的尺寸,可使用transform: translate(-50%, -50%)代替margin负值,然而这种方法存在必定的兼容性问题,IE9(-ms-), IE10+以及其余现代浏览器才支持,在必定的场景下会致使微信闪退的问题。

在介绍下另一种方法前,咱们首先熟悉下margin: auto的填充规则:

  • 若是一侧定值,一侧auto,则auto为剩余空间大小;
  • 若是两侧都是auto,则平分剩余空间。

所以,利用绝对定位absolute元素的流体特性和margin: auto的自动分配特性可以实现水平垂直居中的效果,核心代码以下:

/* CSS代码 */
.box{
    width: 20px;
    height: 20px;
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;
}
复制代码

显示效果以下:

WX20180502-212501@2x

这种方法兼用性好,而且须要提早知道元素的尺寸,减小了依赖,后期维护改动的地方少,何乐而不为呢?

5. 结语

关于absolute的介绍就到这里了,平时咱们应该多思考,多总结,才会有新的体会。计划下一篇文章介绍relative定位,最新文章都会第一时间更新在个人公众号<前端Talkking>里面,欢迎关注。

以上就是本文的所有内容,感谢阅读,若是有表述不正确的地方,欢迎留言指正!

6.参考

  • 张鑫旭 《CSS世界》

 **碰见了,不妨关注下个人微信公众号「前端Talkking」**

相关文章
相关标签/搜索