1. 导航菜单下划线效果
<nav>
<div class="nav-item">菜单A</div>
<div class="nav-item">菜单BBB</div>
<div class="nav-item">菜单CC</div>
<div class="nav-item">菜单DDDDDDD</div>
<div class="nav-item">菜单EEE</div>
</nav>
nav {
display: flex;
align-items: center;
justify-content: center;
height: 80px;
}
.nav-item {
height: 80px;
line-height: 80px;
margin-right: 20px;
cursor: pointer;
}
.nav-item {
height: 100%;
font-size: 20px;
position: relative;
}
/** 这里是重点 */
.nav-item::after {
content: "";
position: absolute;
height: 3px;
width: 100%;
bottom: 0;
left: 0;
-webkit-transform: scaleX(0);
transform: scaleX(0);
background-color: #000;
transition: 0.3s ease-out;
}
.nav-item:hover::after {
transform: scaleX(1);
-webkit-transform: scaleX(1);
}
2. 导航菜单滑块滑动效果
<nav id="nav">
<div class="nav-item"><span>菜单A</span></div>
<div class="nav-item"><span>菜单BBBBB</span></div>
<div class="nav-item"><span>菜单CCC</span></div>
<div class="nav-item"><span>菜单DDDDDDDD</span></div>
<div class="nav-item"><span>菜单EE</span></div>
<div id="slider"></div>
</nav>
body {
display: flex;
align-items: center;
justify-content: center;
}
nav {
display: flex;
align-items: center;
height: 80px;
border-bottom: 1px solid #ccc;
position: relative;
}
.nav-item {
padding: 0 20px;
}
.nav-item span {
display: inline-block; /** 注意添加display:inline-block,否则无法获取宽度 **/
cursor: pointer;
}
#slider {
position: absolute;
left: 20px;
bottom: -2px;
height: 3px;
background-color: #000;
transition: all 0.3s;
}
// 获取对应的dom
const nav = document.getElementById('nav');
const slider = document.getElementById('slider');
// const setSliderPosition = (index) => {
// slider.style.left = navItem[index].childNodes[0].offsetLeft + 'px';
// }
// const setSliderWidth = (index) => {
// slider.style.width = navItem[index].clientWidth - 40 + 'px';
// }
// 设置滑块位置
const setSliderPosition = (span) => {
slider.style.left = span.offsetLeft + 'px'; // 用span标签包裹,准确获取文字的位置,滑块根据该offsetLeft精准定位
}
// 设置滑块宽度
const setSliderWidth = (span) => {
slider.style.width = span.clientWidth + 'px'; // 也可以获取navItem减去内边距40得到宽度
}
// 事件委托
nav.onclick = (e) => {
if (e.target.nodeName.toLowerCase() === 'span') {
setSliderPosition(e.target);
setSliderWidth(e.target);
}
}
3. 简单动画的实现
统一样式
body {
height: 100vh;
display: flex;
justify-content: space-around;
align-items: center;
}
div {
width: 100px;
height: 100px;
}
- 旋转/翻转
<div class="rotateZ"></div>
<div class="rotateX"></div>
<div class="rotateY"></div>
.rotateZ {
animation: ani_rotateZ infinite 4s;
}
.rotateX {
animation: ani_rotateX infinite 4s;
}
.rotateY {
animation: ani_rotateY infinite 4s;
}
/* 旋转动画Z轴 */
@keyframes ani_rotateZ {
0% {
background-color: red;
}
50% {
background-color: green;
transform: rotate(90deg);
}
100% {
background-color: red;
transform: rotate(180deg);
}
}
/* 旋转动画X轴,即翻转 */
@keyframes ani_rotateX {
0% {
background-color: red;
}
50% {
background-color: blue;
transform: rotateX(180deg);
}
100% {
background-color: red;
transform: rotateX(360deg);
}
}
/* 旋转动画Y轴,即翻转 */
@keyframes ani_rotateY {
0% {
background-color: red;
}
50% {
background-color: yellow;
transform: rotateY(180deg);
}
100% {
background-color: red;
transform: rotateY(360deg);
}
}
- 渐隐
<div class="hide"></div>
<div class="show"></div>
<div class="fade"></div>
.hide {
background-color: black;
animation: ani_hide 3s infinite;
}
.show {
background-color: black;
animation: ani_show 3s infinite;
}
.fade {
background-color: black;
animation: ani_fade 3s infinite;
}
/* 隐藏*/
@keyframes ani_hide {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
/* 显示*/
@keyframes ani_show {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
/* 渐隐*/
@keyframes ani_fade {
0% {
opacity: 1;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
- 移动/弹跳/伸缩
<div class="move"></div>
<div class="jump"></div>
<div class="zoom"></div>
/* 移动 */
@keyframes ani_move {
0% {
transform: translateX(0);
}
50% {
transform: translateX(100px);
}
100% {
transform: translateX(0);
}
}
/* 弹跳 */
@keyframes ani_jump {
0% {
transform: translateY(-200px);
}
15% {
transform: translateY(0);
}
30% {
transform: translateY(-100px);
}
45% {
transform: translateY(0);
}
60% {
transform: translateY(-50px);
}
75% {
transform: translateY(0px);
}
90% {
transform: translateY(-25px);
}
100% {
transform: translateY(0);
}
}
/* 放大缩小 注意:translateZ 需要搭配 perspective才能起作用*/
@keyframes ani_zoom {
0% {
transform: perspective(200px) translateZ(0px);
}
25% {
transform: perspective(200px) translateZ(100px);
}
50% {
transform: perspective(200px) translateZ(0px);
}
75% {
transform: perspective(200px) translateZ(-100px);
}
100% {
transform: perspective(200px) translateZ(0px);
}
}