zoukankan      html  css  js  c++  java
  • CSS3制作旋转导航

    慕课网学习CSS3时,遇到个习题,觉得有必要总结学习下:CSS3制作旋转导航

    慕课网习题地址:http://www.imooc.com/code/1883

    示例及源码地址:http://codepen.io/airen/pen/icFba

    老师的源代码内容太多,太复杂,也没有逻辑讲解,所以我就从头捡重点,一边写,一边分析,并且去掉了兼容性,这样看起来简单,所以下面的代码都是在谷歌浏览器才可以适用的,尤其是CSS3部分!看目标效果图:

    image

    总结下要点:

    1、特殊的字体样式

    2、在鼠标移入时,

    1)改变了背景色

    2)出现了3D旋转

    3)出现了下边框

    3、这个情况

    image

    我觉得这里的核心应该是3D旋转,所以我的思路是:

    1、在鼠标滑过时

    1)实现单个 li 的3D旋转

    2)实现单个 li 下边框

    3)实现单个 li 背景颜色改变

    2、考虑全局布局

    3、考虑 Blog 下的特殊情况

    那么好,思路有了,咱么来考虑这个单个 li 的3D旋转,不过在这之前先把静态页面写好(自己写哦,可以参考老师的嘛),Open-mouthed smile,做个小的 li ,代码如下:

    body:

    <body>    
        <ul class="nav-menu">
            <li class="three-d-box"> 
                <a href="#" class="cont">Home</a>    
                <a href="#" class="front">Home</a>            
                <a href="#" class="back">Home</a>                
            </li>
            <li class="three-d-box"> 
                <a href="#" class="cont">Html</a>    
                <a href="#" class="front">Html</a>            
                <a href="#" class="back">Html</a>    
            </li>            
        </ul>    
    </body>

    css:

           * {
                padding: 0;
                margin: 0;
            }
            body {
                padding: 20px;
            }
            .nav-menu {
                background-color: #74adaa;
                 950px;            
                height: 50px;            
                margin: 0 auto;                            
            }
            .three-d-box {
                display: inline-block;            
                position: relative;        
                padding: 0 20px;            
                list-style-type: none;                
            }        
            .three-d-box a {
                display: inline-block;
                 100%;
                height: 100%;
                text-align: center;
                line-height: 50px;            
                font-size: 25px;
                color: white;
                text-decoration: none;
                background-color: #74adaa;                
            }
            .three-d-box .cont {
                color: #74adaa;
            }
            .three-d-box .front,
            .three-d-box .back {
                position: absolute;
                left: 0;
                top: 0;            
                border-right: 1px solid #94c0be;
            }

    这个大家问题应该不大,看看老师源码应该能明白,这只是静态页面!

    image

    这里可能需要解释下,为什么要用3个 a 标签,

    <a href="#" class="cont">Home</a>
    <a href="#" class="front">Home</a>
    <a href="#" class="back">Home</a>
    因为,这里至少要有两个 a ,用来翻转实现 3D 旋转,一前一后(front , back),这个大家应该明白,所以有了两个 a 标签,但是静态页面上,我们只看到一个,结合旋转效果可以发现,这里的多个 a 标签肯定是在同一个位置的,而且是重合的,所以这里在静态页面上实现,就要给 a 标签 absolute 一下,然后 left & top 肯定为 0;但是这样的话,会出错,因为 li 的内容不一定,导航条可长可短,所以每个 li 的长度应该是自适应内容的,所以宽度不能设置,而 li 里面的 a 又是 absolute ,所以这里 li 与 li 之间就会有各种问题,我不知道你是什么问题,我是这样的,当然一开始也有其他样式的,十分奇怪,

    image

    所以最后就想了办法,再加一个内容一模一样的 a 标签,className 为 cont ,解决了上述问题,所以你也看到 front 和 back 都做了 absolute 定位和 cont 重合,但是 cont 没有 absolute ,为的是根据导航 li 的长度自适应宽度,好,静态页面完成,看旋转!

    1、在鼠标滑过时

    1)实现单个 li 的3D旋转

    首先要搞明白,这个3D旋转是怎么实现的 ,把老师的源码旋转速度降到 3秒 之后,我看了好些遍,终于明白了,原理是这样:上图!

    一开始是这样,也就是静态页面,.front & .back 通过定位实现重合:

    image

    放到坐标系就是这样,你看到的就是XY对应浏览器宽高这一面;

    image

    然后,要实现旋转效果需要把静态页面做成这样,当鼠标滑过时, 让 .front 和 .back 这个整体(也就是包裹他两的父元素)顺时针翻转90度(transform: rotateX(90deg)),这样,眼睛会看到 front 从正前方翻过去,. back 从下方翻上来 ; 滑出时,回到原位(即逆时针翻转90度) ;这样就实现了3d 旋转动画!!!听不懂?看图!

    静态页面要做成这样:(请忽略此处O)

    image

    鼠标滑过,包裹他俩的父元素,顺时针翻转90度 ,翻到这样:(请忽略此处O)

    image

    能明白么?不明白好好想想~~~;或者看看下图:

    3D 旋转的时候,其实是在旋转 .front 和 .back 的父元素 ( 即 li :这个时候,li 的中心点应该 在L处,所以上述的变化,就是把这半个长方体,以 L 为原点,立体 顺时针 旋转 90 度。再想想~~

    从这样:(请忽略此处O)

    image

    翻成这样:

    image

    所以,我们的主要任务就是要把静态页面做好,然后把 li transform:rotateX(90deg) 就好了,难点在静态页面!当然还有这个思路!

    放在坐标轴里,我们要把静态页面改成这样就可以了:(请忽略此处O)

    image

    然而我们之前做的页面把 .front 和 .back 是放在这里的,如下图:

    image

    两张图一看,大家有思路了嘛?

    说之前,先确定这里元素的原点:

    注意,原点是居于元素X轴和Y轴的50%处,即O点,CSS变形进行的旋转、位移、缩放,扭曲等操作都是在原点O的基础上进行的;所以我们要在此基础上,完成上面两张图的转换,对,这是在 3d 动态

    旋转 变换之前就要做好的;这里的O点既是 .front 和 .back的原点,也是 他们的父元素 li 的原点。

    image

    然后我们的思路就是:

    先把 .back 绕X轴 逆时针旋转90度transform: rotateX(-90deg)

    image

    然后.back 沿着自身的Z轴(因为之前已经翻转过一次了,所以现在 .back 的Z轴 在图中就是Y轴(我猜的!!!))下移25px , transform: rotateX(-90deg) translateZ(25px);就是这样:

    image

    最后再把 .front 向用户正对面移动 25px 就可以了,即 transform: rotateX(0deg) translateZ(25px);

    image

    此时看看 .front 和 .back 的父元素(li)的 原点 L,还在原位置 ,但是 .front 和 .back都移到位了,而 L 正好在这个半长方体中间,所以,把 li 沿着X轴顺时针翻转90度,就是我们要的 3D 旋转!

    image

    上述代码放一起就这些:

            .three-d-box .front {
                height: 49px;
            }
            .three-d-box .front {
                -webkit-transform: rotateX(0deg) translateZ(25px);
                border-bottom: 1px solid #94c0be;            
            }
            .three-d-box .back {
                -webkit-transform: rotateX(-90deg) translateZ(25px) ;
                /* 面对浏览器,translateX(5px)往右5px,translateY(5px)往下5px,translateZ(5px)正对用户5px */
            }
            /* 准备翻转three-d-box
                鼠标滑过时 */
            .three-d-box:hover {
                -webkit-transform: rotateX(90deg);
            }
                /* 规定动画效果是3D和动画时间 */
            .three-d-box {
                -webkit-transform-style: preserve-3d;
                -webkit-transition: all 4s ease;
            }

    好了,核心3D旋转就说完了~~~接着看思路:

    1、在鼠标滑过时

    1)实现单个 li 的3D旋转(已实现)

    2)实现单个 li 下边框(已实现)

    3)实现单个 li 背景颜色改变(未实现)

    那么好,我们来改变 li 的背景颜色,感觉这个很简单,摆代码之前发现这个小问题,我们的 li 中间有个外边距,效果图没有,那么好,我们把 父层 li 的margin 改下;

    imageimage

    就加个margin-right: -7px;    其他的没动,这下就好了;

    .three-d-box {
                display: inline-block;            
                position: relative;        
                padding: 0 20px;            
                list-style-type: none;    
                margin-right: -7px;        
            }

    改鼠标移入时背景颜色:

            .three-d-box:hover .front,
            .three-d-box:hover .back {
                background-color: #51938f;
                background-image: -webkit-linear-gradient(45deg, #478480 25%, transparent 25%, transparent 75%, #478480 75%, #478480), linear-gradient(45deg, #478480 25%, transparent 25%, transparent 75%, #478480 75%, #478480);
                -webkit-background-size: 5px 5px;
            }

    这个地方看不懂呢,可以三条样式一个个放,先放第一个,再放第二个,再放第三个,就很清楚了,其实就是,先加背景色,然后加背景图片,因为背景图片太大了,把背景图片尺寸变小;

    至于默认的 HOME 的样式,就给 HOME li 加个className 就好了,比方加个 active , 样式里也加下,就变成这样:

            .three-d-box:hover .front,
            .three-d-box:hover .back,
            .active .front,
            .active .back {
                background-color: #51938f;
                background-image: -webkit-linear-gradient(45deg, #478480 25%, transparent 25%, transparent 75%, #478480 75%, #478480), linear-gradient(45deg, #478480 25%, transparent 25%, transparent 75%, #478480 75%, #478480);
                -webkit-background-size: 5px 5px;
            }

    className 也要加哦:

            <li class="three-d-box active"> 
                <a href="#" class="cont">Home</a>    
                <a href="#" class="front">Home</a>                
                <a href="#" class="back">Home</a>                
            </li>

    好了,这下进行第二步:

    1、在鼠标滑过时(已实现)

    1)实现单个 li 的3D旋转(已实现)

    2)实现单个 li 下边框(已实现)

    3)实现单个 li 背景颜色改变(已实现)

    2、考虑全局布局(未实现)

    把第一个做好的 li 复制几个就好了,注意去掉 active ,复制好了,可能会这样:

    image

    那么就把字体调小点就可以了,我是改成了 24px ,当然你也可以把 ul 改长点;

    那么好,现在就进行第三步了:

    1、在鼠标滑过时(已实现)

    1)实现单个 li 的3D旋转(已实现)

    2)实现单个 li 下边框(已实现)

    3)实现单个 li 背景颜色改变(已实现)

    2、考虑全局布局(已实现)

    3、考虑 Blog 下的特殊情况(未实现)

    当我们在 Blog 下放上 明细的代码时,其实也就是这样,

            <li class="three-d-box"> 
                <a href="#" class="cont">Blog</a>    
                <a href="#" class="front">Blog</a>                
                <a href="#" class="back">Blog</a>
                <ul class="dropMenu">
                    <li class="three-d-box">
                        <a href="#" class="cont">Html5</a>
                        <a href="#" class="front">Html5</a>
                        <a href="#" class="back">Html5</a>
                    </li>
                    <li class="three-d-box">
                        <a href="#" class="cont">Css3</a>
                        <a href="#" class="front">Css3</a>
                        <a href="#" class="back">Css3</a>
                    </li>
                    <li class="three-d-box">
                        <a href="#" class="cont">Javascript</a>
                        <a href="#" class="front">Javascript</a>
                        <a href="#" class="back">Javascript</a>
                    </li>
                </ul>                
            </li>

    然后调整下格式:

            .dropMenu {
            position: absolute;        
            left: 0;        
            }        
            .dropMenu .three-d-box {
                 100%;
            }

    结果就发现这样了:

    image

    然后当我们鼠标移上时,就这样: 
    image

    我们看效果图:下拉菜单 和 Blog 应该在两个元素内部,所以 Blog 的父元素 3D 翻转时,下拉菜单的父元素并没有翻转,而是 变长显示了出来,所以这个时候,应该是 横向导航里 li 里面有两个元

    素,一个包裹了 Blog ,包括里面的三个 a, 一个包裹了下拉菜单 ul 及其内容。

    imageimage

    原来的结构:

            <li class="three-d-box"> 
                <a href="#" class="cont">Blog</a>    
                <a href="#" class="front">Blog</a>                
                <a href="#" class="back">Blog</a>
                <ul class="dropMenu">
                    <li class="three-d-box">
                        <a href="#" class="cont">Html5</a>
                        <a href="#" class="front">Html5</a>
                        <a href="#" class="back">Html5</a>
                    </li>
                    <li class="three-d-box">
                        <a href="#" class="cont">Css3</a>
                        <a href="#" class="front">Css3</a>
                        <a href="#" class="back">Css3</a>
                    </li>
                    <li class="three-d-box">
                        <a href="#" class="cont">Javascript</a>
                        <a href="#" class="front">Javascript</a>
                        <a href="#" class="back">Javascript</a>
                    </li>
                </ul>                
            </li>


    为了方便起见,现在我们给这个 li 改下结构,把 Blog 和 下拉菜单分别包裹在不同的元素内: 

            <li> 
                <a href="#" class="three-d-box">
                    <span href="#" class="cont">Blog</span>    
                    <span href="#" class="front">Blog</span>                
                    <span href="#" class="back">Blog</span>
                </a>            
                <ul class="dropMenu">
                    <li>
                        <a href="#" class="three-d-box">
                            <span href="#" class="cont">Html5</span>    
                            <span href="#" class="front">Html5</span>                
                            <span href="#" class="back">Html5</span>
                        </a>                    
                    </li>                
                    <li>
                        <a href="#" class="three-d-box">
                            <span href="#" class="cont">Css3</span>    
                            <span href="#" class="front">Css3</span>                
                            <span href="#" class="back">Css3</span>
                        </a>                    
                    </li>
                    <li>
                        <a href="#" class="three-d-box">
                            <span href="#" class="cont">Javascript</span>    
                            <span href="#" class="front">Javascript</span>                
                            <span href="#" class="back">Javascript</span>
                        </a>                    
                    </li>                
                </ul>                
            </li>

    能明白么?现在咱们把所有代码和样式都改下:

    <style>
        /* 基本样式 */
            * {
                padding: 0;
                margin: 0;
            }
            body {
                padding: 20px;
            }
            .navMenu {
                background-color: #74adaa;
                 950px;            
                height: 50px;            
                margin: 0 auto;                            
            }
            .navMenu>li {
                display: inline-block;    
                list-style-type: none;        
                margin-right: -7px;                                
            }        
            .navMenu li a {
                 100%;
                height: 100%;
                display: block;
                line-height: 50px;            
                font-size: 20px;
                color: white;
                text-decoration: none;
                text-align: center;                        
            }
            .three-d-box {                                    
                position: relative;                        
            }
            .three-d-box .cont {
                display: block;
                color: #74adaa;
                padding: 0 30px;
                height: 50px;
            }                            
            .three-d-box .front,
            .three-d-box .back {            
                display: block;
                 100%;
                height: 100%;            
                position: absolute;            
                left: 0;
                top: 0;            
                border-right: 1px solid #94c0be;
                background-color: #74adaa;
            }
            /* 3d旋转准备样式 */
            .three-d-box .front {
                height: 49px;
            }
            .three-d-box .front {
                -webkit-transform: rotateX(0deg) translateZ(25px);
                border-bottom: 1px solid #94c0be;            
            }
            .three-d-box .back {
                -webkit-transform: rotateX(-90deg) translateZ(25px) ;
                /* 面对浏览器,translateX(5px)往右5px,translateY(5px)往下5px,translateZ(5px)正对用户5px */
    
            }
            /* 准备翻转three-d-box
                鼠标滑过时 */
            .three-d-box:hover,
            .three-d-box:focus {
                -webkit-transform: rotateX(90deg);
            }
            .three-d-box:hover .front,
            .three-d-box:hover .back,
            .active .front,
            .active .back {
                background-color: #51938f;
                background-image: -webkit-linear-gradient(45deg, #478480 25%, transparent 25%, transparent 75%, #478480 75%, #478480), linear-gradient(45deg, #478480 25%, transparent 25%, transparent 75%, #478480 75%, #478480);
                -webkit-background-size: 5px 5px;
            }
                /* 鼠标移出时 */        
            .three-d-box {            
                -webkit-transform-style: preserve-3d;
                -webkit-transition: all 1s ease;
            }
            .dropMenu {
                position: absolute;        
                top: 70px;    
                background-color: #74adaa;    
            }        
            .dropMenu li a {
                 100%;
            }    
            .dropMenu li {            
                list-style-type: none;
                height: 0;        
                -webkit-transform: rotateX(90deg);    
                -webkit-transition: all 4s ease;
            }    
            .navMenu>li:hover .dropMenu li {
                -webkit-transform: rotateX(0deg);
                height: 50px;
            }            
        </style>

    body:

    <body>    
        <ul class="navMenu">
            <li>            
                <a href="#" class="three-d-box active">    
                    <span href="#" class="cont">Home</span>            
                    <span href="#" class="front">Home</span>                
                    <span href="#" class="back">Home</span>
                </a>
            </li>        
            <li> 
                <a href="#" class="three-d-box">
                    <span href="#" class="cont">Service</span>    
                    <span href="#" class="front">Service</span>                
                    <span href="#" class="back">Service</span>
                </a>
            </li>
            <li> 
                <a href="#" class="three-d-box">
                    <span href="#" class="cont">Products</span>    
                    <span href="#" class="front">Products</span>                
                    <span href="#" class="back">Products</span>
                </a>
            </li>
            <li> 
                <a href="#" class="three-d-box">
                    <span href="#" class="cont">About</span>    
                    <span href="#" class="front">About</span>                
                    <span href="#" class="back">About</span>
                </a>
            </li>
            <li> 
                <a href="#" class="three-d-box">
                    <span href="#" class="cont">Contact</span>    
                    <span href="#" class="front">Contact</span>                
                    <span href="#" class="back">Contact</span>
                </a>
            </li>            
            <li> 
                <a href="#" class="three-d-box">
                    <span href="#" class="cont">Blog</span>    
                    <span href="#" class="front">Blog</span>                
                    <span href="#" class="back">Blog</span>
                </a>            
                <ul class="dropMenu">
                    <li>
                        <a href="#" class="three-d-box">
                            <span href="#" class="cont">Html5</span>    
                            <span href="#" class="front">Html5</span>                
                            <span href="#" class="back">Html5</span>
                        </a>                    
                    </li>                
                    <li>
                        <a href="#" class="three-d-box">
                            <span href="#" class="cont">Css3</span>    
                            <span href="#" class="front">Css3</span>                
                            <span href="#" class="back">Css3</span>
                        </a>                    
                    </li>
                    <li>
                        <a href="#" class="three-d-box">
                            <span href="#" class="cont">Javascript</span>    
                            <span href="#" class="front">Javascript</span>                
                            <span href="#" class="back">Javascript</span>
                        </a>                    
                    </li>    
                    <li>
                        <a href="#" class="three-d-box">
                            <span href="#" class="cont">Videogames</span>    
                            <span href="#" class="front">Videogamess</span>                
                            <span href="#" class="back">Videogamess</span>
                        </a>                    
                    </li>            
                </ul>                
            </li>
            <li> 
                <a href="#" class="three-d-box">
                    <span href="#" class="cont">Shop On-Line</span>    
                    <span href="#" class="front">Shop On-Line</span>                
                    <span href="#" class="back">Shop On-Line</span>
                </a>
            </li>                
        </ul>    
    </body>

    样式里最后几行就是处理 Blog 下的特殊情况的,太累了,不写了,自己看代码,不懂再问我,,,

    原理就是:一开始,将 .dropMenu 下的 li 高度设为0且 顺时针旋转90度,这样用户就看不到了呀,鼠标滑过时,再将高度设为 50px , 不旋转,就回来了呀,,,

    欢迎拍砖留言。。。

  • 相关阅读:
    食谱
    食谱
    食谱
    无题
    重要通知
    幼儿食谱
    安卓应用开发常用代码
    安卓开发环境搭建
    《浪潮之巅》读书笔记——第11章 摩托罗拉
    预制redis数据
  • 原文地址:https://www.cnblogs.com/xianshenglu/p/8401181.html
Copyright © 2011-2022 走看看