為什麼傳值時加號變成了空格 常見空格一覽

2021-10-14 08:52:04 字數 2842 閱讀 9810

最近在寫css的時候遇到了乙個問題,有乙個高度屬性值不合法:

從肉眼看沒什麼不妥,根據以往經驗,這應該是有特殊的空格導致,把它endcode一下,果不其然:

查了一下,這是乙個發寬空格,unicode編碼為u+200a。故藉此把常見的普通和特殊空格整理一翻。

這是最常用的空格,拉丁文的空格,ascii編碼0x20。在英文輸入法(和中文輸入法半形狀態)下,由鍵盤空格鍵直接輸出。這個空格的寬度會受到所使用的字型的影響:

例如在上圖所示的這個字型,空格的寬度為69(這個是相對於em來說的,這個字型的em大小為256),我們可以把它改大一點,然後生成乙個新的字型,使用這個新的字型,空格被渲染出來的寬度便會變大。

在html裡面這應該算是第二常用的空格了,它的html實體為「 」(no-break space)。當html有多個連續的普通空格時,瀏覽器在渲染時只會渲染乙個空格,而使用這個不間斷空格,可以禁止瀏覽器合併空格。常用於富文字編輯器之中,當我們在富文字編輯器連續敲下多個空格時,最後輸出的內容便會帶有很多不間斷空格。如下圖所示,實際表現為乙個普通空格加乙個不間斷空格連續交替:

在mac電腦上通過alt + space可以打出乙個不間斷空格。

相信不少人在這個零寬空格上摔過跤,特別是當從一些網頁拷了一些東西到**裡面去的時候,然後再做一些字串處理出現了一些神奇的事情,如下圖所示:

為什麼明明只有4個字元,長度卻是5呢?我們把它encode一下就會發現,其實字串裡面帶了乙個零寬字元:

零寬空格的utf-8編碼便為0xe2808a。

零寬空格廣泛使用於第三方的富文字編輯器裡面,常用於格式隔斷,例如當你在乙個富文字編輯器裡面選中一段文字加粗後,如果啥也不幹,接著在這選中的文字後面鍵入的文字便會自動加粗,為了把格式隔斷,可以在加粗後的文字後面手動插入乙個零寬空格,這樣使用者在接著往後輸時便不會自動延續格式了。

html的標籤的作用也相當於乙個零寬空格,可用於隔斷英文單詞進行換行。如mdn舉的乙個例子:

這個標籤和上面使用html實體的區別在於,這個標籤是無法被拷到純文字裡面的,而html例項或者使用js字串的方式是可以的,因為它本身就是純文字的一部分(unicode),標籤則不是。

eslint有一條禁止不規則的空白 (no-irregular-whitespace)的規則,防止**裡面誤拷貝了一些諸如零寬空格類的空格,以免造成一些誤導。

普通的u+0020是半形空格,與此相對還有乙個全形空格,也叫全寬空格,即乙個em大小,在fontforge裡面可以看到當前字型的em大小:

這個字型的em為256,乙個全寬的字元就是1em,所有的漢字和標點符號的寬度往往被設計成1em。所以全寬空格就和乙個漢字同寬。

乙個em方塊(em square)如下圖紅框所示:

乙個字型在設計的時候不一定是在em方塊裡的,看設計師的想法,有可能會超出,如上面的「@」符號,超出的效果是會導致設定font-size的時候實際渲染的高度會比設定的值會更大,例如設定font-size為100px,如果沒有超出,那麼當前文字高度便為100px,反之會變大。實際看的是ascent和descent的設定:

在這個例子裡面渲染出來的高度應為229 + 66 = 295,100 * (295 / 256) = 110px。

所以使用不同的字型設定相同的字型大小,但實際的大小卻不一樣,便是這個原因。高度超出的比較常見,寬度超出的較少,特別是中文,一般不會超出寬度,所以乙個全寬空格寬度便和乙個普通漢字的寬度一樣大。

全寬用em表示,半寬則用en表示,為em的一半。半寬空格可用於一些對齊的目的,如三個漢字和四個漢字的兩邊對齊:

注意全寬和半寬字元理論上不會受到字型影響,如果字型有這兩個符號的話,那麼應當遵循規範,將這兩個字元的寬度分別置為1em和0.5em,否則直接讓這兩個字元缺失即可,如:

在fontforge裡面打叉就表示符號缺失。

除了半寬,還有三分之一寬(u+2004)、四分之一寬(u+2005)和六分之一寬(u+2006)

零寬空格的前乙個便為發寬空格(hair space),網上關於這個空格的介紹幾乎沒有,只是說它是乙個最窄寬度的空格(像頭髮一樣窄,所以叫發寬)。這個也是開篇提到的空格型別,是從mac的資料夾裡的檔案資訊視窗裡拷的:

為什麼mac要用這個空格呢?可能出於mac的設計審美,普通空白寬度過大,而用發寬空白可能剛好。

除了以上提到的空格外,還有專門用於數學的空格、在德語和法語裡用來隔開連詞的空格,等等,更多型別空格可見維基百科《空格》。

為什麼print在Python 3中變成了函式?

在python 2中,print是乙個語句 statement 而在python 3中變成了函式 function 很多python使用者都會問,為什麼python 3將print變成了函式呢?本文就是python核心開發者brett cannon對此的解釋。今年初python決定遷移到github...

為什麼print在Python 3中變成了函式?

譯者 earlgrey 程式設計派 在python 2中,print是乙個語句 statement 而在python 3中變成了函式 function 很多python使用者都會問,為什麼python 3將print變成了函式呢?本文就是python核心開發者brett cannon對此的解釋。今年...

C 為什麼要用傳引用常量替換傳值

假設現在有乙個person類作為基類,還有乙個student類繼承自person,如下 class person class student public person 現在我們有乙個函式,叫validatestudent,需要傳入乙個student物件,並返回它是否有效。bool validate...