社區(qū)精選 |防御式CSS是什么?這幾點(diǎn)屬性重點(diǎn)防御!
今天小編為大家?guī)淼氖巧鐓^(qū)作者 前端小智 的文章,通過這篇文章看看防御式CSS是什么吧。
很多時候,我們希望有一種方法可以避免某種CSS問題或行為的發(fā)生。我們知道,網(wǎng)頁內(nèi)容是動態(tài)的,網(wǎng)頁上的東西可以改變,從而增加了出現(xiàn)CSS問題或奇怪行為的可能性。
防御式 CSS是一個片段的集合,可以幫助我編寫受保護(hù)的CSS。換句話說,就是將來會有更bug出現(xiàn)。
1.Flexbox 包裹
CSS flexbox 是目前最有用的CSS布局功能之一。在一個包裝器上添加 display: flex,讓子項挨著排序。
問題是,當(dāng)空間不足時,那些子項默認(rèn)不會被包裹成一個新的行。我們需要用 flex-wrap: wrap 來改變這一行為。
下面是一個典型的例子。
.options-list {
display: flex;
}

當(dāng)空間較少時,會出現(xiàn)水平滾動。這應(yīng)該是預(yù)料之中的,實(shí)際上并不是一個 "問題"。

.options-list {
display: flex;
flex-wrap: wrap;
}

使用flexbox時,一般的經(jīng)驗法則是允許包裹,除非你想要一個滾動的包裹。這是另一回事,但盡量使用 flex-wrap 來避免意外的布局行為(在我們的例子中,是水平滾動)。
2.間距
我們開發(fā)者需要考慮不同的內(nèi)容長度。這意味著,間距應(yīng)該添加到組件中,即使它看起來不需要。

在這個例子中,我們在右邊有一個section標(biāo)題和一個操作按鈕。目前,它看起來還不錯。但是,如果標(biāo)題再長一些,會發(fā)生什么呢?

注意到文本太靠近按鈕了嗎?這里,你可能會考慮多行換行,但現(xiàn)在,我們先關(guān)注距。
如果標(biāo)題有空格和文本截斷,我們不會看到這樣的問題。
.section__title {
margin-right: 1rem;
}

3.長內(nèi)容
在構(gòu)建布局時,考慮到長的內(nèi)容是很重要的。正如你在前面所看到的,當(dāng)章節(jié)的標(biāo)題太長時就會被截斷。這是可選的,但對于某些UI來說,考慮到這一點(diǎn)很重要。
對我來說,這是一種防御性的CSS方法。在 "問題 "真正發(fā)生之前就去解決它,這很好。
這里有一份人名清單,現(xiàn)在看起來很完美。

然而,由于這是用戶生成的內(nèi)容,我們需要小心如何防御布局,以防某些內(nèi)容太長。請看下圖:

在這種布局中,一致性非常重要。為了實(shí)現(xiàn)這一點(diǎn),我們可以使用 text-overflow和它的好友來簡單地截斷名稱。

4. 防止圖像被拉伸或壓縮
在無法控制圖片高寬比的情況下,如果用戶上傳的圖片與高寬比不符,最好提前考慮并提供解決方案。
在下面的例子中,我們有一個帶有照片的卡片組件。它看起來不錯。

當(dāng)用戶上傳一個不同大小的圖像時,它將被拉伸。這可不是什么好事。看看圖像是如何被拉伸的!

最簡單的修復(fù)方法是使用CSS object-fit。
.card__thumb {
object-fit: cover;
}

在項目層面上,我傾向于為所有圖像添加 object-fit,以避免出現(xiàn)意外的結(jié)果。
5.鎖定滾動鏈接
你是否曾經(jīng)打開一個模態(tài)并開始滾動,然后當(dāng)你到達(dá)終點(diǎn)并繼續(xù)滾動時,模態(tài)下面的內(nèi)容(主體元素)會滾動?這就是所謂的滾動鏈。
默認(rèn)情況下,當(dāng)觸及頁面頂部或者底部時(或者是其他可滾動區(qū)域),移動端瀏覽器傾向于提供一種“觸底”效果,甚至進(jìn)行頁面刷新。你可能也發(fā)現(xiàn)了,當(dāng)對話框中含有可滾動內(nèi)容時,一旦滾動至對話框的邊界,對話框下方的頁面內(nèi)容也開始滾動了——這被稱為“滾動鏈”。
在過去的幾年里,有一些黑科技來實(shí)現(xiàn)這一點(diǎn),但現(xiàn)在,我們只需要使用CSS 即可,這要感謝overscroll-behavior CSS屬性。
在下面的圖中,可以看到默認(rèn)的滾動鏈接行為。

為了提前避免這種情況,我們可以將其添加到任何需要滾動的組件中(例如:聊天組件、移動菜單...等)。這個屬性的好處是,在有滾動之前,它不會產(chǎn)生影響。
.modal__content {
overscroll-behavior-y: contain;
overflow-y: auto;
}
6. CSS變量回退
CSS變量在網(wǎng)頁設(shè)計中得到了越來越多的應(yīng)用。我們可以應(yīng)用一種方法,在CSS變量值因某種原因為空的情況下,以一種不破壞體驗的方式使用它們。
通過 JS 輸入CSS變量的值時特別有用。下面是一個例子:
.message__bubble {
max-width: calc(100% - var(--actions-width));
}
變量 --actions-width 在 calc() 函數(shù)中被使用,其值來自 JS。假設(shè) JS 由于某種原因失敗了,會發(fā)生什么?max-width 會被計算為零。
我們可以提前避免這種情況,在 var() 中添加一個回退值。
.message__bubble {
max-width: calc(100% - var(--actions-width, 70px));
}
這樣,如果變量沒有定義,就會使用回退 (70px)。這種方法可以在變量可能失敗的情況下使用。
7.使用固定寬度或高度
破壞布局的常見情況之一是對一個有不同長度內(nèi)容的元素使用固定的寬度或高度。
固定高度
我經(jīng)常看到主內(nèi)容部分有固定的高度,而內(nèi)容卻大于這個高度,這就導(dǎo)致了布局的破壞。如下所示:
.main {
height: 350px;
}

為了避免這種情況出現(xiàn),可以使用 min-height 代替 height:

固定寬度
你有沒有見過按鈕,它的標(biāo)簽離左右邊緣太近?這是由于使用了固定寬度。
.button {
width: 100px;
}
如果按鈕的標(biāo)簽大于100px,它將靠近邊緣。如果它太長,文本會泄露出來。這是不好的!

為了解決這個問題,我們可以簡單地用 min-width 代替 width。
.button {
width: 100px;
}
8.忘記 background-Repeat
很多時候,當(dāng)使用一張大的圖片作為背景時,我們往往會忘記考慮設(shè)計在大屏幕上觀看時的情況。該背景將默認(rèn)重復(fù)。

這在筆記本屏幕上大多不會看到,但在大屏幕上很常見。
為了提前避免這種行為,請確保使用重置 background-repeat。
.hero {
background-image: url('..');
background-repeat: no-repeat;
}
9.垂直媒體查詢
有時,我們很想建立一個組件,只通過調(diào)整瀏覽器的寬度進(jìn)行測試。根據(jù)瀏覽器的高度進(jìn)行測試可以發(fā)現(xiàn)一些有趣的問題。
這里有一個我見過多次的例子。我們有一個帶有主要和次要鏈接組件。次要鏈接應(yīng)該位于旁白部分的最底部。
考慮一下下面的例子。主導(dǎo)航和次導(dǎo)航看起來還不錯。在我看到的這個例子中,開發(fā)者給二級導(dǎo)航添加了 position: sticky,這樣它就可以粘在底部了。

然而,如果瀏覽器的高度較小,bug 就來了。注意這兩個導(dǎo)航是如何重疊的。

通過使用CSS垂直媒體查詢,我們可以避免這個問題。
@media (min-height: 600px) {
.aside__secondary {
position: sticky;
bottom: 0;
}
}
這樣,只有當(dāng)視口高度大于或等于600px 時,二級導(dǎo)航才會被粘在底部。好多了,對嗎?
可能有更好的方法來實(shí)現(xiàn)這一行為(比如使用 margin-auto),但在這個例子中專注于垂直查詢。
10. 使用 justify-content:space-between
在一個 flex 的容器中,我們可能會使用 justify-content 來使子項目之間有一定的間距。如果有一定數(shù)量的子項目,布局看起來會很好。然而,當(dāng)它們增加或減少時,布局會看起來很奇怪。
考慮以下例子:

我們有一個有四個項目的 flex 容器。每個項目之間的間距不是 gap 或 margin,它之所以存在是因為容器有 justify-content: space-between。
.wrapper {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
當(dāng)項目的數(shù)量少于4個時,將發(fā)生以下情況:

這并不是好事。對此有不同的解決方案:
margin flexbox gap(謹(jǐn)慎使用) padding(可應(yīng)用于每個子元素的父元素) 增加空的元素,作為間隔。
.wrapper {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}

11. 圖片上的文字



12.小心CSS網(wǎng)格中的固定值
.wrapper {
display: grid;
grid-template-columns: 250px 1fr;
gap: 1rem;
}
@media (min-width: 600px) {
.wrapper {
display: grid;
grid-template-columns: 250px 1fr;
gap: 1rem;
}
}
13.只在需要的時候顯示滾動條

.element {
overflow-y: auto;
}

14.Scrollbar Gutter

.element {
scrollbar-gutter: stable;
}

15. CSS Flexbox中的最小內(nèi)容尺寸
.card {
display: flex;
}

.card__title {
overflow-wrap: break-word;
}
.card__title {
overflow-wrap: break-word;
min-width: 0;
}

16. CSS網(wǎng)格中的最小內(nèi)容尺寸

<div class="wrapper">
<main>
<section class="carousel"></section>
</main>
<aside></aside>
</div>
@media (min-width: 1020px) {
.wrapper {
display: grid;
grid-template-columns: 1fr 248px;
grid-gap: 40px;
}
}
.carousel {
display: flex;
overflow-x: auto;
}
使用 minmax() 將 min-width 應(yīng)用于網(wǎng)格項目 在網(wǎng)絡(luò)中添加 overflow: hidden
@media (min-width: 1020px) {
.wrapper {
display: grid;
grid-template-columns: minmax(0, 1fr) 248px;
grid-gap: 40px;
}
}

17.Auto Fit Vs Auto Fill


