摘要:不同的块级元素的行系统各自独立,就算它们有父子关系。再次注意控制的是内联元素在其所在行的行内居中,它只对带有特性的元素起作用,包括内联块元素。其实这个值对于行中的内联块元素同样有效。
哪里说起呢?就从一道老生常谈的前端面试题开始吧。
块级元素与行内元素问:块级元素和行内元素有什么区别?
估计各位同学都在各种前端面试中被问到过,当然也在各种网站上搜寻过答案。要真正罗列两者的区别可以找到很多,然而从本质上讲,就是这样的区别:
块级(block)元素可以控制它的大小
行内(inline)元素将其排到父级的行系统中
我更愿意把这两者称作为元素的两个特性。因为行内元素具有 inline 特性,所以多个行内元素会排在一行;但它们不具有 block 特性,所以无法使用 width、height 指定它们的宽高。因为块级元素具有 block 特性,所以可以直接指定元素的宽高;因为块级元素不具有 inline 特性,所以它们会独占一行。
这两个特性还可以叠加:同时具有 inline 和 block 特性的就是行内块(inline-block)元素,既可以设定宽高,也会排到行系统中。如果两个特性都不具备,那么就是 display: none。
注意这里所说的 block 和 inline 都是相对于同级元素而言的,对于元素的子级又有不同的布局方式。如果指定不同子节点的布局方式与 block、inline 特性叠加,又有了 table(具有 block 特性、子元素使用 table 方式布局)、inline-table(具有 inline、block 特性,子元素使用 table 方式布局),flex、inline-flex,grid、inline-grid 等等。
有了这样的概念,就可以解释一些特殊的现象。比如 text-align 对块级元素不起作用:因为块级元素所在的行独立于父级行系统之外,一个设置行内位置排布的 CSS 属性当然不会起作用。再比如 margin: 0 auto 只对块级元素起作用:因为只有块级元素独占一行,它才有充足的空间自由的在行中排布。
请再次注意:text-align 排的是元素的子节点,而 margin 排的是元素本身。
HTML 页面默认采用流式布局,水平方向和竖直方向是不对等的。在默认情况下,HTML 页面中的文字总是会按书写顺序(writing-mode)横着从左往右排,一行占满之后会在这行的下面另起一行。text-align 不是不能对竖直方向其作用,只需要当前的行系统是竖排的(writing-mode: vertical-lr)。margin: auto 0 默认情况下不会将一个块级元素竖直居中,因为缺少 inline 特性只是让元素独占一行,而不会让他独占一列。
想让水平方向和竖直方向对等也很简单:position: absolute,如果再使用 top: 0; bottom 0; 将元素竖直占满一列,就可以使用 margin: auto 0 将元素竖直居中。
行系统那块级元素和表格元素有什么区别?区别是:块级(block)元素使用行系统布局子节点。
所谓行系统就是基于行的子节点排布方式,默认情况下从左往右依次排列,超出一行时就折行。每个块级元素都有自己的行系统,block 元素如此,inline-block 元素也如此。不同的块级元素的行系统各自独立,就算它们有父子关系。你完全可以把某个块元素左对齐,然后把其子级的行内块元素右对齐,没有任何问题。
既然有了行的概念,那么每行占多高呢?这就有了行高的概念,由 CSS 属性 line-height 控制,默认值为 normal,不同的浏览器对 normal 的处理不一致,你也可以手工指定其值。可以是一个数字,表示当前元素的 font-size 的倍数,也可以是一个绝对值,多少像素等。
元素的行高可以很大,也可以很小,也许放下行中的元素后上下还有空余,也许刚刚好,也许根本放不下。控制行中节点位置的 CSS 属性是 vertical-align,默认是 baseline。
行中最常存放的节点是文本。由于各个字符的高度各不相同,为了显示的整齐,不能通过简单的对齐上下两边或中心排列行中的字符。每个字符都需要有一个基准去做对齐,这样就有了基线(baseline)的概念。
可以看到图片中的后几个字母 hinx 下边都有一两个短横,它们叫做衬线,带有衬线的字体叫做衬线字体。它们在同一条直线上,这条直线所在的位置就是基线。文本默认按照基线对齐,基线的位置跟当前字体有关,不同的字体位置不同。当行高超出最大字符高度时,基线会往行中间移动,这就是为什么把 line-height 的值设置为父元素高度时可以将文本竖直居中的原因。
vertical-align 还有几个可选值,其中最常用的应该是 middle 了。各位同学应该遇到过这样的问题:给一个内联块元素设置了 vertical-align: middle,但这个元素并非在正中,总会偏离一点点。vertical-align: middle 其实并不是把元素绝对的居于父元素中间(不要看 w3school 等上面的初学者向文档),MDN) 上给的官方说明为:
元素中垂线与父元素的基线加上小写x一半的高度值对齐。
vertical-align: middle 的对齐方式与父元素的基线和字号有关,然而这个值未必就是父元素的中线。那么解决的方法也很简单,设置父元素 font-size: 0,字号为 0 时基线必然在元素正中,这个 小写x一半的高度值 也必然是 0。
额对了,font-size: 0 还有一个用处是干掉多余的空格,这在使用 display: inline-block 做横向布局时非常有用。
再次注意 vertical-align 控制的是内联元素在其所在行的行内居中,它只对带有 inline 特性的元素起作用,包括内联块元素。另外如果你用 vertical-align: middle 使某元素竖直居中于父元素中间,记得同时设置 white-space: nowrap,防止多个元素折行。
前面提到了 text-align,除了常用的 left、center、right 取值以外,还有一个很有用的取值:justify——两端对齐。在只有一行时,两端对齐就相当于左对齐;但是有多行时,两端对齐会将除最后一行外的前面所有行按单词(空白字符)拆分均匀分散对齐。其实这个值对于行中的内联块元素同样有效。
为了使 text-align: justify 生效,你必须保证有多行(只对最后一行之前的行生效),必须保证相邻内联块元素中间有空白字符(并且字号不能为 0)。前者可以通过一个 display:inline-block; width: 100% 的伪元素实现(伪元素作最后一行);后者如果是手写的 HTML 基本一般通常都会有,如果是用 ng-repeat、v-for 生成的元素就要非一些力气手工制造出来。
text-align: justify 这个相对 hack 的用法有很高的浏览器兼容性,需要兼容 IE8 的同学或多或少应该都有使用过,可能也遇到过各种各样的问题。后来的伸缩盒(flex)布局中有更加好用的 justify-content: space-between 是此属性的绝佳替代品,这是后话。
还有一些 CSS 属性控制行系统的布局方式。除了前面的提到的 text-align 和 white-space,还有 word-wrap(控制折行时是否允许拆分单词)、text-overflow(控制超出一行时的处理方式)等等。除此之外,常用的 margin、padding 对于行内元素的效果也有不同之处,留给各位同学自己发现。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/112460.html
摘要:行高行距半行距从上到下四条线分别是顶线,中线,基线,底线。行高指文本行基线间的垂直距离。上图任意两条相同颜色的垂直距离也是行高。父元素不同的行高单位影响子元素的继承。 行高、行距、半行距 showImg(https://segmentfault.com/img/bVAdEh); 从上到下四条线分别是 顶线,中线,基线,底线。 行高 指文本行基线间的垂直距离。上图任意两条相同颜色的垂直距...
摘要:前言多行文本超出高度限制出现省略号移动端多为内核的有扩展属性但并不是规范中的属性端往往要借助去实现这一效果,但麻烦且不是很靠谱,今天就用纯来实现一个完全兼容的多行省略。 前言 多行文本超出高度限制出现省略号 , 移动端多为webkit内核的 , 有扩展属性-webkit-line-clamp , 但并不是CSS规范中的属性 , PC端往往要借助js去实现这一效果,但麻烦且不是很靠谱,今...
摘要:设计思想兼容已有内容避免不必要的复杂性解决现实问题优雅降级尊重事实标准变化新增语义化标签去除纯表示性的标签拖拽离线语法标签不区分大小写推荐小写空标签可以不闭合属性不必引号。遇到这种情况时,会生成匿名块级盒来包含行级盒。 浏览器 浏览器 渲染引擎 JavaScript引擎 IE Trident JScript Edge EdgeHTML Chakra Safari We...
阅读 1763·2021-11-22 09:34
阅读 3062·2019-08-30 15:55
阅读 634·2019-08-30 15:53
阅读 2029·2019-08-30 15:52
阅读 2982·2019-08-29 18:32
阅读 1974·2019-08-29 17:15
阅读 2365·2019-08-29 13:14
阅读 3539·2019-08-28 18:05