1、交错动画
<div class="loading">
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
</div>
body {
display: flex;
height: 100vh;
justify-content: center;
align-items: center;
background: #222;
}
.loading {
$colors: #7ef9ff, #89cff0, #4682b4, #0f52ba, #000080;
display: flex;
animation-delay: 1s;
.dot {
position: relative;
width: 2em;
height: 2em;
margin: 0.8em;
border-radius: 50%;
&::before {
position: absolute;
content: "";
width: 100%;
height: 100%;
background: inherit;
border-radius: inherit;
animation: wave 2s ease-out infinite;
}
@for $i from 1 through 5 {
&:nth-child(#{$i}) {
background: nth($colors, $i);
&::before {
animation-delay: $i * 0.2s;
}
}
}
}
}
@keyframes wave {
50%,
75% {
transform: scale(2.5);
}
80%,
100% {
opacity: 0;
}
}
2、用JS分割文本
一般我们都是从第一个元素开始交错的。但如果要从中间元素开始交错的话,就要给当前元素的延时各加上一个值,这个值就是中间元素的下标到当前元素的下标的距离(也就是下标之差的绝对值)与步长的乘积,即:delay + Math.abs(i - middle) * step
,其中中间元素的下标middle = letters.filter(e => e !== "").length / 2
<p class="landIn">Ano hi watashitachi mada shiranai no Fushigi no monogatari desu.</p>
@import url("https://fonts.googleapis.com/css?family=Lora:400,400i,700");
body {
display: flex;
flex-direction: column;
height: 100vh;
justify-content: center;
align-items: center;
background-image: linear-gradient(rgba(16, 16, 16, 0.8),
rgba(16, 16, 16, 0.8)),
url(https://i.loli.net/2019/10/18/buDT4YS6zUMfHst.jpg);
background-size: cover;
}
p {
margin: 0 9em;
font-size: 2em;
font-weight: 600;
}
.landIn {
display: flex;
flex-wrap: wrap;
line-height: 1.8;
color: white;
font-family: Lora, serif;
white-space: pre;
span {
animation: landIn 0.8s ease-out both;
}
}
@keyframes landIn {
from {
opacity: 0;
transform: translateY(-20%);
}
to {
opacity: 1;
transform: translateY(0);
}
}
let landInTexts = document.querySelectorAll(".landIn");
landInTexts.forEach(landInText => {
let letters = landInText.textContent.split("");
landInText.textContent = "";
letters.forEach((letter, i) => {
let span = document.createElement("span");
span.textContent = letter;
span.style.animationDelay = `${i * 0.05}s`;
landInText.append(span);
});
});
<div class="reveal">sword art online</div>
@import url("https://fonts.googleapis.com/css?family=Raleway:400,400i,700");
body {
display: flex;
height: 100vh;
justify-content: center;
align-items: center;
text-align: center;
background: #222;
}
.reveal {
position: relative;
display: flex;
color: #6ee1f5;
font-size: 2em;
font-family: Raleway, sans-serif;
letter-spacing: 3px;
text-transform: uppercase;
white-space: pre;
span {
opacity: 0;
transform: scale(0);
animation: fadeIn 2.4s forwards;
}
&::before,
&::after {
position: absolute;
content: "";
top: 0;
bottom: 0;
width: 2px;
height: 100%;
background: white;
opacity: 0;
transform: scale(0);
}
&::before {
left: 50%;
animation: slideLeft 1.5s cubic-bezier(0.7, -0.6, 0.3, 1.5) forwards;
}
&::after {
right: 50%;
animation: slideRight 1.5s cubic-bezier(0.7, -0.6, 0.3, 1.5) forwards;
}
}
@keyframes fadeIn {
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes slideLeft {
to {
left: -6%;
opacity: 1;
transform: scale(0.9);
}
}
@keyframes slideRight {
to {
right: -6%;
opacity: 1;
transform: scale(0.9);
}
}
let duration = 0.8;
let delay = 0.3;
let revealText = document.querySelector(".reveal");
let letters = revealText.textContent.split("");
revealText.textContent = "";
let middle = letters.filter(e => e !== " ").length / 2;
letters.forEach((letter, i) => {
let span = document.createElement("span");
span.textContent = letter;
span.style.animationDelay = `${delay + Math.abs(i - middle) * 0.1}s`;
revealText.append(span);
});
3、随机粒子动画
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
200 个 snow!!!
body {
height: 100vh;
background: radial-gradient(ellipse at bottom, #1b2735 0%, #090a0f 100%);
overflow: hidden;
filter: drop-shadow(0 0 10px white);
}
@function random_range($min, $max) {
$rand: random();
$random_range: $min + floor($rand * (($max - $min) + 1));
@return $random_range;
}
.snow {
$total: 200;
position: absolute;
width: 10px;
height: 10px;
background: white;
border-radius: 50%;
@for $i from 1 through $total {
$random-x: random(1000000) * 0.0001vw;
$random-offset: random_range(-100000, 100000) * 0.0001vw;
$random-x-end: $random-x + $random-offset;
$random-x-end-yoyo: $random-x + ($random-offset / 2);
$random-yoyo-time: random_range(30000, 80000) / 100000;
$random-yoyo-y: $random-yoyo-time * 100vh;
$random-scale: random(10000) * 0.0001;
$fall-duration: random_range(10, 30) * 1s;
$fall-delay: random(30) * -1s;
&:nth-child(#{$i}) {
opacity: random(10000) * 0.0001;
transform: translate($random-x, -10px) scale($random-scale);
animation: fall-#{$i} $fall-duration $fall-delay linear infinite;
}
@keyframes fall-#{$i} {
#{percentage($random-yoyo-time)} {
transform: translate($random-x-end, $random-yoyo-y) scale($random-scale);
}
to {
transform: translate($random-x-end-yoyo, 100vh) scale($random-scale);
}
}
}
}
4、伪类
<button
data-text="Start"
class="btn btn-primary btn-ghost btn-border-stroke btn-text-float-up"
>
<div class="btn-borders">
<div class="border-top"></div>
<div class="border-right"></div>
<div class="border-bottom"></div>
<div class="border-left"></div>
</div>
<span class="btn-text">Start</span>
</button>
@import url(https://fonts.googleapis.com/css?family=Lato);
body {
display: flex;
height: 100vh;
justify-content: center;
align-items: center;
text-align: center;
background: #1A1E23;
}
.btn {
--hue: 190;
--ease-in-duration: 0.25s;
--ease-in-exponential: cubic-bezier(0.95, 0.05, 0.795, 0.035);
--ease-out-duration: 0.65s;
--ease-out-delay: var(--ease-in-duration);
--ease-out-exponential: cubic-bezier(0.19, 1, 0.22, 1);
position: relative;
padding: 1rem 3rem;
font-size: 1rem;
line-height: 1.5;
color: white;
text-decoration: none;
background-color: hsl(var(--hue), 100%, 41%);
border: 1px solid hsl(var(--hue), 100%, 41%);
outline: transparent;
overflow: hidden;
cursor: pointer;
user-select: none;
white-space: nowrap;
transition: 0.25s;
&:hover {
background: hsl(var(--hue), 100%, 31%);
}
&-primary {
--hue: 171;
}
&-ghost {
color: hsl(var(--hue), 100%, 41%);
background-color: transparent;
border-color: hsl(var(--hue), 100%, 41%);
&:hover {
color: white;
}
}
&-border-stroke {
border-color: hsla(var(--hue), 100%, 41%, 0.35);
.btn-borders {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
.border-top {
position: absolute;
top: 0;
width: 100%;
height: 1px;
background: hsl(var(--hue), 100%, 41%);
transform: scaleX(0);
transform-origin: left;
}
.border-right {
position: absolute;
right: 0;
width: 1px;
height: 100%;
background: hsl(var(--hue), 100%, 41%);
transform: scaleY(0);
transform-origin: bottom;
}
.border-bottom {
position: absolute;
bottom: 0;
width: 100%;
height: 1px;
background: hsl(var(--hue), 100%, 41%);
transform: scaleX(0);
transform-origin: left;
}
.border-left {
position: absolute;
left: 0;
width: 1px;
height: 100%;
background: hsl(var(--hue), 100%, 41%);
transform: scaleY(0);
transform-origin: bottom;
}
// when unhover, ease-out left, bottom; ease-in right, top
.border-left {
transition: var(--ease-out-duration) var(--ease-out-delay)
var(--ease-out-exponential);
}
.border-bottom {
transition: var(--ease-out-duration) var(--ease-out-delay)
var(--ease-out-exponential);
}
.border-right {
transition: var(--ease-in-duration) var(--ease-in-exponential);
}
.border-top {
transition: var(--ease-in-duration) var(--ease-in-exponential);
}
}
&:hover {
color: hsl(var(--hue), 100%, 41%);
background: transparent;
.border-top,
.border-bottom {
transform: scaleX(1);
}
.border-left,
.border-right {
transform: scaleY(1);
}
// when hover, ease-in left, bottom; ease-out right, top
.border-left {
transition: var(--ease-in-duration) var(--ease-in-exponential);
}
.border-bottom {
transition: var(--ease-in-duration) var(--ease-in-exponential);
}
.border-right {
transition: var(--ease-out-duration) var(--ease-out-delay)
var(--ease-out-exponential);
}
.border-top {
transition: var(--ease-out-duration) var(--ease-out-delay)
var(--ease-out-exponential);
}
}
}
&-text-float-up {
&::after {
position: absolute;
content: attr(data-text);
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
opacity: 0;
transform: translateY(35%);
transition: 0.25s ease-out;
}
// when hover, ease-in top-text; ease-out bottom-text
.btn-text {
display: block;
transition: 0.75s 0.1s var(--ease-out-exponential);
}
&:hover {
// when hover, ease-in bottom-text; ease-out top-text
.btn-text {
opacity: 0;
transform: translateY(-25%);
transition: 0.25s ease-out;
}
&::after {
opacity: 1;
transform: translateY(0);
transition: 0.75s 0.1s var(--ease-out-exponential);
}
}
}
}
7、attr()生成文本内容
<ul class="float-text-menu">
<li><a href="#" data-text="Home">Home</a></li>
<li><a href="#" data-text="Archives">Archives</a></li>
<li><a href="#" data-text="Tags">Tags</a></li>
<li><a href="#" data-text="Categories">Categories</a></li>
<li><a href="#" data-text