前言
移動端開發,經常會遇到的問題,就是文字居中。一般都只能往css方向去fix這個問題。
自己以前也用過position:relative;top:-*px
的方式去解決。🌚
后來才發現,原來不是css的問題,是瀏覽器在渲染象形文字時,就已經錯誤了。
本文參考自知乎回答,用來總結如何填上這個坑~
一、css文字居中
先總結下,前端開發中,常用的文字居中技巧。
- 常規方法
height:20px;
line-height:20px;
- table-cell方式
<p class="text-wrap">
<span class="text">文字居中</span>
</p>
.text-wrap{
display:table;
}
.text{
display:table-cell;
vertical-align:middle;
}
- position方式
<p class="text-wrap">
<span class="text">文字居中</span>
</p>
.text-wrap{
position:relative;
height:20px; /* 必須設置一個高度,一般取文字高度 。因為內容abs定位后,高度為0*/
}
.text{
position:absolute;
top:50%;
left:50%;
transform:translate(-50%, -50%);
}
- flex方式
<p class="text-wrap">
<span class="text">文字居中</span>
</p>
.text-wrap{
display:flex;
justify-content:center; /* 左右居中 */
align-items:center; /* 上下居中 */
}
二、為什么Android、IOS應用css居中不起效
因為文字在content-area內部渲染的時候就已經偏移。css的居中方案都是用來控制整個content-area的居中而已,對content-area內部不會產生實質性的影響。
導致這個問題的本質原因可能是Android在排版計算的時候參考了primyfont字體的相關屬性(即HHead Ascent、HHead Descent等)。
primyfont字體的確定,是依據font-family
里哪個字體在fonts.xml里第一個匹配上。
原生Android下中文字體是沒有family name的,導致匹配上的字體始終不是中文字體。所以渲染的時候出現偏差。
那么,解決這個問題就要在font-family
里顯式申明中文,或者通過什么方法保證所有字符都fallback到中文字體。
三、解決方案
1.針對Android 7.0+設備:上設置 lang 屬性:,同時font-family不指定英文。
比較常用的是設置font-family: sans-serif
。
這個方法是利用了瀏覽器的字體fallback機制,讓英文也使用中文字體來展示。blink早期的內核在fallback機制上存在問題,Android 7.0+才能ok,早期的內核下會導致英文fallback到Noto Sans Myanmar,這個字體非常丑。
2.針對MIUI 8.0+設備:設置font-family: miui
。
這個方案就是顯式申明中文的方案,MIUI在8.0+上內置了小米蘭亭,同時在fonts.xml里給這個字體指定了family name:miui,所以我們可以直接設置。
另外,騰訊的IMWeb團隊也給出了解決方案,但親測,治標不治本。還是上述方案較為完美地解決。
參考
[1] Android瀏覽器下line-height垂直居中為什么會偏離 -- 周祺回答
[2] Android 瀏覽器文本垂直居中問題 -- IMWeb解決方案