美观又实用,纯 CSS 悬浮菜单让网站更加出色

前言

平时我们在浏览网页时,如下图的导航栏已经屡见不鲜了,当鼠标放上去时,右侧隐藏的内容就会慢慢平滑展开,非常美观且实用,那你知道这种效果是怎么实现的吗?下面我们就一起实践一下。

如图所示:
在这里插入图片描述

实现思路

  • 首先我们需要把所有的导航栏通过 fixed 属性定位到网页的右下角;
  • 设置 transition 属性将所有导航栏添加平滑的过渡效果;
  • 利用 right 属性将所有导航栏向右偏移;
  • 当鼠标触摸某一个导航栏时,运用 hover 属性,将 right 的值设置为 0px,配合之前说到的 transition 属性让其右侧内容平滑的展示出来即可。

话不多说,下面直接看源码

完整源码

<template>
  <div class="parentBox">
    <div class="contantsBox">
      <div>
        <span><img src="../assets/yuyue.png" /></span>
        <span>预约体验</span>
      </div>
      <div>
        <span><img src="../assets/kefu.png" /></span>
        <span>联系客服</span>
      </div>
      <div>
        <span><img src="../assets/fhdb.png" /></span>
        <span>回到顶部</span>
      </div>
    </div>
  </div>
</template>
<style lang="scss" scoped>
.parentBox {
  height: 100%;
  background: gainsboro;
  overflow: hidden;
  overflow-y: auto;
  .contantsBox {
    div {
      transition: all 0.7s;
      position: fixed;
      right: -127px;
      width: 180px;
      background: rgba(96, 96, 96, 0.6);
      color: #fff;
      padding: 8px 10px;
      cursor: pointer;
      display: flex;
      align-items: center;
      span:last-child {
        margin-left: 16px;
      }
      img {
        width: 32px;
        height: 32px;
        vertical-align: middle;
      }
    }
    div:nth-child(1) {
      bottom: 197px;
    }
    div:nth-child(2) {
      bottom: 148px;
    }
    div:nth-child(3) {
      bottom: 100px;
    }
    div:hover {
      right: 0px;
      cursor: auto;
      span {
        cursor: pointer;
      }
    }
    div:not(:last-child) {
      border-bottom: 1px solid #fff;
    }
  }
}
// 隐藏浏览器滚动条
::-webkit-scrollbar {
  display: none;
}
</style>

通过上面的代码我们实现了如下的效果:

  • 父容器的高度设置为 100%,这样可以让父容器占据整个可视区域的高度;
  • 父容器的背景颜色设置为灰色,用于给整个界面一个背景色;
  • 父容器设置了垂直方向的滚动条,这样当内容超出父容器的高度时,用户可以通过滚动条来滚动查看内容;
  • 子容器包含了三个 div 元素,每个 div 元素都有一个图标和文本。图标使用了 img 标签,文本使用了 span 标签;
  • 每个子容器的初始位置都在父容器的右侧,通过设置 right 属性为负值来实现;
  • 当鼠标悬停在子容器上时,子容器会向右移动,通过设置 right 属性为 0 来实现。同时,鼠标指针会变为手型,通过设置 cursor 属性来实现;
  • 除了最后一个子容器外,其他子容器之间有一个白色的分割线,通过设置 border-bottom 属性来实现;
  • 代码还包含了一段 css 样式,用于隐藏浏览器的滚动条。通过设置 ::-webkit-scrollbar 样式来实现的。

拓展延伸

当然,上面实现的操作只是一种展现形式,类似的功能在效果上可能大相径庭,接下来带大家一起看看下面这几个案例实现的效果。

案例1

完整源码

<template>
  <div class="parentBox">
    <div class="menusBox">
      <p><span data-text='快速上手'>快速上手</span></p>
      <p><span data-text="进阶用法">进阶用法</span></p>
      <p><span data-text="开发指南">开发指南</span></p>
    </div>
  </div>
</template>
<style lang="less" scoped>
.parentBox {
  padding: 50px;
  height: 100%;
  background: rgb(37, 34, 51);
  .menusBox {
    background: rgba(0, 0, 0, 0.4);
    border-bottom: 1px solid rgba(241, 241, 241, 0.25);
    box-shadow: 0 0 8px rgba(0, 0, 0, 0.4) inset;
    border-radius: 16px;
    width: 30%;
    display: flex;
    justify-content: space-around;
    height: 50px;
    margin: 0 auto;
    overflow: hidden;
    p {
      cursor: pointer;
      span {
        text-transform: uppercase;
        color: #fff;
        margin-top: -50px;
        transition: 0.3s cubic-bezier(0.1, 0.1, 0.5, 1.4);
      }
      span:before {
        content: attr(data-text);
        /*直接使用data-text属性的值*/
        display: block;
        color: rgb(173, 255, 43);
      }
      span:hover {
        margin-top: 0;
      }
    }
    p * {
      display: inline-block;
      font-size: 18px;
      line-height: 50px;
    }
  }
}
</style>

通过上面的代码我们实现了如下的效果:

  • 首先,创建了一个 vue 组件,包含了一个父容器(parentBox)和一个菜单容器(menusBox);
  • 父容器设置了一些样式属性,如内边距、高度和背景颜色;
  • 菜单容器设置了一些样式属性,如背景颜色、边框、阴影和圆角;它的宽度为 30%,居中显示,并且高度为 50px
  • 菜单容器中包含了三个菜单项(p 标签),每个菜单项都有一个可点击的文本(span 标签);
  • 当鼠标悬停在菜单项上时,文本会向上移动,显示出另一个文本;这是通过设置文本的 margin-top 属性来实现的;
  • 组件的样式使用了 less 语法,通过 scoped 属性将样式限定在组件内部。通过这些实现了一个带有动态效果的菜单栏,当鼠标悬停在菜单项上时,文本会有一个向上移动的动画效果。

效果图

在这里插入图片描述


案例2

完整源码

<template>
  <div class="parentBox">
    <div class="navBox">
      <p>导航菜单</p>
      <ul class="menuBox">
        <li><span class="contnatBox">A</span></li>
        <li><span class="contnatBox">B</span></li>
        <li><span class="contnatBox">C</span></li>
        <li><span class="contnatBox">D</span></li>
        <li><span class="contnatBox">E</span></li>
        <li><span class="contnatBox">F</span></li>
        <li><span class="contnatBox">G</span></li>
        <li><span class="contnatBox">H</span></li>
        <li><span class="contnatBox">I</span></li>
      </ul>
    </div>
  </div>
</template>
<style lang="less" scoped>
.parentBox {
  height: 100%;
  background: #74777b;
  padding: 100px 0;
  transform: translate3d(0, 0, 0);
  *:after,
  *:before {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
  }
  span {
    color: rgba(255, 255, 255, 0.6);
    outline: none;
    text-decoration: none;
    -webkit-transition: 0.2s;
    transition: 0.2s;
  }
  span:hover,
  span:focus {
    cursor: pointer;
    color: #74777b;
    text-decoration: none;
  }
  .navBox {
    width: 150px;
    height: 150px;
    line-height: 150px;
    border-radius: 50%;
    background: #fff;
    margin: 70px auto;
    position: relative;
    cursor: pointer;
    text-align: center;
    font-size: 1.75em;
    font-weight: bold;
    color: cornflowerblue;
    transition: 0.24s 0.2s;
    .menuBox {
      list-style: none;
      padding: 0;
      margin: 0;
      position: absolute;
      top: -75px;
      left: -75px;
      border: 150px solid transparent;
      cursor: default;
      border-radius: 50%;
      transform: scale(0);
      transition: transform 1.4s 0.07s;
      z-index: -1;
    }
    .menuBox li {
      position: absolute;
      top: -100px;
      left: -100px;
      transform-origin: 100px 100px;
      transition: all 0.5s 0.1s;
    }
    .menuBox li span {
      width: 45px;
      height: 45px;
      line-height: 45px;
      border-radius: 50%;
      background: #fff;
      position: absolute;
      font-size: 60%;
      color: cornflowerblue;
      transition: 0.6s;
    }
    .menuBox li span:hover {
      background: rgba(255, 255, 255, 0.7);
    }
  }

  .navBox:hover {
    background: rgba(255, 255, 255, 0.8);
  }

  .navBox:hover .menuBox {
    transition: transform 0.4s 0.08s, z-index 0s 0.5s;
    transform: scale(1);
    z-index: 1;
  }

  .navBox:hover .menuBox li {
    transition: all 0.6s;
  }

  .navBox:hover .menuBox li:nth-child(1) {
    transition-delay: 0.02s;
    transform: rotate(85deg);
  }

  .navBox:hover .menuBox li:nth-child(1) span {
    transition-delay: 0.04s;
    transform: rotate(635deg);
  }

  .navBox:hover .menuBox li:nth-child(2) {
    transition-delay: 0.04s;
    transform: rotate(125deg);
  }

  .navBox:hover .menuBox li:nth-child(2) span {
    transition-delay: 0.08s;
    transform: rotate(595deg);
  }

  .navBox:hover .menuBox li:nth-child(3) {
    transition-delay: 0.06s;
    transform: rotate(165deg);
  }

  .navBox:hover .menuBox li:nth-child(3) span {
    transition-delay: 0.12s;
    transform: rotate(555deg);
  }

  .navBox:hover .menuBox li:nth-child(4) {
    transition-delay: 0.08s;
    transform: rotate(205deg);
  }

  .navBox:hover .menuBox li:nth-child(4) span {
    transition-delay: 0.16s;
    transform: rotate(515deg);
  }

  .navBox:hover .menuBox li:nth-child(5) {
    transition-delay: 0.1s;
    transform: rotate(245deg);
  }

  .navBox:hover .menuBox li:nth-child(5) span {
    transition-delay: 0.2s;
    transform: rotate(475deg);
  }

  .navBox:hover .menuBox li:nth-child(6) {
    transition-delay: 0.12s;
    transform: rotate(285deg);
  }

  .navBox:hover .menuBox li:nth-child(6) span {
    transition-delay: 0.24s;
    transform: rotate(435deg);
  }

  .navBox:hover .menuBox li:nth-child(7) {
    transition-delay: 0.14s;
    transform: rotate(325deg);
  }

  .navBox:hover .menuBox li:nth-child(7) span {
    transition-delay: 0.28s;
    transform: rotate(395deg);
  }

  .navBox:hover .menuBox li:nth-child(8) {
    transition-delay: 0.16s;
    transform: rotate(365deg);
  }

  .navBox:hover .menuBox li:nth-child(8) span {
    transition-delay: 0.32s;
    transform: rotate(355deg);
  }

  .navBox:hover .menuBox li:nth-child(9) {
    transition-delay: 0.18s;
    transform: rotate(405deg);
  }

  .navBox:hover .menuBox li:nth-child(9) span {
    transition-delay: 0.36s;
    transform: rotate(315deg);
  }
}
</style>

通过上面的代码我们实现了如下的效果:

  • 首先,我们定义了一个父容器(parentBox),并在其中嵌套了一个导航菜单(navBox);
  • 导航菜单是一个圆形的按钮,具有一些样式属性,如背景颜色、边框半径、字体大小等;
  • 当鼠标悬停在导航菜单上时,会触发一些 css 过渡效果,使菜单展开;
  • 菜单展开的效果是通过 csstransform 属性实现的;菜单的展开是通过改变菜单容器(menuBox)的 transform 属性来实现的;
  • 初始状态下,菜单容器的 scale 属性为 0,即不可见;当鼠标悬停在导航菜单上时,通过改变菜单容器的 scale 属性为 1,菜单容器就会展开;
  • 菜单容器中包含了一些选项(li),每个选项都有一个小圆圈(span);
  • 选项的初始状态是隐藏在菜单容器之外的,通过改变选项的 transform 属性来实现旋转的效果;
  • 当鼠标悬停在选项上时,通过改变选项的背景颜色,使圆圈变成淡蓝色。

效果图

在这里插入图片描述

  • 9
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水星记_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值