安卓自定义下拉列表样式_自定义下拉列表样式

安卓自定义下拉列表样式

安卓自定义下拉列表样式

Custom Drop-Down List Styling

Hi guys! I’m back with another article just for you, and CSS related of course! This time, we are going to talk (and do stuff!) about something a bit more practical than button switches: drop-down lists. The point of this tutorial is to show how to create nice drop-downs without any image but with CSS only. We’ll add some line of jQuery to make them work.

嗨,大家好! 我回来了另一本只为您介绍的文章,并且与CSS有关! 这次,我们将讨论(并做一些事情!)比按钮开关更实用的东西:下拉列表。 本教程的重点是显示如何创建美观的下拉菜单,而不显示任何图像,而仅使用CSS。 我们将添加一些jQuery行以使其工作。

A few things before starting:

开始之前的几件事:

  • You won’t see any vendor prefixes in the CSS snippets, but you will, of course, find them in the files.

    您不会在CSS片段中看到任何供应商前缀,但是您当然会在文件中找到它们。
  • I personally use the box-model where [width] = [element-width] + [padding] + [borders]. I activate it with the following snippet:

    我个人使用[[width] = [element-width] + [padding] + [borders]的盒子模型。 我使用以下代码段激活它:

    
    		*,
    		*:after,
    		*:before {
    		    box-sizing: border-box;
    		}
    		
    

我们如何开始?(How do we start?)

First question: what do we need to create a drop-down? In general, we’ll use a division with a span and an unordered list for the drop-down list (we might tweak this for some examples):

第一个问题:创建下拉菜单需要什么? 通常,我们将使用一个带跨度的除法器和一个无序列表作为下拉列表(对于某些示例,我们可能会对其进行调整):


<div class="wrapper-dropdown">
	<span>I'm kinda the label!</span>
	<ul class="dropdown">
		<li>I'm hidden!</li>
		<li>Me too!</li>
		<li>So do I.</li>
	</ul>
</div>

JavaScript(The JavaScript)

For now and before everything else, we need some JavaScript to make this work. Since it’s basically the same JS snippet for all demos, let’s deal with it now:

就目前而言,在一切之前,我们需要一些JavaScript才能完成这项工作。 由于对于所有演示来说,它基本上都是相同的JS代码段,所以让我们现在处理它:


	//...

	obj.dd.on('click', function(event){
		$(this).toggleClass('active');
		return false;
	});

	//...

	$(function() {

		var dd = new DropDown( $('#dd') );

		$(document).click(function() {
			// all dropdowns
			$('.wrapper-dropdown-1').removeClass('active');
		});

	});

So what does this script do exactly? First, it toggles a class called .active when you click on the wrapper. It means if the wrapper doesn’t have the .active class, it adds it, and if it does, it removes it.

那么,该脚本到底能做什么? 首先,当您单击包装器时,它将切换一个名为.active的类。 这意味着如果包装器没有.active类,则将其添加,如果有,则将其删除。

Second thing, it replicates the default behavior of a select drop-down by closing it if you click anywhere else on the screen. Basically, the script says if we click on a child from the <html> tag (so every single node on the DOM), the wrapper loses its .active class. But we prevent this behavior on the wrapper itself by stopping the propagation. Fairly simple, right?

第二件事,如果您单击屏幕上的任何其他位置,它将通过关闭选择下拉列表来复制默认行为。 基本上,脚本说如果我们从<html>标记中单击一个子项(因此DOM上的每个节点),则包装器将丢失其.active类。 但是我们通过停止传播来防止包装器自身发生此行为。 很简单,对吧?

Well, now we understand how it works, I guess it’s time to create some neat drop-downs!

好了,现在我们了解了它的工作原理,我想是时候创建一些简洁的下拉列表了!

例子1 (Example 1)

Let’s start with something simple: a basic drop-down for gender. Let’s look at the markup first:

让我们从简单的事情开始:性别的基本下拉列表。 让我们先看一下标记:

标记 (The Markup)

We need a few things: a wrapper, a (hidden) drop-down list and a “label” which we will wrap into a span. We use anchors because it seems semantically correct to me, but we could have also used another tag.

我们需要一些东西:包装器,一个(隐藏的)下拉列表和一个“标签”,我们将它们包装成一个范围。 我们使用锚点是因为它对我而言在语义上是正确的,但我们也可以使用其他标记。


<div id="dd" class="wrapper-dropdown-1" tabindex="1">
	<span>Gender</span>
    <ul class="dropdown">
        <li><a href="#">Male</a></li>
        <li><a href="#">Female</a></li>
    </ul>
</div>

CSS(The CSS)

Let’s dig into the CSS which is our focus in this tutorial. We will start with the wrapper:

让我们深入研究CSS,这是本教程的重点。 我们将从包装器开始:


.wrapper-dropdown {
    /* Size and position */
    position: relative; /* Enable absolute positioning for children and pseudo elements */
    width: 200px;
    padding: 10px;
    margin: 0 auto;

    /* Styles */
    background: #9bc7de;
    color: #fff;
    outline: none;
    cursor: pointer;

    /* Font settings */
    font-weight: bold;
}

We did a few things here. First we set a width to our dropdown and some paddings/margins. Next, we gave it some styles. And finally, we set some font settings, which will cascade to the dropdown itself.

我们在这里做了一些事情。 首先,我们为下拉菜单和一些填充/边距设置宽度。 接下来,我们给它一些样式。 最后,我们设置一些字体设置,这些设置将级联到下拉菜单本身。

Let’s finish with the “label” by adding the little arrow on the right with a pseudo-element (styling purpose = no extra markup).

让我们以“标签”结束,在右边添加一个带有伪元素的小箭头(样式目的=没有额外的标记)。


.wrapper-dropdown:after {
    content: "";
    width: 0;
    height: 0;
    position: absolute;
    right: 16px;
    top: 50%;
    margin-top: -6px;
    border-width: 6px 0 6px 6px;
    border-style: solid;
    border-color: transparent #fff;    
}

I think we all know how to create a little triangle with CSS thanks to some border tricks. It’s a hack yep, but it works pretty well so why not? Nothing much there then: a little white down arrow on the right of the wrapper.

我想我们都知道由于一些边框技巧,如何使用CSS创建一个小三角形。 是的,是的,但是效果很好,为什么不呢? 那里没什么了:包装纸右边的白色向下箭头。

We have a nice little button there, but without an actual drop-down it has no point really. So let’s deal with our list!

我们在那里有一个漂亮的小按钮,但是没有实际的下拉菜单实际上没有任何意义。 因此,让我们处理一下清单!


.wrapper-dropdown-1 .dropdown {
	/* Size & position */
    position: absolute;
    top: 100%;
    left: 0; /* Size */
    right: 0; /* Size */

    /* Styles */
    background: #fff;
    font-weight: normal; /* Overwrites previous font-weight: bold; */

    /* Hiding */
    opacity: 0;
    pointer-events: none;
}

What did we just do? We give the drop-down absolute positioning and placed it just behind the button (top: 100%;). We gave it the same width as the button with the left and right values set to 0. And more importantly, we hide it by reducing its opacity to 0. What about pointer-events? Not seeing something doesn’t mean it’s not there. Setting pointer-events to none prevents clicking on the dropdown while it’s “hidden”.

我们刚刚做了什么? 我们给出下拉菜单的绝对位置,并将其放置在按钮的后面( top: 100%; )。 我们将其宽度设置为与按钮的宽度相同,并且将左值和右值设置为0。更重要的是,我们通过将其不透明度降低为0来隐藏它。指针事件呢? 没有看到东西并不意味着它不存在。 将指针事件设置为none可以防止在“隐藏”状态下单击下拉列表。

Let’s give some styles to the list elements inside the dropdown:

让我们为下拉列表中的列表元素提供一些样式:


.wrapper-dropdown-1 .dropdown li a {
    display: block;
    text-decoration: none;
    color: #9e9e9e;
    padding: 10px 20px;
}

/* Hover state */
.wrapper-dropdown-1 .dropdown li:hover a {
    background: #f3f8f8;
}

Okay, so we have a nice button and a nice hidden drop-down menu. Now we have to deal with the “open” case when you click on the button to show the options. With JavaScript we toggle a class .active when we click on the button, so based on this class we can change our CSS to show the drop-down.

好的,我们有一个不错的按钮和一个不错的隐藏下拉菜单。 现在,当您单击按钮以显示选项时,我们必须处理“打开”情况。 使用JavaScript,我们在单击按钮时会切换一个.active类,因此基于该类,我们可以更改CSS以显示下拉菜单。


/* Active state */
.wrapper-dropdown-1.active .dropdown {
    opacity: 1;
    pointer-events: auto;
}

.wrapper-dropdown-1.active:after {
    border-color: #9bc7de transparent;
    border-width: 6px 6px 0 6px ;
    margin-top: -3px;
}

.wrapper-dropdown-1.active {
  background: #9bc7de;
  background: linear-gradient(to right, #9bc7de 0%, #9bc7de 78%, #ffffff 78%, #ffffff 100%);
}			

Three things here:

这里的三件事:

  • First, we make the drop-down appear by turning its opacity to 1. Don’t forget to set the pointer-event to auto to enable the interaction with it!

    首先,我们将下拉菜单的不透明度设置为1,以显示下拉菜单。不要忘记将指针事件设置为auto来启用与它的交互!
  • Next, we change the direction and the color of the little arrow.

    接下来,我们更改小箭头的方向和颜色。
  • Then, we change the background behind the arrow by using a clever gradient on the button. Isn’t that nice?

    然后,通过在按钮上使用智能渐变来更改箭头后面的背景。 那不是很好吗?
JavaScript (The JavaScript)

Last but not least, we also have to add another JavaScript snippet to make the button display the selected value.

最后但并非最不重要的一点是,我们还必须添加另一个JavaScript代码段以使按钮显示所选值。


function DropDown(el) {
    this.dd = el;
    this.placeholder = this.dd.children('span');
    this.opts = this.dd.find('ul.dropdown > li');
    this.val = '';
    this.index = -1;
    this.initEvents();
}
DropDown.prototype = {
    initEvents : function() {
        var obj = this;

        obj.dd.on('click', function(event){
            $(this).toggleClass('active');
            return false;
        });

        obj.opts.on('click',function(){
            var opt = $(this);
            obj.val = opt.text();
            obj.index = opt.index();
            obj.placeholder.text('Gender: ' + obj.val);
        });
    },
    getValue : function() {
        return this.val;
    },
    getIndex : function() {
        return this.index;
    }
}

Very simple code here: when an element is clicked we get its value and display it in the “label”.

此处的代码非常简单:单击某个元素后,我们将获得其值并将其显示在“标签”中。

例子2 (Example 2)

What a beautiful little drop-down to choose your way to sign in! I know, we use to have fancy buttons for that but let’s try something new, shall we?

选择您的登录方式真是个美丽的小下拉菜单! 我知道,我们过去常常为此花哨的按钮,但让我们尝试一些新的东西,对吧?

标记 (The Markup)

<div id="dd" class="wrapper-dropdown-2">Sign in with
	<ul class="dropdown">
		<li><a href="#"><i class="icon-twitter icon-large"></i>Twitter</a></li>
		<li><a href="#"><i class="icon-github icon-large"></i>Github</a></li>
		<li><a href="#"><i class="icon-facebook icon-large"></i>Facebook</a></li>
	</ul>
</div>

The <i> tags are used to display little icons from FontAwesome. I won’t explain all the FontAwesome stuff here because it has already been covered multiple times, I guess. Just make sure it works. 😛

<i>标记用于显示FontAwesome中的小图标。 我想这里不会解释所有FontAwesome的东西,因为它已经被覆盖过多次了。 只要确保它能工作即可。 😛

CSS (The CSS)

Let’s start with the wrapper, shall we? Pretty much the same as the wrapper in the previous example. Note the 5px left border, it’s important for the following. 😉

让我们从包装器开始吧? 与上一个示例中的包装程序几乎相同。 请注意5px的左边框,这对于以下操作很重要。 😉


.wrapper-dropdown-2 {
    /* Size and position */
    position: relative; /* Enable absolute positioning for children and pseudo elements */
    width: 200px;
    margin: 0 auto;
    padding: 10px 15px;

    /* Styles */
    background: #fff;
    border-left: 5px solid grey;
    cursor: pointer;
    outline: none;
}

Now the little arrow. Exactly the same as before:

现在是小箭头。 与之前完全相同:


.wrapper-dropdown-2:after {
    content: "";
    width: 0;
    height: 0;
    position: absolute;
    right: 16px;
    top: 50%;
    margin-top: -3px;
    border-width: 6px 6px 0 6px;
    border-style: solid;
    border-color: grey transparent;
}

And here comes the drop-down list. Again, it’s pretty much the same thing like in the previous example:

这是下拉列表。 同样,它与上一个示例几乎相同:


.wrapper-dropdown-2 .dropdown {
  /* Size & position */
    position: absolute;
    top: 100%;
    left: -5px;
    right: 0px;

    /* Styles */
    background: white;
    transition: all 0.3s ease-out;
    list-style: none;

    /* Hiding */
    opacity: 0;
    pointer-events: none;
}

Please note the transition that we’ll use to make the drop-down progressively appear (animate) instead of simply pop up like in the first demo.

请注意,我们将用于逐步显示下拉列表(动画)的过渡,而不是像第一个演示中那样简单地弹出。

Some styles for the links and the icons:

链接和图标的一些样式:


.wrapper-dropdown-2 .dropdown li a {
    display: block;
    text-decoration: none;
    color: #333;
    border-left: 5px solid;
    padding: 10px;
    transition: all 0.3s ease-out;
}

.wrapper-dropdown-2 .dropdown li:nth-child(1) a { 
    border-left-color: #00ACED;
}

.wrapper-dropdown-2 .dropdown li:nth-child(2) a {
    border-left-color: #4183C4;
}

.wrapper-dropdown-2 .dropdown li:nth-child(3) a {
    border-left-color: #3B5998;
}

.wrapper-dropdown-2 .dropdown li i {
    margin-right: 5px;
    color: inherit;
    vertical-align: middle;
}

/* Hover state */

.wrapper-dropdown-2 .dropdown li:hover a {
    color: grey;
}

We give the links a left border with a color based on the brand they stand for. The text is slightly indented to the right via a margin-right on the icons.

根据链接所代表的品牌,我们为链接的左侧边框加上颜色。 文本通过图标上的右空白向右稍微缩进。

And now, the expanded state. Pretty straight forward: the arrow changes direction, and the drop-down list becomes visible. Thanks to the transition property on the drop-down, it appears progressively (opacity animates from 0 to 1).

而现在,扩展状态。 非常简单:箭头会更改方向,并且下拉列表将变为可见。 由于下拉菜单中的transition属性,它逐渐显示(不透明度从0到1动画)。


.wrapper-dropdown-2.active:after {
    border-width: 0 6px 6px 6px;
}

.wrapper-dropdown-2.active .dropdown {
    opacity: 1;
    pointer-events: auto;
}

JavaScript(The JavaScript)

function DropDown(el) {
    this.dd = el;
    this.initEvents();
}
DropDown.prototype = {
    initEvents : function() {
        var obj = this;

        obj.dd.on('click', function(event){
            $(this).toggleClass('active');
            event.stopPropagation();
        }); 
    }
}

例子3(Example 3)

This one is probably the one which comes the closest to a regular select element. Indeed, when you pick something, the label’s default value is replaced by the picked value. On a side note: it looks great doesn’t it?

这可能是最接近常规选择元素的那个。 确实,当您选择某物时,标签的默认值将替换为所选择的值。 附带说明:看起来不错,不是吗?

标记 (The Markup)

<div id="dd" class="wrapper-dropdown-3" tabindex="1">
	<span>Transport</span>
	<ul class="dropdown">
		<li><a href="#"><i class="icon-envelope icon-large"></i>Classic mail</a></li>
		<li><a href="#"><i class="icon-truck icon-large"></i>UPS Delivery</a></li>
		<li><a href="#"><i class="icon-plane icon-large"></i>Private jet</a></li>
	</ul>
</div>

Not much more than before. Let’s go with the CSS!

没有比以前更多。 让我们一起来看看CSS!

CSS (The CSS)

.wrapper-dropdown-3 {
    /* Size and position */
    position: relative;
    width: 200px;
    margin: 0 auto;
    padding: 10px;

    /* Styles */
    background: #fff;
    border-radius: 7px;
    border: 1px solid rgba(0,0,0,0.15);
    box-shadow: 0 1px 1px rgba(50,50,50,0.1);
    cursor: pointer;
    outline: none;

    /* Font settings */
    font-weight: bold;
    color: #8AA8BD;
}

Here we use some borders, a box-shadow and rounded corners. We need the little arrow:

在这里,我们使用一些边框,一个盒子阴影和圆角。 我们需要小箭头:


.wrapper-dropdown-3:after {
    content: "";
    width: 0;
    height: 0;
    position: absolute;
    right: 15px;
    top: 50%;
    margin-top: -3px;
    border-width: 6px 6px 0 6px;
    border-style: solid;
    border-color: #8aa8bd transparent;
}

This is the same as before, so let’s skip forward to the drop-down and its children.

与之前相同,因此让我们跳至下拉列表及其子项。


.wrapper-dropdown-3 .dropdown {
  /* Size & position */
    position: absolute;
    top: 140%;
    left: 0;
    right: 0;

    /* Styles */
    background: white;
    border-radius: inherit;
    border: 1px solid rgba(0,0,0,0.17);
    box-shadow: 0 0 5px rgba(0,0,0,0.1);
    font-weight: normal;
    transition: all 0.5s ease-in;
    list-style: none;

    /* Hiding */
    opacity: 0;
    pointer-events: none;
}

.wrapper-dropdown-3 .dropdown li a {
    display: block;
    padding: 10px;
    text-decoration: none;
    color: #8aa8bd;
    border-bottom: 1px solid #e6e8ea;
    box-shadow: inset 0 1px 0 rgba(255,255,255,1);
    transition: all 0.3s ease-out;
}

.wrapper-dropdown-3 .dropdown li i {
    float: right;
    color: inherit;
}

.wrapper-dropdown-3 .dropdown li:first-of-type a {
    border-radius: 7px 7px 0 0;
}

.wrapper-dropdown-3 .dropdown li:last-of-type a {
    border-radius: 0 0 7px 7px;
    border: none;
}

/* Hover state */

.wrapper-dropdown-3 .dropdown li:hover a {
    background: #f3f8f8;
}

A few notes here:

这里有一些注意事项:

  • We use a little box-shadow on the links in order to create a subtle light effect on their top.

    我们在链接上使用一个小盒子阴影,以在其顶部创建微妙的灯光效果。
  • To prevent this shadow to go out of the menu, we give the first link rounded corners.

    为了防止该阴影超出菜单,我们将第一个链接设置为圆角。
  • We remove the border of the last link to avoid a 1px weird border at the bottom of the dropdown.

    我们删除了最后一个链接的边框,以避免下拉菜单底部出现1px的怪异边框。
  • We don’t change the markup to place icons on the right: a simple float: right works like a charm.

    我们不会更改标记来在右侧放置图标:一个简单的float: right就像一个吊饰。

Everything looks right except the little arrow on the top right of the drop-down. This arrow is important: without it, the dropdown looks like it’s floating with no connection to the button.

除下拉菜单右上角的小箭头外,其他所有内容均显示正确。 此箭头很重要:没有箭头,下拉列表看起来就像是浮动的,与按钮没有任何连接。


.wrapper-dropdown-3 .dropdown:after {
    content: "";
    width: 0;
    height: 0;
    position: absolute;
    bottom: 100%;
    right: 15px;
    border-width: 0 6px 6px 6px;
    border-style: solid;
    border-color: #fff transparent;    
}

.wrapper-dropdown-3 .dropdown:before {
    content: "";
    width: 0;
    height: 0;
    position: absolute;
    bottom: 100%;
    right: 13px;
    border-width: 0 8px 8px 8px;
    border-style: solid;
    border-color: rgba(0,0,0,0.1) transparent;    
}

Why are we using two pseudo-elements for this arrow? We want to create the border around it. Basically we create a white triangle sitting on top of a grey and slightly larger one. This way, it looks like there is only one little arrow with a border.

为什么我们为此箭头使用两个伪元素? 我们要在其周围创建边框。 基本上,我们在灰色的稍大一点的顶部创建一个白色三角形。 这样,看起来只有一个带边框的小箭头。

An now the expanded state. Always the same thing. However, note how we set the transition to the .dropdown a bit longer than usual (0.5s instead of 0.3s). That way, the opening of the menu is very smooth.

现在是展开状态。 总是一样的东西。 但是,请注意我们如何将过渡到.dropdown的时间设置得比平时更长(0.5s而不是0.3s)。 这样,菜单的打开非常流畅。


.wrapper-dropdown-3.active .dropdown {
    opacity: 1;
    pointer-events: auto;
}

JavaScript(The JavaScript)

To finish this demo, we need to add a little bit of JavaScript to replace the default value of the button by the selected one. We saw how to do it in the first example, but since we don’t keep the “Transport” word here, the JS is very slightly different.

要完成此演示,我们需要添加一些JavaScript以将按钮的默认值替换为所选按钮的默认值。 在第一个示例中,我们看到了如何执行此操作,但是由于这里没有保留“ Transport”一词,因此JS略有不同。


function DropDown(el) {
    this.dd = el;
    this.placeholder = this.dd.children('span');
    this.opts = this.dd.find('ul.dropdown > li');
    this.val = '';
    this.index = -1;
    this.initEvents();
}
DropDown.prototype = {
    initEvents : function() {
        var obj = this;

        obj.dd.on('click', function(event){
            $(this).toggleClass('active');
            return false;
        });

        obj.opts.on('click',function(){
            var opt = $(this);
            obj.val = opt.text();
            obj.index = opt.index();
            obj.placeholder.text(obj.val);
        });
    },
    getValue : function() {
        return this.val;
    },
    getIndex : function() {
        return this.index;
    }
}

例子4(Example 4)

Looks different, doesn’t it? For this one, I thought it would be cool to create a little to-do-list instead of a select drop-down or a drop-down menu. Nothing spectacular, but different than previous demos for sure. 😉

看起来不一样,不是吗? 对于这个,我认为创建一个小的待办事项列表而不是选择下拉菜单或下拉菜单会很酷。 没什么特别的,但是肯定与以前的演示不同。 😉

标记 (The Markup)

<div id="dd" class="wrapper-dropdown-4">To do
	<ul class="dropdown">
		<li><input type="checkbox" id="el-1" name="el-1" value="donut"><label for="el-1">Eat a donut</label></li>
		<li><input type="checkbox" id="el-2" name="el-2" value="neighbour"><label for="el-2">Spy on my neighbours</label></li>
		<li><input type="checkbox" id="el-3" name="el-3" value="T-rex"><label for="el-3">Feed my T-Rex</label></li>
	</ul>
</div>

No more links. No more icons. For each element, we have two things: a checkbox linked to a label.

没有更多链接。 没有更多的图标。 对于每个元素,我们有两件事:链接到标签的复选框。

CSS (The CSS)

.wrapper-dropdown-4 {
    /* Size and position */
    position: relative;
    width: 270px;
    margin: 0 auto;
    padding: 10px 10px 10px 30px;

    /* Styles */
    background: #fff;
    border: 1px solid silver;
    cursor: pointer;
    outline: none;
}

Nothing to say except that we use an important left padding to create enough space for the red lines. Now, the little arrow on the right:

除了使用重要的左填充为红线创建足够的空间外,无话可说。 现在,右边的小箭头:


.wrapper-dropdown-4:after {
    content: "";
    width: 0;
    height: 0;
    position: absolute;
    right: 10px;
    top: 50%;
    margin-top: -3px;
    border-width: 6px 6px 0 6px;
    border-style: solid;
    border-color: #ffaa9f transparent;
}

The dropdown. I’m pretty sure you’re getting used to it. 🙂

下拉菜单。 我敢肯定你已经习惯了。 🙂


.wrapper-dropdown-4 .dropdown {
    /* Size & position */
    position: absolute;
    top: 100%;
    margin-top: 1px; /* border of wrapper */
    left: -1px;
    right: -1px;

    /* Styles */
    background: white;
    border: 1px solid silver;
    border-top: none;
    list-style: none;
    transition: all 0.3s ease-out;
  
    /* Hiding */
    opacity: 0;
    pointer-events: none;
}

We need to set the margin-top to 1px because we need to push it a bit down due to the border of the wrapper. The left is set to -1px to pull the drop-down into position and we’ll give it the same border like its parent, except that we take away the top one.

我们需要将margin-top设置为1px,因为由于包装器的边框,我们需要将margin-top向下推一点。 左侧设置为-1px以将下拉列表拉到适当位置,我们将为其父边框赋予相同的边框,只是我们将顶部边框取走。


.wrapper-dropdown-4 .dropdown li {
    position: relative; /* Enable absolute positioning for checkboxes */
}

.wrapper-dropdown-4 .dropdown li label {
    display: block;
    padding: 10px 10px 10px 30px; /* Same padding as the button */
    border-bottom: 1px dotted #1ccfcf;
    transition: all 0.3s ease-out;
}

.wrapper-dropdown-4 .dropdown li:last-of-type label {
    border: none;
}

.wrapper-dropdown-4 .dropdown li input /* Checkboxes */ {
    position: absolute;
    display: block;
    right: 10px;
    top: 50%;
    margin-top: -8px;
}

/* Hover state */

.wrapper-dropdown-4 .dropdown li:hover label {
    background: #f0f0f0;
}

/* Checked state */

.wrapper-dropdown-4 .dropdown li input:checked ~ label {
    color: grey;
    text-decoration: line-through;
}

Checkboxes are absolutely placed on the middle right of each line but since they are linked to labels, you can click wherever you want on the line to toggle them. When a checkbox is checked, the following respective label becomes grey and crossed-out. Simple but effective.

复选框绝对位于每行的右中间,但是由于它们链接到标签,因此您可以在该行上的任意位置单击以切换它们。 选中复选框后,以下各个标签将变为灰色并划掉。 简单但有效。

And now, we have to deal with the two thin red lines on the left of our little notebook. There are two ways to do this: one with pseudo-elements and one with gradients. Let’s look at both of them.

现在,我们必须处理小笔记本左侧的两条细红线。 有两种方法可以做到这一点:一种是使用伪元素,另一种是使用渐变。 让我们看看它们两者。


/* Red lines: the pseudo-elements way */
.wrapper-dropdown-4 .dropdown:before,
.wrapper-dropdown-4:before {
    content: "";
    width: 4px;
    height: 100%;
    position: absolute;
    top: 0;
    left: 15px;
    border: 1px solid #ffaa9f;
    border-top: none;
    border-bottom: none;
    z-index: 2;
}

/* OR: */
/* Red lines: the gradients way */

.wrapper-dropdown-4 .dropdown,
.wrapper-dropdown-4 {
  background: linear-gradient(left, white 5%, #ffaa9f 5%, #ffaa9f 5.3%, white 5.3%, white 6.5%, #ffaa9f 6.5%, #ffaa9f 6.8%, white 6.8%);
}

.wrapper-dropdown-4 .dropdown li:hover label {
  background: linear-gradient(left, #f0F0F0 5%, #ffaa9f 5%, #ffaa9f 5.3%, #f0F0F0 5.3%, #f0F0F0 6.5%, #ffaa9f 6.5%, #ffaa9f 6.8%, #f0F0F0 6.8%);
}


The first method creates a pseudo-element (two actually: one for the button and one for the dropdown) with left and right borders sitting on top of everything else. The second method fakes the red lines with a gradient on both, the wrapper and the dropdown. So which one is better? Probably the first one, because if you want to change the hover effect on the list elements, you have to change the gradient which is pretty awful. Plus, pseudo-elements have a way better browser support (back to IE8) than gradients (not supported until IE10).

第一种方法创建一个伪元素(实际上是两个:一个用于按钮,一个用于下拉菜单),其左右边界位于其他所有元素的顶部。 第二种方法在包装器和下拉菜单上都使用渐变来伪造红线。 那么哪个更好呢? 可能是第一个,因为如果要更改列表元素的悬停效果,则必须更改非常糟糕的渐变。 另外,伪元素比梯度(IE10之前不支持)具有更好的浏览器支持(回到IE8)。

Let’s end it with the expanded state. Nothing new here.

让我们以扩展状态结束。 这里没有新内容。


/* Active state */

.wrapper-dropdown-4.active:after {
    border-width: 0 6px 6px 6px;
}

.wrapper-dropdown-4.active .dropdown {
    opacity: 1;
    pointer-events: auto;
}

JavaScript(The JavaScript)

function DropDown(el) {
    this.dd = el;
    this.opts = this.dd.find('ul.dropdown > li');
    this.val = [];
    this.index = [];
    this.initEvents();
}
DropDown.prototype = {
    initEvents : function() {
        var obj = this;

        obj.dd.on('click', function(event){
            $(this).toggleClass('active');
            event.stopPropagation();
        });

        obj.opts.children('label').on('click',function(event){
            var opt = $(this).parent(),
                chbox = opt.children('input'),
                val = chbox.val(),
                idx = opt.index();

            ($.inArray(val, obj.val) !== -1) ? obj.val.splice( $.inArray(val, obj.val), 1 ) : obj.val.push( val );
            ($.inArray(idx, obj.index) !== -1) ? obj.index.splice( $.inArray(idx, obj.index), 1 ) : obj.index.push( idx );
        });
    },
    getValue : function() {
        return this.val;
    },
    getIndex : function() {
        return this.index;
    }
}

例子5(Example 5)

Our last example is a little drop-down menu for some admin panel. For this one, we will use a different animation when we toggle it. Instead of appearing/disappearing, it will slide up and down.

我们的最后一个示例是一些管理面板的下拉菜单。 为此,切换时将使用不同的动画。 它不会出现/消失,而是会上下滑动。

标记 (The markup)

<div id="dd" class="wrapper-dropdown-5" tabindex="1">John Doe
	<ul class="dropdown">
		<li><a href="#"><i class="icon-user"></i>Profile</a></li>
		<li><a href="#"><i class="icon-cog"></i>Settings</a></li>
		<li><a href="#"><i class="icon-remove"></i>Log out</a></li>
	</ul>
</div>

CSS(The CSS)

.wrapper-dropdown-5 {
    /* Size & position */
    position: relative;
    width: 200px;
    margin: 0 auto;
    padding: 12px 15px;

    /* Styles */
    background: #fff;
    border-radius: 5px;
    box-shadow: 0 1px 0 rgba(0,0,0,0.2);
    cursor: pointer;
    outline: none;
    transition: all 0.3s ease-out;
}

.wrapper-dropdown-5:after { /* Little arrow */
    content: "";
    width: 0;
    height: 0;
    position: absolute;
    top: 50%;
    right: 15px;
    margin-top: -3px;
    border-width: 6px 6px 0 6px;
    border-style: solid;
    border-color: #4cbeff transparent;
}

Basic stuff there. Let’s go to the dropdown, which is a little bit different than usual.

那里的基本东西。 让我们转到下拉菜单,该下拉菜单与平时有点不同。


.wrapper-dropdown-5 .dropdown {
    /* Size & position */
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;

    /* Styles */
    background: #fff;
    border-radius: 0 0 5px 5px;
    border: 1px solid rgba(0,0,0,0.2);
    border-top: none;
    border-bottom: none;
    list-style: none;
    transition: all 0.3s ease-out;

    /* Hiding */
    max-height: 0;
    overflow: hidden;
}

This time, we don’t turn the opacity to 0 to hide the menu. We set its max-height to 0 and its overflow to hidden. Why its max-height and not its height? Because we don’t know the exact height of the expanded drop-down. So no need of pointer-events this time since the menu is really not there.

这次,我们不将不透明度设置为0以隐藏菜单。 我们将其最大高度设置为0,并将其溢出设置为隐藏。 为什么是最大高度而不是高度? 因为我们不知道扩展下拉列表的确切高度。 因此,由于菜单实际上不存在,因此这次不需要指针事件。

Quick and simple styles for the list elements.

列表元素的快速和简单样式。


.wrapper-dropdown-5 .dropdown li {
    padding: 0 10px ;
}

.wrapper-dropdown-5 .dropdown li a {
    display: block;
    text-decoration: none;
    color: #333;
    padding: 10px 0;
    transition: all 0.3s ease-out;
    border-bottom: 1px solid #e6e8ea;
}

.wrapper-dropdown-5 .dropdown li:last-of-type a {
    border: none;
}

.wrapper-dropdown-5 .dropdown li i {
    margin-right: 5px;
    color: inherit;
    vertical-align: middle;
}

/* Hover state */

.wrapper-dropdown-5 .dropdown li:hover a {
    color: #57a9d9;
}

And now, the active state:

现在,处于活动状态:


/* Active state */

.wrapper-dropdown-5.active {
    border-radius: 5px 5px 0 0;
    background: #4cbeff;
    box-shadow: none;
    border-bottom: none;
    color: white;
}

.wrapper-dropdown-5.active:after {
    border-color: #82d1ff transparent;
}

.wrapper-dropdown-5.active .dropdown {
    border-bottom: 1px solid rgba(0,0,0,0.2);
    max-height: 400px;
}

When the dropdown is open, we change the bottom corners of the button, its color, its arrow direction and arrow color and remove both, its box-shadow and its border. And to show the menu, we set the max-height of the dropdown to 400px. We could have set it to 500px, 1000px ou 1000000px; it doesn’t matter as long as it’s taller than its height.

打开下拉菜单后,我们将更改按钮的底角,其颜色,箭头方向和箭头颜色,并同时删除其框阴影和边框。 为了显示菜单,我们将下拉菜单的最大高度设置为400px。 我们可以将其设置为500px,1000px或1000000px; 只要它比它的高度高就没有关系。

JavaScript (The JavaScript)

function DropDown(el) {
    this.dd = el;
    this.initEvents();
}
DropDown.prototype = {
    initEvents : function() {
        var obj = this;

        obj.dd.on('click', function(event){
            $(this).toggleClass('active');
            event.stopPropagation();
        }); 
    }
}

后备(Fallbacks)

Okay guys, we now have 5 awesome drop-downs working like a charm, but what about legacy browsers? These browsers don’t understand the opacity property. And if some of these do with filters, they don’t understand pointer-events. It sucks and this is why you might want to put a fallback in place.

好的,我们现在有5个很棒的下拉菜单,就像一个超级按钮,但是旧版浏览器呢? 这些浏览器不了解opacity属性。 而且,如果其中一些使用过滤器,它们将无法理解指针事件。 这很糟糕,这就是为什么您可能想要放置一个备用的原因。

This is where our friend Modernizr is coming into play. Roughly, for those who don’t know what Modernizr is, it’s a JavaScript library that detects HTML5 and CSS3 features in the user’s browser. Thanks to this awesome script, we can basically tell the browser “if you don’t support *this* property, then do *that*”. With Modernizr we can have classes added to the html, for example, “no-pointerevents” if there is no support for pointer-events (make sure to select that in the non-core detects when you build your Modernizr). The following is an example of how we can manage the fallback for browsers that don’t support certain CSS properties:

这是我们的朋友Modernizr发挥作用的地方。 粗略地说,对于那些不知道Modernizr是什么的人来说,它是一个JavaScript库,可以检测用户浏览器中HTML5和CSS3功能。 由于有了这个出色的脚本,我们基本上可以告诉浏览器“如果您不支持* this *属性,那么请执行* that *” 。 使用Modernizr,我们可以将类添加到html中,例如,如果不支持指针事件(请确保在构建您的Modernizr时在非核心中选择该选项),则可以使用“ no-pointerevents”。 以下是一个示例,说明如何为不支持某些CSS属性的浏览器管理后备广告:


/* No CSS3 support */

.no-opacity       .wrapper-dropdown-1 .dropdown,
.no-pointerevents .wrapper-dropdown-1 .dropdown {
    display: none;
    opacity: 1; /* If opacity support but no pointer-events support */
    pointer-events: auto; /* If pointer-events support but no pointer-events support */
}

.no-opacity       .wrapper-dropdown-1.active .dropdown,
.no-pointerevents .wrapper-dropdown-1.active .dropdown {
    display: block;
}

If the browser doesn’t support either opacity or pointer-events, then we hide the drop-down with a simple display: none;. If the browser doesn’t support opacity but does support pointer-events, we set those to auto to allow the user to click on the menu once expanded. In the other hand, if the browser doesn’t support pointer-events but does support opacity, we set it to 1 to make the dropdown appear once the .active class is toggled.

如果浏览器不支持不透明度或指针事件,那么我们用简单的display: none;隐藏下拉菜单display: none; 。 如果浏览器不支持不透明度,但支持指针事件,则将其设置为auto以允许用户在展开菜单后单击菜单。 另一方面,如果浏览器不支持指针事件但支持不透明度,则将其设置为1,以在切换.active类后使下拉菜单出现。

When the .active class is toggled, we show the drop-down with display: block;. Easy peasy!

切换.active类时,我们使用display: block;下拉列表display: block; 。 十分简单!

Note: of course this doesn’t apply for the demo with the max-height animation. Only for the others with opacity and pointer-events.

注意:当然,这不适用于具有max-height动画的演示。 仅适用于具有不透明度和指针事件的其他对象。

最后的话 (Final words)

I hope this tutorial helped you understand how to make your custom drop-downs. As you can see, it is fairly straight forward and pretty simple both, the CSS and the JavaScript. Please, don’t forget to use fallbacks or tell your users to enable JavaScript. Thank you for reading this tutorial. And of course if you have any question or related work to show, please do! 🙂

我希望本教程可以帮助您了解如何制作自定义下拉菜单。 如您所见,CSS和JavaScript都非常简单明了。 请不要忘记使用后备功能或告诉您的用户启用JavaScript。 感谢您阅读本教程。 当然,如果您有任何疑问或需要展示的相关工作,请这样做! 🙂

翻译自: https://tympanus.net/codrops/2012/10/04/custom-drop-down-list-styling/

安卓自定义下拉列表样式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值