16 文本

内容

定义在下列小节的属性能够影响字符、空格、单词和段落的视觉表现

16.1 简介'text-indent'属性

'text-indent'
Value:  <length> | <percentage> | inherit
Initial:  0
Applies to:  块容器
Inherited:  yes
Percentages:  参照包含块的宽度
Media:  visual
Computed value:  百分比与指定值相同,或者是绝对长度

该属性指定了块容器中第一行文本的缩进。更精确的,它指定了排列在该块内第一个行框里的第一个盒的缩进。该盒相对行框的左边(或右边,对于从右向左布局)缩进。用户代理要把这种缩进当作空白字符来渲染

'text-indent'只影响元素的第一个格式化行。例如,匿名块盒的第一行会受到影响,如果它是父元素(指匿名块盒)的第一个孩子的话

值含义如下:

<length>
缩进是一个固定长度
<percentage>
缩进是包含块宽度的百分比

'text-indent'的值可以为负,但可能存在具体实现限制。如果'text-indent'值为负或者超出了该块的宽度,上面描述的第一个盒可以从块溢出。'overflow'的值将影响这种从块溢出的文本是否可见

示例:

下例会产生'3em'的文本缩进


p { text-indent: 3em }

注意:因为'text-intent'属性会继承,给一个块元素指定时,它将影响后代inline-block元素。因此,一般最好给被指定了'display:inline-block'的元素指定'text-indent: 0'

16.2 对齐:'text-align'属性

'text-align'
Value:  left | right | center | justify | inherit
Initial:  如果'direction'为'ltr',就是'left',如果'direction'为'rtl'就是'right'
Applies to:  块容器
Inherited:  yes
Percentages:  N/A
Media:  visual
Computed value:  初始值,或者与指定值相同

该属性描述了块容器的行内级内容怎样对齐。值含义如下:

left, right, center, justify
分别为左对齐,右对齐,居中和两端对齐文本,如行内格式化章节所述

文本块是行框的堆叠。对于'left','right'和'center',该属性指定了每个行框中的行内级盒相对于行框的左边和右边怎样对齐,对齐不是相对于视口的。对于'justify',该属性指定了如果可以的话,通过扩宽或者缩紧行框的内容,让行内级盒与行框的两边都对齐,否则就按照其初始值来对齐(另见'letter-spacing''word-spacing'

如果元素'white-space'的计算值为'pre'或者'pre-wrap',那么该元素文本内容的字形及其空白字符都不会因为两端对齐(justification)而发生变化

注意:CSS将来可能会新增一种让'white-space: pre-wrap'文本两端对齐的方法

示例:

本例中,注意因为'text-align'是可继承的,带有类名'important'的DIV元素中的所有块级元素会让它们的行内内容居中


div.important { text-align: center }

注意 应用的实际两端对齐算法取决于用户代理和文本的语言/文字(script)

(与CSS规范)一致的用户代理可能会把'justify'值解释为'left'或者'right',分别取决于该元素的默认书写方向是从左向右还是从右向左

16.3 修饰

16.3.1 下划线,上划线,突出显示(striking)与闪烁'text-decoration'属性

'text-decoration'
Value:  none | [ underline || overline || line-through || blink ] | inherit
Initial:  none
Applies to:  所有元素
Inherited:  no(见下文)
Percentages:  N/A
Media:  visual
Computed value:  与指定值相同

该属性描述了可以给元素文本添加的修饰,(修饰)会应用元素的颜色。在指定或者传播给一个行内元素时,它会影响该元素生成的所有盒,还会进一步传播给分割该行内元素的所有流内块级盒(见9.2.1.1节)。但在CSS 2.1中,修饰是否会传入块级表格是未定义的。对于建立了一个行内上下文的块容器,修饰会传播给一个包住了该块容器的所有流内行内级子级的匿名行内元素。对于所有其它元素,会传播给所有流内子级。注意,文本修饰不会传播给浮动和绝对定位的后代,也不会传播给原子行内级(atomic inline-level)后代的内容,例如,行内块和行内表格

underline(下划线),overline(上划线)和line-through(中划线)只适用于文本(包括空白字符,字母间隔和单词间隔):外边距,边框和内边距会被跳过。用户代理不能再非文本内容上呈现这些文本修饰。例如,不能对图像和行内块加下划线

注意 如果一个元素E既有'visibility: hidden'也有'text-decoration: underline',下划线是不可见的(尽管E的父级的所有修饰都可见的)。然而,CSS 2.1没有指定E的子级中的下划线是可见的还是不可见的:

<span style="visibility: hidden; text-decoration: underline">
 <span style="visibility: visible">
  underlined or not?
 </span>
</span>

这种情况将在CSS3中指定(如何处理)

后代元素的'text-decoration'属性不会影响祖先的修饰。在确定文本修饰线的位置和粗细程度时,用户代理可以考虑后代的主基线(dominant baseline)和字体大小,但每行必须应用相同的基线和粗细程度。相对定位一个后代元素会移动影响该后代元素文本的所有文本修饰,不会影响那一行中修饰的初始位置的计算

值含义如下:

none
不会产生文本修饰
underline
每行文本都有下划线
overline
每行文本上方都有一条线
line-through
每行文本都有一条线从中间穿过
blink
文本闪烁(可见和不可见交替变化)。(与CSS规范)一致的用户代理可以简单的不闪烁文本。注意,不闪烁文本是一项满足WAI-UAAG的checkpoint 3.3(译注:WAI-UAAG是指Web可访问性倡议-用户代理可用性指南)的技术

文本修饰需要的颜色必须来自'text-decoration'所在的元素的'color'属性值。修饰的颜色必须保持相同,即使后代元素具有不同的'color'

某些用户代理已经通过把修饰传播给后代元素实现了text-decoration,而没有保留上面描述的不变的粗细程度和行位置。这在CSS2宽松措辞中可以说是允许的。SVG1,CSS1-only和CSS2-only的用户代理可以实现旧模式,并仍然声称与CSS 2.1这部分一致(这不适用于在本规范发布后开发的UA)

示例:

如下HTML的示例中,所有A元素的文本内容会像超链接(无论访问过与否)一样被加上下划线:


a:visited,a:link { text-decoration: underline }

示例:

下列样式表和文档片段中:


   blockquote { text-decoration: underline; color: blue; }
   em { display: block; }
   cite { color: fuchsia; }

   <blockquote>
    <p>
     <span>
      Help, help!
      <em> I am under a hat! </em>
      <cite> —GwieF </cite>
     </span>
    </p>
   </blockquote>

...blockquote元素的下划线被传播给一个环绕着span元素的匿名行内元素,让文本"Help, help!"变成蓝色,带有来自它下面的匿名行内元素的蓝色下划线,颜色取自blockquote元素。em块中的<em>text</em>也有下划线,因为它位于下划线能传播到的流内块中。最后一行文本是fuchsia(紫红色),但它下方的下划线仍然是来自匿名行内元素的蓝色下划线

Sample rendering of the above underline example

此图展示了上例中所涉及的盒。圆角水绿色线代表包裹着段落元素的行内内容的匿名行内元素,圆角蓝色线代表span元素,橘黄色线代表块

16.4 字母与单词间距'letter-spacing''word-spacing'属性

'letter-spacing'
Value:  normal | <length> | inherit
Initial:  normal
Applies to:  所有元素
Inherited:  yes
Percentages:  N/A
Media:  visual
Computed value:  'normal'或者绝对长度

该属性指定了文本字符间隔的行为。值含义如下:

normal
间隔是当前字体的常规间隔。该值允许用户代理为了让文本两端对齐而改变字符间隔
<length>
该值表示字符间的默认间隔外的字符间间隔。值可以为负,但可能存在具体实现限制。用户代理不能为了让文本两端对齐而进一步增加或者减少字符间间隔

字符间隔算法是依赖用户代理的

示例:

本例中,BLOCKQUOTE元素中的字符间隔增大了'0.1em'


blockquote { letter-spacing: 0.1em }

下例中,不允许用户代理改变字符间间隔:


blockquote { letter-spacing: 0cm }   /* Same as '0' */

当两个字符间产生的间隔与默认间隔不同时,用户代理不应该使用连体字母(ligature)

'word-spacing'
Value:  normal | <length> | inherit
Initial:  normal
Applies to:  所有元素
Inherited:  yes
Percentages:  N/A
Media:  visual
Computed value:  对于'normal',为'0',否则就是绝对长度

该属性指定了单词间的间隔行为。值含义如下:

normal
常规单词间间隔,由当前字体和/或UA定义
<length>
该值表示默认单词间隔外的单词间间隔。值可以为负,但可能存在具体实现限制

单词间隔算法是依赖用户代理的。单词间隔也受两端对齐的影响(见'text-align'属性)。单词间隔会影响每个空格(U+0020)和非间断空格(non-breaking space)(U+00A0),留在空白字符处理规则应用之后的文本中。该属性对其它单词分隔符字符的效果是未定义的。然而,一般标点符号,0预宽(advance width)字符(例如,0预宽空格U+200B)和固定宽度空格(例如,U+3000和U+2000到U+200A)都不受影响

示例:

本例中,H1元素中每个单词间的单词间隔增大了'1em'


h1 { word-spacing: 1em }

16.5 大写'text-transform'属性

'text-transform'
Value:  capitalize | uppercase | lowercase | none | inherit
Initial:  none
Applies to:  所有元素
Inherited:  yes
Percentages:  N/A
Media:  visual
Computed value:  与指定值相同

该属性控制元素文本的大写效果。值含义如下:

capitalize
让每个单词的第一个字符大写,其它字符不受影响
uppercase
让每个单词的所有字符都大写
lowercase
让每个单词的所有字符都小写
none
没有大写效果

每种情况下的实际转换依赖书写语言。确定一个元素的语言的方法见BCP 47([BCP47])(译注:BCP指最佳当前实践)

只有属于"bicameral scripts" [UNICODE](译注:bicameral scripts是指具有大小写差异的文字)的字符会受到影响

示例:

本例中,H1元素中的所有文本都会被转换为大写文本


h1 { text-transform: uppercase }

16.6 空白字符'white-space'属性

'white-space'
Value:  normal | pre | nowrap | pre-wrap | pre-line | inherit
Initial:  normal
Applies to:  所有元素
Inherited:  yes
Percentages:  N/A
Media:  visual
Computed value:  与指定值相同

该属性声明了如何处理元素内的空白字符。值含义如下:

normal
该值引导用户代理把合并空白字符和换行序列作为填充行框的必要操作
pre
该值阻止用户代理合并空白字符序列。只在保留换行符处换行
nowrap
该值和'normal'一样会合并空白字符,但会抑制文本中的换行
pre-wrap
该值阻止用户代理合并空白字符序列。在保留换行符处换行,根据需要填充行框(Lines are broken at preserved newline characters, and as necessary to fill line boxes.)
pre-line
该值引导用户代理合并空白字符序列。在保留换行符处换行,根据需要填充行框

源码中的换行可以用回车换行(U+000D),换行(U+000A)或者它们两个(U+000D U+000A)或者某些其它标识文档片段开始和结束的机制(例如,SGML RECORD-START和RECORD-END token)来表示。CSS 'white-space'处理模型假设所有换行已经被标准化为换行符了。识别其它换行表示的UA必须应用空白字符处理规则,就像已经标准化过了一样。如果没有为文档语言指定换行规则,文档文本中的每个回车换行(U+000D)和CRLF序列(U+000D U+000A)都会被当作单个换行字符。默认标准化规则也适用于生成的内容

UA必须识别换行(U+000A)是换行符。此外,UA也可以把其它强制中断符当作UAX14(译注:指Unicode Standard Annex,Unicode标准附件14)换行符

示例:

下例展示了HTML中PRE和P元素和"nowrap"属性预期的空白字符行为


pre        { white-space: pre }
p          { white-space: normal }
td[nowrap] { white-space: nowrap }

此外,具有非标准的"wrap"属性的HTML PRE元素的效果如下例所示:


pre[wrap]  { white-space: pre-wrap }

16.6.1 'white-space'处理模型

对于每个行内元素(包括匿名行内元素),执行下列步骤,对于双向(bidi)格式化字符,就当它们不存在:

  1. 如果'white-space'被设置为'normal','nowrap'或者'pre-line'的话,换行符(U+000A)周围的每个制表符(U+0009),回车换行(U+000D)或者空格(U+0020)字符会被移除
  2. 如果'white-space'被设置为'pre'或者'pre-wrap'的话,所有没被元素边界隔开的空格(U+0020)序列会被当作一系列非间断空格(non-breaking space)。然而,对于'pre-wrap',在每个序列的结束处存在换行机会
  3. 如果'white-space'被设置为'normal'或者'nowrap',为了渲染的目的,换行符会根据基于内容文字的具体UA算法转换为下列字符之一:空格符,0宽空格符(U+200B)或者没有字符(即,不渲染)
  4. 如果'white-space'被设置为'normal','nowrap'或者'pre-line'
    1. 每个制表符(U+0009)会被转换为一个空格(U+0020)
    2. 所有跟着另一个空格(U+0020)—甚至一个位于行内(盒)前的空格,如果该空格的'white-space'被设置为'normal','nowrap'或者'pre-line'的话—则移除

然后,放置块容器的行内(盒)。放置行内(盒)时,要考虑双向(bidi)重新排序,并按照'white-space'属性指定的方式来换行。换行时,换行位置根据上面的空白字符合并步骤之前的文本来定

当每行都摆放好后,

  1. 如果'white-space'被设置为'normal','nowrap'或者'pre-line'的行开始处有一个空格(U+0020),它会被移除
  2. 所有制表符(U+0009)会被渲染为一个水平位移,到该行下一个制表位的下一个字形的开始边。制表位出现在从该块的开始内容边界起,该块的字体中呈现的空格(U+0020)宽度的8倍的位置(原文:Tab stops occur at points that are multiples of 8 times the width of a space (U+0020) rendered in the block's font from the block's starting content edge.)
  3. 如果'white-space'被设置为'normal','nowrap'或者'pre-line'的行结束处有一个空格(U+0020),它会被移除
  4. 如果'white-space'被设置为'pre-wrap'的行结束处有一个空格(U+0020)或者制表符(U+0009),UA可以视觉上(visually)把它们合并起来

浮动的和绝对定位的元素不会引入换行机会

注意 CSS 2.1没有完整定义换行机会出现的位置

16.6.2 空白字符合并的双向性示例

给出如下标记片段,特别注意空格(为了强调和标识带有不同背景和边框):


 
     <ltr>A <rtl> B </rtl> C</ltr>

...<ltr>元素代表一个从左向右的嵌入(embedding),<rtl>元素代表一个从右向左的嵌入(embedding),假设'white-space'被设置为'normal',上面的处理模型将产生如下结果:

这样会剩下两个空格,一个在A后面处于从左向右的嵌入层级(embedding level),一个在B后面处于从右向左的嵌入层级。然后根据Unicode双向算法来渲染,结果为:


     A  BC

注意,A和B之间有两个空格,而B和C之间没有。有时可以通过使用字符的自然双向性而不是显式嵌入层级来避免。还有,最好避免紧跟在开始标签后和结束标签前的空格(spaces immediately inside start and end tags),因为在处理空白字符合并时,这往往会引发奇怪的事情

16.6.3 控制与合并字符的细节

除U+0009(tab),U+000A(换行),U+0020(空格)和U+202x(bidi格式化字符)外的控制字符会被当作任意常规字符,以相同方式渲染

组合字符(Combining character)应该被当作那些将被组合的字符的一部分。例如,如果具有类似于"o<span>&#x308;</span>"的内容的话,:first-letter会样式化整个字形,而不会只匹配基本字符(base character)