CSS進階(17)—— CSS中的文本處理(上)

CSS可以在衆多的佈局標準中脫穎而出的制勝手段就是其強大的文本處理能力,好比最"簡單"的盒子邊緣文字即將超出就自動換行的能力在CSS流的概念裏幾乎是天生的,並逐漸成爲了行業內的「常規認知」,然而同時代的SVG標準要想讓文字換行,還須要你手動處理一下,對於計算機來講,沒有什麼是與生俱來的,CSS在圖文佈局方面所定製的許多標準在如今看來實際上是很是「人性化」的,本章咱們就來深刻探索一下CSS的文本處理機制。css

我的將本章內容分紅上中下三個章節,本節主要介紹文本(font)屬性相關的知識,下一章則把@font face規則單獨做爲一章進行講解,最後一章講一些處理文本的CSS屬性。閒話很少說,讓咱們來看看font家族有哪些成員,以及這些成員有哪些特性吧。 html

1.font-size的親戚line-height&遠方親戚vertical-align

提及font屬性,在平時的佈局中,最經常使用的就是font-size屬性,提及font-size,咱們一般用一個具體的數值去定義字體的大小,然而除了定義字體的大小外,font-size其實還有一大堆親朋好友,跟font-size有着或遠或近的聯繫,因爲跟font-size有染的CSS屬性太多,這裏只詳細介紹部分屬性,有些遠房親戚或是平時不怎麼用的屬性就一筆帶過了。 java

提到文本,就不得不提內聯元素,提到內聯元素,就不得不提line-height和vertical-align。line-height的部分類別屬性是相對於font-size計算的,而vertical-align的百分比屬性值又是相對於line-height計算的,所以咱們能夠利用這個特性實現一些「自適應佈局」。例如,下面的CSS代碼組合 瀏覽器

<div>文字<img src="./刪除.png"></div>
<style> div { font-size: 20px; line-height:1.5; } div > img { width: 16px; height: 16px; vertical-align: 25%; position: relative; top: 8px; } </style>
複製代碼

本例中,line-height:數值的計算值是font-size*數值 = 20px*1.5 = 30px markdown

vertical-align:百分比的計算值是line-height*百分比 = 30px * 25% = 7.5px 編輯器

在內聯元素章節,咱們瞭解了文字的基線時字符x的下邊緣,而圖片通常以本身的下邊緣做爲基線,所以圖片下邊緣默認和中文的兩個漢字字形底邊緣往上一點的位置對齊,而後咱們經過vertical-align:25%(注意這是一個估計值)聲明讓圖片的下邊緣和中文漢字的中心線對齊,以下圖所示。紅線表示中心線 佈局

當圖片下邊緣對齊文字中心線的時候,咱們就能夠經過transform偏移圖片自己,來使得圖片的中心線和文字的中心線對齊了,這裏我使用了relative相對定位,實現的效果是同樣的。 性能

最終咱們實現了文字和圖標的動態對齊效果(感興趣的能夠嘗試修改文字font-size的值進行測試)。 測試

2.font-size的近親ex、em和rem

爲何要說ex,em和rem是font-size的近親呢,由於這些單位都是font-size的相對單位,是根據font-size的值進行計算的,而且計算獲得的值能夠變成一個相對單位用於佈局。 字體

ex是字符x的高度,font-size的值越大,ex的計算值也就越大,關於ex的內容,在內聯元素那章已經深刻探究過,這裏不過多介紹了。

下面來看看單位em,顧名思義,em就是字母'M'的寬度?的高度?準確的說,不是。用官方的話講:em是值一個字模的高度(這裏能夠參考做者的見解,腦補下活字印刷術的字模)。因爲其計算值接近"M"的寬高值,所以稱其爲em。因爲大寫的"M"和中文字體都擁有方方正正的特性,所以em也能夠被看做是一箇中文字的寬度。例如,瀏覽器默認的font-size是16px,若是div的寬度是160px,那麼這個div正好能夠放下十個漢字,這裏的160px = 10em = 10個漢字。

在本節的開頭我標紅了一句話,不知你們可否根據這句話作對下面這個例題(反正我是沒作對)

<!-- 這可太秀了 -->
<span>hello</span>
<span>world</span>
<style type="text/css"> span{ font-size: 2em; margin: 0 1em; } </style>
複製代碼

已知瀏覽器的默認字體是16px,請問span標籤的font-size和margin計算值是多少?

正常思惟:font-size:2em = 2* 16px = 32px,margin:1em = 16px 那不就是32px和16px嘛?

然鵝,真相併無那麼簡單,來看瀏覽器給出的真相是什麼。

瀏覽器給出的2em的計算值居然跟1em的如出一轍?

既然瀏覽器已經給出最終的結果了,那咱們就來分析一波爲何1em ===2em?不知你有沒有注意到,我在歸納ex,em,rem的時候,有個詞出現了整整三次,是哪位幸運觀衆得到了這份殊榮呢——font-size!爲何這個詞出現的頻率如此之高呢?由於這個相對計算值很是關鍵。以上面那道題爲例,瀏覽器在拿到margin:0 1em的時候會作一件什麼事情呢?首先他會發現,這裏有個相對單位em,既然有em,那margin就得問font-size要值了,此時font-size是2em,那font-size看到em也要找font-size要值?那特麼不是死循環了嗎?

放心,一個小小的CSS還不至於讓瀏覽器進入死循環,CSS會優先計算font-size:2em = 2*瀏覽器默認的font-size=2*16px = 32px,而後再告訴margin:0 1em,我算好了,你拿去用吧,所以margin = 0 1em = 1*font-size = 32px。因而最終的計算值,font-size和margin都是32px。

搞明白相對的概念後,咱們能夠想到利用相對單位作彈性佈局,然而em這個單位受到當前上下文的font-size影響,不是特別穩定,爲了解決這個侷限性,另一個和font-size密切相關的單位rem就出現了。

rem顧名思義,就是root(根)元素的font-size的相對單位,他只會受根元素font-size大小的影響,所以rem被普遍應用於移動端的彈性佈局方案中,雖然rem是根據em衍生出來的,但他們卻有徹底不一樣的命運,em原本是主角,現在卻被摁在冷板凳上萬年上不來臺,rem卻變成了移動端佈局的香餑餑,只能說世事無常鴨~

3.font-size的「偏門」屬性

font-size還支持關鍵字屬性,這點恐怕不少人不知道(又包括我了)。font-size的關鍵字屬性分爲如下兩類

(1)相對尺寸關鍵字。指相對於當前元素的font-size進行計算

larger:大一點。是big標籤的默認font-size。

smaller:小一點。是small標籤的默認font-size。

(2)絕對尺寸關鍵字。與當前元素的font-size無關,僅受瀏覽器設置的字號影響(注意不是根元素,劃重點!瀏覽器字號怎麼設置麻煩本身百度)

絕對尺寸關鍵字總共有7種,很是大,很大,大,中(medium),小,很小,很是小。

這兩個尺寸關鍵字在不一樣瀏覽器的表現各不相同,尤爲是相對尺寸關鍵詞,看看就行了,基本沒什麼使用價值,絕對尺寸關鍵字,除了C位出道的medium,其餘基本都沒用。我的認爲,瞭解一下這兩個偏門屬性就好。

4.特殊的font-size:0與文本隱藏

在PC端的Chrome瀏覽器下有個12px的字號限制,就是文字的font-size的計算值不能小於12px,固然以前也遇到過有個變態需求非得讓我把字體變成10px的,能夠嘗試用transform:scale()去改變元素大小實現(固然瀏覽器都規定字號不小於12px了,儘可能仍是遵循一下)

因爲瀏覽器有字體最小12px的限制,所以你設置font-size:<12px的值均會被看成12px來處理,然而有一個值例外,那就是0,你能夠理解爲0是一個文字隱藏的關鍵字,固然他比關鍵字還厲害一點的是,他真的可讓font-size以0px的值參與計算。然而font-size:0被設計出來以後,跟rem同樣,並無幹本身的老本行,而是在一些特殊領域發揮着一些餘熱,如「如何解決圖片底邊空白問題」,就能夠設置父元素的font-size:0,來消除幽靈空白節點的影響。

5.字體家族族譜管理員font-family

font-family,翻譯成中文,就是字體家族,font-family的默認值受操做系統和瀏覽器的控制,咱們經常使用的Windows和OS系統的默認字體就不同,同一臺系統的Chrome和Firefox瀏覽器的默認字體也不同。

font-family除了支持字體名稱的關鍵字外,還支持「字體種類」。經常使用的字體名稱有:font-family:simsun(宋體),font-family:'Microsoft Yahei'(微軟雅黑)等。若是字體名稱包含空格,必定要用引號包起來。固然font-family也支持對應的中文名稱,可是儘可能使用英文,以防字體解析失敗。

下面咱們來探究一下偏冷門的「字體種類」,我我的認爲,font-family給字體作了族譜後,還給各類習性相近的家族作了個分類,這個分類就是「字體種類」。MDN上文檔分類以下

font-family:serif(襯線字體)、sans-serif(無襯線字體)、monospace(等寬字體)、cursive(手寫字體)、fantasy(奇幻字體)、system-ui(系統字體)

對於中文網站,後面三種字體的應用場景有限,就不過多展開,這裏着重介紹一下襯線字體,無襯線字體和等寬字體。

襯線字體和無襯線字體是字體家族中兩種比較常見的字體,所謂襯線字體,通俗講就是筆畫開始、結束的地方有額外裝飾並且筆畫的粗細會有所不一樣的字體,如「宋體」。而無襯線字體則沒有這些額外的裝飾,並且筆畫的粗細差很少,如如今最經常使用的「雅黑」字體。要注意,無論是襯線仍是無襯線字體,或是上述「字體種類」中的任意一款字體,都有默認的字體關鍵字,通過我的測試,谷歌瀏覽器下serif(襯線字體)的默認字體包就是宋體。sans-serif(無襯線字體)的默認字體包就是微軟雅黑。固然不一樣的操做系統和瀏覽器可能有本身的偏好,所以"字體種類"能夠算做是按照操做系統喜愛展示哪一種字體的一種方式。

下面咱們再來說講等寬字體的實踐價值,所謂等寬字體,通常是針對英文字體而言的,由於中文字體在介紹em的時候就提到了,每一箇中文字體近似因而等寬高的,然而英文字母的大小寫卻又很大的不一樣,以下面這個例子:

<div>iiiiiii</div>
<div>MMMMMMM</div>
複製代碼

因爲markdown編輯器支持標籤語言,所以咱們能夠直接預覽最終效果以下(小提示:你能夠經過瀏覽器直接檢查下面的元素看到CSS樣式)

iiiiiii
MMMMMMM

其實等寬字體的好處我都不用多說了,咱們直接看,我在代碼框裏打出來的代碼,上下就是徹底對齊的,要作到這種對齊,就必須讓每一個字符所佔據的位置保持一致,而在瀏覽器的默認字體下,兩行文字所佔據的位置就差的有點遠了,等寬字體的應用很是多,所謂仁者見仁智者見智,用獲得的時候天然就會想到了。

6.細膩的font-weight

font-weight表示「字重」,就是文字的粗細程度,font-weight有兩個經常使用的關鍵字,normal和bold,事實上除了這兩個字面意義上的關鍵字以外,font-weight還支持如下關鍵字:100/200/300/400/500/600/700/800/900以及相對於父級元素的lighter和bolder。

可能有人懷疑我腦子有問題,爲何不直接寫100-900呢?由於,數字100並非數字,他是關鍵字,只是叫100罷了,若是你來一個100的親戚,100.000001,很差意思,font-weight不認識,也不承認。這時候又有人要說了,font-weight:100也沒有生效呀,爲何設置了font-weight:100以後字體跟200/300/400沒什麼區別?這鍋就不能甩給瀏覽器了,瀏覽器是支持檢測這些關鍵字的,之因此看不到粗細變化,是由於咱們系統裏缺少對應粗細的文字,所以一般狀況下,咱們只用到關鍵字normal(400)和bold(700)就足夠了,若是要看到這種細微的變化,須要咱們的操做系統安裝這些字體包,固然實際生產環境中你不可能要求用戶去按照除了瀏覽器以外的東西,所以想要解決這個問題,就須要藉助@font-face了。這個屬性會在後面深刻探究,這裏不過多展開。

7.font家族其餘屬性font-style和font-variant

font-style除了支持normal和italic(斜體)外,還支持oblique關鍵字,事實上這個關鍵字並無什麼軟用,這裏小小的作個展開。italic表示引用該字體的斜體字體包,一般狀況下,不少文字包並無單獨的斜體包,但有些英文字體包會有斜體字體包,若是招不到斜體字體包,則讓字體直接傾斜。oblique關鍵字的做用就是直接讓文字傾斜,所以我說這個關鍵字沒什麼軟用,一般狀況下,斜體字體包會比文字直接侵襲要好看得多,誰會去用oblique呢?

font-variant也是個不符合我國國情的CSS屬性,他的做用是實現小體型大寫字母,這個屬性能讓m和M的體型保持一致,這個屬性在母語是英文的國家可能用的比較多,對於咱們來講就是個雞肋屬性,瞭解一下便可。

8.深藏不露的font屬性

font支持縮寫,其語法以下:

[ [ <'font-style'> || <'font-variant'> || <'font-weight'> ]? <'font-size'> [ / <'line-height'> ]? <'font-family'> ] 複製代碼

這裏我想跳過font縮寫的相關介紹,由於這屬於CSS的糟粕部分,原文以下:

對於大部分的可縮寫屬性,縮寫並非個問題。您能夠聲明你想要的,任何選項均可以缺失,若是沒有則會應用初始值。例如list-style和background沒有應用的值99%的時間不管如何都不會被繼承的,因此值的設置與否無傷大雅。可是,不少排版屬性都預期從父輩繼承。所以,當你使用font縮寫,事情會變得混亂。若是你對該屬性的複雜性不熟悉,估計你要抓破腦殼了。換句話說,若是我在body元素上聲明文字粗體,我可能本但願裏面的文字都繼承粗體。結果,一旦應用了缺乏font-weight縮寫屬性的font縮寫,文字不是粗體顯示的了。

原文到此結束,本人想吐槽font縮寫的兩個問題,第一,font-family不能省略,font-family那麼又臭又長的屬性連個默認值都沒有,每次縮寫都得聲明,這也太浪費我時間了。第二,line-height能夠省略,但會被繼承,也就是你又是漏寫了個line-height,這個line-height就重置爲normal了,就繼承給後代了,這設定也忒.....

綜上所述,不建議使用font縮寫。

font屬性除了縮寫用法,還支持關鍵字屬性值,這個恐怕不少人不知道(又包括我了),關鍵字列表以下

  • caption:包含說明文字控件的字體(如按鈕,下拉等)。
  • icon:標籤圖標使用的字體,影響全部文件以及文件夾名稱字體。
  • menu:菜單使用的字體(以下拉菜單和菜單列表)。
  • message-box:消息框使用的字體。
  • small-caption:標記小控件使用的字體。
  • status-bar:窗體狀態欄使用的字體。

值得注意的是,聲明瞭font:關鍵字後,就無需定義font-size,font-family等屬性了,由於這些關鍵字本質上也是一種縮寫,已經包含font的各類屬性了。

ont關鍵字在實際使用場景中就是可讓網頁跟着系統走,要知道如今已經有不少桌面軟件能夠修改系統的默認字體了,若是讓瀏覽器能根據用戶的「心情」顯示對應的字體的話,看起來是否是很智能呢?這裏我提供兩種方式,讓字體隨着系統的默認字體改變。第一種,以前提到的font-family字體種類中還有一個被忽略的關鍵字system-ui,使用示例以下:

html{font-family:system-ui}
或者
html{font:menu}
複製代碼

本章的內容到此結束,原本@font face的內容也會放在這一章,但爲了保證文章的閱讀時間不要過長,打算單獨成立一章講講@font face。以爲內容有用的點個贊吧~

不忘初心,方得始終

喜歡博主的童鞋能夠掃描二維碼加博主好友~ 也能夠掃中間二維碼入駐博主的粉絲羣(708637831)~固然你也能夠掃描二維碼打賞並直接包養帥氣的博主一枚。

相關文章
相關標籤/搜索