变量计算组合
各种奇特的组合写法
条形加载条
笨写法
html
<div class="strip-loading">
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
</div>
<style lang="scss">
.strip-loading {
display: flex;
justify-content: center;
align-items: center;
width: 200px;
height: 100px;
p {
border-radius: 3px;
width: 6px;
height: 30px;
background-color: #f66;
animation: beat 1s ease-in-out infinite;
& + p {
margin-left: 5px;
}
&:nth-child(2) {
animation-delay: 200ms;
}
&:nth-child(3) {
animation-delay: 400ms;
}
&:nth-child(4) {
animation-delay: 600ms;
}
&:nth-child(5) {
animation-delay: 800ms;
}
&:nth-child(6) {
animation-delay: 1s;
}
}
}
@keyframes beat {
0%,
100% {
transform: scaleY(1);
}
50% {
transform: scaleY(0.5);
}
}
</style>变量写法
html
<div class="heart-loading">
<ul style="--line-count: 9;">
<li class="line-1" style="--line-index: 1;"></li>
<li class="line-2" style="--line-index: 2;"></li>
<li class="line-3" style="--line-index: 3;"></li>
<li class="line-4" style="--line-index: 4;"></li>
<li class="line-5" style="--line-index: 5;"></li>
<li class="line-6" style="--line-index: 6;"></li>
<li class="line-7" style="--line-index: 7;"></li>
<li class="line-8" style="--line-index: 8;"></li>
<li class="line-9" style="--line-index: 9;"></li>
</ul>
</div>
<style lang="scss">
.heart-loading {
display: flex;
justify-content: center;
align-items: center;
width: 200px;
height: 100px;
ul {
display: flex;
justify-content: space-between;
width: 150px;
height: 10px;
list-style: none;
padding: 0;
margin: 0;
}
li {
--angle: calc(var(--line-index) / var(--line-count) * 0.5turn);
--time: calc((var(--line-index) - 1) * 40ms);
border-radius: 5px;
width: 10px;
height: 10px;
background-color: #3c9;
filter: hue-rotate(var(--angle));
animation-duration: 1s;
animation-delay: var(--time);
animation-iteration-count: infinite;
&.line-1,
&.line-9 {
animation-name: beat-1;
}
&.line-2,
&.line-8 {
animation-name: beat-2;
}
&.line-3,
&.line-7 {
animation-name: beat-3;
}
&.line-4,
&.line-6 {
animation-name: beat-4;
}
&.line-5 {
animation-name: beat-5;
}
}
}
@keyframes beat-1 {
0%,
10%,
90%,
100% {
height: 10px;
}
45%,
55% {
height: 30px;
transform: translate3d(0, -15px, 0);
}
}
@keyframes beat-2 {
0%,
10%,
90%,
100% {
height: 10px;
}
45%,
55% {
height: 60px;
transform: translate3d(0, -30px, 0);
}
}
@keyframes beat-3 {
0%,
10%,
90%,
100% {
height: 10px;
}
45%,
55% {
height: 80px;
transform: translate3d(0, -40px, 0);
}
}
@keyframes beat-4 {
0%,
10%,
90%,
100% {
height: 10px;
}
45%,
55% {
height: 90px;
transform: translate3d(0, -30px, 0);
}
}
@keyframes beat-5 {
0%,
10%,
90%,
100% {
height: 10px;
}
45%,
55% {
height: 90px;
transform: translate3d(0, -20px, 0);
}
}
</style>鼠标放置变色
Details
html
<template>
<div
class="track-btn"
@mousemove="change"
:style="{ '--x': x, '--y': y }"
>
<span>妙用CSS变量,让你的CSS变得更心动</span>
</div>
</template>
<script>
export default {
name: 'ChangeColor',
data() {
return {
x: '0px',
y: '0px'
};
},
methods: {
change(e) {
this.x = `${e.offsetX}px`;
this.y = `${e.offsetY}px`;
}
}
};
</script>
<style lang="scss" scoped>
.track-btn {
overflow: hidden;
position: relative;
border-radius: 25px;
width: 400px;
height: 50px;
background-color: #66f;
cursor: pointer;
line-height: 50px;
text-align: center;
font-weight: bold;
font-size: 18px;
color: #fff;
span {
position: relative;
pointer-events: none; // 不加会卡顿
}
&::before {
--size: 0;
position: absolute;
left: var(--x);
top: var(--y);
width: var(--size);
height: var(--size);
background-image: radial-gradient(
circle closest-side,
#09f,
transparent
);
content: '';
transform: translate3d(-50%, -50%, 0);
transition: width 200ms ease, height 200ms ease;
}
&:hover::before {
--size: 400px;
}
}
</style>妙用CSS变量,让你的CSS变得更心动
悬浮视差按钮
Details
vue
<template>
<div
class="bruce flex-ct-x"
data-title="悬浮视差按钮"
:style="{
'--rx': rx,
'--ry': ry,
'--tx': tx,
'--ty': ty,
'--tz': tz
}"
@mousemove="mousemove"
@mouseup="mouseup"
@mousedown="mousedown"
@mouseleave="mouseleave"
>
<a
class="parallax-btn"
data-name="妙用CSS变量,让你的CSS变得更心动"
></a>
</div>
</template>
<script>
export default {
name: 'ParallaxBtn',
data() {
return {
rx: '0deg',
ry: '0deg',
tx: '0',
ty: '0',
tz: '0px'
};
},
methods: {
mousemove(e) {
const btn = document.getElementsByClassName('parallax-btn')[0];
const btnRect = btn.getBoundingClientRect();
const dx = e.offsetX - btnRect.width / 2;
const dy = e.offsetY - btnRect.height / 2;
this.rx = `${dy / -1}deg`;
this.ry = `${dx / 10}deg`;
},
mouseup(e) {
this.tz = '-12px';
},
mousedown(e) {
this.tz = '-25px';
},
mouseleave(e) {
this.rx = `0`;
this.ry = `0`;
this.ty = `0`;
}
}
};
</script>
<style lang="scss" scoped>
.bruce {
transform: perspective(800px);
transform-style: preserve-3d;
}
.parallax-btn {
position: relative;
width: 400px;
height: 50px;
cursor: pointer;
user-select: none;
line-height: 50px;
text-align: center;
font-size: 18px;
color: #fff;
&::before {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
border-radius: 4px;
background: linear-gradient(135deg, #6e8efb, #a777e3);
box-shadow: 0 2px 5px rgba(#000, 0.2);
content: '';
will-change: transform;
transform: translateY(var(--ty, 0)) rotateX(var(--rx, 0)) rotateY(
var(--ry, 0)
) translateZ(var(--tz, -12px));
transition: box-shadow 500ms ease, transform 200ms ease;
}
&::after {
display: inline-block;
position: relative;
font-weight: bold;
content: attr(data-name);
will-change: transform;
transform: translateY(var(--ty, 0)) rotateX(var(--rx, 0)) rotateY(var(--ry, 0));
transition: transform 200ms ease;
}
&:hover::before {
box-shadow: 0 5px 15px rgba(#000, 0.3);
}
}
</style>心型按钮
Details
vue
<template>
<div class="bruce flex-ct-x" data-title="点赞按钮">
<button class="like-btn">
<div class="like-wrapper">
<div class="like-ripple"></div>
<svg class="like-heart" width="24" height="24" viewBox="0 0 24 24">
<path
d="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z"
></path>
</svg>
<div class="like-particle" style="--line-count: 6">
<div class="like-particle-item" style="--line-index: 1"></div>
<div class="like-particle-item" style="--line-index: 2"></div>
<div class="like-particle-item" style="--line-index: 3"></div>
<div class="like-particle-item" style="--line-index: 4"></div>
<div class="like-particle-item" style="--line-index: 5"></div>
<div class="like-particle-item" style="--line-index: 6"></div>
</div>
</div>
</button>
</div>
</template>
<script>
export default {
name: 'LikeBtn'
};
</script>
<style lang="scss" scoped>
$heart-color: #f66;
$easing: cubic-bezier(0.7, 0, 0.3, 1);
$duration: 500ms;
.like-btn {
position: relative;
z-index: 1;
border: none;
border-radius: 100%;
width: 1em;
height: 1em;
appearance: none;
background-color: #fff;
cursor: pointer;
font-size: 200px;
transition: all $duration $easing;
&::before {
position: absolute;
left: 0;
top: 0;
z-index: -1;
border-radius: inherit;
width: 100%;
height: 100%;
box-shadow: 0 0.3em 0.6em rgba(#000, 0.3);
content: '';
transition: inherit;
}
&::after {
position: absolute;
left: 0;
top: 0;
z-index: -1;
border-radius: inherit;
width: 100%;
height: 100%;
background-color: #fff;
content: '';
}
&:active {
&::before {
animation: depress-shadow $duration $easing both;
}
}
&:focus::after {
animation: depress $duration $easing both;
}
}
.like-wrapper {
display: grid;
justify-content: center;
align-items: center;
> * {
grid-area: 1/1;
margin: auto;
}
}
.like-ripple {
overflow: hidden;
position: relative;
border-radius: 100%;
width: 1em;
height: 1em;
&::before {
position: absolute;
left: 0;
top: 0;
border: 0.4em solid $heart-color;
border-radius: inherit;
width: 100%;
height: 100%;
content: '';
transform: scale(0);
}
.like-btn:focus & {
&::before {
animation: ripple-out $duration $easing;
}
}
}
.like-heart {
display: block;
width: 0.5em;
height: 0.5em;
transform-origin: center 80%;
path {
transition: all $duration $easing;
stroke: $heart-color;
stroke-width: 2;
fill: transparent;
.like-btn:focus & {
fill: $heart-color;
}
}
.like-btn:focus & {
animation: heart-bounce $duration $easing;
}
}
.like-particle {
position: relative;
width: 1px;
height: 1px;
}
.like-particle-item {
--angle: calc(var(--line-index) / var(--line-count) * 1turn);
$color-list: #f66 #66f #f90 #09f #9c3 #3c9;
position: absolute;
left: 0;
top: 0;
border-radius: 0.05em;
width: 0.1em;
height: 0.1em;
transform: translate(-50%, -50%) rotate(var(--angle)) translateY(0) scaleY(
0
);
transition: all $duration $easing;
@each $v in $color-list {
$index: index($color-list, $v);
&:nth-child(#{$index}) {
background-color: $v;
}
}
.like-btn:focus & {
animation: particle-out calc(#{$duration} * 1.2) $easing forwards;
}
}
.like-btn:focus {
cursor: normal;
pointer-events: none;
}
@keyframes depress {
0%,
100% {
transform: none;
}
50% {
transform: translateY(5%) scale(0.9);
}
}
@keyframes depress-shadow {
0%,
100% {
transform: none;
}
50% {
transform: scale(0.5);
}
}
@keyframes heart-bounce {
0%,
80%,
100% {
transform: scale(1);
}
40% {
transform: scale(0.7);
}
}
@keyframes particle-out {
50% {
height: 0.3em;
transform: translate(-50%, -50%) rotate(var(--angle)) translateY(0.8em)
scale(1);
}
60% {
height: 0.2em;
transform: translate(-50%, -50%) rotate(var(--angle)) translateY(0.8em)
scale(1);
}
100% {
transform: translate(-50%, -50%) rotate(var(--angle)) translateY(1em) scale(
0
);
}
}
@keyframes ripple-out {
from {
transform: scale(0);
}
to {
transform: scale(5);
}
}
</style>