如何使用CSS判断鼠标从哪个方向进入元素?

这篇文章发布于 2026年04月27日,星期一,17:35,归类于 CSS相关。 阅读 68 次, 今日 66 次 一条评论

 

一、且看效果

下面是我使用CSS绘制的一个人脸,如果我希望如果用户鼠标从上面进入,表情变成哭丧脸;从下方进入,变成笑脸,该如何实现?

相关代码如下所示:

<div class="face-x">
  <div class="face"></div>
</div>

CSS相关代码(默认效果代码,不含hover交互处理):

.face {
  width: 200px; height: 200px;
  background: #FFD700; /* 经典亮黄色 */
  border-radius: 50%;
  position: relative;
  border: 4px solid #333;
}

/* 使用伪元素绘制眼睛 */
.face::before {
  content: '';
  position: absolute;
  top: 60px; left: 55px;
  width: 20px; height: 20px;
  background: #333;
  border-radius: 50%;
  /* 用阴影复制出另一只眼,省代码 */
  box-shadow: 70px 0 #333;
}

/* 使用伪元素绘制嘴巴 */
.face::after {
  content: '';
  position: absolute;
  top: 100px;
  left: 60px;
  width: 80px;
  height: 20px;
  border-bottom: 8px solid #333;
}

大家不妨自己思考下,有没有什么思路。🤔🤔

二、实现代码与原理

就像变魔术一样,在揭开谜底之前总觉得高深莫测,实际上也就那么回事。

我们直接看最关键的实现代码:

/* 不同方向hover,显示不同表情 */
.face-x {
  width: fit-content;
  position: relative;
  border-radius: 50%;
}
.face-x::after {
  content: '';
  position: absolute;
  inset: 0;
  bottom: 50%;
  /* background: #0008; */
}
.face-x:has(.face:hover) {
  &::after {
    display: none;
  }
  .face::after {
    border-radius: 0 0 50% 50%;
  }
}
.face-x:hover:not(:has(.face:hover)) {
  &::after {
    bottom: 0;
  }
  .face::after {
    top: 120px;
    border-radius: 0 0 50% 50%;
    scale: 1 -1;
  }
}

原理很简单:

创建一个50%高度的覆盖层覆盖在.face元素上,如果用户的鼠标进入后首先触碰的事这个覆盖层,就会匹配.face-x:hover:not(:has(.face:hover)),如果是从另外一个方向进入,由于没有覆盖层阻挡,就会匹配.face-x:has(.face:hover)

如果匹配了前者,那么迅速将覆盖层的尺寸覆盖整个容器元素;如果匹配了后者,迅速隐藏覆盖层。

这样,两种匹配状态就不会冲突。

就是这么简单!

就是这么简单表情包

三、又是学到了的一天

我发现,这年头,大家学习前端技术的热情越来越低了,不仅是行业中,公司内也是如此。

以前内部小测,少说十几人参与,多的时候几十人,现在么,就那固定的四五个人。

包括社区里面,也明显感觉到没那么活跃了。

时代变了。

不过我还是相信,自身的实力才是在风雨中屹立不倒的根本,所以,我还是会继续学习的。

以不变应万变,不忘初心。

不忘初心配图

(本篇完)

分享到:


发表评论(目前一条评论)

  1. tyouzu1说道:

    和想的差不多,不过 .face-x::after 好像缺了 border-radius: 100px 100px 0 0; 🤔