报名成功百度的前端学院挑战之后,我的两名队友就很快消失了。磊神看了遍题说太简单没意思,皇上嘴上说要做要做身体却去了GDC。于是我一个人开始写,能写几个是几个吧。这个学习笔记来自第二题里面的导航垂直居中。新手向。
垂直居中比水平居中麻烦。尤其是像我这样的初学者,望文生义觉得一个 vertical-align:middle
应该就可以搞定,却往往不奏效,很挫败。
这篇老文里用三句话总结了这个问题的根源:
- HTML layout traditionally was not designed to specify vertical behavior. By its very nature, it scales width-wise, and the content flows to an appropriate height based on the available width. Traditionally, horizontal sizing and layout is easy; vertical sizing and layout was derived from that.
- The reason vertical-align:middle isn’t doing what is desired want is because the author doesn’t understand what it’s supposed to do, but …
- … this is because the CSS specification really screwed this one up (in my opinion)—vertical-align is used to specify two completely different behaviors depending on where it is used.
即
- HTML设计时重点就是在水平布局上,垂直上基本指导思想是简单粗暴的「宽不够,高来凑」。 这就从根本上导致水平上调整起来容易,垂直上比较难。
vertical-align
不好用的原因很简单,那就是我们用错了,它不是类似text-align:center
那样直接的用法。- 而这种误用也怪不得大家,是CSS的设计者在一开始就设计的很奇葩:同一个
vertical-align
在两种情景下,作用完全不同。
具体来说,在 table
中,如果一个单元格的CSS里写了 vertical-align:middle
,那么这个单元格就会像我们预期的那这样,内容垂直居中显示。同理,如果是 vertical-align:bottom
,则是贴近底部显示:
vertical-align:middle 居中(默认) |
vertical-align:bottom 底部 |
但前边说了,这只是在 table
这一种情境下。作为其他行内元素的样式时,vertical-align
的作用则完全不同:它决定的,与其说是一个元素在父元素中的垂直位置,不如是同一行里的多个元素以什么基准线对齐。
CSS-Tricks的这篇文章将这种情况下 vertical-align
的作用及其几种常见值梳理的很清楚。比如以下几个:
默认的基线对齐
常用的中间对齐。将元素的垂直中点,与父元素中小写字母的垂直中点对齐。
顶部对齐。将元素顶部与行顶部对齐。
底部对齐。将元素底部与行底部对齐。
看上去很直观,但我最烦CSS的一点就是表面看起来都是理所当然的废话,一写全是坑。上边这几条,尤其是在「居中」时候最喜欢的 vertical-align:middle
,实际使用中,并不是表面上读来那么容易理解。比如让icon对齐文字这么一个简单需求,实际写出来,总是诡异地差着那么几个像素。更多的时候,可能是写完自信满满的一刷新,发现页面根本没啥变化。
这篇《Vertical-Align: All You Need To Know》是我找到的最说人话的解释了,但读了三遍了还是似懂非懂,下篇博文就专门翻译下,帮助自己理解好了。
最后说下我找到的让文字导航居中的3个方案:
1.table
+ table-cell
+ vertical-display:middle
既然前边说过 vertical-align
在 table
中十分听话好使,让文字往哪里对齐就往哪里对齐。那就把要对齐的东西当成表格处理。具体做法是,给要对齐的元素的 父元素 加 display:table
,给要对齐的元素 本身 添加 display:table-cell
,然后再用 vertical-align:middle
就可以了。
HTML:
<div>
<ul>
<li><a>导航项目1</a></li>
<li><a>导航项目2</a></li>
<li><a class="text_bottom_alligned">体重过大的导航项目3</a></li>
</ul>
</div>
CSS:
li{
list-style: none;
margin-left: 50px;
height: 60px;
float: left;
display: table;
}
a{
display: table-cell;
vertical-align: middle;
}
a.text_bottom_alligned{
vertical-align: bottom;
}
2.绝对定位
抛弃不好懂的 vertical-align
,直接用绝对定位。具体做法是,将要对齐的元素设置为 position:absolute
(相应的父元素应该为 position:relative
),然后用 top:50%
让元素顶部垂直居中,再用 margin-top: -5
(此处数值应该为元素高的1/2)或 transform: translate(0, -50%)
抵消被挤下去的位置,完成居中。
HTML:
<div>
<ul>
<li><a>导航项目1</a></li>
<li><a>导航项目2</a></li>
</ul>
</div>
CSS:
li{
list-style: none;
height: 60px;
width: 5em;
float: left;
margin-left: 50px;
position: relative;
}
a{
postion: absolute;
top: 50%;
margin-top: -0.5em;
}
3.行高 line-height
对于单行文字来说,其实只需要文字本身的高度等于它所在的行高,文字自然就会居中。跟前边两个方法想必,这个简单的多。
HTML:
<div>
<ul>
<li><a>导航项目1</a></li>
<li><a>导航项目2</a></li>
</ul>
</div>
CSS:
li{
list-style: none;
height: 60px;
width: 5em;
float: left;
margin-left: 50px;
}
a{
line-height:60px;
}
前几天去观摩了微软的学生创业大赛,一等奖是个叫「Clove」的和「回家吃饭」一模一样的App。不过 Clove 主打的是有机、生态那一套东西,一看就知道服务的是这边一天两回gym的中产阶级。而在中国类似的产品的卖点大概是个「你妈喊你」的归属感吧,所以红烧肉好像卖的特别好。
有工夫算一盘菜有多少卡路里的当地小孩可真幸福。