高級佈局和效果的八個 CSS 技巧
已發表: 2022-03-11在過去的幾年裡,Web 前端開發領域取得了長足的進步。 然而,正如用戶所見,Web 前端仍然是相同的:使用 CSS 樣式的 HTML 標記。
許多佈局問題起初看起來很簡單,但往往被證明是棘手的。 如果沒有對某些 CSS 功能如何工作的廣泛了解,這些高級佈局似乎無法單獨使用 CSS 實現。
在本文中,您將找到八個專家級的 CSS 技巧和竅門,它們利用鮮為人知的 CSS 特性來實現其中一些高級佈局和效果。
1. 最大化 CSS 兄弟選擇器
問題:不使用同級選擇器會失去優化機會。
解決方案:只要有意義就使用兄弟選擇器。 每當您使用項目列表,並且需要以不同的方式處理第一個或最後一個項目時,您的第一反應可能是使用:first-child
和:last-child
偽 CSS 選擇器。
例如,當創建一個純 CSS 的漢堡菜單圖標時:
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Maximizing CSS Sibling Selectors 1。
這是有道理的:除了最後一個之外,每個條都有一個邊距底部。
然而,同樣的效果也可以通過相鄰的兄弟選擇器 (+):
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Maximizing CSS Sibling Selectors 2。
這也是有道理的:第一個柱之後的所有內容都有一個邊距頂部。 這個 CSS 技巧不僅節省了一些額外的字節(對於任何中型項目來說都可以輕鬆添加),而且還開闢了一個充滿可能性的世界。
考慮這張卡片列表:
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Maximizing CSS Sibling Selectors 3。
每個都有一個標題和文本,後者默認隱藏。 如果您只想使活動卡片的文本(使用.active
類)及其後面的內容可見,您可以僅使用 CSS 快速完成:
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Maximizing CSS Sibling Selectors 4。
使用一點 JavaScript,這也可以是交互式的。
然而,僅僅依靠 JavaScript 會產生這樣的腳本:
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Maximizing CSS Sibling Selectors 5。
其中包含 jQuery 作為依賴項可以讓您擁有一些簡短的代碼。
2. 一致的 HTML 元素大小
問題: HTML 元素在不同瀏覽器中的大小不一致。
解決方案:將所有元素的box-sizing
設置為border-box
。 長期以來,Internet Explorer 一直是 Web 開發人員的禍根,它做對了一件事情:它正確地調整了盒子的大小。
其他瀏覽器在計算 HTML 元素的寬度時只查看內容,其他所有內容都視為多餘的。 一個width: 200px
像素的 div,具有 20 20px
的內邊距和 2 2px
的邊框,呈現為 242 像素寬。
Internet Explorer 將填充和邊框視為寬度的一部分。 在這裡,上面的 div 將是 200 像素寬。
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen CSS Box Model Demo 1。
一旦你掌握了竅門,你會發現後一種方法更合乎邏輯,即使它不遵循標準。
如果我說寬度是 200 像素,天哪,即使我有 20 像素的填充,它也會是一個 200 像素寬的盒子。
在任何情況下,以下 CSS 使元素大小(以及佈局)在所有瀏覽器中保持一致:
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen CSS Box Model Demo 2。
第二組 CSS 選擇器保護沒有邊框的 HTML 元素不受佈局干擾。
box-sizing: border-box
非常有用,它是一個相對流行的 CSS 框架 sanitize.css 的一部分。
3.動態高度元素
問題:保持 HTML 元素的高度與其寬度成正比。
解決方案:使用垂直填充代替高度。
假設您希望 HTML 元素的高度始終匹配其 CSS 寬度。 height: 100%
不會更改與其內容高度匹配的元素的默認行為。
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Dynamic Height Elements 1。
答案是將高度設置為 0 並使用 padding-top 或 padding-bottom 來設置.container
的實際高度。 任一屬性都可以是元素寬度的百分比:
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Dynamic Height Elements 2。
現在.container
將保持為正方形,無論它變得多寬。 overflow: hidden
防止長內容打破這個比例。
這種技術,經過一些修改,非常適合創建在任何大小下保持其縱橫比的視頻嵌入。 只需將嵌入與.container
的頂部和左側對齊position: absolute
,將嵌入的兩個尺寸都設置為 100% 以使其“填滿” .container
,並更改.container
的padding-bottom
以匹配視頻的方面比率。
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Dynamic Height Elements 3。
position: relative
for .container
確保iframe
絕對定位正常工作。 新的padding-bottom
只是縱橫比的高度除以其寬度,乘以 100。例如,如果視頻嵌入的縱橫比為 16:9,則 padding-bottom 百分比應為 9 除以 16 (.5625)並乘以 100 (56.25)。
4.動態寬度元素
問題:保持 HTML 元素的寬度與其高度成比例。
解決方案:使用 font-size 作為元素尺寸的基礎。
現在,反過來,或者容器的寬度隨著高度的變化而變化呢? 這一次,它是font-size
的救援。 請記住,寬度和高度可以以em
為單位,這意味著它們可以是元素font-size
的比率。
一個font-size
為 40px、寬度為2em
、高度為1em
的元素將是 80 像素 (40 x 2) 寬和 40 像素 (40 x 1) 高。
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Dynamic Width Elements。
想改變.container
的高度嗎? 更改字體大小。
唯一需要注意的是,僅通過 CSS 無法使元素的字體大小自動匹配其父元素的高度。 然而,這種技術允許將 Javascript 調整大小腳本從以下位置縮減:
var container = document.querySelector( '.container' ); container.style.height = yourDesiredHeight + 'px'; container.style.width = yourDesiredHeight * yourDesiredRatio + 'px';
到:
document.querySelector( '.container' ).style.fontSize = yourDesiredHeight + 'px';
5.動態內容的垂直居中
問題:保持一個 HTML 元素(高度未知)在另一個元素中垂直居中。

解決方案:將外部元素設置為display: table
,然後將內部元素轉換為 CSS table-cell
。 或者只是使用 CSS Flexbox。
可以使用line-height
將一行文本垂直居中:
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的動態內容 1 的筆垂直居中。
對於多行文本或非文本內容,CSS 表格就是答案。 將.container
的顯示設置為table
,然後使用display: table-cell
和vertical-align: middle
為.text
:
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的動態內容 2 的筆垂直居中。
把這個 CSS 技巧想像成margin: 0 auto
的垂直等價物。 如果 Internet Explorer 的錯誤支持是可以接受的,那麼 CSS3 的 Flexbox 是該技術的一個很好的替代方案:
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的動態內容 3 的筆垂直居中。
6. 相同高度的柱子
問題:保持列的高度相同。
解決方案:對於每一列,使用較大的負margin-bottom
值,並使用同樣大padding-bottom
將其取消。 CSS 表格和 Flexbox 也可以使用。
使用float
或display: inline-block
,可以通過 CSS 創建並排的列。
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Same-Height Columns 1。
請注意使用box-sizing: border-box
來正確調整.cols
的大小。 請參閱上面的一致的 HTML 元素大小。
第一列和最後一列的邊界不會一直向下; 它們與較高的第二列的高度不匹配。 要解決此問題,只需將overflow: hidden
添加到.row
。 然後將每個.col
的margin-bottom
設置為 99999px 並將其padding-bottom
設置為 100009px (99999px + 應用於.col
另一側的 10px 填充)。
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Same-Height Columns 2。
一個更直接的替代方案是 Flexbox。 同樣,僅在不需要 Internet Explorer 支持時才使用它。
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Same-Height Columns 3。
另一種具有更好瀏覽器支持的替代方案:CSS 表格(沒有vertical-align: middle
)。
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Same-Height Columns 4。
7. 超越框框
問題:方框和直線太陳詞濫調了。
解決方案:使用transform: rotate(x)
或border-radius
。
從營銷或宣傳冊網站中獲取典型的一系列窗格:具有奇異點的垂直堆疊幻燈片。 它的標記和 CSS 可能看起來像這樣:
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Going Beyond the Box 1。
以使標記更加複雜為代價,這些四四方方的窗格可以變成一堆平行四邊形。
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Going Beyond the Box 2。
這裡發生了很多事情:
每個窗格的高度由 .pane-container 控制。 負邊距底部確保窗格緊密堆疊。
-
.pane-background
、它的子.mask-box
和它的孫子.image
都設置為position: absolute
。 每個元素都有不同的top
、left
、bottom
和right
值。 這消除了由下面詳述的旋轉產生的任何間距。 -
.mask-box
旋轉 2 度(逆時針)。 -
.image
旋轉 -2 度以抵消.mask-box
的旋轉。 -
.mask-box
的溢出是隱藏的,因此其旋轉的頂部和底部會夾住.image
元素。
在相關說明中,將圖像變成圓形或橢圓形非常簡單。 只需將border-radius: 100%
應用於img
元素。
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Going Beyond the Box 3。
諸如此類的實時 CSS 修改減少了在將內容髮佈到網站之前對其進行準備的需要。 無需在 Photoshop 中將圓形蒙版應用於照片,Web 開發人員只需通過 CSS 應用相同的效果,而無需更改原始照片。
另一個優勢是,通過保持內容不變並且不依賴於網站的當前設計,可以促進未來的重新設計或改造。
8.夜間模式
問題:在不創建新樣式表的情況下實現夜間模式。
解決方案:使用 CSS 過濾器。
一些應用程序具有夜間模式,在這種模式下,界面會變暗,以便在弱光下更好地閱讀。 在較新的瀏覽器上,CSS 過濾器可以通過應用類似 Photoshop 的效果來創建相同的效果。
一個有用的 CSS 過濾器是invert
,它(毫不奇怪)反轉元素內所有內容的顏色。 這使得創建和應用一組新樣式變得不必要。
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Night Mode 1。
在黑色文本和白色背景上使用此過濾器可模擬夜間模式。 !important
確保這些新顏色覆蓋任何現有樣式。
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Night Mode 2。
不幸的是,圖像看起來很奇怪,因為它的顏色與其他所有顏色都相反。 好消息是可以同時應用多個過濾器。 添加hue-rotate過濾器將圖像和其他視覺內容恢復正常:
請參閱 CodePen 上 Rico Mossesgeld (@ricotheque) 的 Pen Night Mode 3。
為什麼這行得通? hue-rotate(180deg)
只會產生與invert(1)
相同的效果。 這是通過 JavaScript 驅動的按鈕切換時夜間模式 CSS 將如何工作的演示。
充分利用 CSS
除非瀏覽器或網站的構建方式在未來發生巨大變化,否則良好的 CSS 知識將仍然是 Web 開發領域的一項基本技能。
所有這些 CSS 技巧都有一個共同點:它們最大限度地利用 CSS 作為樣式語言,讓瀏覽器本身完成繁重的工作。 而且,如果做得好,這總是會產生更好的結果、更好的性能,從而帶來更好的用戶體驗。
如果您有任何有趣且有用的 CSS 技巧,請在下面的評論部分告訴我們。