设置左右上下对齐css,CSS上下左右居中
写在前⾯
有了transform、后,⽔平竖直居中已经很容易了,⽐如万能的:
position: absolute;
top: 0; bottom: 0; left: 0; right: 0;
/* 1.内容左上⾓居中 */
top: 50%; left: 50%;
/* 2.负半宽⾼把内容挪回来 */
--transform: translate(-50%, -50%);
关键是利⽤transform百分⽐相对⾃⾝宽⾼计算的特性,如果环境不⽀持transform的话,就需要⽤⼀些⽐较⽼,但很精妙的技巧了
margin居中
⼀个特征明显的⽅法:
position: absolute;
top: 0; bottom: 0; left: 0; right: 0;
/* 1.要求⾃⾝内容相对包含块居中 */
margin: auto;
/* 2.给出⾃⾝宽⾼计算⽅式 */
width: 100px; height: 100px;
原理
关键是利⽤margin的计算规则:
'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = 包含块的宽度
'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = 包含块的⾼度
margin居中,就是要给上⾯的⽅程加上限制条件:
margin-top === margin-bottom && margin-left === margin-right
这是⽤margin实现居中的核⼼
CSS⾥2个步骤实际意义如下:
指定margin计算⽅式,其它必要值可计算的话,auto要求margin平分剩余空间
指定必要值计算⽅式
这⾥的“必要值”要分开看,⽔平⽅向是left, right, width,因为有如下规则:
如果’left’,’width’和’right’全都是’auto’……
如果这3个值都不是’auto’……
否则,把值为’auto’的’margin-left’和’margin-right’设置为0,再在下⾯6条规则中挑1条合适的应⽤
5.如果’width’是’auto’,’left’和’right’都不是’auto’,则求出’width’
也就是说,如果
left: 0;
right: 0;
width: auto;
那么
margin-left: auto;
margin-right: auto;
的实际效果是
left: 0;
right: 0;
margin-left: 0;
margin-right: 0;
width: auto;
margin auto失效(被抹掉变成0了),所以width是必要值,必须给出其计算⽅式,⽐如数值、百分⽐,或者限制条件,⽐如max-width
竖直⽅向是top, bottom, height,对应的规则与⽔平⽅向类似:
5.如果’height’是’auto’,’top’和’bottom’都不是’auto’,则把值为’auto’的’margin-top’和’margin-bottom’设置为0,再求出’height’
所以height也是必要值
这样看来,最显眼的t: 0, b: 0, l: 0, r: 0不是重点,与wdith, height⼀样,只是让margin auto可计算的必要值⽽已,所以应该这样排列:
position: absolute;
/
* 1.要求⾃⾝内容相对包含块居中 */
margin: auto;
/* 2.给出margin auto计算所需的必要值 */
top: 0; bottom: 0; left: 0; right: 0;
width: 100px; height: 100px;
⽽且,tblr全0显然不必要:
top: 30px; bottom: 30px; left: 50px; right: 50px;
也是可以的,更进⼀步,甚⾄可以⽤tblr来抵消上下(左右)padding, border-width的差值
优缺点
缺点:
⽆法应对内容不定⾼度的场景(height必须auto的场景)
WP下⽆效(假设可以忽略)
优点:
兼容[IE8+]
⽀持resize(⽤户拖动内容右下⾓时仍然居中)
inline居中
相当巧妙的⽅式:
.center-inline-container {undefined
/* 1.内容⽔平居中 */
text-align: center;
}
.center-inline-container:before {undefined
/
margin属性值可以为百分比* 0宽空格 */
content: '\200B';
display: inline-block;
/* 2.把内容⾼度撑起来 */
height: 100%;
vertical-align: middle;
}
.center-inline-content {undefined
display: inline-block;
/* 3.竖直居中 */
vertical-align: middle;
}
原理
关键是利⽤vertical-align: middle;实现竖直居中:
把该盒的竖直中点和⽗级盒的基线加上⽗级的半x-height对齐
也就是说:
内容的纵向中点位置 = ⽗级盒的基线位置 + ⽗级的半x-height⾼度
⾸先确定⽗级盒的基线位置:
‘inline-block’(盒)的基线是它的最后⼀个常规流中的⾏盒的基线,除⾮它没有流内⾏盒或者它的’overflow’属性的计算值不为’visible’,此时基线是bottom margin边
需要接着“最后⼀个常规流中的⾏盒的基线”:
包含来⾃同⼀⾏的盒的矩形区域叫做⾏盒
CSS 2.1没有定义⾏盒基线的位置
遇到问题了,规范没说⾏盒的基线在哪个位置,但给了限制条件:
内联级盒是根据其’vertical-align’属性竖直对齐的。如果它们是’top’或者’bottom’对齐,它们必须对齐得让⾏盒⾼度最⼩化
满⾜这些⾮直接限制后,再确定⾏盒的基线位置,那么⾏盒基线位置的影响因素有:
⾏盒⾥的内联级盒的vertical-align、height、line-height
⾏盒所在容器的line-height
其它(可能还有别的)
不同case下⾏盒基线位置可能不⼀样,但很容易把最终基线的位置标出来:
Just add a character at the beginning of the line in questions
⼀般添个⼩写字母x,紧贴着x底部的位置就是基线
接下来确定“⽗级的半x-height⾼度”,这个相对容易:
ex:相关字体的’x-height’
‘ex’单位是根据元素的第⼀个可⽤字体定义的。⼀种异常情况是当’ex’出现在’font-size’属性的值中,此时参考⽗元素的’ex’
之所以叫’x-height’,是因为通常等于⼩写”x”的⾼度。然⽽,不含”x”的字体中也定义了’ex’
字体的x-height可以通过⼏种不同的⽅式得到。有些字体包含关于x-height的可靠规格。如果可靠的字体规格⽆法获得,UA可以根据⼀个⼩写字形的⾼度确定x-height。⼀个可能的启发是看⼩写”o”的字形延伸到基线下⽅多远,并减去其边界框的top值。如果有时确定x-height是不可能或者不现实的,就应该⽤0.5em
也就是说:
x-height = 当前字体的x-height || 根据⼀个⼩写字形的⾼度确定x-height || 0.5em
那么“半x-height⾼度”(0.5ex)⼤约是0.25em
再看CSS⾥的3个步骤:
⽔平居中不是问题
伪元素把⾏盒⾼度撑满容器,配合vertical-align: middle;把⾏盒基线位置拉到容器中⼼附近
内容中⼼点与⾏盒基线上⽅0.5ex位置对齐
看到这⾥很明确了,竖直⽅向根本没居中:
⾏盒基线不等于容器中⼼
⾏盒基线上⽅0.5ex处也不等于容器中⼼
最终两个中⼼是对不上的,所以这种⽅式实现的居中有瑕疵,存在像素级的差异,如下图:
css-center-inline
可以尝试⽤margin-top来修补,但因为⾏盒基线没有确定的计算⽅法,做不到完美修复,从Demo来看,0.25ex似乎最合适,实际应⽤中可能需要微调(如果在意像素级瑕疵的话)
优缺点
缺点:
存在像素级瑕疵⽆法解决,不是完美竖直居中
存在HTML空⽩字符占空间的问题(压缩HTML,或者容器font-size: 0,内容重置font-size),影响⽔平居中需要额外元素/伪元素
优点:
兼容[IE8+]
⽀持不定⾼度内容
在线Demo
P.S.样式、结构及注意事项都在源码⾥
参考资料
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论