基于现有代码,如何用CSS/Bootstrap实现导航栏中间圆形缺口?
实现导航栏中间的圆形缺口
需要在底部导航栏的中间位置制作一个圆形缺口,匹配Figma原型样式,现有HTML和CSS代码如下,请教如何用CSS实现该效果。
现有代码
CSS代码
@import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;600;700&display=swap"); @import url("https://fonts.googleapis.com/css2?family=Quicksand:wght@300;400;500;600;700&display=swap"); .wrapper { border: solid 0.25rem black; box-shadow: 0 0 6vmin rgba(0, 0, 0, 0.2); border-radius: 2vmin; position: relative; width: 40vh; height: 80vh; margin: auto; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; overflow: hidden; } .navbar img { margin: 0 10px; } .navbar a[href="/search"] { margin-right: 40px; } .navbar a[href="/notes"] { margin-left: 40px; } .navbar { display: flex; justify-content: space-between; align-items: center; width: 100%; height: 60px; background-color: #ffffff; box-shadow: 0px 0px 10px rgba(128, 131, 255, 0.75); border-radius: 10px; position: absolute; bottom: 0; left: 0; padding: 0; border: 20px solid var(-clr); } .circle { display: flex; justify-content: center; align-items: center; position: absolute; top: -25px; left: 50%; transform: translateX(-50%); width: 60px; height: 60px; border-radius: 50%; background: linear-gradient( 270deg, rgba(227, 224, 243, 0.245) 0%, rgba(128, 131, 255, 0.255) 100% ), #8083ff; } a[href="/feeds/buckets?show=inprogress"] img { width: 40px; height: 40px; } .top_buttons { margin-top: 45px; display: flex; justify-content: space-between; gap: 35px; } .friends, .for_you { font-family: "Opens Sans", sans-serif; font-size: 14px; font-weight: 400; line-height: 20px; border: 3px solid #8083ff; border-radius: 30px; width: 100px; padding: 4px 8px; text-align: center; } .friends { background-color: #8083ff; color: #ffffff; } .for_you { background-color: #ffffff; color: #8083ff; } .post { background-color: #ffffff; border-radius: 10px; padding: 15px; margin-bottom: 20px; margin-top: 10px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); position: relative; } .post p { font-family: "Opens Sans", sans-serif; font-size: 14px; margin: 0 0 10px; line-height: 15px; font-style: normal; word-wrap: break-word; } .post p:last-child { margin-bottom: 0; } .user-info { display: flex; align-items: center; } .user-picture { width: 40px; height: 40px; border-radius: 50%; margin-right: 10px; background-color: #b1b1b1; position: absolute; top: 10px; left: 10px; } .username { font-weight: normal; margin: 0; line-height: 19px; } .post p:nth-child(2) { margin-top: 20px; } .post-content { margin-left: 60px; margin-top: 10px; font-family: "Open Sans"; font-style: normal; font-weight: 400; font-size: 14px; line-height: 19px; padding-right: 10px; } .posts-container { overflow-y: auto; max-height: calc(80vh - 230px); width: 100%; padding: 0 15px; margin-top: 10px; } .create_post { background-color: #d9d9d9; border-radius: 10px; width: 100%; height: 220px; padding: 6px 14px; font-size: 18px; box-sizing: border-box; margin-bottom: 20px; padding-left: 60px; border: none; position: relative; top: 10px; padding-top: 10%; } .user-input-wrapper { position: relative; width: 100%; } .user-avatar { position: absolute; top: 15%; left: 15px; transform: translateY(-50%); width: 40px; height: 40px; border-radius: 50%; background-color: #b1b1b1; z-index: 1; } .create_post::placeholder { font-size: 14px; font-family: "Open Sans"; font-style: normal; }
HTML代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="../styles/style_friendspost.css" /> <script defer src="myscripts.js"></script> <title>Main Feed</title> </head> <body> <div class="wrapper"> <div class="top_buttons"> <p>Cheer Your Friends!</p> </div> <div class="posts-container"> <% feed.forEach(post => { %> <div class="post"> <div class="user-picture"></div> <div class="post-content"> <p class="username">@<%=post.username%></p> <p><%= post.completed[0] %></p> <p><%= post.bucketName[0] %></p> <p><%= post.messages %></p> </div> </div> <% }) %> </div> <div class="navbar"> <a href="/feeds/home"> <img src="../styles/images/home_icon_noBackground.png" alt="Home" width="40" height="40" /> </a> <a href="/search"> <img src="../styles/images/search_icon_noBackground.png" alt="Search" width="40" height="40" /> </a> <div class="circle"> <a href="/feeds/buckets?show=inprogress"> <img src="../styles/images/bucket_icon_noBackground.png" alt="Bucket" width="50" height="50" /> </a> </div> <a href="/notes"> <img src="../styles/images/note_icon_noBackground.png" alt="Notes" width="40" height="40" /> </a> <a href="/profile"> <img src="../styles/images/profile_icon_noBackground.png" alt="Profile" width="40" height="40" /> </a> </div> </div> </body> </html>
实现方案
通过CSS的clip-path属性裁剪导航栏,同时调整中间圆形按钮的位置,即可实现原型中的圆形缺口效果,具体修改如下:
1. 修改导航栏样式,裁剪圆形缺口
替换原有.navbar的CSS代码,添加clip-path实现缺口,同时优化布局:
.navbar { display: flex; justify-content: space-between; align-items: center; width: 100%; height: 60px; background-color: #ffffff; box-shadow: 0px 0px 10px rgba(128, 131, 255, 0.75); border-radius: 10px 10px 0 0; /* 仅保留顶部圆角 */ position: absolute; bottom: 0; left: 0; padding: 0 20px; /* 增加左右内边距,避免图标贴边 */ /* 裁剪中间圆形缺口,参数可根据实际尺寸调整 */ clip-path: circle(32px at 50% -22px); }
clip-path: circle(32px at 50% -22px)表示在导航栏顶部中间位置,裁剪一个半径32px的圆形缺口,垂直位置设为负数让缺口延伸到导航栏外。
2. 调整中间圆形按钮的位置,嵌入缺口
修改.circle的样式,让按钮刚好嵌入缺口:
.circle { display: flex; justify-content: center; align-items: center; position: absolute; top: -32px; /* 调整偏移距离,让按钮与缺口完全贴合 */ left: 50%; transform: translateX(-50%); width: 64px; /* 增大按钮尺寸,匹配缺口大小 */ height: 64px; border-radius: 50%; background: linear-gradient( 270deg, rgba(227, 224, 243, 0.245) 0%, rgba(128, 131, 255, 0.255) 100% ), #8083ff; box-shadow: 0 0 10px rgba(128, 131, 255, 0.75); /* 添加阴影增强层次感 */ }
3. 优化导航栏链接布局
移除原有链接的自定义margin,改用flex:1让图标均匀分布:
.navbar a { flex: 1; display: flex; justify-content: center; } .navbar a[href="/search"], .navbar a[href="/notes"] { margin: 0; /* 移除原有margin */ }
将以上修改替换原有代码对应的部分,即可实现与原型一致的导航栏圆形缺口效果。
内容的提问来源于stack exchange,提问作者Fernando Daumichen
相关产品推荐
相关产品推荐

