CSS 下拉框特效

demo.gif

想要制作这么一个效果还是比较麻烦的,但是代码并不难理解。首先,来看看 Html 代码。

<div class="container">
    <div class="heading">
        <h2>Custom Select</h2>
    </div>

    <div class="select">
        <p>Please select</p>
        <ul>
            <li data-value="HTML5">HTML5</li>
            <li data-value="CSS3">CSS3</li>
            <li data-value="JavaScript">JavaScript</li>
            <li data-value="JQuery">JQuery</li>
            <li data-value="Backbone">Backbone</li>
        </ul>
    </div>
</div>

可见,我们并没有利用原生的 select 元素,而是利用其它元素来模拟这个效果。我们为 li 元素指定了 data-value,主要是接下来我们会用 JQuery 获取选中值并将其放置到 p 元素下。

下面逐步来看 CSS 代码。

    * {
        margin: 0;
        padding: 0;
    }

    html {
        font-family: 'Terminal';
        font-size: 62.5%;
    }

    body {
        background-color: #33CC66;
    }
  1. 将网页中所有元素的外边距和内边距设置为 0
  2. 将网页中的默认字体设置为 Terminal,字体大小设置为 62.5%, 也就是 10px
  3. 设置背景颜色为 #33CC66
 <link href='http://fonts.googleapis.com/css?family=Lobster|Terminal+Dosis' rel='stylesheet' type='text/css'>

上面我们用到了 Terminal 字体,而且接下来我们还会使用 Lobster 字体,所以用这行代码添加引用。

    .heading, .select {
        display: block;
        width: 22rem;
        margin: 0 auto;
        text-align: center;
    }

    .heading {
        width: 28rem;
        margin-top: 10rem;
        margin-bottom: 2rem;
    }

    .heading h2 {
        font-size: 6rem;
        font-family: 'Lobster';
        color: #ffffff;
    }
  1. 指定 headng, select 宽度并指定其水平居中。
  2. 修改 heading 的宽度,主要是为了让其宽度大于 select 的宽度,显得更加美观。然后指定其上外边距和下外边距。
  3. 设置 headingh2 元素的字体和字体大小,颜色。
.select > p, .select ul {
        background-color: #ffffff;
        font-size: 2rem;
        border: 1px solid bisque;
        border-radius: 5px;
        margin-bottom: 0;
    }

.select > p {
        text-align: left;
        padding: 1rem;
        position: relative;
        border-bottom-right-radius: 0;
        border-bottom-left-radius: 0;
        cursor: pointer;
        color: rgba(102, 102, 102, .6);
    }
.select > p:after {
        display: block;
        width: 10px;
        height: 10px;
        content: '';
        position: absolute;
        top: 1.4rem;
        right: 2rem;
        border-bottom: 1px solid #33CC66;
        border-left: 1px solid #33CC66;
        transform: rotate(-45deg);
        transition: transform .3s ease-out, top .2s ease-out;
    }
  1. 设置 pul 元素的背景颜色和边框等设置。
  2. p 元素单独指定样式,并设置其 position 属性,主要是为了下面绘制右侧的下拉按钮。
  3. 利用 :afterp 元素的右方绘制下拉按钮,可以看出来,我们是利用左下边框然后旋转 -45 度 模拟的这个效果。值得注意的是,我们需要将其 display 设置为 block,并且设置宽高,否则看不到 这个效果。
    .select ul {
        margin-top: 0;
        border-top-left-radius: 0;
        border-top-right-radius: 0;
        list-style-type: none;
        cursor: pointer;
        overflow-y: auto;
        max-height: 0;
        transition: max-height .3s ease-out;
    }

    .select ul li {
        padding-left: 0.5rem;
        display: block;
        line-height: 3rem;
        text-align: left;
    }   
  1. 设置 ul 的一些默认属性,并将其设置最大宽度为 0,指定 overflow-yauto ,这个时候ul 将会被隐藏。
  2. 在这里设置的时候我遇到了一个问题,就是 li 标签始终占不满 ul 的一行,那是因为其默认有 marginpadding ,所以在一开始的时候就将网页中所有元素的外边距和内边距设置成了 0
    .select.open ul {
        max-height: 20rem;
        transform-origin: 50% 0;
        -webkit-animation: slide-down .5s ease-in;
    }

    .select.open > p:after {
        position: absolute;
        top: 1.6rem;
        transform: rotate(-225deg);
        transition: transform .3s ease-in, top .2s ease-in;
    }
  1. open 设置最大高度,并为其指定动画效果。
  2. 将下拉按钮旋转 -225 度,并为其指定动画。

下面我们看看为 ul 元素指定的 slide-down 动画效果,这也是这个下拉特效的关键所在。

    @-webkit-keyframes slide-down {
        0% {
            transform: scale(1, 0);
        }
        25% {
            transform: scale(1, 1.25);
        }
        50% {
            transform: scale(1, 0.75);
        }
        75% {
            transform: scale(1, 1.1);
        }
        100% {
            transform: scale(1, 1);
        }
    }

看到以上代码可能就都明白了,就是不断改变 ul 的大小,让其在 0.75-1.25 之间进行缩放,所以就会有那个跳动的效果了。

下面还有一些简单的 CSS 代码,不再解释。

    .select ul li:hover {
        background-color: rgba(102, 153, 102, 0.4);
    }

    .select .selected {
        background-color: rgba(102, 153, 102, 0.8);
    }

CSS 讲完了,下面就可以看看我们是如何利用 JQuery 控制这个效果的。

我们并不需要下载 JQuery 就可以使用,因为现在已经有很多网站提供了 CDN 服务,比如我使用的 BootCDN

<script src="http://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>

下面就可以使用 JQuery 了。

<script>
    $(document).ready(function () {
        $('.select ul li').on("click", function (e) {
            var _this = $(this);
            $('.select >p').text(_this.attr('data-value'));
            $(_this).addClass('selected').siblings().removeClass('selected');
            $('.select').toggleClass('open');
            cancelBubble(e);
        });

        $('.select>p').on("click", function (e) {
            $('.select').toggleClass('open');
            cancelBubble(e);
        });

        $(document).on('click', function () {
            $('.select').removeClass('open');
        })
    })

    function cancelBubble(event) {
        if (event.stopPropagation) {
            event.preventDefault();
            event.stopPropagation();
        } else {
            event.returnValue = false;
            event.cancelBubble();
        }
    }
</script>
  1. 首先为 p 标签绑定 click 事件,在触发的时候,为 select 添加或移除 open class, 也就是将 ul 显示出来。
  2. li 绑定 click 事件,当选中了一个 li 元素的时候,首先获取到 data-value,然后将其赋值给 p 标签,然后为选中的 li 添加 selected class,与此同时利用 siblings() 方法,让兄弟节点的 selected class 移除。
  3. document 设置click 事件,当我们点击网页中任何一处地方的时候,如果 ul 是打开的,就将其关闭,不过这个时候由于所有元素都在 document 内,所以我们需要阻止事件冒泡,调用自己写的 cancelBubble() 方法。

好了,就讲到这里,有不理解的可在下方留言。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,725评论 1 92
  • 学习CSS的最佳网站没有之一 http://www.w3school.com.cn/tags/index.asp ...
    Amyyy_阅读 1,023评论 0 1
  • 本文主要是起笔记的作用,内容来自慕课网. 认识CSS样式 CSS全称为“层叠样式表 (Cascading Styl...
    0o冻僵的企鹅o0阅读 2,616评论 0 30
  • 一 外部式css样式 (也可称为外联式)就是把css代码写一个单独的外部文件中,这个css样式文件以“.css...
    KunMitnic阅读 925评论 0 1
  • 本课来自http://www.imooc.com/learn/9请不要用作商业用途。 HTML5 HTML介绍 H...
    PYLON阅读 3,197评论 0 5