酷炫好玩的前端特效大集合-持续更新中

4,715 阅读19分钟

两个立体的纽扣按钮

源码
      <div class="container">
        <div class="toggle">
          <input type="radio" name="btn" checked>
          <span class="button"></span>
          <span class="label">+</span>
        </div>
        <div class="toggle">
          <input type="radio" name="btn">
          <span class="button"></span>
          <span class="label"></span>
        </div>
      </div>
:root {
	--toggleBgc: #ccd0d4;
}
body {
	background-color: #333;
	height: 100vh;
	display: flex;
	justify-content: center;
	align-items: center;
}
.container {
	width: 100%;
	// background-color: red;
	display: flex;
	justify-content: center;
	align-items: center;
}
/* 方框 */
.toggle {
	display: inline-block;
	margin: 34px;
	// background-color: blue;
	width: 140px;
	height: 140px;
	position: relative;
	background-color: var(--toggleBgc);
	border-radius: 8px;
	box-shadow : 
              /* 上下左右加内侧深色 */
              inset 0 0 35px 5px rgba(0, 0, 0, 0.3),
              /* 上左右加内侧浅色 */
				      inset 0 2px 1px 1px rgba(255, 255, 255, 0.9),
				      /*  下内侧加深色 */
              inset 0 -2px 1px 0px rgba(0, 0, 0, 0.3),
              /* 下外侧加深色 */
              0 2px 5px 5px rgba(0, 0, 0, 0.3);
}
/* 按钮背部光线 */
.toggle::before {
	content: '';
	position: absolute;
	width: 100px;
	height: 100px;
	border-radius: 50px;
	background-color: #fff;
	left: 50%;
	top: 50%;
	margin-left: -50px;
	margin-top: -50px;
	box-shadow: 0 0 36px 8px rgba(255, 255, 255, 0.6);
}
/* 圆形纽扣按钮 */
.toggle .button {
	display: block;
	width: 96px;
	height: 96px;
	background-color: #ccd0d4;
	// border: 1px solid blue;
	position: absolute;
	border-radius: 96px;
	margin-left: -48px;
	margin-top: -48px;
	left: 50%;
	top: 50%;
	/* 
		x向右正方向,y向下正方向,
		内外要分清,
		x坐标、y坐标、模糊半径blur-radius,扩展半径spread-radius,颜色color
		xybsc
	*/
	box-shadow: 
            /* 下外侧深色 */
        0 15px 25px -5px rgba(0, 0, 0, 0.5),
            /* 下内侧深色 */
				inset 0 -3px 5px -2px rgba(0, 0, 0, 0.2),
            /* 上内侧浅色 */
				inset 0 3px 5px 1px rgba(255, 255, 255, 0.7),
            /*  上下左右内侧浅色 */
				inset 0 0 5px 1px rgba(255, 255, 255, 0.8),
            /*  下内侧浅色 */
				inset 0 20px 30px 0 rgba(255, 255, 255, 0.2);
}
/* +和-符号 */
.toggle .label {
	display: block;
	position: absolute;
	// background-color: #eee;
	color: rgba(0, 0, 0, 0.3);
	width: 100%;
	height: 100%;
	font-size: 46px;
	text-align: center;
	line-height: 139px;
	font-weight: 700;
	top: 0;
	left: 0;
	opacity: 0.9;
	text-shadow:
              1px 1px 3px #ccd0d4,
              0px 0px 0px rgba(0, 0, 0, 0.8),
              2px 2px 4px rgba(0, 0, 0, 0.5);
}
/* 隐形覆盖的单选按钮 */
.toggle input {
  opacity: 0;
  // background-color: red;
  width: 100%;
  height: 100%;
  position: absolute;
  z-index: 1;
  left: 0;
  top: 0;
  margin: 0;
}
/* 单选按钮选中效果 */
.toggle input:checked ~ .button {
  box-shadow: 
              /* 下外侧深色 */
              0 15px 25px -4px rgba(0, 0, 0, 0.4),
              /* 下内侧浅色 */
              inset 0 -3px 6px 2px rgba(255, 255, 255, 0.9),
              /* 上下左右深色 */
              inset 0 8px 25px 0px rgba(0, 0, 0, 0.2);
}

嵌套旋转的两个齿轮

视频讲解教程

哔哩哔哩:嵌套旋转的两个齿轮

源码
<div class='container'>
  <div class='wheel'>
    <div class='gear'>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
    </div>
  </div>
  <div class='wheel'>
    <div class='gear'>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
      <div class='cube'>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
        <div class='side'></div>
      </div>
    </div>
  </div>
</div>
body {
  height: 100vh;
  perspective: 64em;
  background: radial-gradient(#00ffff, #00aaaa);
}
div, :before, :after {
  position: absolute;
  transform-style: preserve-3d;
}
.container {
  top: 50%;
  left: 50%;
  transform: rotateX(-15deg) rotateY(45deg);
}
.side {
  margin: -2.5em;
  width: 5em;
  height: 5em;
  box-shadow: 0 0 1px 1px #eeeeee;
  background-color: #800080;
}
/* 定位5个面*/
.side:nth-child(-n + 4) {
  background-color: #d23d57a0;
}
.side:nth-child(1) {
  transform: rotateY(0deg) translateZ(2.5em);
}
.side:nth-child(2) {
  transform: rotateY(90deg) translateZ(2.5em);
}
.side:nth-child(3) {
  transform: rotateY(180deg) translateZ(2.5em);
}
.side:nth-child(4) {
  transform: rotateY(270deg) translateZ(2.5em);
}
.side:nth-child(5) {
  transform: rotateX(90deg) translateZ(2.5em);
}

/* 将12个小方块环绕起来 */
.cube:nth-child(1) {
  transform: rotateY(0deg) translateZ(12.76314em);
}
.cube:nth-child(2) {
  transform: rotateY(30deg) translateZ(12.76314em);
}
.cube:nth-child(3) {
  transform: rotateY(60deg) translateZ(12.76314em);
}
.cube:nth-child(4) {
  transform: rotateY(90deg) translateZ(12.76314em);
}
.cube:nth-child(5) {
  transform: rotateY(120deg) translateZ(12.76314em);
}
.cube:nth-child(6) {
  transform: rotateY(150deg) translateZ(12.76314em);
}
.cube:nth-child(7) {
  transform: rotateY(180deg) translateZ(12.76314em);
}
.cube:nth-child(8) {
  transform: rotateY(210deg) translateZ(12.76314em);
}
.cube:nth-child(9) {
  transform: rotateY(240deg) translateZ(12.76314em);
}
.cube:nth-child(10) {
  transform: rotateY(270deg) translateZ(12.76314em);
}
.cube:nth-child(11) {
  transform: rotateY(300deg) translateZ(12.76314em);
}
.cube:nth-child(12) {
  transform: rotateY(330deg) translateZ(12.76314em);
}

/* 定位两个齿轮的位置 */
.wheel:nth-child(1) {
  transform: translate(6.38157em);
}
.wheel:nth-child(2) {
  transform: translate(-6.38157em) rotateX(-90deg);
}
.gear {
  animation: r 10s linear infinite;
}

@keyframes r {
  0% {
    transform: rotateY(1turn);
  }
}

动态的可爱天气预报图片

视频讲解教程

哔哩哔哩:动态的可爱天气预报图片

源码
  <div class="container">
      <div class="box sunShower">
          <div class="cloud"></div>
          <div class="sun">
              <div class="rays"></div>
          </div>
      </div>

      <div class="box sunny">
          <div class="sun">
              <div class="rays"></div>
          </div>
      </div>

      <div class="box cloudy">
          <div class="cloud"></div>
          <div class="cloud"></div>
      </div>


      <div class="box rainy">
          <div class="cloud"></div>
          <div class="rain"></div>
      </div>

      <div class="box thunderStorm">
          <div class="cloud"></div>
          <div class="lightning">
              <div class="bolt"></div>
              <div class="bolt"></div>
          </div>
      </div>

      <div class="box flurries">
          <div class="cloud"></div>
          <div class="snow">
              <div class="flake"></div>
              <div class="flake"></div>
          </div>
      </div>

  </div>
:root {
  --color: #B9DEFF;
  --sunColor: #FFCA22;
  --downColor: rgba(18, 117, 204, 1);
  --downColor2: rgba(18, 117, 204, 0.2);
  --start: #81C5F8;
  --end: #1181DF;
}
body {
  height: 100vh;
  background: radial-gradient(var(--start), var(--end));
  display: flex;
  justify-content: center;
  align-items: center;
}
.container {
  width: 600px;
  font-size: 0;
}
.box {
  display: inline-block;
  width: 200px;
  height: 200px;
  /* border: 1px solid red; */
  box-sizing: border-box;
  position: relative;
}
.cloud {
  width: 60px;
  height: 60px;
  background-color: var(--color);
  border-radius: 50%;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -30px;
  margin-left: -30px;
  color: var(--color);
  box-shadow: 0 0 0 6px,
    -35px 11px 0px -5px,
    33px 15px 0px -9px;
  z-index: 1;
}
.cloud::after {
  content: '';
  position: absolute;
  width: 110%;
  height: 6px;
  background: var(--color);
  bottom: -6px;
  left: -6px;
}
.sunShower .sun {
  margin: -32px 16px;
}
.sun {
  position: absolute;
  width: 40px;
  height: 40px;
  background-color: var(--sunColor);
  border-radius: 50%;
  top: 50%;
  left: 50%;
  margin-top: -20px;
  margin-left: -20px;
  color: var(--sunColor);
  box-shadow: 0 0 0 6px;
  animation: spin 12s infinite linear;
}
@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
.rays {
  position: absolute;
  width: 6px;
  height: 18px;
  background-color: var(--sunColor);
  top: -32px;
  left: 50%;
  margin-left: -3px;
  border-radius: 4px;
  box-shadow: 0px 86px;
}
.rays::before,
.rays::after {
  content: '';
  position: absolute;
  width: 6px;
  height: 18px;
  background-color: var(--sunColor);
  transform: rotate(60deg);
  transform-origin: 3px 52px;
  box-shadow: 0px 86px;
  border-radius: 4px;
}
.rays::after {
  transform: rotate(120deg);
}
.cloudy .cloud:nth-child(2) {
  transform: scale(0.5) translate(96px, -48px);
  opacity: 0.7;
  animation: cloud 5s infinite linear;
  animation-direction: alternate;
}
@keyframes cloud {
  0% {
    opacity: 0.5;
  }
  50% {
    opacity: 0.7;
  }
  100% {
    opacity: 0.5;
    transform: scale(0.5) translate(-96px, -48px);
  }
}
.rain,
.lightning,
.snow {
  width: 60px;
  height: 60px;
  position: absolute;
  /* border: 1px solid red; */
  top: 50%;
  left: 50%;
  margin-left: -30px;
  margin-top: 6px;
  z-index: 2;
}
.rain::after {
  content: '';
  position: absolute;
  width: 18px;
  height: 18px;
  background-color: var(--downColor);
  border-radius: 100% 0% 60% 50% / 60% 0% 100% 50%;
  color: var(--downColor);
  box-shadow: 10px 14px 0px -4px,
    -14px 18px 0 -2px,
    -22px -2px 0 -2px;
  left: 50%;
  top: 50%;
  margin-left: -9px;
  margin-top: -9px;
  transform: rotate(-28deg);
  opacity: 0.5;
  animation: rain 3s linear infinite;
}
@keyframes rain {
  0% {
    box-shadow: 10px 14px 0px -4px var(--downColor2),
      -14px 18px 0 -2px var(--downColor2),
      -22px -2px 0 -2px var(--downColor);
  }
  25% {
    box-shadow: 10px 14px 0px -4px var(--downColor2),
      -14px 18px 0 -2px var(--downColor),
      -22px -2px 0 -2px var(--downColor2);
  }
  50% {
    box-shadow: 10px 14px 0px -4px var(--downColor),
      -14px 18px 0 -2px var(--downColor2),
      -22px -2px 0 -2px var(--downColor2);
  }
  100% {
    box-shadow: 10px 14px 0px -4px var(--downColor2),
      -14px 18px 0 -2px var(--downColor2),
      -22px -2px 0 -2px var(--downColor);
  }
}
.bolt {
  position: absolute;
  color: var(--downColor);
  left: 6px;
  top: 6px;
  opacity: 0.5;
}
.bolt::before,
.bolt::after {
  position: absolute;
  content: '';
  border-top: 20px solid transparent;
  border-right: 12px solid;
  border-bottom: 12px solid;
  border-left: 8px solid transparent;
}
.bolt::after {
  border-top: 12px solid;
  border-right: 8px solid transparent;
  border-bottom: 20px solid transparent;
  border-left: 12px solid;
  left: 13px;
  top: 23px;
}
.bolt:nth-child(2) {
  transform: translate(19px, 36px) scale(0.5);
  opacity: 0.3;
  animation: lightning 2s linear infinite;
}
@keyframes lightning {
  45% {
    color: var(--downColor);
    opacity: 0.3;
  }
  50% {
    color: var(--downColor);
    opacity: 0.5;
  }
  55% {
    color: var(--downColor);
    opacity: 0.3;
  }
}
.flake::before,
.flake::after {
  content: '\2744';
  font-size: 16px;
  color: var(--downColor);
  opacity: 0.5;
  position: absolute;
}
.flake::before {
  left: 10px;
  top: 10px;
  animation: spin 10s linear infinite reverse;
}
.flake::after {
  left: 23px;
  top: 16px;
  animation: spin 16s linear infinite;
}
.flake:nth-child(2):before {
  left: 6px;
  top: 30px;
  animation: spin 10s linear infinite;
}
.flake:nth-child(2)::after {
  left: 26px;
  top: 36px;
  animation: spin 13s linear infinite reverse;
}

进度颜色可调节的玻璃拟态进度条

视频讲解教程

哔哩哔哩:进度颜色可调节的玻璃拟态进度条

源码
<div class="container">
    <article>
        <input type="radio" name='changeColor' id="red" checked>
        <input type="radio" name='changeColor' id="cyan">
        <input type="radio" name='changeColor' id="lime">
        <div class="chart">
            <div class="bar">
                <div class="side front">
                    <div class="skin"></div>
                </div>
                <div class="side back">
                    <div class="skin"></div>
                </div>
                <div class="side left">
                    <div class="skin"></div>
                </div>
                <div class="side right">
                    <div class="skin"></div>
                </div>
                <div class="side top">
                    <div class="skin"></div>
                </div>
                <div class="side bottom">
                    <div class="skin"></div>
                </div>
            </div>
        </div>
        <div class="labels">
            <label for="red">Red</label>
            <label for="cyan">Cyan</label>
            <label for="lime">Lime</label>
        </div>
    </article>

    <article>
        <input type="radio" name='changePos' id="pos0">
        <input type="radio" name='changePos' id="pos1" checked>
        <input type="radio" name='changePos' id="pos2">
        <input type="radio" name='changePos' id="pos3">
        <input type="radio" name='changePos' id="pos4">
        <div class="chart pos">
            <div class="bar purple bar30">
                <div class="side front">
                    <div class="skin"></div>
                </div>
                <div class="side back">
                    <div class="skin"></div>
                </div>
                <div class="side left">
                    <div class="skin"></div>
                </div>
                <div class="side right">
                    <div class="skin"></div>
                </div>
                <div class="side top">
                    <div class="skin"></div>
                </div>
                <div class="side bottom">
                    <div class="skin"></div>
                </div>
            </div>
        </div>
        <div class="labels">
            <label for="pos0">1/5</label>
            <label for="pos1">2/5</label>
            <label for="pos2">3/5</label>
            <label for="pos3">4/5</label>
            <label for="pos4">5/5</label>
        </div>
    </article>

    <article>
        <input type="radio" name="changeDynamic" id="dynamic1">
        <input type="radio" name="changeDynamic" id="dynamic2">
        <input type="radio" name="changeDynamic" id="dynamic3" checked>
        <input type="radio" name="changeDynamic" id="dynamic4">
        <input type="radio" name="changeDynamic" id="dynamic5">
        <div class="chart dynamic">
            <div class="bars">
                <div class="bar navy lightGraySide">
                    <div class="side front">
                        <div class="skin"></div>
                    </div>
                    <div class="side back">
                        <div class="skin"></div>
                    </div>
                    <div class="side left">
                        <div class="skin"></div>
                    </div>
                    <div class="side right">
                        <div class="skin"></div>
                    </div>
                    <div class="side top">
                        <div class="skin"></div>
                    </div>
                    <div class="side bottom">
                        <div class="skin"></div>
                    </div>
                </div>
                <div class="bar yellow lightGraySide">
                    <div class="side front">
                        <div class="skin"></div>
                    </div>
                    <div class="side back">
                        <div class="skin"></div>
                    </div>
                    <div class="side left">
                        <div class="skin"></div>
                    </div>
                    <div class="side right">
                        <div class="skin"></div>
                    </div>
                    <div class="side top">
                        <div class="skin"></div>
                    </div>
                    <div class="side bottom">
                        <div class="skin"></div>
                    </div>
                </div>
                <div class="bar red lightGraySide">
                    <div class="side front">
                        <div class="skin"></div>
                    </div>
                    <div class="side back">
                        <div class="skin"></div>
                    </div>
                    <div class="side left">
                        <div class="skin"></div>
                    </div>
                    <div class="side right">
                        <div class="skin"></div>
                    </div>
                    <div class="side top">
                        <div class="skin"></div>
                    </div>
                    <div class="side bottom">
                        <div class="skin"></div>
                    </div>
                </div>
            </div>
        </div>
        <div class="labels">
            <label for="dynamic1">D1</label>
            <label for="dynamic2">D2</label>
            <label for="dynamic3">D3</label>
            <label for="dynamic4">D4</label>
            <label for="dynamic5">D5</label>
        </div>
    </article>
</div>
:root {
  --bgc: #d0d0d0;
  --sideColor: #fefefe4d;
  --navy: #0a4069;
  --labelBorder: #fefefe99;
  --lime: #76c900;
  --red: #ec008c;
  --boxShadow: #333333;
  --cyan: #57caf4;
  --start: #80008080;
  --end: #ff80ff80;
  --yellow: #f1c40f;
  --lightGray: #91919133;
  --transitionDuration: 0.3s;
}
body {
  background-color: var(--bgc);
}
.container {
    height: 100vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}
article {
  width: 20em;
  margin-top: 3em;
  // background-color: wheat;
}
.chart {
  perspective: 1000px; /* 设置整个进度条的视角深度 */
  // border: 1px solid blue;
}
.chart .bar {
  transform: rotateX(-30deg) rotateY(0deg); /* 将进度条旋转一定角度,有助于看出立体效果 */
  transform-style: preserve-3d; /* 设置每个面保留3D变换效果 */
  height: 6em;
  // background-color: red;
  position: relative; /* 用来作为各个面的参考位置 */
}
.bar .side {
  height: 4em;
  width: 100%; /* 这里不能写固定值20em,会导致下面动态进度条的时候无法缩小 */
  background-color: var(--sideColor);
  position: absolute;

  // border: 1px solid red;
  /* 以下是设置字体上下左右居中,每个面先放入文字,立体效果做好后再删除这些文字 */
  text-align: center;
  line-height: 4em;
  color: maroon;
}
/* 以下是移动加旋转每个面到相应的位置 */
.bar .side.front {
  transform: translateZ(2em);
}
.bar .side.back {
  transform: translateZ(-2em);
  position: absolute;
}
.bar .side.left {
  /* 左右两个面的宽度要比别的面短 */
  width: 4em;
  transform: translateX(-2em) rotateY(-90deg);
}
.bar .side.right {
  width: 4em;
  transform: translateX(18em) rotateY(90deg);
}
.bar .side.top {
  transform: translateY(-2em) rotateX(90deg);
  position: absolute;
}
.bar .side.bottom {
  transform: translateY(2em) rotateX(-90deg);
  box-shadow: -1em -1em 3em var(--boxShadow);
}
.bar .side.top::after,
.bar .side.back::after {
  content: '';
  display: block;
  position: absolute;
  bottom: 0px;
  left: 0px;
  height: 0.01em;
  line-height: initial;
  width: 100%;
  box-shadow:  0em 0em 2em 0.2em var(--boxShadow);
}

.labels {
  // background-color: red;
  display: flex;
  justify-content: center;
}
.labels label {
  border: 1px solid var(--labelBorder);
  box-sizing: border-box;
  padding: 1em;
  margin: 0 0.2em;
  cursor: pointer;
  color: var(--navy);
  flex: 1;
  text-align: center;
}
.labels label:first-of-type {
  margin-left: 0;
  border-radius: 0.2em 0 0 0.2em;
}
.labels label:last-of-type {
  margin-right: 0;
  border-radius: 0 0.2em 0.2em 0;
}
input {
  display: none;
}
/* 设置各label选中样式 */
input[id='red']:checked ~ .labels label[for='red'],
input[id='cyan']:checked ~ .labels label[for='cyan'],
input[id='lime']:checked ~ .labels label[for='lime'],
input[id='pos0']:checked ~ .labels label[for='pos0'],
input[id='pos1']:checked ~ .labels label[for='pos1'],
input[id='pos2']:checked ~ .labels label[for='pos2'],
input[id='pos3']:checked ~ .labels label[for='pos3'],
input[id='pos4']:checked ~ .labels label[for='pos4'],
input[id='dynamic1']:checked ~ .labels label[for='dynamic1'],
input[id='dynamic2']:checked ~ .labels label[for='dynamic2'],
input[id='dynamic3']:checked ~ .labels label[for='dynamic3'],
input[id='dynamic4']:checked ~ .labels label[for='dynamic4'],
input[id='dynamic5']:checked ~ .labels label[for='dynamic5']
 {
  color: var(--lime);
  background-color: var(--navy);
}
/* 通过绝对定位给所有面加皮肤 */
.skin {
	position: absolute;
	top: 0;
	left: 0;
	height: 4em;
  width: 100%;
	// background-color: var(--skinColor);
	transition: all var(--transitionDuration) ease-in-out;
}
input ~ .chart .skin {
  opacity: 0.7;
}

input[id='red']:checked ~ .chart .skin {
  background-color: var(--red);
}
input[id='cyan']:checked ~ .chart .skin {
  background-color: var(--cyan);
}
input[id='lime']:checked ~ .chart .skin {
  background-color: var(--lime);
}


/* 分段进度条 */
.pos .skin {
  background: linear-gradient(to right, var(--start), var(--end));
}
.pos .left .skin,
.pos .right .skin {
  background: transparent;
}
input[id='pos0']:checked ~ .chart .skin {
	width: 20%;
}
input[id='pos1']:checked ~ .chart .skin {
	width: 40%;
}
input[id='pos2']:checked ~ .chart .skin {
	width: 60%;
}
input[id='pos3']:checked ~ .chart .skin {
	width: 80%;
}
input[id='pos4']:checked ~ .chart .skin {
	width: 100%;
}

/* 动态进度条 */
.dynamic .navy .skin {
  background-color: var(--navy);
}
.dynamic .yellow .skin {
  background-color: var(--yellow);
}
.dynamic .red .skin {
  background-color: var(--red);
}
.dynamic .left .skin,
.dynamic .right .skin {
  background: transparent;
}
.dynamic .bars .bar.lightGraySide .side {
  background-color: var(--lightGray); /* 这个颜色的透明度很大程度的影响了进度条的透明效果 */
}
.dynamic .bars .bar.lightGraySide .side.left,
.dynamic .bars .bar.lightGraySide .side.right {
  background-color: transparent; /* 左右两边的位置不会随着bar的缩小而改变位置,所以需要隐藏起来 */
  // width: 0;
}
.dynamic .bars {
  width: 100%;
  display: flex;
}
.dynamic .bars .bar {
  flex: 1; /* 设置这里之后bar会平分bars的宽度,side和skin都是百分之百,随着缩小 */
}
.dynamic .bars .bar:nth-child(2) {
  margin: 0 0.5em;
}

/* 设置各个按钮的选择效果 */
input[id='dynamic1']:checked ~ .chart.dynamic .bars .bar:nth-child(2) {
  flex-basis: 30%; /* 这个属性指的是平均之后此元素再多占据的空间的值 */
}

input[id='dynamic1']:checked ~ .chart.dynamic .bars .bar:nth-child(1) .skin {
  width: 30%;
}
input[id='dynamic1']:checked ~ .chart.dynamic .bars .bar:nth-child(2) .skin {
  width: 80%;
}
input[id='dynamic1']:checked ~ .chart.dynamic .bars .bar:nth-child(3) .skin {
  width: 60%;
}


input[id='dynamic2']:checked ~ .chart.dynamic .bars .bar:nth-child(3) {
  flex-basis: 30%;
}
input[id='dynamic2']:checked ~ .chart.dynamic .bars .bar:nth-child(1) .skin {
  width: 60%;
}
input[id='dynamic2']:checked ~ .chart.dynamic .bars .bar:nth-child(2) .skin {
  width: 50%;
}
input[id='dynamic2']:checked ~ .chart.dynamic .bars .bar:nth-child(3) .skin {
  width: 80%;
}


input[id='dynamic3']:checked ~ .chart.dynamic .bars .bar:nth-child(1) .skin {
  width: 70%;
}
input[id='dynamic3']:checked ~ .chart.dynamic .bars .bar:nth-child(2) .skin {
  width: 70%;
}
input[id='dynamic3']:checked ~ .chart.dynamic .bars .bar:nth-child(3) .skin {
  width: 70%;
}

input[id='dynamic4']:checked ~ .chart.dynamic .bars .bar:nth-child(3) {
  flex-basis: 30%;
}
input[id='dynamic4']:checked ~ .chart.dynamic .bars .bar:nth-child(1) .skin {
  width: 50%;
}
input[id='dynamic4']:checked ~ .chart.dynamic .bars .bar:nth-child(2) .skin {
  width: 50%;
}
input[id='dynamic4']:checked ~ .chart.dynamic .bars .bar:nth-child(3) .skin {
  width: 90%;
}

input[id='dynamic5']:checked ~ .chart.dynamic .bars .bar:nth-child(1) {
  flex-basis: 60%;
}
input[id='dynamic5']:checked ~ .chart.dynamic .bars .bar:nth-child(1) .skin {
  width: 60%;
}
input[id='dynamic5']:checked ~ .chart.dynamic .bars .bar:nth-child(2) .skin {
  width: 50%;
}
input[id='dynamic5']:checked ~ .chart.dynamic .bars .bar:nth-child(3) .skin {
  width: 30%;
}

五彩斑斓旋转的球形光影

源码

  <div class="ball">
    <div class="circle circle1">
      <div class="side front">
        <div class="inner"></div>
      </div>
      <div class="side back">
        <div class="inner"></div>
      </div>
      <div class="side left">
        <div class="inner"></div>
      </div>
      <div class="side right">
        <div class="inner"></div>
      </div>
      <div class="side top">
        <div class="inner"></div>
      </div>
      <div class="side bottom">
        <div class="inner"></div>
      </div>
    </div>
    <div class="circle circle2">
      <div class="side front">
        <div class="inner"></div>
      </div>
      <div class="side back">
        <div class="inner"></div>
      </div>
      <div class="side left">
        <div class="inner"></div>
      </div>
      <div class="side right">
        <div class="inner"></div>
      </div>
      <div class="side top">
        <div class="inner"></div>
      </div>
      <div class="side bottom">
        <div class="inner"></div>
      </div>
    </div>
    <div class="circle circle3">
      <div class="side front">
        <div class="inner"></div>
      </div>
      <div class="side back">
        <div class="inner"></div>
      </div>
      <div class="side left">
        <div class="inner"></div>
      </div>
      <div class="side right">
        <div class="inner"></div>
      </div>
      <div class="side top">
        <div class="inner"></div>
      </div>
      <div class="side bottom">
        <div class="inner"></div>
      </div>
    </div>
  </div>
body {
  margin: 0;
  padding: 0;
  min-height: 1vh;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #000;
  background-image: linear-gradient(to right, #ffffff06 50%, transparent 50%);
  background-size: 2em;
  .ball {
    width: 10em;
    height: 10em;
    @keyframes animation1 {
      100% {
        transform: rotateX(360deg) rotateY(720deg) rotateZ(360deg);
      }
    }
    animation: animation1 12s infinite linear;
    transform-style: preserve-3d;
    .circle {
      width: 10em;
      height: 10em;
      position: absolute;
      transform-style: preserve-3d;
      perspective: 400em;
      &2 {
        transform: rotateX(45deg) rotateY(45deg);
      }
      &3 {
        transform: rotateX(45deg) rotateZ(45deg);
      }
      .side {
        width: 100%;
        height: 100%;
        position: absolute;
        border-radius: 50%;
        box-sizing: border-box;
        border: 1px dotted #ffd50059;
        transform-style: preserve-3d;
        perspective: 400em;
        &::before,
        &::after {
          content: '';
          position: absolute;
          top: 0;
          left: 0;
          right: 0;
          bottom: 0;
          margin: auto;
          border: 1px solid;
          border-radius: inherit;
        }
        &::before {
          width: 2.5em;
          height: 2.5em;
          color: gold;
          box-shadow: inset 0 0 2em, 0 0 2em;
        }
        &::after {
          width: 1.5em;
          height: 1.5em;
          color: teal;
          box-shadow: inset 0 0 1em, 0 0 1em;
          transform: translateZ(-2em);
        }
        &.front {
          transform: translateZ(5em);
        }
        &.back {
          transform: translateZ(-5em) rotateY(180deg);
        }
        &.left {
          transform: translateX(-5em) rotateY(-90deg);
        }
        &.right {
          transform: translateX(5em) rotateY(90deg);
        }
        &.top {
          transform: translateY(-5em) rotateX(90deg);
        }
        &.bottom {
          transform: translateY(5em) rotateX(-90deg);
        }
        .inner {
          width: 50%;
          height: 50%;
          position: absolute;
          top: 0;
          left: 0;
          right: 0;
          bottom: 0;
          margin: auto;
          border-radius: inherit;
          color: orangered;
          box-shadow: inset 0 0 2em;
          transform: translateZ(2em);
          transform-style: preserve-3d;
          perspective: 400em;
          &::before,
          &::after{
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            margin: auto;
            border: 1px solid;
            border-radius: inherit;
            box-shadow: inset 0 0 2em, 0 0 2em;
          }
          &::before {
            width: 2.5em;
            height: 2.5em;
            color: crimson;
            transform: translateZ(2em);
          }
          &::after {
            width: 1.5em;
            height: 1.5em;
            color: purple;
            transform: translateZ(4em);
          }
        }
      }
    }
  }
}

玻璃瓶中掷骰子

视频讲解教程

哔哩哔哩:玻璃瓶中掷骰子

源码

  <div class="glass">
    <input type="checkbox" class="click">
    <div class="cube cube1">
      <div>
        <span class="circle circle1"></span>
      </div>
      <div>
        <span class="circle circle2"></span>
        <span class="circle circle2"></span>
      </div>
      <div>
        <span class="circle circle3"></span>
        <span class="circle circle3"></span>
        <span class="circle circle3"></span>
      </div>
      <div>
        <span class="circle circle4"></span>
        <span class="circle circle4"></span>
        <span class="circle circle4"></span>
        <span class="circle circle4"></span>
      </div>
      <div>
        <span class="circle circle5"></span>
        <span class="circle circle5"></span>
        <span class="circle circle5"></span>
        <span class="circle circle5"></span>
        <span class="circle circle5"></span>
      </div>
      <div>
        <span class="circle circle6"></span>
        <span class="circle circle6"></span>
        <span class="circle circle6"></span>
        <span class="circle circle6"></span>
        <span class="circle circle6"></span>
        <span class="circle circle6"></span>
      </div>
    </div>
    <div class="cube cube2">
      <div>
        <span class="circle circle1"></span>
      </div>
      <div>
        <span class="circle circle2"></span>
        <span class="circle circle2"></span>
      </div>
      <div>
        <span class="circle circle3"></span>
        <span class="circle circle3"></span>
        <span class="circle circle3"></span>
      </div>
      <div>
        <span class="circle circle4"></span>
        <span class="circle circle4"></span>
        <span class="circle circle4"></span>
        <span class="circle circle4"></span>
      </div>
      <div>
        <span class="circle circle5"></span>
        <span class="circle circle5"></span>
        <span class="circle circle5"></span>
        <span class="circle circle5"></span>
        <span class="circle circle5"></span>
      </div>
      <div>
        <span class="circle circle6"></span>
        <span class="circle circle6"></span>
        <span class="circle circle6"></span>
        <span class="circle circle6"></span>
        <span class="circle circle6"></span>
        <span class="circle circle6"></span>
      </div>
    </div>
    <div class="cube cube3">
      <div>
        <span class="circle circle1"></span>
      </div>
      <div>
        <span class="circle circle2"></span>
        <span class="circle circle2"></span>
      </div>
      <div>
        <span class="circle circle3"></span>
        <span class="circle circle3"></span>
        <span class="circle circle3"></span>
      </div>
      <div>
        <span class="circle circle4"></span>
        <span class="circle circle4"></span>
        <span class="circle circle4"></span>
        <span class="circle circle4"></span>
      </div>
      <div>
        <span class="circle circle5"></span>
        <span class="circle circle5"></span>
        <span class="circle circle5"></span>
        <span class="circle circle5"></span>
        <span class="circle circle5"></span>
      </div>
      <div>
        <span class="circle circle6"></span>
        <span class="circle circle6"></span>
        <span class="circle circle6"></span>
        <span class="circle circle6"></span>
        <span class="circle circle6"></span>
        <span class="circle circle6"></span>
      </div>
    </div>
  </div>
body {
  margin: 0;
  padding: 0;
  background-image: radial-gradient(#99baca 15%, #817474 100%);
  display: flex;
  justify-content: center;
  align-items: center;
  .glass {
    width: 280px;
    height: 320px;
    background-color: #ffffff26;
    border-radius: 140px/50px;
    box-shadow: 0px 5px 15px 0px #000;
    position: relative;
    &::before,
    &::after {
      content: '';
      position: absolute;
      width: 280px;
      height: 105px;
      box-sizing: border-box;
      border: 10px solid #ffffff26;
      border-radius: 140px/50px;
      box-shadow: 0 0 90px 90px #ffffff1f;
      background-color: #ffffff26;
      z-index: 2;
    }
    &::after {
      width: 270px;
      margin-left: 5px;
      /* 因为上面用到了绝对定位,所以这里就不能用marign: 0 auto了 */
      bottom: -10px;
    }
    .cube {
      position: absolute;
      width: 80px;
      height: 80px;
      left: 50%;
      top: 42%;
      transform-style: preserve-3d;
      z-index: 1;
      @mixin circle {
        .circle {
          border-radius: 50%;
          border: 3px solid rgba(255, 255, 255, 0.2);
          background-color: rgba(255, 255, 255, 0.2);
          box-shadow: 0 0 4% rgba(255, 255, 255, 0.2), inset 0 0 4% rgba(255, 255, 255, 0.2);
          position: absolute;
          box-sizing: border-box;
          width: 25px;
          height: 25px;
        }

        .circle1 {
          top: 50px;
          left: 50px;
          transform: translate(-15px, -15px);
        }

        .circle2:nth-child(1) {
          top: 15px;
          left: 15px;
        }
        .circle2:nth-child(2) {
          bottom: 15px;
          right: 15px;
        }

        .circle3:nth-child(1) {
          top: 10px;
          left: 10px;
        }
        .circle3:nth-child(2) {
          top: 0px;
          bottom: 0px;
          left: 0px;
          right: 0px;
          margin: auto;
        }
        .circle3:nth-child(3) {
          bottom: 10px;
          right: 10px;
        }

        .circle4:nth-child(1) {
          top: 15px;
          left: 15px;
        }
        .circle4:nth-child(2) {
          top: 15px;
          right: 15px;
        }
        .circle4:nth-child(3) {
          bottom: 15px;
          left: 15px;
        }
        .circle4:nth-child(4) {
          bottom: 15px;
          right: 15px;
        }

        .circle5:nth-child(1) {
          top: 15px;
          left: 15px;
        }
        .circle5:nth-child(2) {
          top: 15px;
          right: 15px;
        }
        .circle5:nth-child(3) {
          top: 50px;
          left: 50px;
          transform: translate(-15px, -15px);
        }
        .circle5:nth-child(4) {
          bottom: 15px;
          left: 15px;
        }
        .circle5:nth-child(5) {
          bottom: 15px;
          right: 15px;
        }

        .circle6:nth-child(1) {
          top: 5px;
          left: 15px;
        }
        .circle6:nth-child(2) {
          top: 5px;
          right: 15px;
        }
        .circle6:nth-child(3) {
          top: 50%;
          left: 15px;
          transform: translateY(-50%);
        }
        .circle6:nth-child(4) {
          top: 50%;
          right: 15px;
          transform: translateY(-50%);
        }
        .circle6:nth-child(5) {
          bottom: 5px;
          left: 15px;
        }
        .circle6:nth-child(6) {
          bottom: 5px;
          right: 15px;
        }
      }
      &.cube1 {
        transform: rotateX(24deg) rotateY(40deg) translate(-100%, -140%);
        transition: transform 0.5s ease 0s;
        @include circle();
      }
      &.cube2 {
        transform: rotateX(-30deg) rotateY(-27deg) translate(-196%, 34%);
        transition: transform 0.75s ease 0s;
        @include circle();
      }
      &.cube3 {
        transform: rotateX(148deg) rotateY(71deg) translate(10%, -100%);
        transition: transform 0.85s ease 0s;
        @include circle();
      }
      div {
        position: absolute;
        width: 100px;
        height: 100px;
        left: 50%;
        top: 50%;
        border-radius: 8px;
        background: radial-gradient(rgb(141 242 255), rgb(107 209 255));
        box-shadow: 0 0 4px rgba(255, 255, 255, 0.2), inset 0 0 4px rgba(255, 255, 255, 0.2);
        &:nth-child(1) {
          transform: translate3d(0, 0, 50px);
        }
        &:nth-child(2) {
          transform: rotateX(90deg) translate3d(0, 0, 50px);
        }
        &:nth-child(3) {
          transform: rotateX(180deg) translate3d(0, 0, 50px);
        }
        &:nth-child(4) {
          transform: rotateX(270deg) translate3d(0, 0, 50px);
        }
        &:nth-child(5) {
          transform: rotateY(90deg) translate3d(0, 0, 50px);
        }
        &:nth-child(6) {
          transform: rotateY(-90deg) translate3d(0, 0, 50px);
        }
      }
    }
  }

  .click {
    width: 100%;
    height: 320px;
    opacity: 0;
    position: absolute;
    z-index: 3;
    margin: 0;
    cursor: pointer;
    outline: none;
    & + .glass {
      animation: unshake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
      transform: translate3d(0, 0, 0);
    }
    &:checked + .glass {
      animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
      transform: translate3d(0, 0, 0);
      backface-visibility: hidden;
      .cube1 {
        transform: rotateX(-57deg) rotateY(-40deg) translate(-107%, -41%);
        transition: transform 0.5s ease 0s;
      }
      .cube2 {
        transform: rotateX(-130deg) rotateY(-57deg) translate(-283%, -346%);
        transition: transform 0.75s ease 0s;
      }
      .cube3 {
        transform: rotateX(-133deg) rotateY(71deg) translate(13%, -212%);
        transition: transform 0.85s ease 0s;
      }
    }
  }

  @keyframes shake {
    0% {
      transform: translate(1px, 1px) rotate(0deg);
    }
    10% {
      transform: translate(-1px, -2px) rotate(-1deg);
    }
    20% {
      transform: translate(-3px, 0px) rotate(1deg);
    }
    30% {
      transform: translate(3px, 2px) rotate(0deg);
    }
    40% {
      transform: translate(1px, -1px) rotate(1deg);
    }
    50% {
      transform: translate(-1px, 2px) rotate(-1deg);
    }
    60% {
      transform: translate(-3px, 1px) rotate(0deg);
    }
    70% {
      transform: translate(3px, 1px) rotate(-1deg);
    }
    80% {
      transform: translate(-1px, -1px) rotate(1deg);
    }
    90% {
      transform: translate(1px, 2px) rotate(0deg);
    }
    100% {
      transform: translate(1px, 1px) rotate(0deg);
    }
  }

  @keyframes unshake {
    0% {
      transform: translate(1px, 1px) rotate(0deg);
    }
    10% {
      transform: translate(-1px, -2px) rotate(-1deg);
    }
    20% {
      transform: translate(-3px, 0px) rotate(1deg);
    }
    30% {
      transform: translate(3px, 2px) rotate(0deg);
    }
    40% {
      transform: translate(1px, -1px) rotate(1deg);
    }
    50% {
      transform: translate(-1px, 2px) rotate(-1deg);
    }
    60% {
      transform: translate(-3px, 1px) rotate(0deg);
    }
    70% {
      transform: translate(3px, 1px) rotate(-1deg);
    }
    80% {
      transform: translate(-1px, -1px) rotate(1deg);
    }
    90% {
      transform: translate(1px, 2px) rotate(0deg);
    }
    100% {
      transform: translate(1px, 1px) rotate(0deg);
    }
  }
}

多层卡片

视频讲解教程

哔哩哔哩:多层卡片

源码

  <div class="levels">
    <div class="level one">
      <div class="title">One</div>
      <div class="content">One Content</div>
    </div>
    <div class="level two">
      <div class="title">Two</div>
      <div class="content">Two Content</div>
    </div>
    <div class="level three">
      <div class="title">Three</div>
      <div class="content">Three Content</div>
    </div>
    <div class="level four">
      <div class="title">Four</div>
      <div class="content">Four Content</div>
    </div>
  </div>
:root {
  --fontColor: #ffc0cb;
  --one1: #bd7be8;
  --one2: #8063e1;
  --two1: #7f94fc;
  --two2: #3f58e3;
  --three1: #21bbfe;
  --three2: #2c6fd1;
  --four1: #415197;
  --four2: #352f64;
  --levelShadow: #22325480;
}
.levels {
  position: absolute;
  top: 50%;
  left: 50%;
  margin-left: -140px;
  margin-top: -90px;
  transform-style: preserve-3d;
  user-select: none;
}
.levels .level {
  width: 280px;
  height: 140px;
  border-radius: 12px;
  color: var(--fontColor);
  cursor: pointer;
  transition: all 0.4s ease;
  transform: rotateX(45deg) rotateY(-15deg) rotate(45deg);
  opacity: 0.9;
  margin-top: -70px;
}
.levels .level.one {
  background: linear-gradient(135deg, var(--one1), var(--one2));
  box-shadow: 20px 20px 60px var(--levelShadow), 1px 1px 0px 1px var(--one2);
  z-index: 4;
}
.levels .level.two {
  background: linear-gradient(135deg, var(--two1), var(--two2));
  box-shadow: 20px 20px 60px var(--levelShadow), 1px 1px 0px 1px var(--two2);
  z-index: 3;
}
.levels .level.three {
  background-image: linear-gradient(135deg, var(--three1), var(--three2));
  box-shadow: 20px 20px 60px var(--levelShadow), 1px 1px 0px 1px var(--three2);
  z-index: 2;
}
.levels .level.four {
  background-image: linear-gradient(135deg, var(--four1), var(--four2));
  box-shadow: 20px 20px 60px var(--levelShadow), 1px 1px 0px 1px var(--four2);
  z-index: 1;
}
.levels .level .title {
  position: absolute;
  top: 28px;
  left: 15px;
  font-size: 26px;
  font-weight: bold;
}
.levels .level .content {
  position: absolute;
  font-weight: 700;
  bottom: 15px;
  left: 15px;
  font-size: 16px;
}
.levels .level:hover {
  transform: rotateX(30deg) rotateY(-15deg) rotate(30deg) translate(-25px, 50px);
  opacity: 0.6;
}
.levels .level:hover:after {
  transform: translateX(100%);
  transition: all 1.2s ease-in-out;
}
.levels .level::after {
  content: '';
  position: absolute;
  top: 0px;
  left: 0;
  width: 100%;
  height: 100%;
  transform: translateX(-100%);
  background: linear-gradient(60deg, rgba(255,255,255,0) 20%, rgba(255,255,255,0.1), rgba(255,255,255,0) 80%);
}

迷幻般的渐变投影

视频讲解教程

哔哩哔哩:迷幻般的渐变投影

源码

  <div class="shadow"></div>
    body
      margin 0
      padding 0
      background-color #000000
      .shadow
        position relative
        width 400px
        height 250px
        background linear-gradient(to top, #000, #262626)
        margin 200px auto;
        &::before
        &::after
            content ''
            position absolute
            top -2px
            left -2px
            width calc(100% + 4px)
            height calc(100% + 4px)
            background linear-gradient(45deg, #fb0094, #0000ff, #00ff00, #ffff00, #ff0000, #fb0094, #0000ff, #00ff00, #ffff00, #ff0000)
            background-size 400%
            z-index -1
            animation animate 20s linear infinite
            background-position 0% 0
            @keyframes animate
              0%
                background-position 0 0
              50%
                background-position 300% 0
              100%
                background-position 0 0
        &::after
          filter blur(20px)

波浪圆

视频讲解教程

哔哩哔哩:波浪圆

源码

  <div class="loader">
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
  </div>
@keyframes animate
  0%, 100%
    transform translateZ(-100px)
  50%
    transform translateZ(100px)
*
  margin 0
  padding 0
body
  background-color #9c27b0
  display flex
  justify-content center
  align-items center
  min-height 100vh
  .loader
    position relative
    width 300px
    height 300px
    transform-style preserve-3d
    perspective 500px
    perspective-origin: -10px 0px;
    transform rotateX(60deg) 
    span
      border: 5px solid #fff
      border-radius 50%
      box-shadow 0 5px 0 #ccc, inset 0 5px 0 #ccc
      position absolute
      animation animate 3s ease-in-out infinite
      for row in 1..15
        &:nth-child({row})
          top (row - 1) * 10px
          bottom (row - 1) * 10px
          right (row - 1) * 10px
          left (row - 1) * 10px
          animation-delay 1.5s - (row / 10)

旋转的3D白色纸张

视频讲解教程

哔哩哔哩:旋转的3D白色纸张

源码

  <div class="box">
    <div class="spans">
      <span class="span"></span>
      <span class="span"></span>
      <span class="span"></span>
      <span class="span"></span>
    </div>
  </div>
body
  margin 0
  padding 0
  background-color #607d8b
  .box
    width 200px
    height 300px
    // background-color #fff
    position absolute
    left calc(50% - 100px)
    top calc(50% - 100px)
    transform-style preserve-3d
    transform rotateY(-45deg)
    perspective 1000px
    perspective-origin 160% 50%
    &::before
      content ''
      position absolute
      background-color #000000
      width 100%
      height 50px
      left 0
      bottom -100px
      transform rotateX(90deg)
      filter blur(40px)
      opacity 0.5
      animation animate2 0.5s linear infinite
      @keyframes animate2
        0%
          transform translateZ(0px)
        100%
          transform translateZ(100px)
    .spans
      // background-color wheat
      height 100%
      transform-style preserve-3d
      animation animate 5s linear infinite
      @keyframes animate
        0%
          transform rotateX(0deg)
        100%
          transform rotateX(359deg)
      span
        // background-color red
        position absolute
        width 100%
        height 100%
        border-radius 20px
        background linear-gradient(#f1f1f1, #bbbbbb, #f1f1f1)
        for row in 1..4
          &:nth-child({row})
            transform rotateX((row - 2) * 45deg)

奔跑在高速公路上的白色线条

视频讲解教程

哔哩哔哩:奔跑在高速公路上的白色线条

源码

  <div class="line">
    <div class="shadow"></div>
  </div>
 body
  margin 0
  padding 0
  display flex
  justify-content center
  align-items center
  min-height: 100vh
  background radial-gradient(#9bdfff, #009be4)
  .line
    width 800px
    height 160px
    background #525252
    position relative
    transform perspective(500px) rotateX(30deg)
    transform-origin bottom
    transform-style preserve-3d
    &::before
      content ''
      position absolute
      width 100%
      height 10px
      background linear-gradient(to right, #fff 0%, #fff 70%, #525252 70%, #525252 100%)
      background-size 120px
      left 0
      top 50%
      transform translateY(-5px)
      animation animate 0.5s linear infinite
      @keyframes animate
        0%
          background-position 0px
        100%
          background-position -120px
    &::after
      content ''
      position absolute
      width 100%
      height 30px
      background-color #333333
      bottom -30px
      transform perspective(500px) rotateX(-25deg)
      transform-origin top
    .shadow
      position absolute
      width 95%
      height 60px
      background linear-gradient(#000, transparent)
      bottom -93px
      left 400px
      transform translateX(-50%)
      opacity 0.5

边框流动的幻影按钮

视频讲解教程

哔哩哔哩:边框流动的幻影按钮

源码

  <a href="">
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    按钮 Button
  </a>
  <a href="">
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    按钮 Button
  </a>
  <a href="">
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    按钮 Button
  </a>
*
  margin 0
  padding 0
  box-sizing: border-box
  background-color #050801
body
  display flex
  flex-direction column
  min-height: 100vh
  justify-content center
  align-items center
  a
    display inline-block
    padding 25px 30px
    // background-color red
    color #03e9f4
    text-decoration none
    letter-spacing: 4px
    text-transform uppercase
    position relative
    overflow hidden
    transition 0.5s
    margin 40px 0
    -webkit-box-reflect: below 1px linear-gradient(transparent, #0005)
    &:hover
      background-color #03e9f4
      color #050801
      box-shadow 0 0 5px #03e9f4, 0 0 25px #03e9f4, 0 0 50px #03e9f4, 0 0 200px #03e9f4
    &:nth-of-type(1)
      filter hue-rotate(290deg)
      /* 会影响包含块 */
    &:nth-of-type(3)
      filter hue-rotate(160deg)
    span
      position absolute
      &:nth-child(1)
        width 100%
        height 2px
        top 0
        left 0
        background linear-gradient(to right, transparent, #03e9f4)
        animation animate1 1s linear infinite
        animation-delay 0s
        @keyframes animate1
          0%
            left -100%
          50%, 100%
            left 100%
      &:nth-child(2)
        width 2px
        height 100%
        top -100%
        right 0
        background linear-gradient(to bottom, transparent, #03e9f4)
        animation animate2 1s linear infinite
        animation-delay 0.25s
        @keyframes animate2
          0%
            top -100%
          50%, 100%
            top 100%
      &:nth-child(3)
        width 100%
        height 2px
        bottom 0
        right -100%
        background linear-gradient(to left, transparent, #03e9f4)
        animation animate3 1s linear infinite
        animation-delay 0.5s
        @keyframes animate3
          0%
            right -100%
          50%, 100%
            right 100%
      &:nth-child(4)
        width 2px
        height 100%
        bottom -100%
        left 0
        background linear-gradient(to top, transparent, #03e9f4)
        animation animate4 1s linear infinite
        animation-delay 0.75s
        @keyframes animate4
          0%
            bottom -100%
          50%, 100%
            bottom 100%