这篇文章发布于 2013年11月19日,星期二,19:29,归类于 CSS相关。 阅读 251140 次, 今日 2 次 56 条评论
by zhangxinxu from http://www.zhangxinxu.com
本文地址:http://www.zhangxinxu.com/wordpress/?p=3794
一、悠悠哉哉说点什么
本来我有个很好的计划,就是本文用漫画来写,把话痨的火影漫画的文字重新抹掉,然后填本文相关的技术文字 。
哈,是不是很好啊!但是,想到了一个残酷的现实——流量,我一个月只有30G流量,几乎月月爆棚,要是这里全部用火影的图片要实现,页面没个1M搞不下来哈~,文章要是3000访问,就差不多3G,天哪,我表示压力很大。于是,我决定还是中规中矩用文字加一两小截图表示下吧~
二、绝对定位元素的居中实现
如果要问如何CSS实现绝对定位元素的居中效果,很多人心里已经有答案了。
兼容性不错的主流用法是:
.element { width: 600px; height: 400px; position: absolute; left: 50%; top: 50%; margin-top: -200px; /* 高度的一半 */ margin-left: -300px; /* 宽度的一半 */ }
但,这种方法有一个很明显的不足,就是需要提前知道元素的尺寸。否则margin
负值的调整无法精确。此时,往往要借助JS获得。
CSS3的兴起,使得有了更好的解决方法,就是使用transform
代替margin
. transform
中translate
偏移的百分比值是相对于自身大小的,于是,我们可以:
.element {
width: 600px; height: 400px;
position: absolute; left: 50%; top: 50%;
transform: translate(-50%, -50%); /* 50%为自身尺寸的一半 */
}
于是乎,无论绝对定位元素的尺寸是多少,其都是水平垂直居中显示的。
然,问题很明显,兼容性不好。IE10+以及其他现代浏览器才支持, IE9(-ms-), IE10+以及其他现代浏览器才支持。中国盛行的IE8浏览器被忽略是有些不适宜的(手机web开发可忽略)。
实际上,绝对定位元素的居中实现还有另外一种方法,可以说是权衡了上面的尺寸自适应以及兼容性的一个方案,其实现的核心是margin:auto
.
三、margin:auto实现绝对定位元素的居中
首先,我们来看下CSS代码:
.element {
width: 600px; height: 400px;
position: absolute; left: 0; top: 0; right: 0; bottom: 0;
margin: auto; /* 有了这个就自动居中了 */
}
代码两个关键点:
- 上下左右均
0
位置定位; margin: auto
于是,就居中了。上面代码的width: 600px
height: 400px
仅是示意,你修改为其他尺寸,或者不设置尺寸(需要是图片这种自身包含尺寸的元素),都是居中显示的。很有意思的~~
您可以狠狠地点击这里:margin:auto与绝对定位元素的垂直居中demo
点击demo页面中间的按钮,让原本static
的框框absolute
化,可以发现其是水平垂直居中的。
不知诸位新技能get否?
对了,该方法IE8+以及其他浏览器都是OK的。
上图为8~10月份,百度流量统计员给出的浏览器访问数据。IE6+IE7大概14%的样子。显然,很快,此方法就要开始称霸PC武林了!
三、悠悠哉哉再说点什么
可能有人会问,为何margin: auto;
会让绝对定位元素居中了呢?哈哈,原因是………………
.
.
.
.
我也不知道!
可能需要查询规范寻找一些线索。但,待会儿我还有篮球比赛,恕我没有足够精力去深入。欢迎有相关研究的达人分享其内部机制原理,不甚感谢!
更新于2017年2月18日
今天正好有看到自己的这篇文章,我更新下原因吧!
当一个绝对定位元素,其对立定位方向属性同时有具体定位数值的时候,流体特性就发生了,例如:
<div class="box"></div>
.box { position: absolute; left: 0; right: 0; }
如果只有left
属性或者只有right
属性,则由于包裹性此时.box
宽度是0
。但是,在本例中,因为left/right
同时存在,因此宽度就不是0
,而是自适应于.box
包含块的padding box
宽度,也就是随着包含块padding box
的宽度变化,.box
的宽度也会跟着一起变。
具有流体特性绝对定位元素的margin:auto
的填充规则和普通流体元素一模一样:
- 如果一侧定值,一侧
auto
,auto
为剩余空间大小; - 如果两侧均是
auto
, 则平分剩余空间;
:
例如,下面的CSS代码:
.father { width: 300px; height:150px; position: relative; } .son { position: absolute; top: 0; right: 0; bottom: 0; left: 0; }
此时.son
这个元素的尺寸表现为“格式化宽度和格式化高度”,和<div>
的“正常流宽度”一样,同属于外部尺寸,也就是尺寸自动填充父级元素的可用尺寸的,然后,此时我们给.son
设置尺寸,例如:
.son { position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 200px; height: 100px; }
此时宽高被限制,原本应该填充的空间就被多余了出来,这多余的空间就是margin:auto
计算的空间,因此,如果这时候,我们再设置一个margin:auto
,那么:
.son { position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 200px; height: 100px; margin: auto; }
我们这个.son
元素就水平和垂直方向同时居中了。因为,auto
正好把上下左右剩余空间全部等分了,自然就居中啦!
// zxx: 更新end—-
欢迎讨论,欢迎交流。
本文为原创文章,转载请注明来自张鑫旭-鑫空间-鑫生活[http://www.zhangxinxu.com]
本文地址:http://www.zhangxinxu.com/wordpress/?p=3794
(本篇完)
- 理解SVG transform坐标变换 (0.395)
- CSS fixed固定定位transofrm失效及居中小技巧 (0.301)
- 深入理解CSS的width:auto (0.263)
- absolute元素在text-align属性下的对齐显示 (0.229)
- CSS相对定位|绝对定位(五)之z-index篇 (0.150)
- 不同CSS布局实现与文字鼠标选择的可用性 (0.117)
- 大小不固定的图片、多行文字的水平垂直居中 (0.113)
- css行高line-height的一些深入理解及应用 (0.113)
- 最近整的MooTools库下Mbox弹框插件 (0.113)
- 关于一个JS功能实现的思维方式 (0.113)
- CSS 相对/绝对(relative/absolute)定位系列(四) (RANDOM - 0.038)
一场打了四年的篮球赛哦
“`
.center {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: fit-content;
width: fit-content;
margin: auto;
}
“`
水平垂直居中+内容动态显示,666.最近做的一个小项目,加上内容动态显示可把我难坏了
学习了!膜拜!
想知道为什么在普通流中 margin:auto;不能垂直居中,而在absolute中可以
https://www.zhihu.com/question/21644198
不知你是否找到了答案……看这个问题的第一个回答,有解释~
文中表示:
当一个绝对定位元素,其对立定位方向属性同时有具体定位数值的时候,流体特性就发生了。
正常的static,是流体
absoulte不是流体,但是,相对的两个属性值都有的时候,就表现为流体了,这样,上下都设置值,就可以让它在上下都居中了
今天面试了一个前端关于垂直居中的问题,他跟我说absolute后margin:auto就可以了,我说他是胡扯,今天在这里道歉
第一,你不如三思而后说;
第二,你不如找到那个人的联系方式,诚恳道歉;
第三,你不如当时问问他说出这种方法的原理;
第四,你在这里道歉有啥用……
鑫哥! 定位元素的margin值的left和top相对于谁来定位?
层叠上下文那里,如果子元素也创建了层叠上下文,那么在渲染的时候要如何处理这个子元素?
那如果这个子元素有z-index=-1呢,他会到谁下面去? 多层嵌套层叠上下文会怎么处理? 这个问题困扰了我好久哇~~ 求指点
这种方法也还是不能直接使未知宽度、高度的div居中吧?
今天看了好多你的文章,明白了很多,相见恨晚,简直像看小说哈哈哈
为何设置margin-top时 直接跨越了上面最接近的函数
还有一种办法是父级display:table;子级display:table-cell; vertical-align:center;
简洁,精确,实用
很经典
IE8里面无效
ie7不兼容啊,不兼容啊。
鑫哥,上面这个“三、margin:auto实现绝对定位元素的居中”,在按钮按下之前,element就是居中的,按下以后多了个.dialog_absolute { position: absolute; left: 0; top: 0; right: 0; bottom: 0; z-index: 1; }。结果还是居中,那么我想问加类名dialog_absolute有什么作用?这里可能转牛角尖了,望看到的人教导教导
就是让他水平垂直都居中啊
用了position 之后我们的margin:0 auto 失效。
然而我们要水平垂直都居中。那么就用.dialog_absolute的方法。
这里有一篇关于居中的文章《CSS3 Flexbox轻松实现元素的水平居中和垂直居中》可以作为这里的补充说明!http://yunkus.com/article/css3/286.html
博主总结的经验总是能解决我的难题,真是佩服
原因大概是~~float为什么可以让文字环绕,人家愿意呗。
“IE10+以及其他现代浏览器才支持”
transform 2d Transforms 不是IE9(-m-transform)就支持了么?为什么说IE10才支持?
方法很好,让我大开眼界,不过就是有点hack的味道
不会啊。也就最后一个方法有点hack的味道吧。其他方法都是解释的通的
还是不明白为什么,margin:0 auto; 不需要设置top,left等值,而这个就需要,果然是黑科技么?
你那是水平居中,而这个是水平垂直都居中
http://hi.barretlee.com/2014/08/07/position-and-margin/
简要的解释了下。
人精这你也知道
啊啊啊啊啊啊大感谢!!!!非常感谢!!!!
鑫哥,我在你这里学到了不少css新的思想,感谢你,我想知道为什么这篇文章讲的内容,无法在ie7下实现居中呢
@taodongsheng 你好,此方法不使用与IE6和IE7~
必须要定义高度,不然按照w3c的说法
If all three of ‘top’, ‘height’, and ‘bottom’ are auto, set ‘top’ to the static position and apply rule number three below.
Android 2.+默认浏览器不兼容
第一次来鑫哥哥的博客就不想走了~~鑫哥哥,有问题可以在这里提么?
鑫哥好,默默关注你很久了,哈哈哈,学到不少东西,在此表示一下感谢,喜欢你搞笑的风格!么么哒
margin:auto,IE8不行
貌似文中的 absolute 都写成了 position: aboslute; 。。。。。。。。。。
@于江水 哈,确实有几处写得有问题,多谢提醒!
国内网站最早是在百度云上看到相关用法的。侧边是这么写的.aside{position:absolute;left:0;top:0;bottom:0;width:210px;},用来适应父元素高度100%,对于脱离文档流的布局方式,子元素是不知道父元素的高度的,但是很多时候有脱离文档流布局(定位和浮动)和子元素适配父元素高度的双重需求,就可以用这种方法,兼容IE7+,没测IE6。至于垂直水平居中是基于此的更高应用。国外网站最早在http://codepen.io/shshaw/full/gEiDt上看到这种写法,并给这种技术取名做absolute centering。感兴趣的可以看下。
看起来像是 left/right为0时,让margin:0 auto生效
top/bottom为0则是让margin:auto 0;生效
至于为什么会生效,估计是这样:
刚刚试着把left/right设为同等值但不为0,如100,效果不变
假设页面宽是1000,盒子宽300,left = right = 100;
那剩下可活动的500,则会让margin:auto “平分”掉
left=right=0时,用调试工具看,它的margin左右都到了边缘
而left=right=100时,margin部份则是各距离边缘100
这时就很好理解了,而垂直居中则是同理。
至于ie6/7无效,估计是定位下margin的auto值没起作用
顺便一提,没定位的情况下,margin:auto不会垂直居中的,这有点恶心
但照上面“定位平分”的方法却能做到,顺便请教下张大人,left=right=100
right实际是生效了,但视觉上为什么还是left=100不会被后面的覆盖
刚刚测试的时候发现博主将决定定位的值写错了
垂直居中的东西,茶艺花园里面很早就有这个了,ie8+用display:table,而ie7-用outer绝对定位top:50%,inner用相对定位top:-50%
一直在关注博主的东东,学到很多东西,最近想到一个左中右排版的东西(不清楚有没有别人想到过,很想跟博主分享一下),利用display:inner-block改变子元素(即要实现左中右排版的东西),外部让子元素不换行,然后定义左右内边距(左右内边距定于左右子元素的宽),第一个子元素用外边距挪移到外部元素的左内边距里面,为了兼容ie7-,要在外部元素中关闭滚动条–(这样实现左中右排版可以避免定位,而且中间的宽度可以自由化)
比如我这样:
结构是:
外层
div
设置为position:relative;
.center-middle{
position:absolute;
top:0;
bottom:0;
left:0;
right:0;
margin:auto;
}
上面的
p
是不垂直居中的。如果换成一个图片便可以。
这样为什么?
@淡墨素然的青春 因为没有
width/height
限制,文字的这个p
元素被上下左右拉伸了。图片自身含有尺寸。so?文本垂直居中还是不好解决呢
在他的”上一層”加上寬高就可以了,可以隨便用一個 div 包起來
这种情况下,是宽高为0,还是margin为0,还是各自一半???有默认值吗??
不错,还不能大规模使用,都是IE的错
用过linode的人表示,用linode主机吧,别再用万网的了。真心的。2T流量哦。
Linode
1 GB RAM
8 CPU (1x priority)
48 GB Storage
2 TB Transfer
$20 / month
定高 div 被设置为 top:0; bottom:0;。但是因为它有固定高度,其实并不能和上下都间距为 0,因此 margin:auto; 会使它居中。
http://www.w3.org/TR/CSS2/visudet.html#abs-non-replaced-height
具体而言,就是这个式子:
‘top’ + ‘margin-top’ + ‘border-top-width’ + ‘padding-top’ + ‘height’ + ‘padding-bottom’ + ‘border-bottom-width’ + ‘margin-bottom’ + ‘bottom’ = height of containing block
当width, height全部被指定,而margin为auto时,可计算出实际margin值。
其实当width,height未指定时,会有限计算width和height
顺带一提火影的鸣人插图好骚,佐助超想干他
哇,多谢你的评论,现在是比较清楚了
拿高度来说吧(宽度是一样的),css的视觉格式化模型是这样的:
‘top’ + ‘margin-top’ + ‘border-top-width’ + ‘padding-top’ + ‘height’ + ‘padding-bottom’ + ‘border-bottom-width’ + ‘margin-bottom’ + ‘bottom’ = 包含块的高度
当top/height/bottom 这3个值不是auto,而 margin:auto ,则:
margin-top=margin-bottom=(包含块的高度 – 定位元素高度)/2
http://www.w3.org/TR/CSS2/visudet.html#abs-non-replaced-height
这个原理其实和普通block元素使用margin:0 auto可以水平居中是类似的。
定位元素高度:包括top/bottom的值。。。。。写的还是不严谨。。。。