接下来逐条累加不一样状况下的垂直居中实现。css
1. line-height行高简单粗暴实现法:line-height:Npx(N = 与元素高度相同的值)html
2. vertical-middle上场:前端
1. 帮多行文本找一个继父来领养他,让继父弥补父元素给他带来的伤害(行高和水平居中对齐的样式修改)css3
2. margin负边距简单处理一下底部小“裂痕”程序员
1. 新增兄弟节点实力辅助,目标元素轻松上王者chrome
1. 新增兄弟节点实力辅助,目标元素轻松上王者小程序
1. absolute定位飘起来浏览器
2. 上左50%方位值,先让左上角处于视图中心点ide
3. margin负边距,再让身子中心点挪到视图中心点布局
4. calc自动计算实现
1. absolute定位飘起来
2. 上左50%方位值,先让左上角处于视图中心点
3. translate -50%偏移,实现自动化偏移相应数值到中心点
1. 两端对齐交给爹地
2. 兄弟齐心,vertical-align: middle;实现居中布局
(一)灵魂辅助的vertical-align:middle值
(二)拥有家世渊源的table来救场
(三)带着尚方宝剑的display: table-cell
(四)小机灵鬼儿translate对应方向上的-50%
(五)flex大大一句话 水平垂直全拿下
实现方式:
正如N的值那样,这种解决方法就是要盒模型是有高度设置的。举例:
假如设计稿元素高度是300px,行高就设置为300px,这样,就能够实现垂直居中的问题。
.box1{ text-align: center; line-height: 300px; }
如图: 影视二字就能够垂直居中了。
可行性分析:就像图片中看到的那样,只有两个字,他们排在一行不会换行。因此实际应用中要确保必定是单行文本不会换行。由于一旦换行的话,行高就会应用于文字,因为行高过大的缘由,会致使剩下的文字跑出画面了。
如右图: 这种状况也可使用overflow:hidden;作一下保障措施。不过治标不治本。
另外补充一点:
有人看到这个现象可能会想是由于line-height致使的,那我给文字包裹一个框好比span,而后给span文字元素单独设置一个正常的行高不久能够了吗?
真的能够了吗?
看图:
中间文字部分就是span包裹的,并设置以下:
.box1 { text-align: center; line-height: 300px; } .span1 { line-height: 21px; display: inline-block; }
结果怎么样呢?
不只文字和行数少一点的时候,不能彻底的垂直居中。甚至文字再多会有这样的现象:
可见这种假设不合理。
因此单独设置一个行高就解决垂直居中问题看似大快人心,可是代码很不健壮,只局限于特别个别的状况。经不起考验。
那好,如今我直接使用这个方法实现一个宽高固定的图片垂直居中应该也很赞了吧?!
结果一顿操做这个结果我很不满意:
这不用比较也知道,个人图片没有上下垂直居中啊!毛线。那个标题还那么深,实例打脸。
但到底是由于什么呢?我往图片后边写了一个x辅助理解,发现图片底部和x字符的底部绝对是对齐的!!这下明白了吧!图片默认是文本基线对其的。文本垂直居中,就到垂直正中间那里。可是图片底部为了与文字底部对其,因此留给顶部的空间就很少了。没有x的时候会有一个空白的换行节点在捣鬼,这也是为何单独文字的时候看不出毛病,单独图片使用一样的方法却有问题的缘由。
啊,这就是听张鑫旭老师讲课的收获!
接下来,要实现单个图片的垂直居中效果我只须要让图片和文字水平一条线垂直对其就能够了。
.box1 { text-align: center; line-height: 300px; } img { vertical-align: middle; }
line-height配合vertical-align,搞定。
可是真的要1像素走查的时候,你又会发现,这种作法仍是不能彻底彻底的垂直居中,底部仍是差那么一两像素。这个问题接下来再说。
这种效果其实和中间只有一个图片一个道理,由于你须要帮多行文本找一个继父来领养他,因此结构上就是这样:
1 <div class="content-box"> 2 <div class="content">我是多行文本。多行文本水平垂直居中的原理跟上一页图片的实现是同样的,区别在于要把多行文本所在的容器的display水平转换成和图片同样的,也就是inline-block,以及重置外部继承的text-align和line-height属性值。</div> 3 </div>
中间content这个元素就比如一个图片,要实现他的水平垂直居中,那么他就得变成一个inline-block元素,(图片自己就是inline-block因此在上一段才没有强调。)
.content-box { line-height: 300px; text-align: center; } .content { width: 500px; display: inline-block; vertical-align: middle; }
不出乎意料的这里出现了上边两个出现过的问题:
1.由于父元素行高的缘由,content内部行高太高致使文字行距过大:
因此content内部就要单独设置行高以覆盖继承自父元素的值:ling-height:21px;(通常改成比字体大小大个四、5像素便可。)
2. 由于父元素要对inline-block的子元素content实行text-align:center;限制,致使content内部的文字都居中了,
因此须要text-align:left;纠正。
哇,我惊喜的发现,如今文字行数增多或减小,好像真的看上去垂直居中了哎!
等等,高兴的太早,又发现和单个图片垂直居中的相同问题,顶部和底部预留的空间好像不通常多啊!
红框是我加的before、after等伪类,以显示的让咱们看到上下的剩余空间相差多少。
这一点真的和以前的图片问题很接近:
我把两个例子的代码挪到一个html页面,惊奇的发现,底部剩余空间都是比顶部少4像素!
因而,一不作二不休,我直接使用margin负值让元素再以前的基础上向上4像素,竟真的实现了绝对的垂直居中。
总结:要想绝对的垂直居中,有了上边的核心代码设置外,还要加一个margin-top: -4px;就能够啦!
不过具体状况具体分析,换个页面,字体大小不同,对行高的影响也不同,天然误差也不必定是4像素,新的负数值再从新计算便可。
总结关键点:
一、父子齐心,line-height断难题。
二、鼎鼎大名,margin负边距。
可行性分析:这种再根据当前页或当前元素字体大小调整margin负边距大小值的作法实属有点不妥。
不过还好最近跟大神学了一招“万能胶”。这里暂且按下不表。请看下文如何不动声色且完美的解决这误差的几像素。
既然父元素高度不固定,那确定就没有line-height秀的机会了。
(特别说明,第三条系列中的父元素height值只是为了撑开而后填充背景色看的。高度不肯定不表明没有高度,因此这里是高度值随意改变,内部子元素永远垂直居中的独秀专场)。
那咱们派谁打头阵呢?只见父元素眯眼一想,span,让你的vertical-align出来表演一下吧!我再给你生个小弟弟大家一块儿秀!
不卖关子,直接上代码和解释:
<div class="box"> <img src="https://img1.mukewang.com/user/57a6f85b00013c7202090209-100-100.jpg" alt=""> <span class="assist"></span> </div>
.box { height: 200px; text-align: center; background: #f5f5f5; border: 1px solid #eee; } img { /* 第一步,元素inline-block化,由于图片自己是因此省去。 */ /* display:inline-block; */ /* 第三步,图片和辅助元素同时垂直居中对齐 */ vertical-align: middle; } span.assist { /* 第二步,0宽度100%高度的辅助元素 */ display: inline-block; height: 100%; /* 第三步,图片和辅助元素同时垂直居中对齐 */ vertical-align: middle; }
所谓三步走策略,这里偷懒把注释都写进代码里了。越是经典的解决方法越是直接背诵就行了。我就不喋喋不休分散看官的注意力了。
再不懂的去慕课网听张老师的课程。连接(3分27秒左右):https://www.imooc.com/video/10407。
1 <div class="box box2"> 2 <span class="txts"> 3 大小不固定的文字垂直居中 4 <br> 5 多行文本也能够哦! 6 </span> 7 <i></i> 8 </div>
.box2 span.txts { /* inline-block化,造成块状总体才适用垂直居中。 */ display: inline-block; vertical-align: middle; } .box2 i { display: inline-block; height: 100%; vertical-align: middle; }
这里css有偷懒,只是针对文本的设置,其余普通公用设置见上边第1条单个图片绝对垂直居中那里。
仍是给文本生个小弟弟陪他玩耍:
见第三条第二点。同理,单行文本换成多行便可。。。
这个很常见了,就很少说什么了:
直接上代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="author" content="guojufeng@ xing.org1^"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>宽高肯定的正经弹层</title> <style> .mask{ position: absolute; top: 0; right: 0; bottom: 0; left: 0; background: rgba(0,0,0,.5); } .layer{ width: 300px; height: 300px; position: absolute; top: 50%; left: 50%; /* margin: -150px auto auto -150px; */ margin-top: -150px; margin-left: -150px; text-align: center; background: #fff; border-radius: 8px; } span{ padding: 100px; display: inline-block; } </style> </head> <body> <h1>我是body里的内容,哦吼吼!xing.org1^</h1> <!-- 蒙层 --> <div class="mask"> <!-- 弹层 - 垂直居中实现 --> <div class="layer xingorg1"> <span>我是宽高固定的弹层元素,我实现了垂直居中。</span> </div> </div> </body> </html>
2019-03-03 15:41:55 补calc写法实现:
此次重点说说来救场的transform:translate(负值%);
css3中,translate就是指定元素像对应方向偏移,x是水平偏移,y是垂直方向的偏移,由于这篇是方法汇总,不作过多介绍,请自行查看w3c或实验。也看移驾这篇文章:http://www.javashuo.com/article/p-vxemvgjy-kc.html
不过他有一个屌炸天的特性是,当偏移数值的单位为百分比的时候,会相对于自己的长宽来计算偏移值。
好比元素的宽度是300px的时候,咱们让他再向左移动50%宽度,配合上left:50%;就能实现居中。
恰好,translateX(-50%)自动计算获得的就是元素自身宽度的50%值。因此,咱们不须要知道目标元素的宽高也同样能实现居中了。
对于这一特性,这个慕课网问答这里讲的很好:http://www.imooc.com/qadetail/129282
他除了适用于这个弹层的场景,一样适用于其余场景的居中。由于即便不浮动,translate移动对兄弟元素没有影响。
请看:
这种现象和margin移动不同。只不过其余场景使用translate有点大材小用。
box盒使用固定宽度的width+margin auto,实现水平居中。
position:relative,top: 50%;实现垂直方向的偏移。
由于没有高度固定,因此没法确切的使用margin-top负值实现垂直居中
可是translateY属性,会自动根据盒子高度计算偏移值。translateY(-50%)就会向上偏移50%的高度值。因此:
position:relative(或者absolute); + top: 50%; + transform:translateY(-50%);能够实现垂直方向的绝对居中效果。
可是,学习就要触类旁通,咱们一样能够
position: absolute;
left: 50%;
transform: translateX(-50%);
同样能够实现!
那么,若是跟以前的垂直居中合并起来的话,transform是否是也能够写一条呢?
固然,具体写法以下:
transform: translate(-50%,-50%);
好了,废话说的再多也不如贴源码运行一探究竟:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="author" content="guojufeng@ xing.org1^"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>translateY实现垂直居中</title> <style> html, body, ul { height: 100%; margin: 0; } .mask { position: absolute; top: 0; right: 0; bottom: 0; left: 0; background: rgba(0, 0, 0, .5); } .layer { position: absolute; top: 50%; left: 50%; /* transform: translateX(-50%) translateY(-50%); 这种写法也能够,至关于写两个translate*/ transform: translate(-50%,-50%); text-align: center; background: #fff; border-radius: 8px; } .box { /* width: 500px;*/ /* height: 350px; */ padding: 30px 10px; background: rgba(255, 51, 255, 0.2901960784313726); } </style> </head> <body> <h1>我是body里的内容,哦吼吼!xing.org1^</h1> <h1>translate负值实现元素的水平垂直居中</h1> <!-- 蒙层 --> <div class="mask"> <!-- 弹层 - 垂直居中实现 --> <div class="layer xingorg1"> <div class="box"> <ul> <li>关键点</li> <li>left: 0; right: 0; bottom: 0; margin: auto;</li> <li>top: 50%;</li> <li>transform: translateY(-50%);</li> <li>这些li是为了撑开box的高度</li> </ul> </div> </div> </div> </body> </html>
可是,bug来的太忽然、、、2018-09-26 10:29:06
上边的gif太快,是否是没发现这个方法的一个问题呢?
来个静态截图:
没看出来?那看下边这个图:
发现了吗?
div.box 我并无设置宽度,可是他默认展现的最大宽度(在没有border和padding的状况下),是父元素(body)宽度的50%!
后来我就想由于什么?
在张鑫旭大神的absolute课程中,讲过方位值left和right这些,若是设置50%,是从父元素本来宽度的50%处开始左边距的。(固然这不是人家的原话,是个人理解)。
也就是说,在我不设置right的状况下,left:50%;也就至关于这个box盒子剩下的活动空间就是从left: 50% 到 最右边了。
要说明这个,其实直接去掉transform的居中效果就能够一眼看出来了:
若是再狠点,right也设置50%,那box的宽度就被挤没了。
发现这个问题后,我恍然大悟虽然这个方法很好用,可是他仍是有不少局限性。最好只用在垂直居中上,毕竟有不少场景不适用。
好比这种:
我要想要中间那块根据文案的多少,宽度自适应,而且还能永远水平居中的话,就不适用上边这种方案,否则会发生车祸现场:
那么,这种状况的水平居中该怎么作呢?
一眼明了,水平居中简单吧!直接给内联元素的父亲设置text-align就好了。
不过最近我又发现了原理差很少的另外一种absolute定位元素实现居中的写法,现补充以下:(2019-01-08 14:45:04 )
上下左右0+自适应的margin实现
以下:
给一个宽高300的定位元素垂直水平居中。
* 注意这里宽高300虽然有要求,可是经我实际测试,宽高自动增删都不影响垂直水平居中,说明在宽高不定的元素中,也就能够实现。
不说废话了,代码以下:
<div class="clas class3">test3</div>
css:
先看诱惑人的结果,就是无论文字单行仍是多行,无论图片改为多大,都能实现的效果:
而后再说解决方法。核心就是用了 vertical-align:middle;
html结构:
<div class="box"> <span>单行文字</span> <img src="https://img1.mukewang.com/user/57a6f85b00013c7202090209-40-40.jpg" alt=""> </div> <div class="box"> <span>多行文字<br />文字文字文字文字<br />文字文字文字文字</span> <img src="https://img1.mukewang.com/user/57a6f85b00013c7202090209-40-40.jpg" alt=""> </div> <div class="box"> <span>由于vertical-align只对inline/inline-block元素起做用,而浮动会让元素block水平化,就不能使用vertical-align对齐了</span> <img src="https://img1.mukewang.com/user/57a6f85b00013c7202090209-40-40.jpg" alt=""> </div>
关键点1:外边的box实现两端对齐
由于vertical-align只对inline/inline-block元素起做用,而浮动会让元素block水平化,就不能使用vertical-align对齐了。
因此这里才用 text-align: justify; 附加给父元素,实现图文的两端对齐效果
关键点2:文本span元素
vertical-align: middle;
这里文本由于须要有个宽度值限制,因此inline-block化了,要知道,不是必须便可。
关键点3:img元素
vertical-align: middle;
具体见上边第三条的例子,用一个span空标签放到须要垂直居中元素的后边或者前边,做为辅助兄弟元素。
同时给这个辅助元素和目标元素vertical-align:middle; display:inline-block;一顿操做便可。
css 中有一个用于竖直居中的属性 vertical-align,在父元素设置此样式时,会对inline-block类型的子元素都有用。
就像上例中辅助元素的vertical-align原理同样,td 标签默认状况下就默认设置了 vertical-align 为 middle,因此咱们不须要显式地设置,使用table布局就能够完成完美的自动水平垂直居中了。
可是这种布局方式毕竟拘束,在实现垂直居中后,还须要一大堆的代码把tabel的样子抹掉。
因此知道有这种方法,平时根本不用也不必用,我也不去实践了。
即,设置块级元素的 display 为 table-cell。
之因此说display:table-cell; 是带着尚方宝剑的,是由于这么作就至关于设置为表格单元显示。
但这种方法兼容性比较差,只是提供你们学习参考。
在 chrome、firefox 及 IE8 以上的浏览器下能够设置块级元素的 display 为 table-cell(设置为表格单元显示),激活 vertical-align 属性,
注意 IE六、7 并不支持这个样式, 兼容性比较差。
<div class="container"> <div> <p>看我是否能够居中。</p> <p>看我是否能够居中。</p> <p>看我是否能够居中。</p> </div> </div>
<style> .container { height:300px; background:#ccc; display:table-cell; /*IE8以上及Chrome、Firefox*/ vertical-align:middle; /*IE8以上及Chrome、Firefox*/ } </style>
这种方法的好处是不用添加多余的无心义的标签,但缺点也很明显,它的兼容性不是很好,不兼容 IE六、7并且这样修改display的block变成了table-cell,破坏了原有的块状元素的性质。
具体原理和使用方法及案例见上边。再也不赘述。
这个相信不用我说,你们一看就明白怎么回事了。
Flex弹性盒布局属性,此系列中还有两个属性justify-content 和 align-items 分别用于实现水平居中和垂直居中。
具体flex的学习能够参考这两篇:
Flex 布局教程:语法篇 做者: 阮一峰
http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
Flex 布局教程:实例篇做者: 阮一峰
http://www.ruanyifeng.com/blog/2015/07/flex-examples.html
简易的代码见下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="author" content="guojufeng@ xing.org1^"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>万能方法</title> </head> <body> <div class="flex xingorg1"> <span>前端小学生~ _xing.org1^</span> </div> <div class="flex xingorg1"> <span>不会搞艺术的程序员不是好的设计师 _xing.org1^ 不会搞艺术的程序员不是好的设计师 _xing.org1^ </span> </div> <style> .flex{ margin-bottom: 10px; padding: 20px; width: 300px; height: 300px; background: #f5f5f5; border: 1px solid #eee; /* flex写法 */ display: flex; justify-content: center; align-items: center; } </style> </body> </html>
虽然说古老的ie不支持这种布局,可是写上hack后,用在移动端的项目中简直完美啊。
小程序不就默认这么写的么。
2018-09-11 12:42:49
声明:
请尊重博客园原创精神,转载或使用图片请注明:
博主:xing.org1^
出处:http://www.cnblogs.com/padding1015/