纯css使用transform实现同心圆导航栏菜单
2017-01-07 10:32
351 查看
最近遇到客户来了一个我没遇到过的需求。那就是制作一个同心圆菜单栏。因为公司没有其他人指导我,所以我自己在网上搜索了很久,最后是根据(http://www.w3cplus.com/css3/building-a-circular-navigation-with-css-transforms.html)这个链接上的教程逐步实现了。是使用纯css3的transform来实现的,没有用过什么插件。之前对transform属性接触的比较少,所以刚开始做的时候有点吃力,当你理解后你就会知道transform是有多么的强大,当然做的时候遇到一个bug我怎么也解决不了,下面我会提出来的,希望哪位大神能够解决的告知一声;
制作的步骤:
1.我们需要将导航项绝对定位在容器里面
2.将每一项的变换原点设置成他们的右下角
3.然后往左上角平移导航项,让它们的变换原点和容器中心相吻合
4.然后按照公式顺时针旋转每一项到指定的位置:对于第i项,需要旋转:i*x,其中x是圆心角的值。
5.然后让它们变形以获取我们想要的圆心角(使用上面提到过的公式)。
6.反向倾斜a标签,意味着按列表项需要按相反的值倾斜, 然后用- [90 – (x/2) ]的值反向 旋转,x是圆心角的值。那么对于40度的圆心角,我们需要倾斜a标签-40度并且按-[ 90 – (40/2) ] = -70 度旋转。
a标签被绝对定位在它们的父级中,而且列表项的overflow被设置为hidden,这意味着a标签的一部分被裁切,所以为了确保a标签中的文字/图标出现在可见部分,我们将内容居中对齐。
使用到的数学知识:
旋转导航项到指定位置:角度y = i * x (i是第几项,x是圆心角的值)
按照90-x倾斜(x是圆心角的值)
如果要相对称反方向旋转导航项(这一步实际上和前一步合并)
“反向倾斜”“反向旋转”导航中的a标签(设置text-align为center)
其他不说了,贴上我的代码;
html源码:
b6a1
css源码:
最后提一下自己遇到的一个问题,就是我设置了li隐藏,因为它是绝对定位的,脱离了文档流,所以我想去除掉他的溢出,但是我没有实现到,可以用边框就能检验到,所以他依旧占着空间造成滚动条的出现,我是这样来解决的:
希望哪位牛人能有解决方法告诉我一声。如下图:
最后附上自己最终实现客户需要的效果:
制作的步骤:
1.我们需要将导航项绝对定位在容器里面
2.将每一项的变换原点设置成他们的右下角
3.然后往左上角平移导航项,让它们的变换原点和容器中心相吻合
4.然后按照公式顺时针旋转每一项到指定的位置:对于第i项,需要旋转:i*x,其中x是圆心角的值。
5.然后让它们变形以获取我们想要的圆心角(使用上面提到过的公式)。
6.反向倾斜a标签,意味着按列表项需要按相反的值倾斜, 然后用- [90 – (x/2) ]的值反向 旋转,x是圆心角的值。那么对于40度的圆心角,我们需要倾斜a标签-40度并且按-[ 90 – (40/2) ] = -70 度旋转。
a标签被绝对定位在它们的父级中,而且列表项的overflow被设置为hidden,这意味着a标签的一部分被裁切,所以为了确保a标签中的文字/图标出现在可见部分,我们将内容居中对齐。
使用到的数学知识:
旋转导航项到指定位置:角度y = i * x (i是第几项,x是圆心角的值)
按照90-x倾斜(x是圆心角的值)
如果要相对称反方向旋转导航项(这一步实际上和前一步合并)
“反向倾斜”“反向旋转”导航中的a标签(设置text-align为center)
其他不说了,贴上我的代码;
html源码:
<!doctype html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0" name="viewport" /> <title></title> <link rel="stylesheet" href="css/shouye.css"> </head> <body> <header id="header"> <ul> <li><a href="">我的朋友圈</a></li> <li><a href="">消息提醒<em>3</em></a></li> <li><a href="">佩戴天数<em>6</em></a></li> </ul> </header> <div class="logo"> <img src="img/logo.png" alt=""> </div> <div class="wrap"> <!-- 制作圆的外层导航 --> <div class="csstransforms"> <div class="cn-wrapper" id="cn-wrapper"> <ul> <li><a href="#"><span>血氧</span></a></li> <li><a href="#"><span>心率</span></a></li> <li><a href="#"><span>呼吸</span></a></li> <li><a href="#"><span>体温</span></a></li> <li><a href="#"><span>体重</span></a></li> <li><a href="#"><span>身高</span></a></li> <li><a href="#"><span>血压</span></a></li> <li><a href="#"><span>BMI</span></a></li> </ul> </div> </div> <!-- 制作圆的第二层导航 --> <div class="csstransforms2"> <div class="cn-wrapper2" id="cn-wrapper2"> <ul> <li><a href="#"><span>睡眠</span></a></li> <li><a href="#"><span>运动</span></a></li> <li><a href="#"><span>饮食</span></a></li> <li><a href="#"><span>情绪</span></a></li> </ul> </div> </div> <!-- 制作圆的最内层的logo --> <div class="lat"> <div class="img"> <img src="img/yuan.png" alt=""> </div> </div> </div> <!-- 遮罩层 --> <div id="cn-overlay" class="cn-overlay"></div> <footer id="footer"> <ul> <li><a href="">Life Watch</a></li> <li><a href="">天使服务</a></li> <li><a href="">SOS</a></li> <li><a href="">健康数据</a></li> <li><a href="">个人中心</a></li> </ul> </footer> </body> </html>
b6a1
css源码:
@charset 'ute-8'; *{ margin: 0; padding: 0; } li { list-style: none; } a { text-decoration: none; }
body { overflow-x: hidden; overflow-y: hidden;/* 禁止滚动条 */ }
/* header */ #header{ width: 100%; height: 50px; background-color: #3cb649; position: fixed; top:0; z-index: 9999; } #header li { width: 33.3%; height: 50px; line-height: 50px; float: left; text-align:center; } #header li:nth-child(3){ text-indent: 20px; } #header li a { display: block; color: #FFF; } #header li em { font-style: normal; position: relative; top: -4px; left: 2px; } /* end header */ /* logo */ .logo { width: 100%; height: 40px; position: fixed; top: 50px; background-color: #fff; } .logo img { display: block; width: 60%; position: relative; left: 18%; } /* end logo */ .csstransforms .cn-wrapper li, .csstransforms2 .cn-wrapper2 li { position: absolute; transform-origin: 100% 100%;/* 变形原点,bottom right | right bottom 等价于 100% 100% ,每一项的变换原点设置成他们的右下角*/ overflow: hidden; left: 40%; top:150px; } .csstransforms .cn-wrapper li a, .csstransforms2 .cn-wrapper2 li a { box-sizing: border-box;/* 为了设置内边距让字体居中一点的时候不会让圆变形 */ display: block; position: absolute; border-radius: 50%; text-decoration: none; color: #fff; text-align: center;/* 为了确保a标签中的文字/图标出现在可见部分,将内容居中对齐 */ transition: opacity 0.3s, color 0.3s; } .csstransforms .cn-wrapper li { font-size: 1.2em; width: 10em; height: 10em; margin-top: -1.3em; margin-left: -8em; } .csstransforms .cn-wrapper li a { font-size: 1.18em; height: 13em; width: 13em; bottom: -6.5em; right: -6.5em; transform: skew(-45deg) rotate(-68.5deg) scale(1);/* 反向倾斜a标签,意味着按列表项需要按相反的值倾斜, 然后用- [90 – (x/2) ]的值反向 旋转,x是圆心角的值。那么对于45度的圆心角,我们需要倾斜a标签-40度并且按-[ 90 – (40/2) ] = -68.5 度旋转 */ padding-top: 10px; } .csstransforms2 .cn-wrapper2 li { font-size: 1.3em; width: 6.5em; height: 6.5em; margin-top: 1.6em; margin-left: -4.7em; transition: border .3s ease; } .csstransforms2 .cn-wrapper2 li a { font-size: 1.18em; height: 8em; width: 8em; bottom: -4em; right: -4em; transform: rotate(-45deg) scale(1); padding-top: 15px; } /* 外圈旋转与倾斜 */ .csstransforms .cn-wrapper li:first-child { transform: skew(45deg);/* 90deg-xdeg, x是你想得到的圆心角的值。*/ } .csstransforms .cn-wrapper li:nth-child(2) { transform: rotate(45deg) skew(45deg); } .csstransforms .cn-wrapper li:nth-child(3) { transform: rotate(90deg) skew(45deg) } .csstransforms .cn-wrapper li:nth-child(4) { transform: rotate(135deg) skew(45deg); } .csstransforms .cn-wrapper li:nth-child(5) { transform: rotate(180deg) skew(45deg); } .csstransforms .cn-wrapper li:nth-child(6) { transform: rotate(225deg) skew(45deg); } .csstransforms .cn-wrapper li:nth-child(7) { transform: rotate(270deg) skew(45deg); } .csstransforms .cn-wrapper li:nth-child(8) { transform: rotate(315deg) skew(45deg); } /* 修改外圈背景颜色 */ .csstransforms .cn-wrapper li:nth-child(1) a { background-color: #70a4cc;/* 血氧 */ } .csstransforms .cn-wrapper li:nth-child(2) a { background-color: #0a71bc;/* 心率 */ } .csstransforms .cn-wrapper li:nth-child(3) a { background-color: #70a4cc;/* 呼吸 */ } .csstransforms .cn-wrapper li:nth-child(4) a { background-color: #0a71bc;/* 体温 */ } .csstransforms .cn-wrapper li:nth-child(5) a { background-color: #70a4cc;/* 体重 */ } .csstransforms .cn-wrapper li:nth-child(6) a { background-color: #0a71bc;/* 身高 */ } .csstransforms .cn-wrapper li:nth-child(7) a { background-color: #70a4cc;/* 血压 */ } .csstransforms .cn-wrapper li:nth-child(8) a { background-color: #0a71bc;/* BMI */ } /* 内圈旋转与倾斜 */ .csstransforms2 .cn-wrapper2 li:first-child { } .csstransforms2 .cn-wrapper2 li:nth-child(2) { transform: rotate(90deg); } .csstransforms2 .cn-wrapper2 li:nth-child(3) { transform: rotate(180deg); } .csstransforms2 .cn-wrapper2 li:nth-child(4) { transform: rotate(270deg); } /* 修改内圈背景颜色 */ .csstransforms2 .cn-wrapper2 li:nth-child(1) a { background-color: #70a4cc;/* 睡眠 */ } .csstransforms2 .cn-wrapper2 li:nth-child(2) a { background-color: #0a71bc;/* 运动 */ } .csstransforms2 .cn-wrapper2 li:nth-child(3) a { background-color: #70a4cc;/* 饮食 */ } .csstransforms2 .cn-wrapper2 li:nth-child(4) a { background-color: #0a71bc;/* 情绪 */ } /* 最里层 */ .lat { height: 5em; width: 5em; position: absolute; left: 41%; top: 285px; margin-top: -8px; margin-left: -6px; background-color: #0a71bc; border-radius: 50%; } .lat .img { height: 3em; width: 3em; margin: 4px 0 0 15px; } .lat img { display: block; width: 100%; } /* @media screen and (max-width:480px){ } */ @media screen and (max-width:320px){ .csstransforms .cn-wrapper li, .csstransforms2 .cn-wrapper2 li { left: 38%; top:100px; } .csstransforms .cn-wrapper li a { font-size: 1em; height: 12em; width: 12em; bottom: -6em; right: -6em; } .csstransforms2 .cn-wrapper2 li a { font-size: 1em; height: 7em; width: 7em; bottom: -3.5em; right: -3.5em; padding-top: 10px;/* 为了设置内边距的时候不会让圆变形 */ } .lat { height: 4em; width: 4em; left: 34%; top: 243px; margin-top: -8px; margin-left: 18px; } .lat .img { height: 2em; width: 2em; margin: 8px 0 0 15px; } .lat img { display: block; width: 100%; } } .cn-overlay{ width:100% height:100%; background-color: #eeedf3; position:fixed; top:0; left:0; bottom:0; right:0; transition: all .3s ease; z-index:-2; pointer-events:auto; opacity:0.8; } #footer { width: 100%; height: 40px; position: fixed; bottom: 0; background-color: #e7e7e7; } #footer li { height: 40px; line-height: 40px; float: left; text-align: center; } #footer li:first-child{ width: 26%; box-sizing: border-box; border-right: 1px solid #0e7a9e; } #footer li:nth-child(2){ width: 20%; } #footer li:nth-child(3){ width: 14%; height: 50px; border-radius: 50%; background-color: #3cb649; position: relative; top: -20px; } #footer li:nth-child(4){ width: 20%; box-sizing: border-box; border-right: 1px solid #0e7a9e; } #footer li:nth-child(5){ width: 20%; } #footer li a { color: #333; font-size: 14px; } #footer li:nth-child(3) a{ font-size: 20px; color: #daede9; }
最后提一下自己遇到的一个问题,就是我设置了li隐藏,因为它是绝对定位的,脱离了文档流,所以我想去除掉他的溢出,但是我没有实现到,可以用边框就能检验到,所以他依旧占着空间造成滚动条的出现,我是这样来解决的:
body { overflow-x: hidden; overflow-y: hidden;/* 禁止滚动条 */ }
希望哪位牛人能有解决方法告诉我一声。如下图:
最后附上自己最终实现客户需要的效果:
相关文章推荐
- css实现会折叠、展开的菜单导航栏效果
- 纯CSS实现菜单、导航栏的3D翻转动画效果
- css实现会折叠、展开的菜单导航栏效果
- CSS中使用text-transform实现首字母大写
- 使用XTablayout实现横向滑动菜单,可以设置文字下面导航栏的宽度
- 使用CSS创建Digg样式风格的导航栏或菜单
- css中使用ul li ul li ul li ul li 实现四层级联菜单
- CSS中使用text-transform实现首字母大写
- 简单 纯css 多级导航菜单 制作教程1 - 使用ul li 制作导航栏
- 使用CSS双层滑动门技术实现三态玻璃效果水平导航菜单
- javascript使用DOM模型和CSS实现菜单的折叠和展开
- 使用DIV+CSS实现下拉列表菜单
- 在Asp.Net 2.0中使用Css Tab Design样式美化菜单
- 在Asp.Net 2.0中使用Css Tab Design样式美化菜单
- 编写纯 CSS 弹出菜单的原理及实现 By shawl.qiu
- 使用CSS+JavaScript实现可拖动的窗口的源代码(推荐)
- 使用函数递归实现基于php和MySQL的动态树型菜单
- 使用struts-menu_详细(1)实现动态菜单
- 在Asp.Net 2.0中使用Css Tab Design样式美化菜单
- 在Asp.Net 2.0中使用Css Tab Design样式美化菜单