前言
平时我们在浏览网页时,如下图的导航栏已经屡见不鲜了,当鼠标放上去时,右侧隐藏的内容就会慢慢平滑展开,非常美观且实用,那你知道这种效果是怎么实现的吗?下面我们就一起实践一下。
如图所示:
实现思路
- 首先我们需要把所有的导航栏通过
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
过渡效果,使菜单展开; - 菜单展开的效果是通过
css
的transform
属性实现的;菜单的展开是通过改变菜单容器(menuBox
)的transform
属性来实现的; - 初始状态下,菜单容器的
scale
属性为0
,即不可见;当鼠标悬停在导航菜单上时,通过改变菜单容器的scale
属性为1
,菜单容器就会展开; - 菜单容器中包含了一些选项(
li
),每个选项都有一个小圆圈(span
); - 选项的初始状态是隐藏在菜单容器之外的,通过改变选项的
transform
属性来实现旋转的效果; - 当鼠标悬停在选项上时,通过改变选项的背景颜色,使圆圈变成淡蓝色。
效果图