# 文本属性

# 缩进和行内对齐

# 缩进文本 text-indent

允许值:<length> | <percentage>

默认值:0

百分数:相对于父级元素的宽度

用于将元素的第一行文本缩进指定的长度。可以为负值。

# 文本对齐 text-align

允许值:start | end | left | right | center | justify | match-parent | start end

默认值:start(CSS3),CSS2.1中由浏览器指定,通常会根据书写方向,如英语是 left

作用在块级元素之上,指定当前块级元素之中的行内元素或行内块的对齐方式。

start / end 针对于语言书写方向,当语言从左向右书写时,等效于 left / right

justify 表示两端对齐,但有些浏览器只在单词之间增加空白,有些不止是在单词之间,还会在字母之间增加空白以保证两端拉伸对齐,但规定当设置了 letter-spacing 时浏览器不应该再去调整字母之间的间距。以至于不确定浏览器会调整多少行文本,以至于可能会影响元素的高度。

有个新属性能更好控制,但截止 2017 年末多数浏览器还未支持:text-justify

match-parent 表示与父元素一致,但不同于 inherit 直接将父元素的 start / end 值直接继承,match-parent 会将其计算成 left / right 再给到元素。

start end 截止 2017 年末并未实现。

# 对齐文本的最后一行 text-align-last

允许值:auto | start | end | left | right | center | justify

默认值:auto

text-align 类似,但此属性控制元素中最后一行的文本对齐方式。

但其实在段落中如果有强制换行 <br> 元素,则换行的前一行也会被此属性生效。

如果元素的第一行也是最后一行(只有一行)的情况,此属性优先级比 text-align 高。

# 块级对齐

# 行的高度 line-height

允许值:<number> | <length> | <percentage> | normal

默认值:normal

百分数:相对于元素的字体大小

对块级元素而言,控制元素中文本行基线的最小距离,注意是最小距离而不是定死的值。

不影响置换元素的布局,但依然作用到置换元素上。

假设 font-size(即内容区域)是 14 像素高,line-height 计算为 18 像素。差值(4 个像素)分成两半,每一半应用于内容区域的顶部和底部。这将创建一个 18 像素高的内联框,内容区域上下各有 2 个额外的像素。

默认值 normal 通常是字体高度的 1.2 倍左右。

继承父元素的 line-height 值时,依据的是父元素的字体大小计算,更好的方法是设定一个纯数字,继承的将是设定的换算系数,而不是计算得到的值,纯数字值将应用到当前元素及所有后代元素之上,因此各元素的行高都会根据自身的字体大小计算。

# 纵向对齐 vertical-align

允许值:baseline | sub | super | top | text-top | middle | bottom | text-bottom | <length> | <percentage>

默认值:baseline

百分数:相对于元素的 line-height

继承性:否

只能用于行内元素和置换元素(例如图像和表单输入框等)

不会影响块级元素中文本的对齐方式,可以控制单元格中元素的纵向对齐方式。

# 基线对齐 baseline

默认值 baseline 强制元素的基线与父元素的基线对齐。如果目标元素没有基线,例如图像、表单或其他置换元素,元素的底端与父元素的基线对齐。

一些浏览器始终把置换元素的底边放在基线上,即便行中没有其他文本也是如此。

比如一个单元格中只有一个图像,图像会被放置在基线上,但在某些浏览器中,基线下方有一点空间,从而导致图像下方会出现间隙。

基线下方有一点空间,是因为基线以 字母 x 的底部为准,但很多字母的底部会有超出 x 的底部的。

# 上标和下标 super / sub

sub 将元素放在下标处,及元素的基线(置换元素的底边线)会低于父元素的基线。

supersub 的作用相反,让元素的基线(置换元素的底边线)高于父元素的基线。

注意,这两个属性不会改变元素的字体大小。要改变大小的话需要使用 font-size 控制。

# 底端对齐 bottom / text-bottom

bottom 把元素所在行内框的底边与父级块元素的底边对齐,低于文本的基线。

text-bottom 相对行中文本的底边对齐。

# 顶端对齐 top / text-top

bottom / text-bottom 作用相反。

# 中线对齐 middle

middle 这个值通常会用在图像上,与字面意思不同,它把行内元素所在方框的中线与父元素基线向上便宜 0.5ex 处的线对齐(1ex 等于父元素的 font-size)

由于大多数浏览器将 1ex 视为 0.5em,所以 middle 通常将元素的垂直中点与父元素基线之上的 1 / 4 em 对齐,但这不是一个规范定义的距离,因此不同浏览器之间可能有所不同。

# 百分数

把元素的基线(置换元素的底边)相对父元素的基线抬升或下降指定的量(指定的百分数相对于元素自身的 line-height 计算)。正百分数抬升,负百分数下沉。值太大可能会出现在相邻的行上。

# 长度值

把元素抬升或下沉多少距离。

注意,抬升或下沉的文本不会变成其他行的一部分,也不会与其他行中的文本重叠。

可以看出,纵向对齐的元素可能影响行的高度。因为抬升和下降都会被包含在行高之中。

# 单词间距和字符间距

# 单词间距 word-spacing

允许值:<length> | normal

默认值:normal

继承性:是

控制单词之间的距离,长度正负均可,正值增大距离,负值减小距离。默认值相当于 word-spacing: 0

注意:单词 word 指两侧有空白的字符串,没有空白的无论多长都算做一个单词。

# 字符间距 letter-spacing

允许值:<length> | normal

默认值:normal

继承性:是

控制字符或字母之间的距离,长度正负均可,正值增大距离,负值减小距离。默认值相当于 letter-spacing: 0

# text-alignword-spacingletter-spacing 的影响

如果设置了 text-align: justify 两端对齐,word-spacing 即使设置了值也会被自动调整,letter-spacing 设置了长度值(也就是非默认值 normal )则不会被自动调整。

注意,继承得到的值是计算后的值,也就是不管字符比父元素大还是小,单词间距和字符间距都与父元素一样,如果希望将字符间距设置为相当于当前元素的字体大小时,需要单独设置而不是使用继承的计算值。

p {
  letter-spacing: 0.25em;
}
small {
  font-size: 50%;
  letter-spacing: 0.25em; /* 单独设置才会基于当前元素字体大小 */
}
1
2
3
4
5
6
7

# 文本转换 text-transform

允许值:uppercase | lowercase | capitalize | none

默认值:none

继承性:是

  • uppercase 全部转为大写
  • lowercase 全部转为小写
  • capitalize 仅将各单词首字母转为大写

# 文本装饰 text-decoration

允许值:none | [ underline ‖ overline ‖ line-through ‖ blink ]

默认值:none

继承性:否

  • underline 为文本增加下划线
  • overline 为文本增加上划线
  • line-through 为文本增加中划线(删除线)
  • blink 让文本闪烁,基本不支持或被计划弃用
a {
  text-decoration: none; /* 去除 a 元素 默认自带的文本装饰(下划线) */
}

/* 同时设置多个值 */
a:link,
a:visited {
  text-decoration: underline overline;
}
1
2
3
4
5
6
7
8
9

# 怪异的装饰

<p>
  This paragraph, which is black and has a black underline, also contains
  <strong>strongly emphasized text</strong> which has the black underline
  beneath it as well.
</p>
1
2
3
4
5
p {
  text-decoration: underline; /* 父元素设置下划线 */
  color: black;
}

/* 被包裹的元素没有设置,也不会继承 */
strong {
  color: gray;
}
1
2
3
4
5
6
7
8
9

上例的结果是 strong 元素包裹的文本也会有下划线,即使不继承,但父元素的下换线将其包裹,也会为其增加下划线,并且此下划线是无法取消的,即便是这样写也无法取消:

p {
  text-decoration: underline;
  color: black;
}
strong {
  color: gray;
  text-decoration: none; /* 显示声明依然无法取消父元素作用在自己身上的下划线 */
}
1
2
3
4
5
6
7
8

# 文本渲染效果 text-rendering

允许值:auto | optimizeSpeed | optimizeLegibility | geometricPrecision

默认值:auto

继承性:是

这是新增属性,其实是一个 SVG 属性,指定浏览器在显示文本时优先考虑什么方面。

  • optimizeSpeed 优先考虑绘制速度,而不是清晰度,也就是绘图速度应该优先于绘制字距、连结等易读特性。
  • optimizeLegibility 优先考虑易读性
  • geometricPrecision 让浏览器尽量优先精准地绘制文本,确保能无损缩放
  • auto 浏览器自行决定。

# 文本阴影 text-shadow

允许值:none | [<length> ‖ <length> <length> <length>?]#

默认值:none

继承性:是

文本默认没有阴影,定义阴影由三个长度值和一个可选的颜色(颜色值在前面或后面均可)。如果省略颜色将会使用文本颜色。

text-shadow: 横向偏移 纵向偏移 阴影模糊半径 颜色

div {
  text-shadow: 1px 1px;
}
div {
  text-shadow: 0.1em 0.5em red;
}
div {
  text-shadow: 0 0 3px red;
}
div {
  text-shadow: 2px 3px 4px red;
}
1
2
3
4
5
6
7
8
9
10
11
12

# 处理空白 white-space / tab-size

允许值:normal | nowrap | pre | pre-wrap | pre-line

默认值:normal

继承性:否

  • normal 将所有空白压缩成一个空格
  • nowrap 禁止元素中的文本换行,除非是使用 <br> 元素,比如:单元格中禁止换行
  • pre 保留所有空白并完全按照空白渲染,即便一行内的文本长也不会自动换行
  • pre-wrap 保留所有空白,并且一行内的长文本将正常换行,换行符及生成的换行符均保留
  • pre-line 空白序列将像常规那也折叠,但是保留换行
空白 换行符 自动换行
normal 折叠 保留 允许
nowrap 折叠 忽略 允许
pre 折叠 忽略 禁止
pre-wrap 保留 保留 禁止
pre-line 保留 保留 允许

# 设定制表符宽度或等于几个空格 tab-size

允许值:<length> | <integer>

默认值:8

继承性:是

由于 white-space 取某些值时会将空白保留下来,那制表符(Unicode码 0009)也将显示成制表符了。

默认情况,一个制表符相当于8个连续空格,设定为数字值表示多少个空格,设定为长度值则渲染成指定的长度。

div {
  tab-size: 4;
}
div {
  tab-size: 2em;
}
1
2
3
4
5
6

截止2017年末,webkit 和 gecko 支持此属性,但只支持整数值,不支持长度值。

# 换行折断 hyphens / word-break / overflow-wrap(word-wrap)

# 换行折断连字符 hyphens

允许值:manual | auto | none

默认值:manual

继承性:是

单词较长,但行宽比较小时,是否加上连字符。U+00AD&shy;

  • manual 表示只在文档中手动插入的连字符处才断字,否则不断字,
  • none 即使有手动插入的连字符也不断字
  • auto 没有手动插入的连字符也可自动断字

断字规则没有规范定义,由浏览器决定,通常和语言有很大关系。

# 单词折断 word-break

允许值:normal | break-all | keep-all

默认值:normal

继承性:是

如果一串文本太长,一行显示不下,就会发生软换行(自动换行),换行符和 br 元素是硬换行。

通常文本在何处换行是浏览器自行决定,但通过此属性可以影响换行的地方。

  • normal 按正常方式换行,也就是在单词之间换行
  • break-all 可以在任何字符之间进行换行,及时是单词内,使用时连字符不会显示。
  • keep-all 禁止在字符之间软换行,可能导致文本行超出元素宽度。

英语和 CJK 语言处理方式不同,CJK 语言表示一个字符就是一个词的语言,比如中文。

不同语言的词内换行行为:

非CJK语言 CJK语言 是否有断字符
normal 照常 照常
break-all 任何字符之间 任何字符之间
keep-all 照常 序列两侧

也就是说,在英语中 normalkeep-all 效果相同。

但在中文中,normal 能够正常换行,keep-all 只在字符串两侧有空白或标点处进行换行。

<div>
  中文中文中文中文中文中文中文中文中文中文中文中文中文中文中文中文中文中文
</div>
<div>
  abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabc
</div>
1
2
3
4
5
6

上例中,使用 normal 时中文会照常换行,英文则不会,使用 keep-all 时均不会自动换行,但在中文里插入一个空格或标点则会自动换行。

# 针对 CJK 语言(中文等)的行折断规则 line-break

允许值:auto | loose | normal | strict

默认值:auto

继承性:是

此属性也能影响文本软换行方式,尤其是处理 CJK 语言符号两侧的换行,以及非CJK标点符号两侧的换行方式。

也就是说,line-break 始终作用域特定的 CJK 字符,不管文本内容中是什么语言。比如 中英文混合的一段文本,只会作用于其中的中文部分。除非显示把内容声明为中文或其他CJK语言。

  • loose 宽松换行规则,用于文本行较短的情况
  • normal 常规换行规则,但没有准确定义何为常规规则
  • strict 最严格的换行规则,但没有准确定义何为最严格

# 单词溢出换行规则 overflow-wrap(原 word-wrap)

允许值:normal | break-word

默认值:normal

继承性:是

  • normal 正常换行方式,即只在单词之间换行,如果单词长度超出宽度,文本将会溢出。
  • break-word 单词长度超出宽度时可以在单词内部换行,但如果单词长度没有超出宽度则不会折断。

注意,只有在 white-space 属性的值允许换行时,此属性才会起作用,否则无效。

word-wrap 作为别名,效果完全一样,但 word-wrap 的浏览器支持度却更广,为了兼容,可以两者同时书写:

pre {
  word-wrap: break-word;
  overflow-wrap: break-word;
}
1
2
3
4

截止 2017 年末,overflow-wrap 才得到了广泛支持。

``

overflow-wrap: break-word;word-vreak: break-all; 看似作用一样,但并非如此。

仅当内容有溢出(一个连续字符串超出行宽)时,overflow-wrap: break-word; 才会将单词折断并换行,否则,会将后面显示不下的单词放到下一行显示。而 word-vreak: break-all; 不同,它在内容接触边界时换行,也就是说一个单词(连续字符串)虽然在当前行显示不下,但在下一行能显示下的情况下,也不会放到下一行,而是就在当前行往后排,并折断单词,将折断部分放到下一行显示。

div{
  margin: 20px;
  width: 300px;
  outline: 1px solid #f00;
}
.word-break{
  word-break: break-all;
}
.word-wrap{
  margin: 20px;
  width: 300px;
  outline: 1px solid #f00;
  word-wrap: break-word;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- 这两行文本效果一样 -->
<div class="word-break">
  abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabc
</div>
<div class="word-wrap">
  abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabc
</div>

<!-- 这两行文本显示不一样 -->
<!-- word-break 会将逗号后的文本在第二行接着往后显示,并在触及边界时折断到第三行 -->
<div class="word-break">
  abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdab, cdabcdabcdabcdabcdabcdabc
</div>
<!-- word-wrap 会在逗号之后直接换行,将逗号后的字符串直接移到第三行完整显示 -->
<div class="word-wrap">
  abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdab, cdabcdabcdabcdabcdabcdabc
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 书写模式

不同语言的书写模式(书写方向)是不同的,有从左至右,从右至左,从上到下等。

# 设定书写模式 writing-mode

允许值:horizontal-tb | vertical-rl | vertical-lr

默认值:horizontal-tb

继承性:是

  • horizontal-tb 行内方向横向,块级方向左上到下
  • vertical-rl 行内方向为纵向,块级排列为从右至左
  • vertical-lr 行内方向为纵向,块级排列为从左至右

# 改变字符方向 text-orientation

允许值:mixed | upright | sideways

默认值:mixed

继承性:是

设置书写模式后,可能还会想改变文本行之中字符的方向,比如竖向排列中文时混合了英文和数字时,要控制英文和数字的字符方向。

  • mixed 混合排列,中文竖向排列时,之间的英文不会随着竖向排列字符,而是头朝右连续排列。
  • upright 直排,中文竖向排列时,英文字符也一个一个头朝上排列。
  • sideways 侧排,中文竖向排列时,中英文都头朝右排列。

# 声明方向 direction / unicode-bidi

CSS2 时代的两个属性,规范明确不建议用在 HTML 文档上,而是使用 HTML 的 dir 属性和 <bdo> 元素。

此处列出因为旧的样式表可能仍有使用。

# 方向 direction

允许值:ltr | rtl

默认值:ltr

继承性:是

设置块级元素中,文本的书写方向,表格列布局的方向,内容在横向上溢出元素框的方向,以及两端对齐的元素中最后一行的位置。

对行内元素来说,只有当属性 unicode-bidi 设置为 embedbi -override 时,direction 属性才适用(请参阅下面对 unicode-bidi 的描述)。

*:lang(ar),
*:lang(he) {
  direction: rtl;
}
1
2
3
4

虽然 CSS 试图解决写入方向的问题,但是 Unicode 有一个更健壮的方法来处理方向性。通过 Unicode -bidi 属性,开发者可以利用 Unicode 的部分功能。

# unicode-bidi

允许值:normal | embed | bidi-override

默认值:normal

继承性:否

  • normal 根据双向算法,目标元素不会打开新的嵌套层级。对于内联元素,隐式重新排序可以跨元素边界进行。

  • embed 对于行内元素,根据双向算法,打开新的嵌套层级,这一级嵌套的方向由 direction 属性指定,元素内部隐式重拍,在元素开头添加一个 LRE 字符(U+202A,针对direction: ltr;)或一个RLE 字符(U+202B,针对direction: rtl;),在元素末尾添加一个 PDF 字符(U+202C)。

  • bidi-override 覆盖行内元素的书写方向。对于块级元素,覆盖行内后代的书写方向。这意味着,在元素内部,重新排序是严格按照 direction 属性的顺序进行的,而双向算符所做的隐式重排将被忽略。此时,在元素开头增加一个 LRO 字符(U+202D,针对 direction: ltr)或 一个 RLO字符(U+202E,针对direction: rtl;),在元素的末尾添加一个 PDF 字符 (U+202C)。

(完)