内容简介:前言:作为学习“基本视觉格式化”的第二篇,我们在对上一篇中“块盒子”整个“格式化”过程中可以得到:当元素的 display 属性为这些元素不会在之前或之后生成“行分隔符”,所以处于正常流中的行内元素会
本文推荐 PC 端阅读~ 本文同步更新于: - 「公众号:前端一万小时」 - 「知乎:Oli's 前端一万小时」 本文版权归 “前端一万小时” 所有,未经授权,请勿转载! 复制代码
css_08 复制代码
前言:作为学习“基本视觉格式化”的第二篇,我们在对上一篇中“块盒子”整个“格式化”过程中可以得到: 所谓的“格式化”,其实就是确定这个“块/行内 盒子”的自身长度、高度,以及与其上下左右相邻“盒子”之间的距离和协调的过程。在确定这个“长度、高度、距离和协调”的过程中会有很多“规则”,那我们学的就是这个“规则”。 接下来的“行内盒子”格式化相对于“块盒子”格式化的知识点会更细、更分散。不过作为最基本的理论知识,这篇依然很重要。
1 “行内盒子”怎么来的
当元素的 display 属性为 inline、inline-block 或 inline-table 时,该元素将成为“行内级元素”。
选择器 { display: inline、inline-block 或 inline-table; } 复制代码
这些元素不会在之前或之后生成“行分隔符”,所以处于正常流中的行内元素会 “水平” 摆放,它们是块级元素的后代。
显示时,它不会生成内容块,但是可以与其他行内级内容一起显示为多行。
同理,“行内级元素”会生成“行内级盒子”,该盒子同时会参与“行内格式化上下文(inline formatting context)”的创建。
:trophy: 小总结:
“行内元素”在一个文本内生成“行内盒子”,而不会打断这行文本(即这种元素可以出现在另一个元素的内容中,而不会破坏其显示,常见的如: a
、 span
、 strong
、 em
等)。
2 “行内盒子”格式化
在正式学习前,有一个观念我们需要建立:
从某种程度上来讲,块级元素中包含的各“文本行”本身都是“行内元素”(即使它没有用行内元素的标记包围起来)。
既然“文本行”可以看作是“行内元素”,那我们就可以把抽象化的“行内元素”、“行内盒子”具象成:给“文本”格式化。然后举一反三,彻底弄懂与之相关的所有知识。
接下来,我们先学习一些前置基础知识,然后再细讲怎样“格式化”。
2.1 一些基本概念
2.1.1 匿名文本
<div>生活不像林黛玉<span>不会因为忧郁</span>而风情万种</div> 复制代码
未包含在行内元素的字符串(生活不像林黛玉 而风情万种)就叫“ 匿名文本 ”。
注意,空格也是匿名文本的一部分,因为空格与其他字符一样都是正常的字符。
2.1.2 非替换元素、替换元素
- 非替换元素:
如果元素的内容包含在文档中,则称之为“非替换元素”。
例如:如果一个段落的文本内容都放在该元素的本身之内,这个段落就是一个“非替换元素”。
- 替换元素:
指用作为其他内容占位符的一个元素。
例如:
img 元素,它只是指向一个图像文件,这个图像文件将插入到文档流中该 img 元素本身所在的位置;
大多数“表单”元素也可以“替换”(如 <input type="radio">
)。
2.1.3 “文本行”基础概念——内容区、行内框/行内盒子、间距、行框
1. 内容区
-
非替换元素中,内容区可以是元素中各字符的 em 框串在一起构成的框(font-size 的值确定了各个 em 框的高度),也可以是由元素中字符字形描述的框。换句话说,内容区的高度就是 font-size 的值。
-
替换元素中,内容区就是元素的固有高度再加上可能有的 margin、边框或 padding 。
2. 行间距
行间距是 font-size 与 line-height 的差值,被分成两半在内容区的上下(上下半间距)。
行间距只应用于非替换元素。
3. 行内框(即行内各个元素对应生成的“行内盒子”)
- 非替换元素,行内框高度 = line-height ;
- 替换元素:
① “替换元素” 不与 文字结合(如 img 元素):行内框高度 = 替换元素的固有高度再加上可能有的 margin、边框或 padding ;
② “替换元素” 与 文字结合(如 input 中 type=text
、 type=textarea
、 type=button
等与文字结合的表单元素):如果字体行高 大于 “替换元素的固有高度再加上可能有的 margin、边框或 padding”,则“行内框”的高度为“行高”。否则就是“替换元素的固有高度再加上可能有的 margin、边框或 padding”。总之就是“谁大是谁”!
4. 行高
两行文字“基线”的距离。
5. 行框(即文本整行对应生成的“行内盒子”)
一行有很多“行内盒子——inline box”,“行框”是包含该行中出现的“行内盒子”的最高点和最低点的最小盒子。
换句话说,“行框”的上边界要位于最高“行内盒子”的上边界,而“行框”的底边要放在最低“行内盒子”的下边界。
6. 基线
不同元素的“基线”位置不同,整个“行框”会有一个“基线”,行内元素的位置是基于两者“基线”对齐。
2.2 行内盒子格式化
要弄清“行内盒子格式化”,让我们先充分理解关于“文本”的两个重要属性——line-height 和 vertical-align 。
2.2.1 line-height
:warning:line-height 只影响行内元素和其他行内内容,而不影响块级元素,至少不会直接影响块级元素。
:warning:line-height 有继承性 。
2.2.2 vertical-align
作为 line-height 的“断背”:vertical-align ,这个属性只能用于“行内元素”和“替换”元素, 且不能继承 。
行内元素/替换元素 { vertical-align: 值; } 复制代码
有以下“值”可以取:
-
baseline
元素基线与父元素的基线对齐。
:warning:对于一些可替换元素,比如
type=textarea
, HTML 标准没有说明它的基线,这意味着对其使用这个关键字时,各浏览器表现可能不一样。 -
sub
元素基线与父元素的下标基线对齐。
-
super
元素基线与父元素的上标基线对齐。
-
text-top
元素顶端与父元素字体的顶端对齐。
-
text-bottom
元素底端与父元素字体的底端对齐。
-
middle
元素中垂线与父元素的基线加上小写 x 一半的高度值对齐。
-
<length>
元素基线超过父元素的基线指定高度(可以取负值)。 -
<percentage>
同<length>
,百分比相对于 line-height —— 这是证明他们俩是“断背”强有力的证据。
:bulb:以下两个值是相对于整行文本来说的:
-
top
元素及其后代的顶端与整行的顶端对齐。
-
bottom
元素及其后代的底端与整行的底端对齐。
如果元素没有基线 baseline,则以它的外边距的下边缘为基线。
2.3 总结:“行内盒子”格式化步骤概述
-
首先,以下步骤确定文本行中各元素对应的“行内盒子”的高度:
第一,得到各行内“非替换元素”及不属于后代行内元素的所有文本的 font-size 值和 line-height 值,再将 line-height 减去 font-size,这就得到了框的“行间距”。这个“行间距”除以 2,将其一半分别应用到 “em 框”的顶部和底部;
第二,得到各“替换元素”的 height、margin-top、margin-bottom,padding-top、 padding-bottom、border-top-width 和 border-bottom-width 值,把它们加在一起。
-
其次,对于各内容区,确定它在整行“基线”的上方和下方分别超出多少:
这个任务并不容易:你必须知道各元素及匿名文本各部分的“基线”的位置, 还要知道该行本身“基线”的位置,然后把它们 对齐 。另外,对于替换元素,要将其底边放在整行的“基线”上。
-
继而,对于指定了 vertical-align 值的元素,确定其垂直偏移量:
由此可知该元素的“行内盒子”要向上或向下移动多远,并改变元素在“基线”上方或下方超出的距离。
-
最后,既然已经知道了所有“行内盒子”会放在哪里,再来计算最后的“行内盒子”——行框的高度:
为此,只需将“基线”与最高“行内框”顶端之间的距离加上“基线”与最低“行内框”底端之间的距离。
2.4 实例讲解——弄懂 line-height
2.4.1 :question:问: line-height: 2;
和 line-height: 200%;
有什么区别?
答:
line-height: 2
和 line-height: 200%
都表示行高是字体大小的 2 倍,但是它们是有区别的。
当它们写在父容器中时,子元素的字体大小不一样的时候,区别就体现出来了:
-
line-height: 2;
写在父容器中,那么子元素的行高都是 自身高度 的 2 倍,是相对大小。 子元素的字体大小不同,行高也会不同 。 -
line-height: 200%;
写在父容器中,那么浏览器会立刻计算出行高的具体值,假如父容器的默认字体大小16px ,那么计算得到的行高就是 2×16px=32px ,子元素的行高都会继承这个 32px ,是 固定大小 。子元素的字体大小不同,行高都是固定某个值。
2.4.2 :question:问:行内元素的“边框”、“边界”等“框属性”是由 font-size 还是 line-height 控制?
答:
对于行内元素来说,上下的 margin padding 不生效,只有左右的 margin padding 生效!
上下 padding 只是撑开了边框,对高度是没有影响的。你对他加一些边框和背景色,他也可以看得到变化,但实质上对高度没有影响。
所以,行内元素的“边框”、“边界”是由 font-size 而不是 line-height 控制。
2.4.3 :question:问:height=line-height 可以用来垂直居中单行文本?
答:是的。
HTML
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JS Bin</title> </head> <body> <p>Hello Oli的前端一万小时</p> </body> </html> 复制代码
CSS
p { width: 300px; border: 1px solid blue; height: 50px; line-height: 50px; } 复制代码
2.5 实例讲解——弄懂 inline-block
2.5.1 :question:问:inline-block 有什么特性?
答:
- 既呈现 inline 的特性(不占据一整行, 宽度由内容宽度决定 );
- 又呈现 block 特性(可设置宽高,内外边距)。
2.5.2 :question:问:inline-block 在实际工作中有什么作用?
答:
如果看到页面上有一排并列的按钮,如果不用浮动,就可以用 inline-block 。
HTML
<div class="wrap"> <span class="box">hello,Oli的前端一万小时</span> <span class="box">hello,Oli的前端一万小时</span> </div> 复制代码
CSS
body { text-align: center; } .box { border: 1px solid; width: 100px; display: inline-block; } 复制代码
2.5.3 :question:问:怎么去除上边问题中两个按钮中间的缝隙问题?
答:
之所以有空隙,是因为 html 文档里边两个 span 之间有很多空白字符,被浏览器当做一个,故会有空隙。
解决方式有 2 种:
- 第一种 是在 html 里边把这个空格去掉;
<div class="wrap"> <span class="box">hello,Oli的前端一万小时</span><span class="box">hello,Oli的前端一万小时</span> </div> 复制代码
- 第二种 是把包含两个 span 的 div 字体先设置为 0 (这里的空白字符就没有宽度高度,不占位),然后再在 box 里边去设置回去。
body { text-align:center; } .wrap { font-size: 0; } .box { border:1px solid; width: 100px; display: inline-block; font-size: 14px; } 复制代码
2.5.4 :question:问:一个页面有一排高度不一样的产品图,这时如果我们用 inline-block ,怎样使他们“顶端对齐”?
答:
HTML
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JS Bin</title> </head> <body> <div class="wrap"> <span class="box b1">hello,Oli的前端一万小时</span> <span class="box b2">hello,Oli的前端一万小时</span> </div> </body> </html> 复制代码
CSS
body { text-align:center; } .wrap { font-size: 0; } .box { border:1px solid; width: 100px; display: inline-block; font-size: 14px; } .b1 { padding: 40px; } .b2 { padding: 10px; } 复制代码
以上代码会出现以下问题(它会以字的“基线”对齐,而不会以整个框的顶端对齐):
如果想对齐(用 vertical-align 属性):
CSS
body { text-align:center; } .wrap { font-size: 0; } .box { border: 1px solid; width: 100px; display: inline-block; font-size: 14px; vertical-align: top; } .b1 { padding: 40px; } .b2 { padding: 10px; } 复制代码
后记:后续的文章将还会涉及“行内盒子”在实例中的运用,届时我们还再用代码来阐述本篇的基础理论,眼下不作过多赘述。
我们都要记住一点:理论不懂就实践,实践不会就学理论!
加油!
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。