button 使用 flex 佈局的相容性問題 在低版本的手機系統中,我們發現 不能夠作為 flex 容器,即使在 CSS 中指定了 且 autoprefixer 也已經轉換成相容屬性,也還是不起作用。具體表現在其內容並不能使用 flex 佈局對齊,比如說居中。 這裡的背景是,我們經常需要展示一些按 ...
button 使用 flex 佈局的相容性問題
在低版本的手機系統中,我們發現 button
不能夠作為 flex 容器,即使在 CSS 中指定了 display: flex
且 autoprefixer 也已經轉換成相容屬性,也還是不起作用。具體表現在其內容並不能使用 flex 佈局對齊,比如說居中。
這裡的背景是,我們經常需要展示一些按鈕,用戶可點擊執行特定的操作。如果只是簡單把 div
寫成按鈕的樣子,裡面直接寫文本的話,會產生至少兩個問題: 1. 語義和無障礙都不夠友好; 2. 低版本手機文本節點不能對齊。
<div class="btn">
我是一個按鈕
</div>
.btn {
display: flex;
align-items: center;
justify-content: center;
color: #fff;
}
為瞭解決第一個問題,我們直接使用標準的 button
標簽即可。不考慮使用 a
標簽原因是既要處理預設的點擊行為,也要為了 a11y 指定 WAI-ARIA 的 role="button"
,按鈕數量多了之後寫起來就比較煩人。而對於第二個問題,我們一般可把按鈕的內容(這裡只有一個文本節點)包裹在 span
里。
<button class="btn">
<span>我是一個按鈕</span>
</button>
.btn {
display: flex;
align-items: center;
justify-content: center;
& > span {
color: #fff;
}
}
但上面這種方案,經過測試發現在低版本系統上還是有問題,文本並沒有被居中!這個時候我們可以選擇把 span
設為 width: 100%
並設置文本居中屬性 text-align: center
,但這種方法相當於放棄了 flex 佈局,轉而使用了傳統的對齊方案。而且既然水平方向的 flex 排版不起作用,我們也不能期望垂直方向的也能正常工作。
經過搜索,我們發現 ionic-team/ionic#5310 提供了一種方案,原來的 button
還是保持 block 的顯示佈局不變,將 flex 佈局的屬性設置在裡面的 span
元素上。經測試,這種方案在我們需要相容的機型( and 4.4.4+ / iOS 8.4+ )上都能正常工作。
.btn {
display: inline-block;
& > span {
width: 100%;
height: 100%;
display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: center;
}
}
該方案一直被 ionic 項目沿用至今,我目前看到的代碼位於 button.scss#L43 #L241 。反查資料可知這是 flex box 在早期瀏覽器實現的 bug ,並早已有人給出了 workaround ,詳見 Flexbug #9 - Some HTML elements can't be flex containers 。
2020 年了,希望大家都能往小康衝刺,都能換上更好更新的手機,也希望 Web 前端能夠儘早擺脫對較低版本瀏覽器內核的相容吧。