CSS3 流動邊框


CSS3 流動邊框(仿王者榮耀等待效果)的三種實現方式

原地址  https://www.jianshu.com/p/3c241aeae992
 

<!DOCTYPE html>

<html>

<head>

<meta charset="utf8">

<style>

:root {

--border-anim-size: 10em;

--border-anim-width: calc(var(--border-anim-size) / 20);

--border-anim-width-double: calc(var(--border-anim-width)*2);

--border-anim-duration: 5s;

--border-anim-border-color: gray;

--border-anim-hover-color: LightCoral;

}

body {

display: flex;

}

.border-anim {

width: var(--border-anim-size);

height: var(--border-anim-size);

position: relative;

border: 1px solid  var(--border-anim-border-color);

}

.border-anim::before, .border-anim::after {

content: '';

position: absolute;

border: var(--border-anim-width) solid var(--border-anim-border-color);

/* 讓邊框在內容區域內繪制 */

box-sizing: border-box;

transition: background-color 1s;

}

.border-anim::before {

animation: anim-border-run calc(var(--border-anim-duration) * 2) linear infinite;

}

.border-anim::after {

animation: anim-border-run calc(var(--border-anim-duration) * 2) calc(var(--border-anim-duration) / -1) linear infinite;

}

.border-anim:hover::before, .border-anim:hover::after {

 

}

.border-anim-content {

width: calc(100% - var(--border-anim-width-double));

height: calc(100% - var(--border-anim-width-double));

margin: var(--border-anim-width);

border: 1px solid var(--border-anim-border-color);

}

@keyframes anim-border-run {

/* 這里將動畫分成了4步;也可以改為2步,這時before和after用的就要是兩套keyframes了 */

from, to {

width: var(--border-anim-width-double);

height: 100%;

top: 0;

left: 0;

}

25% {

width: 100%;

height: var(--border-anim-width-double);

top: calc(100% - var(--border-anim-width-double));

left: 0;

}

50% {

width: var(--border-anim-width-double);

height: 100%;

top: 0;

left: calc(100% - var(--border-anim-width-double));

}

75% {

width: 100%;

height: var(--border-anim-width-double);

top: 0%;

left: 0%;

}

/* 需要設置臨界效果,否則會漸變 */

from, to, 24.9% {

border-left-color: var(--border-anim-border-color);

border-top-color: transparent;

border-right-color: transparent;

border-bottom-color: var(--border-anim-border-color);

}

25%, 49.9% {

border-left-color: transparent;

border-top-color: transparent;

border-right-color: var(--border-anim-border-color);

border-bottom-color: var(--border-anim-border-color);

}

50%, 74.9% {

border-left-color: transparent;

border-top-color: var(--border-anim-border-color);

border-right-color: var(--border-anim-border-color);

border-bottom-color: transparent;

}

75%, 99.9% {

border-left-color: var(--border-anim-border-color);

border-top-color: var(--border-anim-border-color);

border-right-color: transparent;

border-bottom-color: transparent;

}

}

</style>

<style>

.border-anim2 {

width: var(--border-anim-size);

height: var(--border-anim-size);

position: relative;

border: 1px solid var(--border-anim-border-color);

}

.border-anim2-edge {

position: absolute;

/* 必須把其他邊框置0,否則有默認值存在 */

border: 0px solid var(--border-anim-border-color);

box-sizing: border-box;

}

/*

注意:CSS中不能前向選擇,而只能后向選擇!

因為如果CSS支持了父選擇器,那就必須要頁面所有子元素加載完畢才能渲染HTML文檔,

因為所謂“父選擇器”,就是后代元素影響祖先元素,如果后代元素還沒加載處理,如何影響祖先元素的樣式?

於是,網頁渲染呈現速度就會大大減慢,瀏覽器會出現長時間的白板。

*/

/* 波浪號和加號都是選擇其后的元素,區別是加號只取一個,波浪取所有

.border-anim-content:hover ~ .border-anim2-edge { */

.border-anim2:hover > .border-anim2-edge {

 

}

.border-anim2-left {

width: var(--border-anim-width-double);

height: 100%;

left: 0;

border-left-width: var(--border-anim-width);

animation: anim2-border-run-left var(--border-anim-duration) calc(var(--border-anim-duration) / -2) linear infinite;

}

.border-anim2-top {

height: var(--border-anim-width-double);

width: 100%;

top: 0;

border-top-width: var(--border-anim-width);

animation: anim2-border-run-top var(--border-anim-duration) linear infinite;

}

.border-anim2-right {

width: var(--border-anim-width-double);

height: 100%;

right: 0;

border-right-width: var(--border-anim-width);

animation: anim2-border-run-right var(--border-anim-duration) calc(var(--border-anim-duration) / -2) linear infinite;

}

.border-anim2-bottom {

height: var(--border-anim-width-double);

width: 100%;

bottom: 0;

border-bottom-width: var(--border-anim-width);

animation: anim2-border-run-bottom var(--border-anim-duration) linear infinite;

}

@keyframes anim2-border-run-left {

from, to {

height: 0;

}

50% {

height: 100%;

}

from, to, 49.9% {

top: 0;

bottom: auto;

}

50%, 99.9% {

top: auto;

bottom: 0;

}

}

@keyframes anim2-border-run-top {

from, to {

width: 0;

}

50% {

width: 100%;

}

from, to, 49.9% {

left: auto;

right: 0;

}

50%, 99.9% {

left: 0;

right: auto;

}

}

@keyframes anim2-border-run-right {

from, to {

height: 0;

}

50% {

height: 100%;

}

from, to, 49.9% {

top: auto;

bottom: 0;

}

50%, 99.9% {

top: 0;

bottom: auto;

}

}

@keyframes anim2-border-run-bottom {

from, to {

width: 0;

}

50% {

width: 100%;

}

from, to, 49.9% {

left: 0;

right: auto;

}

50%, 99.9% {

left: auto;

right: 0;

}

}

</style>

<style>

.border-anim3 {

width: var(--border-anim-size);

height: var(--border-anim-size);

position: relative;

border: 1px solid var(--border-anim-border-color);

box-sizing: border-box;

}

.border-anim3::before, .border-anim3::after {

content: '';

position: absolute;

width: 100%;

height: 100%;

top: 0;

left: 0;

}

.border-anim3::before {

box-shadow: 0 0 0 var(--border-anim-width) var(--border-anim-border-color) inset;

animation: anim3-border-run calc(var(--border-anim-duration) * 2) calc(var(--border-anim-duration) / -1) linear infinite;

}

.border-anim3::after {

box-shadow: 0 0 0 var(--border-anim-width) var(--border-anim-border-color) inset;

animation: anim3-border-run calc(var(--border-anim-duration) * 2) linear infinite;

}

.border-anim3:hover::before, .border-anim3:hover::after {

/* 如果只在hover的時候設置transition,那么進入有效,但是退出無效(即退出時不會有緩動) */

transition: background-color 1s;

 

}

@keyframes anim3-border-run {

/*

clip通過對元素進行剪切來控制元素的可顯示區域(clip的區域顯示,其他隱藏)

clip屬性只能在元素設置了“position:absolute”或者“position:fixed”屬性起作用

shape函數聲明:rect(top right bottom left)

rect()和<top>和<bottom>指定偏移量是從元素盒子頂部邊緣算起;<left>和<right>指定的偏移量是從元素盒子左邊邊緣算起(包括邊框)。

如果<right>和<bottom>設置為auto時,他們就相當於元素的寬度(這個寬度包括元素的border、padding和width),或者簡單的理解為100%

注意:1.值不能設置為百分比。 2.在動畫設置過程里不能使用auto,使用auto沒有動畫效果(因此建議使用SCSS或者LESS之類的預處理器)

*/

/*

clip動畫有3種方案,但是都有點小瑕疵(在線條粗的時候明顯,線條細的情況下完全看不出來)

(1)使用如下的1和9作為邊界,當拐彎的時候,尾部多余的邊界會跟着動

(2)將下面的1和9替換為0和10,當拐彎的時候,線條寬度會變為0

(3)在每個狀態后面一步立即重置它,但是會出現抖動

*/

from, to {

clip: rect(0, 1em, 10em, 0);

}

1% {

clip: rect(1em, 1em, 10em, 0);

}

25% {

clip: rect(9em, 10em, 10em, 0);

}

25.1% {

clip: rect(9em, 10em, 10em, 1em);

}

50% {

clip: rect(0, 10em, 10em, 9em);

}

50.1% {

clip: rect(0, 10em, 9em, 9em);

}

75% {

clip: rect(0, 10em, 1em, 0);

}

75.1% {

clip: rect(0, 9em, 1em, 0);

}

}

</style>

</head>

<body>

<section>

<h1>(1)通過兩矩形的移動來制作動畫</h1>

<div class="border-anim">

<div class="border-anim-content"></div>

</div>

</section>

<section>

<h1>(2)通過四個邊框的長度來控制動畫</h1>

<div class="border-anim2">

<div class="border-anim-content"></div>

<div class="border-anim2-edge border-anim2-left"></div>

<div class="border-anim2-edge border-anim2-top"></div>

<div class="border-anim2-edge border-anim2-right"></div>

<div class="border-anim2-edge border-anim2-bottom"></div>

</div>

</section>

<section>

<h1>(3)通過clip的裁剪來顯示動畫</h1>

<div class="border-anim3">

<div class="border-anim-content"></div>

</div>

<section>

</body>

</html>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM