從太陽的自然光到我們家中的人造光,離線世界中的光線無處不在。光線會影響我們的視覺能力,也可以用來創造美感。您可以使用 CSS 建立光效,從而提高網站的視覺吸引力。雖然網頁沒有光源,但我們可以利用 CSS 的一些屬性和元素來建立模仿光線的視覺效果。本文將向你展示用 CSS 建立光效的五種方法。
霓虹燈或熒光燈
在現實世界中,霓虹燈是通過電流穿過氣體而產生的。霓虹燈的亮度和色彩取決於氣體的種類。因此,霓虹燈常用於裝飾展示。
您可以使用 CSS 為陰影新增顏色,從而建立這種效果。您可以使用兩個屬性來建立陰影,即 box-shadow
和 text-shadow
。
box-shadow
屬性會在元素周圍新增陰影,而 text-shadow
則會在文字周圍新增陰影。
這是我們正在使用的 HTML:
<div> <h1>Neon/Glowing Light</h1> <h3>Colored shadows create glowing light</h3> </div>
下面介紹如何使用 box-shadow
建立霓虹燈效果:
.content { box-shadow: 0px 0px 10px 10px #00c2cb; }
下面是如何使用 text-shadow
進行相同操作:
.content h1 { text-shadow: 0px 0px 10px #00c2cb, 0px 0px 20px #fff; }
下面是一張截圖,顯示了它的外觀:
box-shadow
和 text-shadow
的樣式類似。不同的是,文字陰影沒有 spread
。
您可以新增多個陰影層並使用不同的顏色來建立這種效果。
下面是 CodePen 演示:
請注意,還有第三種為元素新增陰影的方法,那就是使用 CSS drop-shadow()
過濾器。該過濾器只適用於影象,非常適合為背景透明的影象新增陰影。
漫反射
漫反射是指光線從粗糙的表面反射出來,如水泥牆、地板、紙張和衣服。
為此,您將使用 :before
偽元素。您可以使用任何 HTML 元素,但在本例中我們將使用一些文字。
<div> <h1>Diffuse Reflection</h1> </div>
接下來,建立一個偽元素,其 background-color
和尺寸與文字相同:
.content h1 { position: relative; font-size: 3rem; font-weight: 600; color: #00c2cb; text-shadow: 0px 0px 10px #00c2cb, 0px 0px 20px #00c2cb; margin: 3px; } .content h1::before { content: ""; position: absolute; top: 80%; left: 0; height: 100%; width: 100%; background: #00c2cb; }
此時,你所擁有的只是一個普通的盒子。
為了讓它看起來像光的反射,我們需要更多的屬性,如 transform
, blur
, 和 opacity
。
.content h1::before { content: ""; position: absolute; top: 80%; left: 0; height: 100%; width: 100%; background: #00c2cb; transform: perspective(10px) rotateX(10deg) scale(1, 0.2); filter: blur(1em); opacity: 0.5; }
perspective()
函式是 Z 軸上的距離,可以產生深度的錯覺;它就像你的視點。 rotateX()
函式可以水平旋轉元素。最後,scale()
在 x 軸和 y 軸上縮放元素,使其看起來更大或更小。在本例中,我們將在 Y 軸上縮小元素。
下面是反射的截圖:
您還可以新增更多功能,如懸停效果。
這是您可以與之互動的 CodePen:
鏡子反射
如果沒有光線,你就無法看到鏡子中的自己。使用 CSS 建立鏡面反射有兩種方法:使用 box-reflect
屬性或偽元素。
box-reflect
屬性對瀏覽器的支援有限。它只能在 Chrome、Edge 和 Opera 上使用 -webkit-
字首。火狐瀏覽器不支援。
box-reflect: <position> <offset> <mask>;
在本例中,我們將使用一張圖片。
<div> <img src="1.jpg" alt="" /> </div>
然後,應用 box-reflect
屬性並指定反射的位置。
.content img { -webkit-box-reflect: below; }
下面是此時您將看到的截圖:
它是影象的複製品。然後,你可以在影象和倒影之間新增一個間隙。我們可以使用漸變透明的 linear-gradient
蒙版。
.content img { -webkit-box-reflect: below 5px linear-gradient(transparent 50%, #22232e20); }
下面是結果截圖。
下面是 CodePen 演示:
同樣,只有在支援 -webkit-
字首的瀏覽器上才能看到這種效果,即使在 CodePen 上檢視也是如此。
您還可以將此效果應用於文字。這就是使用相同程式碼所獲得的效果:
由於 box-reflect
反映的是 HTML 元素周圍的 “box”,因此影象和反射之間有很大的差距。
您可以調整偏移量來減小間隙。
-webkit-box-reflect: below -30px linear-gradient(transparent 20%, #22232e20);
接著是偽元素。使用該方法為文字新增倒影的一種方法是輸入偽元素的 content
屬性。
.content h1::before { content: "Mirror Reflection"; position: absolute; top: 60%; left: 0; height: 100%; width: 100%; transform: rotate(180deg) scaleX(-1); opacity: 0.1; filter: blur(2px); }
要新增淡出效果,可新增與 :before
元素大小相同的 :after
偽元素,併為其新增漸變 background
,從透明漸變為與父元素背景相同的顏色。
.content h1::after { content: ""; position: absolute; top: 60%; left: 0; height: 100%; width: 100%; background: linear-gradient(transparent, #22232e 80%); }
另外,在使用偽元素為文字新增反射時,也可以使用 data-text
HTML 屬性。
<div> <h1 data-text="Mirror Reflection">Mirror Reflection</h1> </div>
然後,您可以使用 CSS 進行樣式調整:
.content h1::before { content: attr(data-text); position: absolute; top: 60%; left: 0; height: 100%; width: 100%; transform: rotate(180deg) scaleX(-1); opacity: 0.2; }
這就是如何為文字新增映象效果。所有現代瀏覽器都支援偽元素。
下面是 CodePen 演示:
對於圖片,您需要使用 background-image
屬性,而不是圖片本身。
下面是 HTML:
<section id="main"> <div class="image"></div> </section>
然後,您可以在 div
中新增一個 background-image
,其類名為 image
。
.image { background-image: url(/1.jpg); background-size: cover; background-position: center; background-repeat: no-repeat; background-color: red; width: 350px; height: 200px; position: relative; }
然後,新增偽元素,它將具有與主元素相同的大部分屬性。transform
屬性將旋轉和反轉反射影象。
.image::before { content: ""; position: absolute; top: 102%; left: 0; width: 350px; height: 200px; background-color: red; background-image: url(/1.jpg); background-size: cover; background-position: center; background-repeat: no-repeat; transform: scaleY(-1); opacity: 0.2; }
最後,新增第二個偽元素,完成反射效果。
.image::after { content: ""; position: absolute; top: 102%; left: 0; width: 350px; height: 200px; background-image: linear-gradient(transparent, #22232e 50%); }
為了避免重複,可以簡化 CSS 程式碼。
.image { background: url(/1.jpg) center / cover no-repeat; width: 350px; height: 200px; position: relative; } .image::before, .image::after { content: ""; position: absolute; top: 102%; left: 0; width: 350px; height: 200px; } .image::before { transform: scaleY(-1); opacity: 0.2; background: url(/1.jpg) center / cover no-repeat; } .image::after { background-image: linear-gradient(transparent, #22232e 50%); }
下面的 CodePen 演示了這種效果:
水面倒影
您將按照與鏡面反射幾乎相同的步驟使用偽元素來獲得這種效果。不同之處在於新增了 feTurbulence
和 feDisplacementMap
這兩個 SVG 濾鏡基元來建立水波效果。
您將在 HTML 文件的 body
中新增 SVG。SVG 濾鏡與 HTML <filter>
元素配合使用,CSS filter
屬性將通過 id
引用該元素。
下面是一個 SVG 語法示例:
<svg> <filter id=""> <!--Add filter primitives--> </filter> </svg>
我們從 feTurbulence
過濾器原型開始。
<svg> <filter id="water"> <feTurbulence id="turbulence" type="turbulence" numOctaves="1" result="WAVES" ></feTurbulence> </filter> </svg>
當應用於影象時,會產生噪點效果。下面是它的截圖:
該基元包含兩個屬性: numOctaves
和 baseFrequency
,用於控制失真程度。
接下來,新增 feDisplacementMap
原始元素。這將把一個元素的紋理應用到另一個元素上。在本例中,它將把 feTurblance
建立的變形(以 result
或名稱 WAVES
表示)應用到 sourceGraphic
(即偽元素反射)上。
<svg> <filter id="wavy"> <feTurbulence id="turbulence" type="turbulence" numOctaves="1" result="NOISE" ></feTurbulence> <feDisplacementMap in="SourceGraphic" in2="NOISE" scale="50" ></feDisplacementMap> <animate xlink:href="#turbulence" attributeName="baseFrequency" dur="60s" keyTimes="0;0.5;1" values="0.01 0.02;0.1 0.2;0.01 0.02" repeatCount="indefinite" ></animate> </filter> </svg>
<animate>
元素定義了 SVG 動畫的行為。它包含一個連結,指向我們要應用動畫的基元的 id
。它還包含了我們要應用動畫的屬性名稱,即 baseFrequency
。接著,設定動畫的持續時間和 keyTimes
,其功能類似於 CSS 動畫中的 @keyframes
。然後,在每個停止點新增動畫屬性 values
和迭代。
下面的 CodePen 演示了這種效果:
聚光燈懸停效果
您需要使用 JavaScript onmousemove
事件監聽器來建立此效果。
我們將從 HTML 開始,HTML 將是一張帶有一些文字的簡單卡片。
<section> <div class="content" style="--light: #00c2cb;"> <h1>Spotlight Effect</h1> <h3>Hover on this card to see the magic</h3> </div> </section>
它包含一個 CSS 自定義屬性 --light
,即燈光的顏色。
接下來,使用 CSS 建立樣式。
section { display: flex; justify-content: center; align-items: center; gap: 50px; flex-wrap: wrap; } .content { position: relative; width: 600px; height: 400px; border-radius: 20px; background: rgba(31,32,39,1); overflow: hidden; display: flex; justify-content: center; align-items: center; flex-direction: column; z-index: 1; } .content h1{ font-size: 3rem; color: #00c2cb; z-index: 3; } .content h3{ font-size: 20px; color: #e0ffff; z-index: 3; }
現在在卡片上建立一個 :before
偽元素。
.content::before{ content: ''; position: absolute; background: radial-gradient(var(--light),transparent,transparent); width: 600px; height: 600px; }
background
將作為聚光燈,它是一個radial-gradient
,使用 HTML 中指定的自定義顏色。
下面是你應該得到的截圖:
let content = document.querySelectorAll('.content'); content.forEach(card => { card.onmousemove = function (e) { let x = e.pageX - card.offsetLeft; let y = e.pageY - card.offsetTop; card.style.setProperty('--x', x + 'px'); card.style.setProperty('--y', y + 'px'); }; });
onmousemove
事件監聽器會計算滑鼠指標相對於元素的 X 和 Y 座標,並將自定義屬性 --x
和 --y
設定為這些座標。
接下來,將此應用於 :before
偽元素。
.content::before{ content: ''; position: absolute; top: var(--y); left: var(--x); transform: translate(-50%,-50%); background: radial-gradient(var(--light),transparent,transparent); width: 600px; height: 600px; opacity: 0; transition: 0.5s, top 0s, left 0s; } .content:hover::before{ opacity: 1; }
我們還將不透明度設定為 0
,使聚光燈在懸停在卡片上時可見。
此時,您可以決定新增 :after
偽元素。
.content::after{ content: ''; position: absolute; inset: 2px; border-radius: 18px; background-color: rgba(31,32,39,0.7); z-index: 2; }
與 :before
元素相比,該元素的背景略微透明,並且有一個 inset
,因此看起來就像卡片有邊框一樣。
下面是一個程式碼段,顯示了您可以與之互動的最終結果:
小結
你剛剛學會了用 CSS 建立光效的五種不同方法。首先,我們為兩個陰影屬性新增了顏色,以建立霓虹燈光。然後,我們使用 :before
和 :after
偽元素以及 box-reflect
CSS 屬性,介紹了幾種反射型別。最後,我們使用 onmousemove
JavaScript 事件監聽器建立了聚光燈效果。
燈光在離線環境下有很多用途,在線上環境下也可以增加網站的視覺吸引力。
評論留言