比如我们有些链接鼠标悬浮会上下滚动文字,或者导航左右滑动会左右移动背景,这种情况下面我们就需要使用 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>
导航例子
利用这种技巧你可以创建一个导航条,这样当用户悬停在导航条上时,就会出现连续滑动动画效果。
<!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>Nav Link</title> </head> <body> <header class="nav"> <ul> <li class="nav-item"> <div class="nav-extend top"> <a href="#">YZA Voku™</a> </div> <div class="nav-extend bottom"> <a href="#">Voku Design™</a> </div> <div class="nav-wrapper"> <a href="#" class="nav-item-content">Voku.Studio™</a> <div class="nav-director"></div> <div class="nav-line nav-line-left"></div> <div class="nav-line nav-line-right"></div> </div> </li> <li class="nav-item"> <div class="nav-wrapper"> <a href="#" class="nav-item-content">Blog</a> <div class="nav-director"></div> <div class="nav-line nav-line-left"></div> <div class="nav-line nav-line-right"></div> </div> </li> <li class="nav-item"> <div class="nav-wrapper"> <a href="#" class="nav-item-content">Project</a> <div class="nav-director"></div> <div class="nav-line nav-line-left"></div> <div class="nav-line nav-line-right"></div> </div> </li> <li class="nav-item"> <div class="nav-wrapper"> <a href="#" class="nav-item-content">Link</a> <div class="nav-director"></div> <div class="nav-line nav-line-left"></div> <div class="nav-line nav-line-right"></div> </div> </li> <li class="nav-item"> <div class="nav-wrapper"> <a href="#" class="nav-item-content">About</a> <div class="nav-director"></div> <div class="nav-line nav-line-left"></div> <div class="nav-line nav-line-right"></div> </div> </li> </ul> </header> </body> </html>
总结
两种方法都是同样的思想,在实现方面略有差异。你可以根据自己的实际情况选择使用哪种方法。