- 原文地址:Common CSS Issues For Front-End Projects
- 原文做者:Ahmad Shadeed
- 譯者:Chor
快速摘要:近年來,跨瀏覽器的渲染和交互已經越發一致。不過,它仍然沒有達到徹底一致,有不少小問題會讓你出錯。除了這些問題以外,還有不一樣的屏幕尺寸、語言偏好和明顯的人爲錯誤等不肯定因素,咱們從中發現了許多會讓開發者出錯的小問題。css
在瀏覽器中實現用戶界面時,最好是儘量地減少這些差別和問題,以便 UI 呈現出預測的樣子。記住全部的這些差別是很困難的,因此我列舉了一系列常見問題以及解決方案。當你在作一個新項目的時候,能夠將其做爲一份方便的參考指南。 html
咱們開始吧。前端
button
和 input
元素的背景添加按鈕時,重置它的背景,不然在跨瀏覽器時它的呈現會有所不一樣。下面的例子分別展現了 Chrome 和 Safari 中的同一個按鈕,後者默認會有一個灰色背景。git
(大圖預覽)github
重置背景能夠解決這個問題:web
button { appearance: none; background: transparent; /* 其它樣式 */ }
https://codepen.io/shadeed/pe...瀏覽器
查看 Ahmad Shadeed(@shadeed)在 Codepen 上的代碼 按鈕和輸入框。app
scroll
和 auto
爲了限制一個元素的高度並容許用戶在其中滾動,添加 overflow: scroll-y
。在 macOS 下的 Chrome 中,這看起來不錯,可是在 Windows 下的 Chrome 中,滾動條始終存在(即便內容很短)。這是由於 scroll-y
會無視內容,一直顯示滾動條。而 overflow: auto
只在須要的時候纔會顯示滾動條。less
左邊:macOS 下的 Chrome。右邊:Windows 下的 Chrome (大圖預覽)dom
.element { height: 300px; overflow-y: auto; }
https://codepen.io/shadeed/pe...
查看 Ahmad Shadeed(@shadeed)在 Codepen 上的代碼 overflow-y。
flex-wrap
要想讓一個元素表現得像彈性容器那樣,只需添加 display: flex
。可是,若是沒有添加 flex-wrap
,那麼當屏幕尺寸縮小的時候,將會出現水平滾動條。
<div class="wrapper"> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> </div>
.wrapper { display: flex; } .item { flex: 0 0 120px; height: 100px; }
上面的例子在大屏幕下表現正常。在移動端下,瀏覽器將會出現水平滾動條。
左邊:出現水平滾動條,而且項目沒有換行。右邊:項目換行,呈兩行顯示 (大圖預覽)
解決方法很簡單。wrapper 應該在空間不足時讓項目換行。
.wrapper { display: flex; flex-wrap: wrap; }
https://codepen.io/shadeed/pe...
查看 Ahmad Shadeed(@shadeed)在 Codepen 上的代碼 overflow-y。
justify-content: space-between
對一個彈性容器應用 justify-content: space-between
時,它會爲元素分配空間,使它們互相之間的距離相等。咱們的例子中有 8 個卡片項目,看起來沒什麼問題。若是因爲某種緣由,項目的數量是 7 呢?第二行的元素看起來將會與第一行的不一樣。
包含 8 個項目的 wrapper (大圖預覽)
包含 7 個項目的 wrapper(大圖預覽)
https://codepen.io/shadeed/pe...
查看 Ahmad Shadeed(@shadeed)在 Codepen 上的代碼 overflow-y。
在這種狀況下,使用 CSS 網格將會更加合適。
在手機屏幕上瀏覽文章的時候,一個長詞或者內聯連接可能會致使頁面出現水平滾動條。使用 CSS 的 word-break
能夠防止這個問題。
(大圖預覽)
.article-content p { word-break: break-all; }
(大圖預覽)
當使用透明起點和終點添加漸變的時候,在 Safari 下會呈現一片漆黑。這是由於 Safari 沒法識別關鍵字 transparent
。經過使用 rgba(0, 0, 0, 0)
來替代它,咱們能夠達到預期的效果。注意下面的截圖:
頂部: Chrome 70。底部:Safari 12 (大圖預覽)
.section-hero { background: linear-gradient(transparent, #d7e0ef), #527ee0; /* 其它樣式 */ }
應該替換爲:
.section-hero { background: linear-gradient(rgba(0, 0, 0,0), #d7e0ef), #527ee0; /* 其它樣式 */ }
auto-fit
和 auto-fill
差別的誤解在 CSS 網格佈局中,repeat
函數能夠在不使用媒體查詢的狀況下建立響應式列布局。爲此,可使用 auto-fill
或者 auto-fit
。
.wrapper { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); }
(大圖預覽)
簡而言之,auto-fill
將會在不擴展列寬度的狀況下對它們進行排列,而auto-fit
則會在存在空列的時候使其寬度塌陷爲 0。Sara Soueidan 寫了一篇不錯的文章討論過這個問題。
若是你在視窗不夠高的時候將一個元素固定在屏幕頂部,會發生什麼事呢?很簡單:它將佔用屏幕空間,最終致使可供用戶瀏覽網站的垂直區域變得很小、很不舒服,影響他們的體驗。
@media (min-height: 500px) { .site-header { position: sticky; top: 0; /* 其它樣式 */ } }
上面的代碼中,咱們讓瀏覽器只在視窗高度等於或大於 500 像素的時候才固定頂部。
還有一點很重要:使用 position: sticky
的時候,除非指定 top
屬性,不然它不會生效。
(大圖預覽)
https://codepen.io/shadeed/pe...
查看 Ahmad Shadeed(@shadeed)在 Codepen 上的代碼 overflow-y。
max-width
添加圖片時,定義 max-width: 100%
,這樣圖片會在屏幕較小的時候改變大小。不然瀏覽器將會顯示水平滾動條。
img { max-width: 100%; }
main
和 aside
元素CSS 網格可用於定義佈局中的 main
部分和 aside
部分,這是 CSS 網格的絕佳用途。問題是,即便 aside
是空的,它的高度也會和 main
的高度相等。
要修復這個問題,可讓 aside
元素與其父元素的起點對齊,這樣它的高度就不會擴展了。
.wrapper { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); grid-gap: 20px; } // align-self 將會讓 aside 元素與其父元素的起點對齊。 aside { grid-column: 1 / 4; grid-row: 1; align-self: start; } main { grid-column: 4 / 13; }
(大圖預覽)
https://codepen.io/shadeed/pe...
查看 Ahmad Shadeed(@shadeed)在 Codepen 上的代碼 overflow-y。
fill
使用 SVG 時,若是在 SVG 內部添加 fill
,有時候它可能不會如預期的那樣生效。要修復這個問題,要麼移除 SVG 自身的 fill
屬性,要麼覆蓋 fill: color
。
舉個例子:
.some-icon { fill: #137cbf; }
若是 SVG 有一個內聯 fill 的話,這段代碼將不會生效。應該替換爲:
.some-icon path { fill: #137cbf; }
不管什麼時候,我都很喜歡使用僞元素。僞元素爲咱們提供了一種建立假元素的方法,主要用來裝飾,同時又無需將其添加到 HTML 中。
使用它們的時候,開發者可能會忘記作下面的事情:
content: ""
屬性,display
屬性的狀況下設置它們的 width
和 height
下面的例子中,咱們有一個標題,其標記是一個僞元素。必須給元素添加 content: ""
屬性,同時還要爲它設置 display: inline-block
,以使 width
和 height
像預期的那樣生效。
(大圖預覽)
display: inline-block
時奇怪的空隙給兩個或兩個以上的元素設置 display: inline-block
或者 display: inline
,將會致使它們之間產生一個微小的空隙。緣由是瀏覽器會將元素看成字詞去解釋,從而給每一個元素之間添加一個字符的空隙。
下面的例子中,每一個項目的右側都有一個 8px
的空隙,可是使用 display: inline-block
而產生的小空隙將會使其變爲 12px
,這不是咱們想要的效果。
li:not(:last-child) { margin-right: 8px; }
(大圖預覽)
經過給父元素設置 font-size: 0
能夠簡單地解決這個問題。
ul { font-size: 0; } li { font-size: 16px; /* 應該在這裏從新設置字體大小,由於它會從父元素繼承 `font-size: 0`。*/ }
(大圖預覽)
https://codepen.io/shadeed/pe...
查看 Ahmad Shadeed(@shadeed)在 Codepen 上的代碼 overflow-y。
for="ID"
使用表單元素時,確保全部的 label
元素都分配到了一個 ID。這將提升它們的可訪問性,點擊的時候,相關的輸入框將得到焦點。
<label for="emailAddress">Email address:</label> <input type="email" id="emailAddress">
(大圖預覽)
給整個文檔設置字體的時候,字體並不會應用於諸如 input
, button
select
和 textarea
這些元素上。默認狀況下,它們並不會繼承文檔字體,由於瀏覽器給它們應用了系統字體。
要修復這個問題,直接設置字體屬性:
input, button, select, textarea { font-family: your-awesome-font-name; }
有些元素的寬度可能會致使出現一個水平滾動條。
要找到問題的根源,最簡單的方法就是使用 CSS outline。Addy Osmani 寫了一個方便的腳本 。將其添加到瀏覽器的控制檯,頁面上全部元素的輪廓都會顯示出來。
[].forEach.call($$("*"), function(a) { a.style.outline = "1px solid #" + (~~(Math.random() * (1 << 24))).toString(16); });
(大圖預覽)
用 CSS 調整一張圖片的大小時,若是縱橫比與圖片的寬高不一致,則圖片會被壓縮或拉伸。
解決方法很簡單:使用 CSS 的 object-fit
。它的功能和給背景圖片設置 background-size: cover
相似。
img { object-fit: cover; }
(大圖預覽)
object-fit
並不是百試百靈。一些圖片必須在不裁剪或者不調整大小的狀況下顯示,而且某些平臺會強制用戶以特定的尺寸裁剪或上傳圖片。例如,Dribbble 規定上傳的縮略圖尺寸爲 800 x 600 像素。
input
添加正確的 type
爲 input
使用正確的 type
。這將改善移動端的用戶體驗,並使用戶更容易訪問。
這是部分 HTML:
<form action=""> <p> <label for="name">Full name</label> <input type="text" id="name"> </p> <p> <label for="email">Email</label> <input type="email" id="email"> </p> <p> <label for="phone">Phone</label> <input type="tel" id="phone"> </p> </form>
每一個輸入框分別獲取焦點時,看起來是這樣的:
(大圖預覽)
在一個從右到左的佈局中添加諸如 + 972-123555777
的手機號碼時,加號將會位於號碼末尾。要修復這個問題,能夠從新指定手機號碼的方向。
p { direction: ltr; }
(大圖預覽)
這裏提到的全部問題都是我在前端開發工做中最常遇到的。個人目標是在開發 web 項目時按期檢查這份清單。
你在 CSS 中有沒有常常遇到什麼問題呢?歡迎在評論區分享!