【翻译】关于vertical-align所有你需要知道的
本文是翻译过来的,如果有不对的地方还请指教~,原文链接:Vertical-Align: All You Need To Know
前面一些说明,可以略过不看吧
我经常需要对元素进行垂直方向上的布局。
CSS提供了一些方法来实现这个功能,比如float,position: absolute,手动地增加margin或padding。
我并不是很喜欢这些方法。Floats只能让元素在顶端布局,而且需要手动清除浮动。absolute定位让元素离开文档流,且不再影响它的周围环境。利用固定的margigin和padding会让布局不够灵活。
但还有另一个方法:vertical-align。我想它应该得到更多的信任。技术上,使用vertical-align来布局是一个hack。因为,它不是为此而设计的。它主要是用来布局文本和文本旁的元素。当然,你也可以在不同的上下文中用vertical-align来灵活地布局元素。该方式下,元素的大小不需要被知道,元素在文档流中,其它元素可以对它的改变做出相应改变。
古怪的vertical-align
vertical-align有时很奇怪。使用它有时会让人沮丧。比如,对于有些元素设置vertical-align后它会有影响,但是有些却不会。我仍然在vertical-align的黑暗中一次又一次摸索。
不幸的是,大多数的分析比较表面。尤其是如果我想用vertical-align进行布局。他们主要关注解释尝试利用vertical-align来布局一个元素中所有元素是一个错误。他们给出了vertical-align的基本介绍,并说明在一些简单情况下元素如何布局。但是,他们没有解释tricky的部分。
所以,我把这篇文章的目标设置为:一次性完全地阐明vertical-align的行为。通过学习W3C CSS规范以及一些实例得到这篇文章。
正文开始——
一、哪些元素可以使用vertical-align
vertical-align是用于inline级元素。这些元素的display属性为:
- inline:包裹文本的基本标签
- inline-block:块元素以inline方式呈现。它们可以设置宽度和高度,也可以设置padding、border和margin
- inline-table(在本文中没有考虑)
inline级元素分布在一个行中。如果元素过多在一行中放不下时,那么一个新行就会在下面被创建。所有这些行都叫做line盒子,它包裹了这一行中的所有内容。不同的内容大小意味着line盒子有不同的高度。下图用红线标出line盒子的顶边和底边。
line盒子会勾勒出在其中内容的轮廓。在这些line盒子中,vertical-align用于对一个独立的元素进行布局。
二、基线baseline和外边缘outer-edge
垂直布局的最重要的关键点是它包含的元素的基线。在有些情况下,包裹元素的line盒子的顶边和底边也很重要。让我们来看看不同元素类型的基线和外边缘。
inline元素
图中线的标识说明:红线:line height顶边和底边;绿线:字体font的高度font-size(=基线上方的高度+基线下方的深度);蓝线:基线
line-height = font-size的高度 | line height = font-size的2倍 | line height = font-size的一半 |
inline元素的外边缘让元素布局在line的顶边和底边之间。如果line-height小于font的高度,这就不重要了。所以,外边缘就是图中的红线。
inline元素的基线是字符所在的位置。就是图中的蓝线。粗略地说,就是字体高度的中间的下方。
inline-block元素
元素盒子模型:红线:外边距margin;黄色:border,绿色:padding,蓝色:内容区域;蓝线:inline-block元素的基线
inline-block元素的外边缘是它的margin的顶边和底边,就是上图中的红线。
inline-block元素的baseline依赖于元素是否包含处于在正常流中的内容
inline-block元素中一个字符c inline-block元素的baseline为正常流中的 最后一个内容元素的baseline |
inline-block元素中一个字符c,且overflow: hidden inline-block元素的baseline为盒子margin的底边 |
inline-block元素中没有内容,但是为内容区域设置了宽高 inline-block元素的baseline为盒子margin的底边 |
line盒子
text盒子在line盒子中,它的顶边和底边由图中绿色标识。这个text盒子可以看作是一个line盒子中没有任何布局的inline元素。它的高度与父元素的font-size高度对应。因此,text盒子就是包含line盒子中未格式化的文本。也就是图中的绿色部分。因为,text盒子与baseline是绑定在一起,当baseline移动时它也会随着移动。
对文本元素用灰色进行标亮
line盒子顶边与最上面元素的顶边一致,line盒子底边与最下面元素的底边一致。它是由红线标识。
line盒子的基线由蓝线标识。因为line盒子的基线是不可见的,可能不是很明显看到baseline在哪。但是,你可以在line的开头添加一个字符,比如图中的X,如果这个元素没有用任何方法布局,那么它默认在baseline上。
CSS 2.1 does not define the position of the line box's baseline.
这可能是最令人疑惑的部分。这意味着,baseline被放置在需要满足其它条件如vertical-align以及最小化line盒子的高度。
总结两点
- line盒子,它是垂直布局发生的位置。它有baseline,text盒子,顶边,底边
- inline级元素。它们是被布局的对象。它们有baseline,顶边和底边(font-size)
三、vertical-align的值
vertical-align不同的设置值相对于不同的元素
默认值为baseline
- 根据line盒子的baseline分布元素的baseline
baseline | sub | super | <percentage> | <length> |
与line盒子baseline重合 | line盒子baseline下 | line盒子baseline上 | 相对于line-height的大小 | 绝对长度 |
- 根据line盒子的baseline分布元素的外边缘
middle:元素顶边、底边的中点是在(line盒子baseline+X高度一半)位置
- 根据line盒子的text盒子分布元素的外边缘
text-top:元素的顶边与line盒子的text盒子的顶边重合
text-bottome:元素的底边是line盒子的text盒子的底边重合
- 根据line盒子的外边缘分布元素的外边缘
top:元素的顶边和line盒子的顶边重合
bottom:元素的底边和line盒子的底边重合
四、为什么vertical-align以这种方式来呈现?(几个实例)
让一个icon和文本都垂直居中
<!-- left mark-up -->
<span class="icon middle"></span>
Centered?
<!-- right mark-up -->
<span class="icon middle"></span>
<span class="middle">Centered!</span> <style type="text/css">
.icon { display: inline-block;
/* size, color, etc. */ }
.middle { vertical-align: middle; }
</style>
Centered? 没有设置样式,默认在基线上 因为取的是小写字母x的高度,而C是大写, 所以Centered?看起来并没有垂直居中 |
对Centered!设置垂直居中 |
line盒子基线移动
为了满足vertical-align的布局设置,line盒子的基线会自动发生移动
情形一
<!-- left mark-up -->
<span class="tall-box text-bottom"></span>
<span class="short-box"></span>
<!-- right mark-up -->
<span class="tall-box text-top"></span>
<span class="short-box"></span>
<style type="text/css">
.tall-box,
.short-box { display: inline-block;
/* size, color, etc. */ } .text-bottom { vertical-align: text-bottom; }
.text-top { vertical-align: text-top; }
</style>
两个元素一高一矮,矮的不设置分布,默认在baseline上 高的设置text-bottom |
两个元素一高一矮,矮的不设置分布, 默认在baseline上 高的设置text-top, 而text盒子是在baseline周围, 为了让高的能实现text-top布局, 所以需要让baseline上移 |
- 情形二
<!-- left mark-up -->
<span class="tall-box bottom"></span>
<span class="short-box"></span>
<!-- right mark-up -->
<span class="tall-box top"></span>
<span class="short-box"></span>
<style type="text/css">
.tall-box,
.short-box { display: inline-block;
/* size, color, etc. */ }
.bottom { vertical-align: bottom; }
.top { vertical-align: top; }
</style>
高:vertical-align: top 矮:默认 |
高:vertical-align: bottom 矮:默认 虽然设置的是相对于line盒子的top, 基线也会上移 |
- 情形三
<!-- left mark-up -->
<span class="tall-box text-bottom"></span>
<span class="tall-box text-top"></span> <!-- mark-up in the middle -->
<span class="tall-box text-bottom"></span>
<span class="tall-box text-top"></span>
<span class="tall-box middle"></span> <!-- right mark-up -->
<span class="tall-box text-bottom"></span>
<span class="tall-box text-top"></span>
<span class="tall-box text-100up"></span> <style type="text/css">
.tall-box { display: inline-block;
/* size, color, etc. */ } .middle { vertical-align: middle; }
.text-top { vertical-align: text-top; }
.text-bottom { vertical-align: text-bottom; }
.text-100up { vertical-align: 100%; }
</style>
两个较高的元素, 一个text-top,一个text-bottom |
增加第三个元素,设置为middle 该元素没有超过line盒子的边界,故 对baseline位置和line盒子高度没有影响 |
增加第三个元素,设置为vertical-align: 100% 左图是原文的,右图是自己实现的,好像有点不太一样 黄色部分元素x的基线应该在line盒子基线上line盒子高度的100% |
- inline级元素底部有小间隙
比如布局一个li列表,这是由于baseline底部会留一些空间来放置文本的下行部分
<ul>
<li class="box"></li>
<li class="box"></li>
<li class="box"></li>
</ul> <style type="text/css">
.box { display: inline-block;
/* size, color, etc. */ }
</style>
解决方案:让这些元素设置成vertical-align
<ul>
<li class="box middle"></li>
<li class="box middle"></li>
<li class="box middle"></li>
</ul> <style type="text/css">
.box { display: inline-block;
/* size, color, etc. */ }
.middle { vertical-align: middle; }
</style>
这种情形不会在有文本内容的inline-block元素中发生,因为内容已经把baseline移到上方
inline级元素水平方向的间隙会破坏布局
两个inline-block宽度都设置为50%,且html中有换行符,那么导致这两个元素间会有一个间隙,一行放不下它们,第二个元素会被放在第二行
<!-- left mark-up -->
<div class="half">50% wide</div>
<div class="half">50% wide... and in next line</div> <!-- right mark-up -->
<div class="half">50% wide</div><!--
--><div class="half">50% wide</div> <style type="text/css">
.half { display: inline-block;
width: 50%; }
</style>
- span和input
<div style="height: 40px;">
x
<span style="border: 1px solid red; display: inline-block; height: 100%; width: 50px;"></span>
<input type="text" style="height: 100%; border: 1px solid green;">
</div>
五、让vertical-align不再神秘!
当vertical-align并不如你所相像地那样表现,那么请考虑以下两个问题:
- line盒子的baseline、顶边、底边在哪?
- 内联级元素的baseline、顶边、底边在哪?
我的个人总结(非翻译)
- 文本只根据line-height来进行布局:垂直居中(父子中大的line-height)
- line-height和height总是取较大的值
- 文本的line-height和height再小也会让文本显示
- 先根据line-height进行布局,height变到很小的时候,文本的下方区域会变小,直到文本底边,上方区域不变
【翻译】关于vertical-align所有你需要知道的的更多相关文章
- Loser应该知道的6个残酷人生事实(血泪翻译)
Loser应该知道的6个残酷人生事实(血泪翻译) - Acfun - 天下漫友是一家 Loser应该知道的6个残酷人生事实(血泪翻译)
- What is Vertical Align?
https://css-tricks.com/what-is-vertical-align/ ************************************************* CSS ...
- [技术翻译]您应该知道的13个有用的JavaScript数组技巧
本次预计翻译三篇文章如下: 01.[译]9个可以让你在2020年成为前端专家的项目 02.[译]预加载响应式图像,从Chrome 73开始实现 03.[译]您应该知道的13个有用的JavaScript ...
- 十件你需要知道的事,关于openstack-trove(翻译)
开源数据库即服务OpenStack Trove应该知道的10件事情 作者:Ken Rugg,Tesora首席执行官 Ken Rugg是Tesora的创始人,CEO和董事会成员. Ken的大部分职业都是 ...
- Android 程序员必须知道的 53 个知识点
1. android 单实例运行方法 我们都知道 Android 平台没有任务管理器,而内部 App 维护者一个 Activity history stack 来实现窗口显示和销毁,对于常规从快捷方式 ...
- 关于WPF你应该知道的2000件事
原文 关于WPF你应该知道的2000件事 以下列出了迄今为止为WPF博客所知的2,000件事所创建的所有帖子. 帖子总数= 1,201 动画 #7 - 基于属性的动画 #686 - 使用动画制作图像脉 ...
- 每个极客都应该知道的Linux技巧
每个极客都应该知道的Linux技巧 2014/03/07 | 分类: IT技术 | 0 条评论 | 标签: LINUX 分享到:18 本文由 伯乐在线 - 欣仔 翻译自 TuxRadar Linux. ...
- 我们必须要知道的RESTful服务最佳实践
看过很多RESTful相关的文章总结,参齐不齐,结合工作中的使用,非常有必要归纳一下关于RESTful架构方式了,RESTful只是一种架构方式的约束,给出一种约定的标准,完全严格遵守RESTful标 ...
- 隔壁小孩都要知道的Drupal配置
i春秋作家:Arizona 原文来自:隔壁小孩都要知道的Drupal配置 隔壁小孩都要知道的Drupal配置 Drupal是一个开源的PHP内容管理系统,具有相当复杂的架构.它还具有强大的安全模型.感 ...
随机推荐
- Javaweb学习笔记——(十二)——————JSP指令:page指令、include指令、taglib指令,JavaBean,内省,EL表达式
JSP指令JSP指令分类 JSP有三大指令: *page指令 *include指令 *taglib指令 在JSP中没有任何指令是必须的. 但基本上每个JSP都是使用page指令============ ...
- 服务器上定时自动执行php
两种方式: 一.Linux 服务器Linux原生支持crontab,所以可以利用这一功能做定时任务 步骤: 1.编辑crontab文件:Linux:crontab -e 2.输入代码:0 0 * * ...
- mysql插入记录INSERT与多表更新
1.第一种:INSERT [INTO] tbl_name[ (col_name, ... ) ] {VALUES | VALUE}({expr |default}, ... ), (...), .. ...
- 卷积中的full、same、valid
通常用外部api进行卷积的时候,会面临mode选择. 本文清晰展示三种模式的不同之处,其实这三种不同模式是对卷积核移动范围的不同限制. 设 image的大小是7x7,filter的大小是3x3 ...
- 使用函数输出水仙花数 (void的用法)
6-11 使用函数输出水仙花数 (20 分) 水仙花数是指一个N位正整数(N≥3),它的每个位上的数字的N次幂之和等于它本身.例如:153=13+53+33. 本题要求编写两个函数, ...
- JQuery属性选择
css: JQuery基本选择器: 解释 层叠选择器:
- (6)Java数据结构-- 转:JAVA常用数据结构及原理分析
JAVA常用数据结构及原理分析 http://www.2cto.com/kf/201506/412305.html 前不久面试官让我说一下怎么理解java数据结构框架,之前也看过部分源码,balab ...
- 用v-for进行table循环
<table class="mytable mt10"> <template v-for="(item,index) in device_fault&q ...
- 线程变量---ThreadLocal类
用处:保存线程的独立变量.对一个线程类(继承自Thread) 思想:如果一个资源会引起线程竞争,那就为每一个线程配置一个资源.相比于synchronized是一种空间换时间的策略 当使用ThreadL ...
- mybatis-plus调用自身的 selectById 方法报错:org.apache.ibatis.binding.BindingException:
mybatis-plus的版本号是 2.0.1,在调用自身的insert(T)的时候没有报错,但是执行update报错,调用selectById.deleteById的时候也报错.也就是涉及到需要主键 ...