漂亮的CSS移动端底部导航栏实现
先看效果:

这个效果的实现,重点是使用了svg滤镜
完整代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
html,body{
margin: 0;
background-color: #e0e0e0;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
#box{
width: 320px;
height: 640px;
background-color: #efefef;
position: relative;
}
.footer{
position: absolute;
bottom: 0;
left: 0;
right: 0;
display: flex;
justify-content: space-between;
background-color: #fff;
background-image: linear-gradient(45deg, #ffe8e8, #ffffff, #edf9ff);
}
.tag{
display: block;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
flex: 1;
position: relative;
z-index: 4;
cursor: pointer;
}
.tag span{
position: relative;
top: 0;
border-radius: 50%;
transition: 0.6s;
display: flex;
width: 60px;
height: 60px;
align-items: center;
justify-content: center;
color: #a9b5bf;
}
.tag.current span{
top: -20px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.05);
background-image: linear-gradient(45deg, #ffe8e8, #ffffff, #edf9ff);
}
.tag span svg{
width: 24px;
fill: #a9b5bf;
}
.tag.current span svg{
fill: #5b6c7a;
}
.footer-bg{
position: absolute;
left: 0;
right: 0;
bottom: 60px;
height: 60px;
background-color: #efefef;
z-index: 2;
filter: url(#goo);
transition: 0.3s;
}
.dot{
width: 78px;
height: 64px;
background-color: #efefef;
position: absolute;
left: 0%;
top: 46px;
transform: translateX(1px);
border-radius: 50%;
transition: 0.3s;
}
.content{
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 60px;
z-index: 3;
transition: background-color 0.3s;
text-align: center;
color: #fff;
}
</style>
</head>
<body>
<div id="box">
<div class="content">
<main>
<h1>Text</h1>
<p>content position here</p>
<p>click & next</p>
</main>
</div>
<div class="footer-bg">
<div class="dot"></div>
</div>
<footer class="footer">
<div onclick="setCurrent(1)" class="tag tag1 current"><span><svg t="1697425088462" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4895" width="200" height="200"><path d="M900.745478 430.904767l-330.418307-308.008394c-16.679524-19.033077-40.82902-29.982212-66.411112-29.982212-25.172779 0-49.322274 10.846807-65.2855 28.8566L120.491656 430.802438c-15.860897 16.270211-20.465674 39.805736-11.665434 60.783052 8.80024 20.977316 29.163585 34.075347 51.880484 34.075347l28.651944 0 0 314.148096c0 48.708304 38.987109 88.309383 87.695413 88.309383l136.608374 0c17.702808 0 33.461377-14.325972 33.461377-32.02878L447.123813 687.032677c0-8.902568 5.832717-16.781853 14.735285-16.781853l96.393325 0c8.902568 0 15.656241 7.981613 15.656241 16.781853l0 208.954532c0 17.805136 14.837614 32.02878 32.540422 32.02878l136.608374 0c48.708304 0 88.616369-39.498751 88.616369-88.309383l0-314.148096 28.549615 0c22.61457 0 42.977915-13.098031 51.778155-33.973019C921.006495 470.812831 916.504047 447.174978 900.745478 430.904767L900.745478 430.904767 900.745478 430.904767M900.745478 430.904767 900.745478 430.904767z" p-id="4896"></path></svg></span></div>
<div onclick="setCurrent(2)" class="tag tag2"><span><svg t="1697425146769" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10385" width="200" height="200"><path d="M697.995 113.419c-70.292-0.023-137.597 28.416-186.521 78.81-48.918-50.405-116.223-78.845-186.521-78.81-143.994 0-261.128 117.81-261.128 262.588 0 60.857 21.186 120.158 61.737 169.399l333.351 342.183a72.81 72.81 0 0 0 52.561 22.307c19.958 0 38.61-7.934 52.602-22.272l335.439-344.606c38.559-47.143 59.62-106.142 59.608-167.011 0-144.779-117.132-262.588-261.128-262.588" p-id="10386"></path></svg></span></div>
<div onclick="setCurrent(3)" class="tag tag3"><span><svg t="1697425204633" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="17807" width="200" height="200"><path d="M554.6 319c79.3 0 119-39.7 119-119S634 80.9 554.6 80.9c-79.3 0-119 39.7-119 119.1s39.7 119 119 119z m-303.4 0c79.3 0 119-39.7 119-119s-39.7-119.1-119-119.1-119 39.7-119 119.1 39.6 119 119 119zM908 409.4c-29.2-10-71.2 22.5-71.2 22.5l-130.2 110c-34.9-126-139.8-189.1-314.8-189.1C173.3 352.9 64 451.2 64 647.9 64 844.6 173.3 943 391.8 943c171.4 0 275.6-60.6 312.6-181.6l116.7 119.2s54.3 33.9 83.5 24.2c34.7-11.6 55.3-67.1 55.3-67.1V470.8c0.1 0-24.6-52-51.9-61.4z" p-id="17808"></path></svg></span></div>
<div onclick="setCurrent(4)" class="tag tag4"><span><svg t="1697425179323" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15873" width="200" height="200"><path d="M849.285816 446.006983c0-216.528522-175.531805-392.065444-392.065444-392.065444-216.528522 0-392.065444 175.536922-392.065444 392.065444 0 212.83848 169.602769 386.054543 381.026016 391.899668l-25.116027 122.098849 264.222777-195.065697-0.019443 0.005117C784.570909 693.817975 849.285816 577.470107 849.285816 446.006983L849.285816 446.006983zM467.13314 689.13635c-4.620227 0-9.250688-0.098237-13.896498-0.294712-86.150102-3.632737-165.779697-40.636512-224.213551-104.208387l17.995863-30.619368c54.015218 58.760289 127.618563 92.971461 207.246111 96.326882 79.639828 3.359514 155.851581-24.548092 214.611869-78.564333l16.542768 32.077579C625.272833 659.136082 548.224016 689.13635 467.13314 689.13635L467.13314 689.13635zM467.13314 689.13635" p-id="15874"></path></svg></span></div>
</footer>
</div>
<svg width="0" height="0">
<defs>
<filter id="goo">
<feGaussianBlur in="SourceGraphic" stdDeviation="15" result="blur" id="blurFilter"></feGaussianBlur>
<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 30 -15" result="goo"></feColorMatrix>
<feComposite in="SourceGraphic" in2="goo" operator="atop"></feComposite>
</filter>
</defs>
</svg>
<script>
function setCurrent(index) {
const tags = document.querySelectorAll('.tag')
tags.forEach(tag => {
tag.classList.remove('current')
})
const tag = document.querySelector('.tag' + index)
tag.classList.add('current')
const dot = document.querySelector('.dot')
dot.style.left = 25 * (index-1) + '%'
setColor(index)
}
function setColor(index) {
const colors = ['#a9b5bf', '#a9bfb7', '#bcbfa9', '#bfa9a9']
const color = colors[index-1]
const bg = document.querySelector('.footer-bg')
const dot = document.querySelector('.dot')
const content = document.querySelector('.content')
const svg = document.querySelector('.tag.current span svg')
bg.style.backgroundColor = color
dot.style.backgroundColor = color
content.style.backgroundColor = color
const svgs = document.querySelectorAll('.tag span svg')
svgs.forEach(svg => {
svg.style.fill = '#a9b5bf'
})
svg.style.fill = color
}
setCurrent(1)
</script>
</body>
</html>导航的平滑圆角融合实现:
1. SVG滤镜
<svg width="0" height="0"> <defs> <filter id="goo"> <feGaussianBlur in="SourceGraphic" stdDeviation="15" result="blur" id="blurFilter"></feGaussianBlur> <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 30 -15" result="goo"></feColorMatrix> <feComposite in="SourceGraphic" in2="goo" operator="atop"></feComposite> </filter> </defs> </svg>
2. 使用滤镜的DOM
<div class="footer-bg"> <div class="dot"></div> </div>
3. 用CSS给DOM添加SVG滤镜
.footer-bg{
filter: url(#goo);
}4. 控制融合效果偏移位置JS
function setCurrent(index) {
const tags = document.querySelectorAll('.tag')
tags.forEach(tag => {
tag.classList.remove('current')
})
const tag = document.querySelector('.tag' + index)
tag.classList.add('current')
const dot = document.querySelector('.dot')
dot.style.left = 25 * (index-1) + '%'
setColor(index)
}这4点是实现的主要内容。其它代码看完整代码吧。
2023-10-16 11:08:41
402
0
参与讨论