Talk is cheap. Show me your code

七种通过 CSS 实现的按钮 Hover 特效

最近写了太多的逻辑代码,写几行 CSS 换换脑子

 

 

一、一闪而过

很常见的效果,其实就是一个倾斜长条平移了一段距离而已

要点在于给 button 设置 overflow: hidden; 以及确保长条的初始位置和结束位置在按钮区域外面

 

HTML

<button class="shiny-button">Hover Me</button>

CSS

button {
  background: transparent;
  border: none;
  cursor: pointer;
}

button.shiny-button {
  color: #fff;
  border: 1px solid #fff;
  padding: 8px 40px;
  position: relative;
  overflow: hidden; /* 非常重要 */
}

.shiny-button::after {
  content: '';
  display: block;
  position: absolute;
  top: -120px;
  left: -80px;
  width: 36px;
  height: 360px;
  background: #fff;
  opacity: 0.16;
  transform: rotate(-45deg);
  transition: all 500ms ease-out;
}

.shiny-button:hover::after {
  left: 200%;
}
View Code

 

 

二、两极翻转

在 Hover 的时候执行 X 轴翻转,然后切换文本

这里的关键点在于使用 backface-visibility: hidden; 隐藏翻转到背面的文本

 

HTML

<button class="flip-button">
  <div class="flex-center flip-text front">Hover Me</div>
  <div class="flex-center flip-text back">Hello Wise.Wrong</div>
</button>

CSS

button {
  background: transparent;
  border: none;
  cursor: pointer;
}

.flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

button.flip-button {
  color: #fff;
  border: 1px solid #fff;
  position: relative;
  width: 200px;
  height: 40px;
}

.flip-text {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  transition: all 600ms ease-in-out;
  transform-style: preserve-3d;
  backface-visibility: hidden;
}

.flip-text.back {
  transform: rotateX(0.5turn);
}

.flip-button:hover .flip-text {
  transform: rotateX(0.5turn);
}

.flip-button:hover .flip-text.back {
  transform: rotateX(0turn);
}
View Code

 

  

三、单向填充

这个效果实现的方案就很很多了,比如设置伪元素 after 宽度从 0 过渡为 100%

不过个人更喜欢用背景 background 来实现

 

HTML

<button class="fill-button">Hover Me</button>

CSS

button {
  --bg-color: #555660;
  --font-color: #fff;
  background-color: transparent;
  border: none;
  cursor: pointer;
  transition: var(--transition-config);
}

button.fill-button {
  color: var(--font-color);
  border: 1px solid var(--font-color);
  position: relative;
  padding: 8px 40px;
  transition: all 600ms ease-out;
  /* 以下为核心代码 */
  background-size: 200% 100%;
  background-position: right bottom;
  background-image: linear-gradient(to right, var(--font-color) 50%, var(--bg-color) 50%);
}

button.fill-button:hover {
  color: var(--bg-color);
  background-position: left bottom;
}
View Code

 

 

四、径向扩散

创建一个圆形的背景层,然后通过 scale 放大

调整背景层的圆心位置,还可以实现从矩形角落放大

 

HTML

<button className="radial-button">Hover Me</button>

CSS

html {
  --font-color: #fff;
  --bg-color: rgba(255, 255, 255, 0.4);
}

button {
  background-color: transparent;
  border: none;
  cursor: pointer;
}

button.radial-button {
  position: relative;
  overflow: hidden;
  z-index: 1;
  border: 1px solid var(--font-color);
  color: var(--font-color);
  padding: 12px 40px;
}

.radial-button::before {
  content: '';
  position: absolute;
  z-index: -1;
  top: 50%;
  left: 50%;
  width: 1em;
  height: 1em;
  border-radius: 50%;
  background-color: var(--bg-color);
  transform-origin: center;
  transform: translate3d(-50%, -50%, 0) scale(0, 0);
  transition: transform 500ms ease-in-out;
}

.radial-button:hover::before {
  transform: translate3d(-50%, -50%, 0) scale(15, 15);
}
View Code

 

  

五、组成边框

创建四条边框线,然后用定位改变他们的位置

 

HTML

<div class="line-button-wrapper">
  <button class="line-button">Hover Me</button>
  <div class="line-gourp">
    <div class="line line-top"></div>
    <div class="line line-left"></div>
    <div class="line line-right"></div>
    <div class="line line-bottom"></div>
  </div>
</div>

CSS

html {
  --font-full-color: #fff;
  --font-color: rgba(255, 255, 255, 0.8);
}

button {
  background-color: transparent;
  border: none;
  cursor: pointer;
}

button.line-button {
  position: relative;
  z-index: 2;
  color: var(--font-color);
  padding: 12px 40px;
  border: 1px solid transparent;
}

.line-button-wrapper {
  position: relative;
  display: inline-block;
}

.line-button-wrapper .line-button,
.line-button-wrapper .line {
  transition: all 600ms ease-out;
}

.line-button-wrapper:hover .line-button {
  color: var(--font-full-color);
}

.line-button-wrapper:hover .line-gourp .line {
  opacity: 1;
  transform: translate(0, 0);
}

.line-gourp,
.line-gourp .line {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
}

.line-gourp .line {
  border: 1px solid transparent;
  opacity: 0;
}

.line.line-top {
  border-top-color: var(--font-full-color);
  bottom: auto;
  transform: translateX(-50%);
}

.line.line-bottom {
  border-bottom-color: var(--font-full-color);
  top: auto;
  transform: translateX(50%);
}

.line.line-left {
  border-left-color: var(--font-full-color);
  right: auto;
  transform: translateY(80%);
}

.line.line-right {
  border-right-color: var(--font-full-color);
  left: auto;
  transform: translateY(-80%);
}
View Code

 

  

六、逐帧动画

这个效果来自旧版的 B 站,下文展示的相关代码也是从 B 站的源码中 copy 而来

首先需要一张逐帧平铺的长图(下图),然后通过动画 animation 中的 steps 方法调整长图 background-position,最终实现动图

 

HTML

<button class="rocket-button"></button>

CSS

button {
  background-color: transparent;
  border: none;
  cursor: pointer;
}

button.rocket-button {
  background-image: url("https://static.hdslb.com/bl2se/images/rocket_frame.png");
  width: 150px;
  height: 175px;
  background-position-x: -600px;
}

.rocket-button:hover {
  animation: fly 0.4s steps(1) infinite;
}

@keyframes fly {
  0% {
    background-position-x: 0;
  }
  25% {
    background-position-x: -150px;
  }
  50% {
    background-position-x: -300px;
  }
  75% {
    background-position-x: -450px;
  }
  to {
    background-position-x: -600px;
  }
}
View Code

 

 

七、七十二变

这也是通过逐帧动画来实现的,但关键点在于,需要通过 animation-play-state 来控制动画的暂停与播放

此外还可以通过设置 animation-delay 为负值,来控制初始显示的图标

 

HTML

<button class="random-button">
  Hover Me
  <span class="random-button-icon"></span>
</button>

CSS

html {
  --icon-height: 30px;
}

button {
  background-color: transparent;
  border: none;
  cursor: pointer;
}

button.random-button {
  color: #fff;
  border: 1px solid #fff;
  padding: 12px 40px;
}

.random-button-icon {
  width: 22px;
  height: var(--icon-height);
  margin-left: 4px;
  overflow: hidden;
  display: inline-block;
  vertical-align: middle;
  position: relative;
}

.random-button-icon::after {
  content: '😂😠😎😳😡😭😀🙄😷😱';
  display: block;
  font-size: 20px;
  line-height: var(--icon-height);
  transform: translateY(0);
  /* 声明动画效果 */
  animation: random-icon 2s steps(1) infinite;
  /* 暂停动画 */
  animation-play-state: paused;
  /* 通过负值延迟来设置初始显示的 Icon */
  animation-delay: -0.4s;
}

.random-button:hover .random-button-icon::after {
  /* hover 的时候播放动画 */
  animation-play-state: running;
}

@keyframes random-icon {
  0% {
    transform: translateY(0);
  }
  10% {
    transform: translateY(-30px);
  }
  20% {
    transform: translateY(-60px);
  }
  30% {
    transform: translateY(-90px);
  }
  40% {
    transform: translateY(-120px);
  }
  50% {
    transform: translateY(-150px);
  }
  60% {
    transform: translateY(-180px);
  }
  70% {
    transform: translateY(-210px);
  }
  80% {
    transform: translateY(-240px);
  }
  90% {
    transform: translateY(-270px);
  }
  to {
    transform: translateY(-300px);
  }
}
View Code

我这里是通过伪元素的 content 添加了一串 emoji 表情

也可以像上面的“逐帧动画”那样直接设置一个背景长图,然后通过 background-position 来控制每一帧的内容

 


另外推荐一个 GitHub 仓库:Hover-Buttons,分享了很多 hover 特效~

 

posted @ 2022-05-16 16:59  Wise.Wrong  阅读(4981)  评论(0编辑  收藏  举报