CSS文本样式
最近偶然发现,定宽容器中的的文字,如果中文会自动换行,英文不会自动换行。原本只是为了解决这个问题,后逐渐深入css文字处理,发现这里面另有乾坤。
为了便于理解,我将文字处理,分为了字体与文本这两块:
- 字体包括字体,颜色,大小,字样,加粗等
- 文本内容杂而多,大致分为如下部分:
- 文本区域尺寸,包括行高
- 文本排版,包括大小写,对齐,间距,缩进
- 文本换行,包括溢出,换行
- 文本装饰,包括下划线,阴影
字体
关于字体样式,整理了下面几点:
font-family
可以设置多个字体,使用逗号分隔,浏览器按顺序查找对应字体,如果系统存在对应字体则使用,如果不存在则查询下一个字体,依次类推;- 关于字体颜色,常见的一个BUG是突然发现页面上字体不显示,这种情况下可以检测字体颜色是否与背景色一致;
font-style
设置字体倾斜,如果对应字体的font-family没有设计斜体,指定italic也会应用oblique;font-weight
可以设置数值,范围为100-900的整百位数(实际上100到300可能映射到同样的字体粗细上面);- 字体大小除了应用在常规的文章排版上,现在正逐渐流行基于
rem
的移动端自适应布局。 - 提到字体,就不能不提到字体图标,常见的如fontawesome,iconfont等,可以通过设置字体样式达到之前必须使用精灵图才能实现的效果,十分方便。
行高
行高是刚接触CSS就学习的一个属性,然而对它的了解却仅限于设置文字居中,这实在是惭愧得很,这里有一篇关于行高的详解博客。
首先需要明白的是文字的__顶线__,中线,基线__和__底线:指文本行从上到下的四条基准线,跟vertical-align
的属性值相对应,(大概可以想象成写英文单词时的四线本)。
然后需要明白的是文字的__行高__,__字体大小__和__行距__这三个概念:
- 行高指上下文本行之间基线的竖直距离;
- 字体大小指该行文本行顶线到底线的竖直距离;
- 行距指上一行文本行的底线到下一行文本行的顶线之间的距离,即(行高-字体大小);
最后是__内容区__,__行内框__和__行框__这三个概念:
- 内容区指文本行顶线和底线所撑开的范围,即由字体大小决定;
- 行内框是一个浏览器渲染模型(类似于BFC,这里应该叫IFC)。在没有设定行高的时候,行内框与内容与大小相同;设定行高时,行内框大小也不会发生变化,而是在其上下增加半行距;
- 行框也是一个浏览器渲染模型,每行文本行都有自己的行框,其高度等于该行所有内联元素行内框的最大值;
搞定上面的几个概念,终于能够明白行高了。前面提到行高指的是两行文本行之间基线的竖直距离,两行文本行之间的行距是行高与文本字体大小之差。
可以使用比例指定行高大小为字体的倍数,关于行高的继承性,有一个小小的坑,在子元素并未继承父元素字体大小的情况下:
- 如果行高使用的是百分数,则会先将父容器的行高计算出来在继承给子元素(即百分数*父容器字体大小);
- 如果行高使用的小数,则会直接将该乘积因子继承给子元素,再计算子元素的行高(即小数*子容器字体大小);
排版
关于排版这几个属性,日常用的也不是很多,简单了解一下:
- 使用text-transform进行文本大小写转换;
- 使用text-align设置文本内中对齐方式,需要注意的是这条属性对于图片等内联-块状元素也是同样生效的;
- 关于文本间距,又分为字间距(letter-spacing)和词间距(word-spacing),区分这两种间距十分容易,字间距在一组连续的字中生效,词间距在两个以空格分隔的词组间生效:
- 使用text-indent设置文本缩进大小,一般使用em表示相对缩进几个字符,手册上说text-indent是一个复合属性,一个很少用的到属性值each-line表示对每行强制换行的文本都执行对应大小的缩进,但是很多浏览器都不支持(所以并没有什么用处);
换行
文本换行是之前很少注意到的一个地方,最近的项目中却频繁出现了类似的要求:处理定宽标题中多余的文字,处理某个网站英文版本导航栏由于单词过长导致的排版问题。
突然又会想起之前遇到的“包含块内的p内的字是中文会自动换行,是英文不会自动换行”的问题。基于上述原因,因此开始学习相关内容,这篇文章的初衷也源于此。
接下来讨论的换行主要是针对西文字符的,因为亚洲文字文本拥有默认的white-space:normal,当遇到文本框边界时自动换行,而默认的非亚洲文本并不会自动换行,直接溢出整个文本框。
换行有两个属性(word-wrap和word-break),这两者都指定了文本换行的规则,但是又有不同:
word-break
word-break的换行属性值有normal
,break-all
和keep-all
三个:
- break-all表示允许非亚洲语言文本行可以在任意字符间换行,即当该文本行放不下最后一个单词时会打断该单词
- keep-all会检测该行文本是否有足够的空间容纳最后的那个单词,如果不能,则该单词会换行显示,如果第二行整行都不能放下这个单词,那也不会再换行,而是直接溢出
- normal表示依照空格换行,与keep-all类似,具体的区别我还真没弄明白
word-warp
word-warp的换行属性值有normal
和break-word
两个:
- normal与上面的keep-all类似,如果第二行整行不能放下这个单词就会溢出,
- break-word表示文本会在边界换行,与keep-all类似,但是如果第二行整行都不能放下这个单词,则会打断该单词并实现换行效果。
处理文本溢出
设置word-break:break-all之后单词会非常生硬地换行,而平常书本上的换行单词都有短横线连接符,可以使用hyphens属性实现,但是目前的谷歌浏览器不支持。
.elp {
-moz-hyphens: auto;
-ms-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
}
然后就是解决文本溢出的问题,常用的方法是:
.elp {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
其中white-space属性是用来设置文本内的空格处理方式,下面是几个常用的属性值(详情参加手册):
- pre 不合并文字间的空白距离,当文字超出边界时不换行,也就是说会解析HTML代码中的所有空白(包括为了清晰代码格式而使用的缩进);
- nowrap 强制在同一行内显示所有文本,合并文本间的多余空白(即存在空格则会保留一个空格),直到文本结束或者遭遇br对象;
- pre-wrap 用等宽字体显示预先格式化的文本,不合并文字间的空白距离,当文字碰到边界时发生换行,但是长单词在换行之后仍然可能溢出文本框
- pre-line 保持文本的换行,不保留文字间的空白距离,当文字碰到边界时发生换行。
而上面处理文本溢出的方法采用的就是忽略全部空格,因此这样只能实现处理一行文本溢出的情况,关于多行文本溢出,可以使用下面这段CSS样式,需要注意的是该方法只能在webkit内核的浏览器下才能生效,希望以后标准能够加入到所有浏览器中。如果考虑兼容性的化可以使用JS实现该效果。
.elp {
width: 100px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp:3;
-webkit-box-orient: vertical;
}
文本装饰和阴影
最常见的文本装饰就是a标签的默认下划线underline
,而关于字体阴影text-shadow
是CSS3新增的属性,这个在另外的文章里面再谈吧。
最后
关于文本样式最后需要注意一点:貌似所有的文本样式都是可以继承的,因此为父容器指定公共的字体样式是很明智的做法。
但是,并不能完全依赖于继承样式,否则就会困惑于为什么“a标签的字体样式为什么与父容器的字体样式不一致,我明明设置了呀”这样的问题,而关于这个问题,只需要明白继承样式的优先级非常低就很清晰了。
你要请我喝一杯奶茶?
版权声明:自由转载-非商用-保持署名和原文链接。
本站文章均为本人原创,参考文章我都会在文中进行声明,也请您转载时附上署名。