W
WebIsFun
Writing

CSS 方向判断

使用纯 CSS 来是实现方向判断,在某些特定的场景下很有用。

December 20, 2025


比如我们有些链接鼠标悬浮会上下滚动文字,或者导航左右滑动会左右移动背景,这种情况下面我们就需要使用 CSS 来实现方向判断。

判断原理

比如要实现鼠标从上往下和从下往上的判断,CSS 没有提供给我们可以判断鼠标移动方向的快捷方法。

解决的思路是我们需要通过两个元素来接收鼠标的hover从而判断鼠标是从上往下还是从下往上。

|------------|
|            |
|      ↓     |
|            |
|------------|
|            |
|      ↑     |
|            |
|------------|

方法1

使用两个div元素分别放在容器的上方和下方(超出容器不可见),然后分别为他们的:before高度设置为容器的一半用来接收:hover事件。当:before被hover时将div移入到容器中。

具体的实现方法如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="/style.css" />
    <title>Css Direction</title>
    <style>
      /* css direction */
      @layer {
        .dir {
          position: absolute;
          transition: all 0.4s ease;

          &:before {
            content: '';
            position: absolute;
            width: 100%;
            height: 50%;
          }

          &:hover {
            bottom: 0;
            z-index: 1;
          }

          &:hover:before {
            width: 100%;
            height: 100%;
            transform: none;
          }
        }

        .bottom {
          background: pink;
          bottom: -100%;

          &:before {
            bottom: 100%;
            left: 0;
            transform-origin: 0 100%;
          }
        }

        .top {
          background: aqua;
          bottom: 100%;

          &:before {
            top: 100%;
            right: 0;
            transform-origin: 100% 0;
          }
        }
      }
    </style>
  </head>
  <body>
    <div class="box">
      <div class="content">CSS Direction</div>
      <div class="dir top">Top -> Buttom</div>
      <div class="dir bottom">Bottom -> Top</div>
    </div>
  </body>
</html>

这种方法是非常好理解的一种方法,他在hover和行为表现上都很容易理解。

方法2

这种方法实现原理其实和方法1的思想是一样,但是不同的是没有使用 :before 来创建元素,而是使用 clip-path 来创建一个裁剪层。

裁剪层的关键在于它会至于实际元素的上层,hover 相应也是在实际元素之上。所以正是利用这个特性才可以实现正确的 hover 判断来实现方向效果。

具体的实现方法如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="/style.css" />
    <title>Css Direction 2</title>
    <style>
      /* css direction */
      @layer {
        .box {
          overflow: hidden;
          position: relative;

          &:hover:not(:has(.director:hover)) .director {
            clip-path: inset(100% 0 0 0);
          }

          &:hover:not(:has(.director:hover)) .top {
            top: 0;
          }
        }

        .panel {
          position: absolute;
          width: 100%;
          height: 100%;
          transition: all 400ms ease;
        }

        .top {
          top: -100%;
          background: lightsalmon;
        }

        .bottom {
          bottom: -100%;
          background: lightgreen;
        }

        .director {
          position: absolute;
          inset: 0;
          background: red;
          z-index: 30;
          clip-path: inset(50% 0 0 0);
          opacity: 0;

          &:hover {
            clip-path: inset(0 0 0 0);
          }
          &:hover ~ .bottom {
            bottom: 0;
          }
        }
      }
    </style>
  </head>
  <body>
    <div class="box">
      <div class="content">CSS Direction</div>
      <div class="director"></div>
      <div class="panel bottom">Bottom -> Top</div>
      <div class="panel top">Top -> Bottom</div>
    </div>
  </body>
</html>

总结

两种方法都是同样的思想,在实现方面略有差异。你可以根据自己的实际情况选择使用哪种方法。