david2tdw / blog

学习记录
1 stars 1 forks source link

[CSS] 纯CSS判断鼠标进入方向 #167

Open david2tdw opened 4 years ago

david2tdw commented 4 years ago

关键点: 利用了伪元素生成了 4 个三角形组成了一个正方形,通过 hover 哪个透明的三角形来判断用户的操作方位。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSS边界智能判断移动方向</title>
  <style>
    .box {
      margin: 5em auto;
      position:relative;
      width: 10em;
      height: 10em;
      line-height: 10em;
      overflow: hidden; /* 隐藏box外部的元素 */
    }

    .box-right, .box-left, .box-top, .box-bottom, .box-center {
      position: absolute;
      width: inherit;
      height: inherit;
      text-align: center;
      line-height: inherit;
      transition: transform 0.4s ease;  /* 设置transform属性的过渡效果 */
    }
    /* 给每个正方形添加一个菱形伪元素, 触发hover事件 */
    .box-right:before, .box-left:before, .box-top:before, .box-bottom:before, .box-center:before {
      content: '';
      position: absolute;
      width: 70.1%; /* width 和height是相对.box-right, .box-left, .box-top, .box-bottom, .box-center 的宽高比。 */
      height: 70.1%;
      transform: rotate(45deg);
    }
    /* hover时 将正方形恢复到center里面 */
    .box-right:hover, .box-left:hover, .box-top:hover, .box-bottom:hover, .box-center:hover {
      transform: translateX(0);
      z-index: 1; /* hover时覆盖在最上面,防止触发其他菱形元素的hover事件 */
    }

    .box-right:hover:before, .box-left:hover:before, .box-top:hover:before, .box-bottom:hover:before, .box-center:hover:before {
      width: 100%;
      height: 100%;
      transform: none; /* 设置hover时的before属性,hover时before不需要旋转 */
    }
    /* 将右边正方形移动到外面 */
    .box-right {
      background: blue;
      transform: translateX(100%); /* 向右移动.box元素的宽度 */
    }
    /* 调整右边菱形的位置 */
    /* transform-origin 设置旋转元素的基点位置, 该属性必须与 transform 属性一同使用 */
    .box-right:before {
      right: 100%;
      bottom: 0;
      transform-origin: 100% 100%; /* 调整旋转元素旋转后的位置 */
    }
    /* .box-right:hover的兄弟元素.box-center 设定向左移动100%(将center移动到外面) */
    .box-right:hover ~ .box-center {
      transform: translateX(-100%);
    }
    .box-left {
      background: green;
      transform: translateX(-100%);
    }
    .box-left:before {
      left: 100%;
      transform-origin: 0 0;
    }
    .box-left:hover ~ .box-center {
      transform: translateX(100%);
    }
    .box-top {
      background: red;
      transform: translateY(-100%); /* translateY 向上移动为负 */
    }
    .box-top:before {
      top: 100%;
      right: 0;
      transform-origin: 100% 0; /* top, right, tranform-origin 控制菱形的位置 */
    }
    /* 顶部元素hover的时候,将center向下移动100% */
    .box-top:hover ~ .box-center {
      transform: translateY(100%);
    }
    .box-bottom {
      background: yellow;
      transform: translateY(100%);
    }

    .box-bottom:before {
      bottom: 100%;
      left: 0;
      transform-origin: 0 100%;
    }
    .box-bottom:hover ~ .box-center {
      transform: translateY(-100%);
    }
    .box-center {
      background: orange;
      z-index: -1; /* 让中间区域在最下层,否则无法触发其他元素的hover事件 */
    }
  </style>
</head>
<body>
  <div class="box">
    <div class="box-right">Right → Left</div>
    <div class="box-left">Left → Right</div>
    <div class="box-top">Top → Bottom</div>
    <div class="box-bottom">Bottom → Top</div>
    <div class="box-center">Hover from any side</div>
  </div>
</body>
</html>

伪元素实现边界智能判断移动

david2tdw commented 4 years ago

简易版:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>判断鼠标进入方向简易版</title>
    <style>
      body {
        padding: 2em;
        text-align: center;
      }
      .block {
        position: relative;
        display: inline-block;
        overflow: hidden;
        width: 10em;
        height: 10em;
        vertical-align: middle;
        transform: translateZ(0);
      }
      .block_hoverer {
        position: absolute;
        z-index: 1;
        width: 100%;
        height: 100%;
        opacity: 0;
        transition: all 0.3s ease;
        transition-property: top, left;
        transform: rotate(45deg);
      }

      .block_hoverer:nth-child(1) {
        background: red;
        top: -70.7%;
      }

      .block_hoverer:nth-child(2) {
        background: lime;
        top: 70.7%;
      }

      .block_hoverer:nth-child(3) {
        background: orange;
        left: -70.7%;
      }

      .block_hoverer:nth-child(4) {
        background: blue;
        left: 70.7%;
      }
      .block_hoverer:hover {
        opacity: 1;
        top: 0;
        left: 0;
        cursor: pointer;
        transform: rotate(0);
        z-index: 10;
      }

      .block_content {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        text-align: center;
        line-height: 10em;
        background: #333;
        color: #fff;
      }
    </style>
  </head>
  <body>
    <p class="text">从不同方向使鼠标指针移过下面的内容</p>
    <p>↓</p>
    <span>→ </span>
    <div class="block">
      <div class="block_hoverer">上</div>
      <div class="block_hoverer">下</div>
      <div class="block_hoverer">左</div>
      <div class="block_hoverer">右</div>
      <div class="block_content">
        Hover me!
      </div>
    </div>
    <span> ←</span>
    <p>↑</p>
  </body>
</html>

面试官:你可以用纯 CSS 判断鼠标进入的方向吗?