HOW - CSS 常见效果实现

发布于:2024-06-18 ⋅ 阅读:(24) ⋅ 点赞:(0)

常见 CSS 效果实现总结。

渐隐渐显

<!DOCTYPE html>
<html>
<style>
  body {
    background-color: black;
    color: #fff;
  }

  .click_links {
    font-size: 44px;
    animation: a_link_enter 3s linear infinite;
  }

  @keyframes a_link_enter {
    0% {
      opacity: 0;
    }

    30% {
      opacity: 1;
    }

    70% {
      opacity: 1;
    }

    100% {
      opacity: 0;
    }
  }
</style>

<body>
  <span class="click_links">请点击进入</span>
</body>

</html>

曲线&抛物线

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <style>
    .outer-div {
      width: 100px;
      height: 100px;
      padding: 10px;
      background-color: #fff;
    }

    .inner-div {
      height: 100%;
      background-color: yellow;
    }

    .outer-div:hover {
      transform: translateX(100px);
      transition: transform 2s linear;
    }

    .outer-div:hover>.inner-div {
      transform: translateY(100px);
      transition: transform 2s cubic-bezier(.55, 0, .85, .36);
    }
  </style>
</head>

<body>
  <div class="outer-div">
    <div class="inner-div">Hello</div>
  </div>
</body>

</html>

更多关于抛物线的解释阅读 WHAT - CSS Animationtion 动画系列(二)

气泡框

<!DOCTYPE html>
<html>
<style>
  body {
    background-color: red;
  }

  .wrapper {
    width: 300px;
    height: 200px;
    margin-top: 100px;
    position: relative;
    border: 2px solid #cccccc;
    border-radius: 15px;
    background: rgba(0, 0, 0, 0.5);
  }

  .wrapper:before {
    content: '';
    width: 0;
    height: 0;
    border: 20px solid transparent;
    border-bottom-color: #cccccc;
    position: absolute;
    top: 0;
    right: 20%;
    margin-top: -40px;
  }

  .wrapper:after {
    content: "";
    width: 0;
    height: 0;
    border: 18px solid transparent;
    border-bottom-color: #FFFFFF;
    position: absolute;
    top: 0;
    right: 21%;
    margin-top: -36px;
  }
</style>

<body>
  <!-- 方案一 -->
  <!-- https://blog.csdn.net/LLL_liuhui/article/details/80916265 -->
  <!-- 有边框的三角形、空心三角形(叠加两层div 外层作为边框) -->

  <!-- div border方案 -->
  <div class="wrapper"></div>

  <!-- svg方案 -->
  <div>
    <svg xmlns="http://www.w3.org/2000/svg" width="181" height="69" viewBox="0 0 181 69" fill="none">
      <path
        d="M37.4416 41.7506L23.125 66.6287V42V41.5H22.625H7C3.41015 41.5 0.5 38.5899 0.5 35V7C0.5 3.41015 3.41015 0.5 7 0.5H174C177.59 0.5 180.5 3.41015 180.5 7V35C180.5 38.5899 177.59 41.5 174 41.5H90.5H37.875H37.5859L37.4416 41.7506Z"
        fill="black" fill-opacity="0.5" stroke="white" />
    </svg>

    <svg xmlns="http://www.w3.org/2000/svg" width="181" height="61" viewBox="0 0 181 61" fill="none">
      <g filter="url(#filter0_b_1345_620)">
        <path
          d="M0 7C0 3.13401 3.13401 0 7 0H174C177.866 0 181 3.13401 181 7V35C181 38.866 177.866 42 174 42H90.5H57.875L35.625 60.5L42.625 42H7C3.13401 42 0 38.866 0 35V7Z"
          fill="black" fill-opacity="0.2" />
        <path
          d="M57.875 41.5H57.6943L57.5553 41.6155L36.764 58.9027L43.0926 42.1769L43.3488 41.5H42.625H7C3.41015 41.5 0.5 38.5899 0.5 35V7C0.5 3.41015 3.41015 0.5 7 0.5H174C177.59 0.5 180.5 3.41015 180.5 7V35C180.5 38.5899 177.59 41.5 174 41.5H90.5H57.875Z"
          stroke="white" />
      </g>
      <defs>
        <filter id="filter0_b_1345_620" x="-10" y="-10" width="201" height="80.5" filterUnits="userSpaceOnUse"
          color-interpolation-filters="sRGB">
          <feFlood flood-opacity="0" result="BackgroundImageFix" />
          <feGaussianBlur in="BackgroundImage" stdDeviation="5" />
          <feComposite in2="SourceAlpha" operator="in" result="effect1_backgroundBlur_1345_620" />
          <feBlend mode="normal" in="SourceGraphic" in2="effect1_backgroundBlur_1345_620" result="shape" />
        </filter>
      </defs>
    </svg>
  </div>
</body>

</html>

水波纹

<!DOCTYPE html>
<html>
<style>
  body {
    background-color: red;
  }

  .wrapper {
    width: 300px;
    height: 200px;
    margin-top: 100px;
    position: relative;
    border: 2px solid #cccccc;
    border-radius: 15px;
    background: rgba(0, 0, 0, 0.5);
  }

  .wrapper:before {
    content: '';
    width: 0;
    height: 0;
    border: 20px solid transparent;
    border-bottom-color: #cccccc;
    position: absolute;
    top: 0;
    right: 20%;
    margin-top: -40px;
  }

  .wrapper:after {
    content: "";
    width: 0;
    height: 0;
    border: 18px solid transparent;
    border-bottom-color: #FFFFFF;
    position: absolute;
    top: 0;
    right: 21%;
    margin-top: -36px;
  }
</style>

<body>
  <!-- 方案一 -->
  <!-- https://blog.csdn.net/LLL_liuhui/article/details/80916265 -->
  <!-- 有边框的三角形、空心三角形(叠加两层div 外层作为边框) -->

  <!-- div border方案 -->
  <div class="wrapper"></div>

  <!-- svg方案 -->
  <div>
    <svg xmlns="http://www.w3.org/2000/svg" width="181" height="69" viewBox="0 0 181 69" fill="none">
      <path
        d="M37.4416 41.7506L23.125 66.6287V42V41.5H22.625H7C3.41015 41.5 0.5 38.5899 0.5 35V7C0.5 3.41015 3.41015 0.5 7 0.5H174C177.59 0.5 180.5 3.41015 180.5 7V35C180.5 38.5899 177.59 41.5 174 41.5H90.5H37.875H37.5859L37.4416 41.7506Z"
        fill="black" fill-opacity="0.5" stroke="white" />
    </svg>

    <svg xmlns="http://www.w3.org/2000/svg" width="181" height="61" viewBox="0 0 181 61" fill="none">
      <g filter="url(#filter0_b_1345_620)">
        <path
          d="M0 7C0 3.13401 3.13401 0 7 0H174C177.866 0 181 3.13401 181 7V35C181 38.866 177.866 42 174 42H90.5H57.875L35.625 60.5L42.625 42H7C3.13401 42 0 38.866 0 35V7Z"
          fill="black" fill-opacity="0.2" />
        <path
          d="M57.875 41.5H57.6943L57.5553 41.6155L36.764 58.9027L43.0926 42.1769L43.3488 41.5H42.625H7C3.41015 41.5 0.5 38.5899 0.5 35V7C0.5 3.41015 3.41015 0.5 7 0.5H174C177.59 0.5 180.5 3.41015 180.5 7V35C180.5 38.5899 177.59 41.5 174 41.5H90.5H57.875Z"
          stroke="white" />
      </g>
      <defs>
        <filter id="filter0_b_1345_620" x="-10" y="-10" width="201" height="80.5" filterUnits="userSpaceOnUse"
          color-interpolation-filters="sRGB">
          <feFlood flood-opacity="0" result="BackgroundImageFix" />
          <feGaussianBlur in="BackgroundImage" stdDeviation="5" />
          <feComposite in2="SourceAlpha" operator="in" result="effect1_backgroundBlur_1345_620" />
          <feBlend mode="normal" in="SourceGraphic" in2="effect1_backgroundBlur_1345_620" result="shape" />
        </filter>
      </defs>
    </svg>
  </div>
</body>

</html>

悬浮&漂浮

<!DOCTYPE html>
<html lang="en">
  <div class="itemActivity3Whale"></div>
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<style>
  .itemActivity3Whale {
    position: absolute;
    top: 120px;
    left: 14px;
    width: 56px;
    height: 72px;
    background-image: url("../../assets/images/footballTour/footballtour-activity3-whale.png");
    background-repeat: no-repeat;
    background-size: 100% 100%;
    animation: a_whale_suspended 3s linear both infinite;
  }

  @keyframes a_whale_suspended {
    0% {
      transform: scale(1, 1) translate(0, 0px);
    }

    20% {
      transform: scale(1.10, 0.94) translate(0, 0px);
    }

    40% {
      transform: scale(0.92, 1.08) translate(0, -10px);
    }

    60% {
      transform: scale(1.05, 0.98) translate(0, 0px);
    }

    80% {
      transform: scale(0.98, 1.02) translate(0, -6px);
    }

    100% {
      transform: scale(1, 1) translate(0, 0px);
    }
  }
</style>

<body>

</body>

</html>

长按控制进度条

<!DOCTYPE html>
<html>
<style>
  body {
    background-color: gray;
    margin: 0px;
  }

  #circle {
    transition: all .1s;
    stroke-dasharray: 314, 314;
    stroke-dashoffset: 314;
  }

  #triangle {
    transition: all .1s;
    position: absolute;
    top: 30px;
    left: 95px;
    transform-origin: 5px 70px;
  }

  .triangleAni {
    animation: a_whale_suspended 2s linear both infinite;
  }

  @keyframes a_whale_suspended {
    0% {
      transform: scale(1, 1) translate(0, 0px);
    }


    50% {
      transform: scale(1, 1) translate(0, -2px);
    }


    100% {
      transform: scale(1, 1) translate(0, 0px);
    }
  }
</style>

<body>
  <!-- <div id="circleButton">
    <svg width="200" height="200" viewBox="0 0 200 200">
      <circle id="circleBg" transform="rotate(-90 100 100)" cx="100" cy="100" r="50" fill="none" stroke-width="10"
        stroke="gray" />
      <circle id="circle" stroke-linecap="round" transform="rotate(-90 100 100)" cx="100" cy="100" r="50" fill="none"
        stroke-width="10" stroke="green" />
      <circle cx="100" cy="100" r="45" fill="#040404" />
      <text x="100" y="100" fill="#6b778c" text-anchor="middle" dominant-baseline="central">
        <tspan id="percent">0</tspan>%
      </text>
    </svg>
  </div> -->

  <div id="circleButton">
    <svg width="200" height="200" viewBox="0 0 200 200">
      <circle id="circleBg" transform="rotate(-90 100 100)" cx="100" cy="100" r="50" fill="none" stroke-width="10"
        stroke="rgba(255, 255, 255, 0.4)" />
      <circle id="circle" transform="rotate(-90 100 100)" stroke-linecap="round" cx="100" cy="100" r="50" fill="none"
        stroke-width="10" stroke="#FFC700" />
      <circle cx="100" cy="100" r="45" fill="#FFF" />
    </svg>
    <svg id="triangle" class="triangleAni" width="10" height="10">
      <polygon id="triangleSelf" points="0 0, 10 0, 5 10, 0 0" fill="#FFC700" />
    </svg>
  </div>

</body>

<script>
  // 更推荐使用path绘制圆形
  // https://www.joubn.com/blog/js/2017-09-26-svg-path-arc

  let circle = document.getElementById('circle')
  // let percent = document.getElementById('percent')
  let triangle = document.getElementById('triangle')
  let triangleSelf = document.getElementById('triangleSelf')

  let init = 314
  let v = init

  let rotate = 360

  function getPercent(num) {
    // let percent = Math.round(((init - num) / init) * 100)
    let percent = (((init - num) / init)).toFixed(2)
    return percent
  }

  function getRotate(v) {
    let percent = getPercent(v)

    triangle.style.transform = `rotate(${rotate * percent}deg)`

    const percents = percent * 100
    if (percents > 70 && percents < 90) {
      circle.style.stroke = 'red'
      triangleSelf.style.fill = 'red'
    } else {
      circle.style.stroke = '#FFC700'
      triangleSelf.style.fill = '#FFC700'
    }
  }

  function add() {
    console.log('2222');
    v = v - 3
    if (v <= 0) {
      if (timer) {
        clearInterval(timer)
        timer = null
      }
      v = 0
    }
    getRotate(v)
    // percent.innerHTML = getPercent(v)
    circle.style['stroke-dashoffset'] = v
  }
  function minus(reset) {
    if (reset) {
      v = 314
    } else {
      v = v + 10
      if (v >= 314) {
        v = 314
      }
    }
    // percent.innerHTML = getPercent(v)
    console.log(v);
    circle.style['stroke-dashoffset'] = v
  }

  let progressBtn = document.getElementById('circleButton')
  let timer;
  // handle presses through the mouse cursor
  progressBtn.addEventListener('mousedown', toggleActive);
  progressBtn.addEventListener('mouseup', removeActive);

  function toggleActive() {
    if (timer) {
      return
    }
    console.log('1111');
    triangle.classList.remove('triangleAni')
    timer = setInterval(() => {
      add();
    }, 16);
  }
  function removeActive() {
    // console.log(minus);
    // if (timer) {
    //   clearInterval(timer)
    //   timer = null
    //   minus(true)
    // }

    if (timer) {
      clearInterval(timer)
      timer = null
    }
  }
</script>

</html>

圆弧&圆形进度条

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>HTML5中的SVG属性实现圆形进度条效果</title>
</head>

<body>

  <svg width="300" height="300" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <path id="ring" fill="none" stroke="#fd30ae" stroke-width="10px" />
  </svg>

  <script>
    var path = document.getElementById('ring');
    var r = 100;
    var progress = 0.5;
    //将path平移到我们需要的坐标位置
    ring.setAttribute('transform', 'translate(' + 150 + ',' + 150 + ')');

    // 计算当前的进度对应的角度值
    var degrees = progress * 360;

    // 计算当前角度对应的弧度值
    var rad = degrees * (Math.PI / 180);

    //极坐标转换成直角坐标
    var x = (Math.sin(rad) * r).toFixed(2);
    var y = -(Math.cos(rad) * r).toFixed(2);

    //大于180度时候画大角度弧,小于180度的画小角度弧,(deg > 180) ? 1 : 0
    var lenghty = window.Number(degrees > 180);

    //path 属性
    var descriptions = ['M', 0, -r, 'A', r, r, 0, lenghty, 1, x, y];

    // 给path 设置属性
    path.setAttribute('d', descriptions.join(' '));
  </script>
</body>

</html>

引导蒙层

<!DOCTYPE html>
<html>
<style>
  body {}

  /* z-index方案 */
  /* .mask {
    position: absolute;
    top: 0;
    width: 100%;
    height: 100vh;
    background-color: rgba(0, 0, 0, .2);
  }

  .click_links {
    width: 100px;
    height: 100px;
    background-color: antiquewhite;
    margin-bottom: 10px;
  }

  .show {
    position: relative;
    z-index: 100;
  } */

  /* 动态opacity方案 */
  /* .wrap {
    display: flex;
    flex-wrap: wrap;
    width: 150px;
  }

  .z {
    width: 50px;
    height: 50px;
    transition: all 1s;
  }

  .z1 {
    background: blue;
  }

  .z2 {
    background: black;
  }

  .z3 {
    background: yellow;
  }

  .z4 {
    background: red;
  }

  .z5 {
    background: green;
  }

  .z6 {
    background: orange;
  } */

  /* canvas xor方案 */
  .content {
    padding: 10px;
  }

  #mask {
    position: fixed;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    z-index: 900;
  }
</style>

<body>
  <!-- z-index方案 -->
  <!-- 该方案最简单 -->
  <!-- <div class="click_links">请点击进入</div>
  <div class="click_links">请点击进入</div>
  <div class="click_links">请点击进入</div>
  <div class="click_links">请点击进入</div>
  <div id="clickme" class="click_links show">请点击进入</div>
  <div class="click_links">请点击进入</div>
  <div class="click_links">请点击进入</div>
  <div class="click_links">请点击进入</div>
  <div id="maskdiv" class="mask"></div>
  <script>
    const div = document.getElementById('clickme');
    const mask = document.getElementById('maskdiv')
    div.addEventListener('click', () => {
      mask.className = ''
    })
  </script> -->

  <!-- 动态opacity方案 类似于骨架屏 -->
  <!-- <div class="wrap">
    <div class="z z1"></div>
    <div class="z z2"></div>
    <div class="z z3"></div>
    <div class="z z4"></div>
    <div id="z5div" class="z z5"></div>
    <div class="z z6"></div>
  </div>
  <script>
    let arry = Array.from(document.querySelectorAll(".z"));
    let index = -1;
    let direct = 1;
    arry.forEach((d, i) => {
      (i !== 4) && (d.style.opacity = 0.5)
    });
    const div = document.getElementById('z5div');
    div.addEventListener('click', () => {
      arry.forEach((d, i) => {
        (i !== 4) && (d.style.opacity = 1)
      });
    })
  </script> -->

  <!-- canvas xor方案 -->
  <!-- 该方案最为灵活 -->
  <!-- 思路
        1. 新增一个canvas,绘制两次图形
        2. 第一次绘制全屏半透明阴影
        3. 第二次使用 xor 绘制一个和需要高亮的元素位置和尺寸完全重合的区域。因为 xor 会透明,所以可以让下层元素完全显示出来
  -->
  <div class="content one">我是第一个div,我是第一个div</div>
  <div class="content two">我是第二个div,我是第二个div</div>
  <div class="content three">我是第三个div,我是第三个div</div>
  <div class="content four">我是第四个div,我是第四个div</div>
  <canvas id="mask"></canvas>
  <script>
    function mask(cls) {
      // 获取需要高亮的元素的位置和尺寸信息
      let targetNode = document.querySelector(`.${cls}`);
      let pos = targetNode.getBoundingClientRect();

      // 设置canvas尺寸
      let canvas = document.getElementById("mask");
      let width = window.innerWidth;
      let height = window.innerHeight;
      canvas.setAttribute("width", width);
      canvas.setAttribute("height", height);

      // 绘制canvas
      var ctx = canvas.getContext("2d");
      ctx.globalCompositeOperation = 'source-over';
      ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
      ctx.fillRect(0, 0, width, height);
      ctx.fill();

      ctx.fillStyle = 'white';
      ctx.globalCompositeOperation = "xor";
      ctx.fillRect(pos.left, pos.top, pos.width, pos.height);
      ctx.fill();
    }

    let array = ['one', 'two', 'three', 'four'];
    let i = 0;
    setInterval(() => {
      mask(array[i]);
      i++;
      if (i >= 4) i = 0;
    }, 1000)
  </script>

  <!-- border透明度方案 -->
  <!-- 一个div有四个边框,如果我们把边框都设置成半透明,然后中间的区域设置成全透明就可以实现区域引导蒙层了,然后再把边框设置成超过屏幕的大小,就是全景引导蒙层了 -->

  <!-- box-shadow 阴影的尺寸+透明度方案 -->
  <!-- 与上面一个方案类似 box-shadow: 10px 10px 5px 100px rgba(0,0,0,.5); -->
  <!-- box-shadow 的阴影距离切勿盲目设置过大,经过测试这个值如果过大,比如4000px,在部分手机上阴影无法显示出来。设置为2000px为佳。 -->

  <!-- 页面节点复制方案 -->
  <!-- 该方案类似于dialog,将要显示的内容放到dialog中,底层页面节点被蒙层挡住。只是在这里我们可以把需要高亮的元素复制到dialog内容里,并设置同等位置和尺寸 -->

</body>

</html>

随机物品掉落

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <style>
    .rain_area {
      width: 100px;
      height: 100px;
    }

    .drop {
      display: inline-block;
      width: 5px;
      height: 5px;
      border-radius: 50%;
      background-color: black;
    }

    .drop1 {
      animation: a_drop_1 1s 0.6s linear both infinite;
    }

    .drop2 {
      animation: a_drop_1 0.8s 0.9s linear both infinite;
    }

    .drop3 {
      animation: a_drop_1 1.1s 1s linear both infinite;
    }

    .drop4 {
      animation: a_drop_1 1.1s 0.9s linear both infinite;
    }

    @keyframes a_drop_1 {
      0% {
        opacity: 0;
        transform: translate(0, 0);
        scale: (1, 1);
      }

      20% {
        opacity: 1;
        transform: translate(0, 30px);
        scale: (1, 2);
      }

      45% {
        opacity: 1;
        transform: translate(0, 79px);
        scale: (1, 2);
      }

      50% {
        opacity: 1;
        transform: translate(0, 81px);
        scale: (1, 1);
      }

      75% {
        opacity: 0.6;
        transform: translate(0, 96px);
        scale: (1, 1);
      }

      100% {
        opacity: 0;
        transform: translate(0, 116px);
        scale: (1, 1);
      }
    }
  </style>
</head>

<body>
  <!-- 关键:除非时间是各个元素时间的最小公倍数,否则不会回归到初始状态,从而产生随即感 -->

  <div class="rain_area">
    <div class="drop drop1"></div>
    <div class="drop drop2"></div>
    <div class="drop drop3"></div>
    <div class="drop drop4"></div>
  </div>
</body>

</html>

渐变边框

<!DOCTYPE html>
<html>
<style>
  .border-box {
    border: 4px solid transparent;
    border-radius: 16px;
    position: relative;
    background-color: #222;
    background-clip: padding-box;
    /*important*/
  }

  .border-box::before {
    content: '';
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
    bottom: 0;
    z-index: -1;
    margin: -4px;
    border-radius: inherit;
    /*important*/
    background: linear-gradient(to right, #8F41E9, #578AEF);
  }
</style>

<body>
  <div class="border-box">
    <div class="content">
      Lorem ipsum dolor, sit amet consectetur adipisicing elit. Iste ratione necessitatibus numquam sunt nihil quos
      saepe sit facere. Alias accusamus voluptate accusantium facere fugiat animi temporibus adipisci! Corporis,
      accusamus tempora.
    </div>
  </div>
</body>

</html>

光晕

<!DOCTYPE html>
<html>
<style>
  body {
    background-color: black;
  }

  div {
    width: 407px;
    height: 407px;

    background: radial-gradient(50% 50% at 50% 50%, #2B50D7 0%, rgba(43, 80, 215, 0) 100%);
    filter: blur(40px);
  }
</style>

<body>
  <div></div>
</body>

</html>

按钮下压反馈

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .splash-section__button {
      display: flex;
      align-items: center;
      justify-content: center;
      height: 44px;
      border-radius: 30px;
      background-color: #3b8beb;
      color: #ffffff;
      font-weight: 600;
      font-size: 16px;
      width: 240px;

      border: none;
    }

    .splash-section__button:active {
      background-color: #1b6bcb;
      transform: translate(0, 2px);
    }
  </style>
</head>

<body>
  <button class="splash-section__button">
    Create a Free Profile
  </button>
  </div>
</body>

</html>

头像(圆形+半透明阴影)

<!DOCTYPE html>
<html>
<style>
  .outer {
    width: 100px;
    height: 100px;
    border-radius: 50%;
    background-color: rgb(156, 140, 140);

    position: relative;
    text-align: center;

    overflow: hidden;
  }

  .shadow {
    background: rgba(0, 0, 0, 0.73);
    position: absolute;
    width: 100px;
    height: 25px;
    bottom: 0;
    color: white;
  }
</style>

<body>
  <div class="outer">
    <div class="shadow">html test</div>
  </div>
</body>

</html>