transform,transition,animation的混合使用——高手

每個(gè)制作出來(lái)的css3動(dòng)畫(huà)都凝結(jié)了設(shè)計(jì)者和創(chuàng)作者智慧的結(jié)晶,以此,我們要向前輩致敬;動(dòng)畫(huà)的出現(xiàn)給單調(diào)的網(wǎng)頁(yè)平添了活性,是單純的展示頁(yè)面變得不再那么枯燥,所以,作為一個(gè)web前端的開(kāi)發(fā)者能夠創(chuàng)作出屬于自己的特有的動(dòng)畫(huà),我感到很高興。

今天,我向大家介紹實(shí)現(xiàn)css下拉菜單的動(dòng)畫(huà)制作的不同方法,希望能給大家有所幫助和啟示。首先,先來(lái)個(gè)效果圖給大家看一看:


鼠標(biāo)滑過(guò)--下拉菜單動(dòng)畫(huà)
單擊--下拉菜單動(dòng)畫(huà)

那么接下來(lái)我就給大家介紹一下這個(gè)動(dòng)畫(huà)的組成,它主要包括三個(gè)小動(dòng)畫(huà)組成。第一部分就是鼠標(biāo)的滑過(guò)的漸變動(dòng)畫(huà);第二部分,就是右邊的三角小箭頭的動(dòng)畫(huà),這個(gè)說(shuō)起來(lái)也很簡(jiǎn)單,這個(gè)三角形是使用css樣式寫(xiě)的控制元素的四條邊的顏色和各邊的顯隱來(lái)形成;第三部分,就是展開(kāi)的下拉框。

根據(jù)我之前寫(xiě)過(guò)的一篇文章《transform,transition,animation的混合使用——進(jìn)階》中對(duì)動(dòng)畫(huà)的組合形式的分類,將動(dòng)畫(huà)的實(shí)現(xiàn)分類有transform和transition組合,transform和animation組合,再結(jié)合動(dòng)畫(huà)的觸發(fā)形式,pc端常見(jiàn)的鼠標(biāo)滑過(guò)、鼠標(biāo)單擊,wap端的觸摸形式,該動(dòng)畫(huà)的最終的呈現(xiàn)形式將以下四種常見(jiàn)形式:
第一種,實(shí)現(xiàn)方案用transition(鼠標(biāo)滑過(guò))
第二種,實(shí)現(xiàn)方案用animation(鼠標(biāo)滑過(guò))
第三種,實(shí)現(xiàn)方案用transition(鼠標(biāo)單擊或觸摸)
第四種,實(shí)現(xiàn)方案用animation(鼠標(biāo)單擊或觸摸)

我將詳細(xì)講解前兩種的實(shí)現(xiàn),后兩種的實(shí)現(xiàn)(略講),由于是觸發(fā)方式的改變,所以對(duì)于javascript有一定使用經(jīng)驗(yàn)的同學(xué)將會(huì)根據(jù)自己的使用習(xí)慣很容易的形成自己所需要的代碼,進(jìn)而形成自己的css動(dòng)畫(huà)下拉菜單的解決方案。

鼠標(biāo)滑過(guò)--下拉菜單動(dòng)畫(huà)

transition和transform組合
html代碼:

<div class="l-drop-menu l-menu-1">
        <span>下拉菜單</span>
        <ul class="l-list">
            <li class="l-list-item"><a >百度一下</a></li>
            <li class="l-list-item"><a >bing搜索</a></li>
            <li class="l-list-item"><a >iconfont</a></li>
        </ul>
    </div>

css代碼:

.l-list {
    position: absolute;
    top: 100%;
    z-index: -1;
    width: 100%;
    padding: 4px 0;
    background-color: #fff;
    border: 1px solid #cecece;
    box-sizing: border-box;
    opacity: 0;
}

.l-list-item {
    list-style: none;
    padding: 4px 8px;
}

.l-list-item a {
    display: block;
    padding: 4px 0;
    font-size: 16px;
    color: #000;
    text-align: center;
    text-decoration: none;
    transition: all 0.2s linear;
}

.l-list-item a:hover {
    color: #fff;
    background-color: #cecece;
}

.l-drop-menu {
    position: relative;
    width: 142px;
    height: auto;
    margin: 0 auto;
}

.l-drop-menu>span {
    position: relative;
    display: block;
    padding: 8px 20px;
    text-align: center;
    color: #58a;
    background-color: #fff;
    cursor: pointer;
}

.l-drop-menu>span::after {
    position: absolute;
    top: 8px;
    right: 16px;
    content: '';
    width: 0;
    height: 0;
    overflow: hidden;
    border-width: 8px;
    border-style: dashed dashed solid;
    border-color: transparent transparent #c2c2c2;
    transition: all 0.3s linear;
}

.l-drop-menu>span:hover {
    color: #fff;
    background-color: #cecece;
}

.l-drop-menu>span:hover::after {
    top: 16px;
    border-style: solid dashed dashed;
    border-color: #ffffff transparent transparent;
}

以上是animation和transition兩種不同實(shí)現(xiàn)形式的公用代碼。

transiton實(shí)現(xiàn)形式的代碼

.l-menu-1 .l-list {
     transform: translate3d(0, 10px, 0);
    backface-visibility: hidden;
    transition: all 0.3s linear;
}

.l-menu-1:hover .l-list {
    z-index: 2;
    overflow: auto;
    opacity: 1;
    transform: translate3d(0, 0, 0);
}

animation實(shí)現(xiàn)形式的css代碼

.l-menu-2 .l-list{
    animation: l-animation-up 0.5s;
}

.l-menu-2:hover .l-list{
    z-index: 2;
    opacity: 1;
    animation: l-animation-down 0.5s;
}

@-webkit-keyframes l-animation-down {
    from {
        -webkit-transform: translate3d(0, 10px, 0);
        opacity: .1
    }
    to {
        -webkit-transform: translate3d(0, 0, 0);
        opacity: 1
    }
}

@keyframes l-animation-down {
    from {
        transform: translate3d(0, 10px, 0);
        opacity: .1
    }
    to {
        transform: translate3d(0, 0, 0);
        opacity: 1
    }
}

@-webkit-keyframes l-animation-up {
    from {
        -webkit-transform: translate3d(0, 0, 0);
        opacity: 1
    }
    to {
        -webkit-transform: translate3d(0, 10px, 0);
        opacity: .1
    }
}

@keyframes l-animation-up {
    from {
        transform: translate3d(0, 0, 0);
        opacity: 1
    }
    to {
        transform: translate3d(0, 10px, 0);
        opacity: .1
    }
}

代碼曬完了,我們就來(lái)說(shuō)一說(shuō)做這個(gè)動(dòng)畫(huà)的注意點(diǎn)吧!

1.第一種用transition和transform的形式,下拉框我們通常的實(shí)現(xiàn)形式通過(guò)定位來(lái)實(shí)現(xiàn),本案例的實(shí)現(xiàn)形式和傳統(tǒng)的實(shí)現(xiàn)形式并無(wú)二樣;
2.第一種用transition和transform的形式,我們傳統(tǒng)的控制顯隱我們使用的是display:none,display:block;但明顯這種方案用在這里不合適,使用這種解決方案的結(jié)果就是沒(méi)用過(guò)渡效果,也即是沒(méi)有了動(dòng)畫(huà)效果,我采用了opacity和z-index來(lái)解決這種問(wèn)題(詳情查看和分析代碼);
3.第二種用animation和transform的形式,這種實(shí)現(xiàn)形式我相信大家在學(xué)習(xí)和工作中都看過(guò),但這種形式要實(shí)現(xiàn)的動(dòng)畫(huà)效果和第一種之間,我覺(jué)得地址用實(shí)現(xiàn)形式更好,因?yàn)檫@個(gè)第二種,只有展開(kāi)時(shí)的過(guò)渡效果,而沒(méi)有閉合時(shí)的過(guò)渡效果,對(duì)于要求并不高的同學(xué)來(lái)說(shuō),或許這樣的效果還不錯(cuò),但是對(duì)于我這種追求極客的來(lái)說(shuō),我還是不滿足,所以,我就試著有加入了一個(gè)移開(kāi)時(shí)的動(dòng)畫(huà),實(shí)現(xiàn)了跟第一種一樣的動(dòng)畫(huà)效果(有一個(gè)刷新頁(yè)面的問(wèn)題),但我要接著說(shuō)的是在第二點(diǎn)中我有提過(guò)有opacity和z-index解決transition形式動(dòng)畫(huà)沒(méi)有過(guò)渡的情況,在第二種形式,display:none,display:block這種控制顯隱的方式也可用。

animation和transition對(duì)比以及animation的刷新問(wèn)題效果圖

綜上,下拉菜單動(dòng)畫(huà)最優(yōu)選擇第一種,其次,選擇第二種。

演示地址:https://lvzhenbang.github.io/css3-animate/drop-menu-anim.html

單擊--下拉菜單動(dòng)畫(huà)

單擊的動(dòng)畫(huà)和鼠標(biāo)滑過(guò)的動(dòng)畫(huà)效果區(qū)別就是觸發(fā)形式的不同,從而造成了css代碼的相應(yīng)差異,transition通過(guò)單擊實(shí)現(xiàn)就是通過(guò)改變?cè)谠刂刑砑?l-menu-active來(lái)實(shí)現(xiàn);animation通過(guò)單擊實(shí)現(xiàn)就是通過(guò)在元素中添加.l-menu-in, .l-menu-out來(lái)實(shí)現(xiàn)的。

html代碼同上

css代碼 公用和上面兩個(gè)例子重合的代碼如下:

.l-list {
    position: absolute;
    top: 100%;
    display: none;
    width: 100%;
    background-color: #fff;
    box-sizing: border-box;
}

.l-list-item {
    list-style: none;
    padding: 4px 8px;
    border-top: 1px solid #cecece;
}

.l-list-item a {
    display: block;
    padding: 4px 0;
    font-size: 16px;
    color: #000;
    text-align: center;
    text-decoration: none;
    -webkit-transition: all 0.2s linear;
}

.l-list-item a:hover {
    color: #fff;
    background-color: #cecece;
}

.l-drop-menu {
    position: relative;
    width: 142px;
    height: auto;
    margin: 0 auto;
}

.l-drop-menu>span {
    position: relative;
    display: block;
    padding: 10px 20px;
    text-align: center;
    color: #58a;
    background-color: #fff;
    cursor: pointer;
}

.l-drop-menu>span::after {
    position: absolute;
    top: 16px;
    right: 16px;
    content: '';
    width: 0;
    height: 0;
    overflow: hidden;
    border-width: 8px;
    border-style: solid dashed dashed;
    border-color: #58a transparent transparent;
    -webkit-transition: all 0.3s linear;
    transition: all 0.3s linear;
}

transition實(shí)現(xiàn)的代碼:

.l-drop-menu.l-menu-active>span, .l-drop-menu.l-menu-in>span {
    color: #fff;
    background-color: #cecece;
}

.l-drop-menu.l-menu-active>span::after, .l-drop-menu.l-menu-in>span::after {
    top: 8px;
    border-style: dashed dashed solid;
    border-color: transparent transparent #58a;
}

.l-menu-1.l-menu-active .l-list {
    display: block;
    -webki-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
}

.l-menu-1 .l-list {
    -webkit-transform: translate3d(0, 10px, 0);
    transform: translate3d(0, 10px, 0);
    -webkit-transition: all 0.3s linear;
    transition: all 0.3s linear;
}

animation的代碼:

.l-menu-2.l-menu-out .l-list {
    display: none;
    -webkit-animation: l-animation-up 0.5s;
    animation: l-animation-up 0.5s;
}

.l-menu-2.l-menu-in .l-list {
    display: block;
    -webkit-animation: l-animation-down 0.5s;
    animation: l-animation-down 0.5s;
}

@-webkit-keyframes l-animation-down {
    from {
        -webkit-transform: translate3d(0, 10px, 0);
    }
    to {
        -webkit-transform: translate3d(0, 0, 0);
    }
}

@keyframes l-animation-down {
    from {
        transform: translate3d(0, 10px, 0);
    }
    to {
        transform: translate3d(0, 0, 0);
    }
}

@-webkit-keyframes l-animation-up {
    from {
        -webkit-transform: translate3d(0, 0, 0);
    }
    to {
        -webkit-transform: translate3d(0, 10px, 0);
    }
}

@keyframes l-animation-up {
    from {
        transform: translate3d(0, 0, 0);
    }
    to {
        transform: translate3d(0, 10px, 0);
    }
}

綜上,你會(huì)發(fā)現(xiàn)transition實(shí)現(xiàn)的動(dòng)畫(huà),當(dāng)你單擊時(shí)發(fā)現(xiàn)動(dòng)畫(huà)用display:none,display:block;這種方式依然不能達(dá)到預(yù)期的效果,所以還是應(yīng)該采用opacity和z-index的方案;但是使用animation測(cè)沒(méi)有任何問(wèn)題,與此同時(shí)當(dāng)你刷新網(wǎng)頁(yè)時(shí),不會(huì)出現(xiàn)問(wèn)題。

所以,當(dāng)單擊實(shí)現(xiàn)下拉菜單這兩種方案都不錯(cuò),但是理解起來(lái)相對(duì)簡(jiǎn)單的是animation的形式。

單擊--下拉菜單動(dòng)畫(huà)(左邊是使用display:none,display:block)

關(guān)于如何改transition的單擊實(shí)現(xiàn)方案,各位同學(xué)可以當(dāng)作一個(gè)小例子來(lái)實(shí)踐一下。

transition的js代碼:

var menu1 = document.getElementsByClassName('l-menu-1')[0];

menu1.onclick = function() {
    var className = menu1.className;
    if (~className.indexOf('l-menu-active')) {
        menu1.className = className.replace(' l-menu-active', '');
    } else {
        menu1.className += ' l-menu-active';
    }
}

animation的js代碼:

var menu2 = document.getElementsByClassName('l-menu-2')[0];
menu2.onclick = function() {
    var className = menu2.className;
    if (~className.indexOf('l-menu-in')) {
        menu2.className = className.replace('l-menu-in', 'l-menu-out');
    } else {
        menu2.className += ' l-menu-in';
    }
}

演示地址:https://lvzhenbang.github.io/css3-animate/drop-menu-anim2.html

源代碼下載地址:github地址:https://github.com/lvzhenbang/css3-animate/tree/gh-pages

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容