我在文本输入中使用占位符,效果很好。但我也希望在选择框中使用占位符。当然,我可以使用以下代码:

<select>
    <option value="">Select your option</option>
    <option value="hurr">Durr</option>
</select>

但“选择您的选项”是黑色而不是浅灰色。所以我的解决方案可能是基于CSS的。jQuery也很好。

这只会使下拉列表中的选项变灰(因此单击箭头后):

option:first {
    color: #999;
}

问题是:人们如何在选择框中创建占位符?但这已经得到了回应,欢呼。

使用此选项会导致所选值始终为灰色(即使在选择实际选项后):

select {
    color: #999;
}

当前回答

由于本主题中提供的答案之间的样式和功能不同,下表阐明了所提供的HTML、HTML+CSS和HTML+CSS+Javascript解决方案的样式和适用的表单逻辑。

我不得不使用代码格式,因为出于某种原因,标记中不允许使用表。将使用代码段提供一个HTML表来解决表限制。

我将这篇文章标记为社区维基,这样任何人都可以详细介绍新的文章,但请将JQuery、React、Angular、CoffeeScript等添加到另一篇文章中,以保持此表的简单。

         | Technologies |                                                                Styling                                                                |
  Post   | CSS | Java-  | Select: Placeholder |  Select: valid option  |                  Option: placeholder                    |     Option: valid option     |
   ID    |     | script | Color |  Validation | Color |    Required    | Visibility | Selectable | Color |   Cond. formatting    | Color |   Cond. formatting   |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
41167307 | No  |   No   | Black |   Invalid   | Black |      Yes       |  Visible   |     No     | Grey  |          No           | Black |          No          |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
50200912 | No  |   No   | Black |    Valid    | Black |       No       | Invisible  |    N/A     |  N/A  |          No           | Black |          No          |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
5859221  | No  |   No   | Black |    Valid    | Black |       No       |  Visible   |     No     | Grey  |          No           | Black |          No          |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
38120777 | No  |   No   | Black |    Valid    | Black |       No       | Invisible  |    N/A     |  N/A  |          No           | Black |          No          |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
54860799 | Yes |   No   | Grey  |   Invalid   | Black |      Yes       | Invisible  |    N/A     |  N/A  |          No           | Black |          No          |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
52661024 | Yes |   No   | Grey  |   Invalid   | Black |      Yes       | Invisible  |    N/A     |  N/A  |          No           | Black | select:invalid{Grey} |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
8442831  | Yes |   No   | Grey  |   Invalid   | Black |      Yes       | Invisible  |    N/A     |  N/A  |          No           | Black | select:invalid{Grey} |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
29806043 | Yes |   No   | Grey  |   Invalid   | Black |      Yes       | Invisible  |    N/A     |  N/A  |          No           | Black |          No          |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
61966461 | Yes |   No   | Grey  |   Invalid   | Black |      Yes       | Invisible  |    N/A     |  N/A  | select:valid{visible} | Black |          No          |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
44406771 | Yes |   No   | Grey  |   Invalid   | Grey  |      No        |  Visible   |     No     | Grey  |          No           | Black | select:invalid{Grey} |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
40603035 | Yes |   No   | Black |    Valid    | Black |      No        | Invisible  |    N/A     |  N/A  |          No           | Black |          No          |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
22994211 | Yes |   No   | Grey  |    Valid    | Black |      No        | Invisible  |    N/A     |  N/A  |          No           | Black |          No          |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
21722343 | Yes |   No   | Grey  |    Valid    | Grey  |      No        | Invisible  |    N/A     |  N/A  |          No           | Black |          No          |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
48960650 | Yes |  Yes   | Grey  |   Invalid   | Black |      No        | Invisible  |    N/A     |  N/A  |          No           | Black |          No          |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
5805194  | Yes |  Yes   | Grey  |    Valid    | Black |      No        |  Visible   |    Yes     | Black |          No           | Black |          No          |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
50840409 | Yes |  Yes   | Grey  |    Valid    | Black |      Yes       |  Visible   |    Yes     | Grey  |          No           | Black |          No          |

其他回答

我不满足于仅使用HTML/CSS的解决方案,所以我决定使用JavaScript创建一个自定义选择。

这是我在过去30分钟里写的,因此可以进一步改进。

您所要做的就是创建一个简单的列表,其中包含很少的数据属性。代码自动将列表转换为可选择的下拉列表。它还添加了一个隐藏的输入以保存所选值,因此可以在表单中使用。

输入:

<ul class="select" data-placeholder="Role" data-name="role">
  <li data-value="admin">Administrator</li>
  <li data-value="mod">Moderator</li>
  <li data-value="user">User</li>
</ul>

输出:

<div class="ul-select-container">
    <input type="hidden" name="role" class="hidden">
    <div class="selected placeholder">
        <span class="text">Role</span>
        <span class="icon">▼</span>
    </div>
    <ul class="select" data-placeholder="Role" data-name="role">
        <li class="placeholder">Role</li>
        <li data-value="admin">Administrator</li>
        <li data-value="mod">Moderator</li>
        <li data-value="user">User</li>
    </ul>
</div>

假定为占位符的项的文本将灰显。占位符是可选的,以防用户想要恢复其选择。同样使用CSS,select的所有缺点都可以被克服(例如,选项的样式无法设置)。

//帮助程序功能可更快/更轻松地创建元素// https://github.com/akinuri/js-lib/blob/master/element.jsvar elem=函数(tagName、属性、子项、isHTML){让父母;if(tagName类型==“string”){parent=document.createElement(tagName);}else if(HTMLElement的tagName实例){parent=tagName;}if(属性){for(属性中的let属性){parent.setAttribute(属性,属性[attribute]);}}var isHTML=isHTML||null;if(children || children==0){elem.append(父级、子级、isHTML);}返回父项;};elem.append=函数(父级、子级、isHTML){if(HTMLTextAreaElement的父实例|| HTMLInputElement的父示例){if(文本的子实例||typeof children==“string”||typeofchildren===“number”){parent.value=子项;}else if(数组的子实例){children.forEach(函数(child){elem.append(父级,子级);});}else if(typeof children==“function”){elem.append(父级,子级());}}其他{if(HTMLElement的子实例||文本的子实例){parent.appendChild(children);}否则如果(typeof children==“string”| | typeof children==“number”){if(isHTML){parent.innerHTML+=子级;}其他{parent.appendChild(document.createTextNode(children));}}else if(数组的子实例){children.forEach(函数(child){elem.append(父级,子级);});}else if(typeof children==“function”){elem.append(父级,子级());}}};//初始化页面上的所有选择$(“ul.select”).each(函数){var parent=this.parentElement;var refElem=this.nextElementSibling;var container=elem(“div”,{“class”:“ul select container”});var hidden=elem(“input”,{“type”:“hidden”,“name”:this.dataset.name,“class”:“隐藏”});var selected=elem(“div”,{“class”:“selected placeholder”}[elem(“span”,{“class”:“text”},this.dataset.placeholder),elem(“span”,{“class”:“icon”},“&#9660;”,true),]);var placeholder=elem(“li”,{“class”:“placeholder”},this.dataset.placeholder);this.insertBefore(占位符,this.children[0]);container.appendChild(隐藏);container.appendChild(选中);container.appendChild(this);parent.insertBefore(容器,refElem);});//使用所选选项更新必要的元素$(“.ul选择容器ul li”).on(“单击”,函数(){var text=this.innerText;var value=this.dataset.value | |“”;var selected=this.parentElement.previousElementSibling;var hidden=selected.previousElementSibling;hidden.value=selected.dataset.value=值;selected.children[0].innerText=文本;if(this.classList.incontains(“占位符”)){selected.classList.add(“占位符”);}其他{selected.classList.remove(“占位符”);}selected.parentElement.classList.remove(“可见”);});//打开选择下拉列表$(“.ul select container.selected”).on(“单击”,函数(){if(this.parentElement.classList.incontains(“可见”)){this.parentElement.classList.remove(“可见”);}其他{this.parentElement.classList.add(“可见”);}});//焦点丢失时关闭选择$(文档).on(“点击”,功能(e){var container=$(e.target)最近(“.ul select container”);如果(container.length==0){$(“.ul select container.visible”).removeClass(“可见”);}});.ul选择容器{宽度:200px;显示:表格;位置:相对;边距:1em 0;}.ul-select-container.visible ul{显示:块;填充:0;列表样式:无;边距:0;}.ul选择容器ul{背景色:白色;边框:1px实心hsla(0,0%,60%);边框顶部:无;-webkit用户选择:无;显示:无;位置:绝对;宽度:100%;z指数:999;}.ul选择容器ul li{衬垫:2px 5px;}.ul选择容器ul li.placeholder{不透明度:0.5;}.ul选择容器ul li:悬停{背景色:闪避蓝;颜色:白色;}.ul选择容器ul li占位符:悬停{背景色:rgba(0、0、0和.1);颜色:初始;}.ul选择容器。已选择{背景色:白色;填充:3px 10px 4px;衬垫:2px 5px;边框:1px实心hsla(0,0%,60%);-webkit用户选择:无;}.ul选择容器。已选择{显示:柔性;调整内容:间距;}.ul选择容器.selected.placeholder.text{颜色:rgba(0、0、0和.5);}.ul选择容器已选择图标{字体大小:.7em;显示:柔性;对齐项目:居中;不透明度:0.8;}.ul选择容器:悬停.selected{边框:1px实心hsla(0,0%,30%);}.ul选择容器:悬停选定图标{不透明度:1;}<script src=“https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js“></script><ul class=“select”数据占位符=“Role”数据名称=“Role”><li data value=“admin”>管理员</li><li data value=“mod”>主持人</li><li data value=“user”>用户</li></ul><ul class=“select”数据占位符=“Sex”数据名称=“Sex”><li data value=“male”>男性</li><li数据值=“female”>女性</li></ul>


更新:我改进了这一点(使用向上/向下/输入键进行选择),稍微整理了一下输出,并将其转换为对象。电流输出:

<div class="li-select-container">
    <input type="text" readonly="" placeholder="Role" title="Role">
    <span class="arrow">▼</span>
    <ul class="select">
        <li class="placeholder">Role</li>
        <li data-value="admin">Administrator</li>
        <li data-value="mod">Moderator</li>
        <li data-value="user">User</li>
    </ul>
</div>

初始化:

new Liselect(document.getElementsByTagName("ul")[0]);

进一步检查:JSFiddle,GitHub(已重命名)。


更新:我已经重写了一遍。我们可以只使用select,而不使用列表。这样,即使没有JavaScript(如果禁用),它也可以工作。

输入:

<select name="role" data-placeholder="Role" required title="Role">
    <option value="admin">Administrator</option>
    <option value="mod">Moderator</option>
    <option>User</option>
</select>

new Advancelect(document.getElementsByTagName("select")[0]);

输出:

<div class="advanced-select">
    <input type="text" readonly="" placeholder="Role" title="Role" required="" name="role">
    <span class="arrow">▼</span>
    <ul>
        <li class="placeholder">Role</li>
        <li data-value="admin">Administrator</li>
        <li data-value="mod">Moderator</li>
        <li>User</li>
    </ul>
</div>

JSFiddle,GitHub。

我遇到了同样的问题,在搜索时我遇到了这个问题,在我找到了一个好的解决方案后,我想和你们分享一下,以防有人从中受益。

这里是:

HTML格式:

<select class="place_holder dropdown">
    <option selected="selected" style=" display: none;">Sort by</option>
    <option>two</option>
    <option>something</option>
    <option>4</option>
    <option>5</option>
</select>

CSS:

.place_holder {
    color: gray;
}
option {
    color: #000000;
}

JavaScript:

jQuery(".dropdown").change(function () {
    jQuery(this).removeClass("place_holder");
});

在客户进行第一次选择后,不需要灰色,因此JavaScript代码删除了place_holder类。

多亏了@user1096901,作为Internet Explorer浏览器的解决方案,您可以再次添加place_holder类,以防再次选择第一个选项:)

在Angular中,我们可以添加一个选项作为占位符,它可以隐藏在选项下拉列表中。我们甚至可以添加一个自定义下拉图标作为背景,代替浏览器下拉图标。

技巧是仅在未选择值时启用占位符css

/**我的组件模板*/

 <div class="dropdown">
      <select [ngClass]="{'placeholder': !myForm.value.myField}"
 class="form-control" formControlName="myField">
        <option value="" hidden >Select a Gender</option>
        <option value="Male">Male</option>
        <option value="Female">Female</option>
      </select>
    </div>

/**我的组件.TS*/

constructor(fb: FormBuilder) {
  this.myForm = this.fb.build({
    myField: ''
  });
}

/**全局.scss*/

.dropdown {
  width: 100%;
  height: 30px;
  overflow: hidden;
  background: no-repeat white;
  background-image:url('angle-arrow-down.svg');
  background-position: center right;
  select {
    background: transparent;
    padding: 3px;
    font-size: 1.2em;
    height: 30px;
    width: 100%;
    overflow: hidden;

    /*For moz*/
    -moz-appearance: none;
    /* IE10 */
    &::-ms-expand {
      display: none;
    }
    /*For chrome*/
    -webkit-appearance:none;
    &.placeholder {
      opacity: 0.7;
      color: theme-color('mutedColor');
    }
    option {
      color: black;
    }
  }
}

类似于:

HTML格式:

<select id="choice">
    <option value="0" selected="selected">Choose...</option>
    <option value="1">Something</option>
    <option value="2">Something else</option>
    <option value="3">Another choice</option>
</select>

CSS:

#choice option { color: black; }
.empty { color: gray; }

JavaScript:

$("#choice").change(function () {
    if($(this).val() == "0") $(this).addClass("empty");
    else $(this).removeClass("empty")
});

$("#choice").change();

工作示例:http://jsfiddle.net/Zmf6t/

我喜欢这个被接受的解决方案,而且它在没有JavaScript的情况下工作得很好。

我只想补充一下,我是如何对一个受控选择的React组件采用这个答案的,因为我花了几次时间才弄清楚。合并react select并使用它将非常简单,但除非您需要这个存储库提供的惊人功能,而我不需要这个功能,否则就不需要在我的捆绑包中添加更多的KB。注意,react select通过各种输入和html元素的复杂系统处理select中的占位符。

在React中,对于受控组件,不能将所选属性添加到选项中。React通过select本身的value属性以及一个更改处理程序来处理select的状态,其中值应该与选项本身中的一个value属性匹配。

例如

<select value={this.state.selectValue} onChange={this.handleChange} required={true}>
    {options}
</select>

既然将所选属性添加到其中一个选项中是不正确的,而且实际上会引发错误,那么该怎么办?

只要你想一想,答案很简单。既然我们希望我们的第一个选项被选中、禁用和隐藏,我们需要做三件事:

将隐藏和禁用的属性添加到第一个定义的选项。将第一个选项的值设置为空字符串。将select的值初始化为空字符串。

state = { selectValue = "" } // State or props or their equivalent

// In the render function
<select value={this.state.selectValue} onChange={this.handleChange} required={true}>
    <option key="someKey" value="" disabled="disabled" hidden="hidden">Select from Below</option>
    {renderOptions()}
</select>

现在,您可以按照上面的指示(或通过className,如果您愿意)设置选择的样式。

select:invalid { color: gray; }