Jak utworzyć element zastępczy dla pola "Wybierz"?

Używam symboli zastępczych do wprowadzania tekstu, co działa dobrze. Ale chciałbym również użyć zastępczego elementu dla moich pól wyboru. Oczywiście mogę po prostu użyć tego kodu:

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

Ale "Wybierz swoją opcję" jest w kolorze czarnym zamiast lightgrey. Więc moje rozwiązanie może być oparte na CSS. jQuery też jest w porządku.

To tylko sprawia, że opcja jest szara w rozwijanym menu (więc po kliknięciu strzałki):

option:first {
    color: #999;
}

Pytanie brzmi: jak ludzie tworzą placeholdery w selectboxach? Ale to już zostało odebrane, zdrówko.

I użycie tego powoduje, że wybrana wartość jest zawsze szara (nawet po wybraniu prawdziwej opcji):

select {
    color: #999;
}
Author: Peter Mortensen, 2011-04-27

30 answers

A non-CSS-no JavaScript / jQuery odpowiedź:

<select>
    <option value="" disabled selected>Select your option</option>
    <option value="hurr">Durr</option>
</select>
 3172
Author: David,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-01 13:06:09

Po prostu natknąłem się na to pytanie, a oto, co działa w Firefoksie i Chrome (przynajmniej):]}

<style>
select:invalid { color: gray; }
</style>
<form>
<select required>
    <option value="" disabled selected hidden>Please Choose...</option>
    <option value="0">Open when powered (most valves do this)</option>
    <option value="1">Closed when powered, auto-opens when power is cut</option>
</select>
</form>

Opcja wyłączona zatrzymuje wybieranie <option> zarówno za pomocą myszy, jak i klawiatury, podczas gdy samo użycie 'display:none' pozwala użytkownikowi nadal wybierać za pomocą strzałek na klawiaturze. Styl 'display:none' sprawia, że pole listy wygląda "ładnie".

Uwaga: użycie pustego atrybutu value w opcji "placeholder" umożliwia walidację (wymagany atrybut) wokół posiadania "zastępczego", więc jeśli opcja nie jest zmieniona, ale jest wymagana, przeglądarka powinna poprosić Użytkownika o wybranie opcji z listy.

Aktualizacja (Lipiec 2015):

Ta metoda jest potwierdzona w następujących przeglądarkach:

  • Google Chrome-v. 43.0.2357.132
  • Mozilla Firefox-V.39. 0
  • [39]}Safari - V.8.0. 7 (symbol zastępczy jest widoczny w rozwijanym menu, ale nie można go wybrać)
  • Microsoft Internet Explorer - v. 11 (Symbol zastępczy jest widoczny w rozwijanym menu, ale nie można go wybrać)
  • Projekt Spartan - V.15. 10130 (symbol zastępczy jest widoczny w rozwijanym menu, ale nie można go wybrać)]}

Aktualizacja (Październik 2015):

Usunąłem style="display: none" na rzecz atrybutu HTML5 hidden, który ma szerokie wsparcie. Element hidden ma podobne cechy jak display: none W Safari, Internet Explorerze (projekt Spartan wymaga sprawdzenia), gdzie option jest widoczny w rozwijanym menu, ale nie jest do wyboru.

Aktualizacja (Styczeń 2016):

Gdy element select jest required pozwala na użycie pseudoklasy :invalid CSS, która pozwala na stylizowanie elementu select w jego stanie "placeholder". :invalid działa tutaj ze względu na pustą wartość w symbolu zastępczym option.

Po ustawieniu wartości, pseudoklasa :invalid zostanie usunięta. Opcjonalnie możesz również użyć :valid, jeśli chcesz.

Większość przeglądarek obsługuje tę pseudo-klasę. Internet Explorer 10 i nowsze. W niektórych przypadkach (Mac w Chrome / Safari) musisz zmienić domyślny wygląd okna select, aby wyświetlały się pewne style, np. background-color i color. Kilka przykładów i więcej na temat kompatybilności znajdziesz na stronie developer.mozilla.org .

Natywny wygląd elementu Mac w Chrome:

Wybierz box native Mac w Chrome

Używanie zmienionego elementu obramowania Mac w Chrome:

Zmienione pole wyboru Mac w Chrome

 876
Author: William Isted,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-01 13:12:48

Dla wymaganego pola istnieje rozwiązanie czysto CSS w nowoczesnych przeglądarkach:

select:required:invalid {
  color: gray;
}
option[value=""][disabled] {
  display: none;
}
option {
  color: black;
}
<select required>
  <option value="" disabled selected>Select something...</option>
  <option value="1">One</option>
  <option value="2">Two</option>
</select>
 270
Author: MattW,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-28 16:09:06

Coś takiego:

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();

Przykład roboczy: http://jsfiddle.net/Zmf6t/

 105
Author: Albireo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-01 13:06:35

Właśnie dodałem Ukryty atrybut option Jak Poniżej. To działa dobrze dla mnie.

<select>
  <option hidden>Sex</option>
  <option>Male</option>
  <option>Female</option>
</select>
 50
Author: Ajithkumar S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-01 13:20:27

Poniższe rozwiązanie działa również w Firefoksie, bez żadnego JavaScript:

option[default] {
  display: none;
}
<select>
  <option value="" default selected>Select Your Age</option>
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
  <option value="4">4</option>
</select>
 37
Author: Dani-Br,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-01 13:14:10

Miałem ten sam problem i podczas wyszukiwania natknąłem się na to pytanie, a po znalezieniu dobrego rozwiązania dla mnie, chciałbym podzielić się nim z wami, na wypadek, gdyby ktoś mógł z niego skorzystać.

Oto jest:

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");
});

Po wykonaniu przez Klienta pierwszego wyboru, nie ma potrzeby stosowania koloru szarego, więc kod JavaScript usuwa klasę place_holder.

Dzięki @ user1096901, jako obejście dla Przeglądarka Internet Explorer, możesz dodać klasę place_holder ponownie w przypadku, gdy pierwsza opcja zostanie wybrana ponownie:)

 26
Author: rramiii,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-01 13:18:57

Nie ma potrzeby stosowania żadnego JavaScript czy CSS, tylko trzy atrybuty:

<select>
    <option selected disabled hidden>Default Value</option>
    <option>Value 1</option>
    <option>Value 2</option>
    <option>Value 3</option>
    <option>Value 4</option>
</select>

W ogóle nie pokazuje opcji; po prostu ustawia wartość opcji jako domyślną.

Jeśli jednak nie podoba Ci się Element Zastępczy o tym samym kolorze co reszta , możesz go naprawić w następujący sposób:

<!DOCTYPE html>
<html>
    <head>
        <title>Placeholder for select tag drop-down menu</title>
    </head>

    <body onload="document.getElementById('mySelect').selectedIndex = 0">
        <select id="mySelect" onchange="document.getElementById('mySelect').style.color = 'black'"     style="color: gray;    width: 150px;">
          <option value="" hidden>Select your beverage</option> <!-- placeholder -->
          <option value="water" style="color:black" >Water</option>
          <option value="milk" style="color:black" >Milk</option>
          <option value="soda" style="color:black" >Soda</option>
        </select>
    </body>
</html>

Oczywiście możesz rozdzielić funkcje i przynajmniej select CSS na osobne pliki.

Uwaga: funkcja onload koryguje odświeżanie bug.

 24
Author: Jacob Schneider,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-01 14:23:58

Użytkownik nie powinien widzieć symbolu zastępczego w opcjach select. Sugeruję użycie atrybutu hidden dla opcji zastępczej i nie potrzebujesz atrybutu selected dla tej opcji. Możesz to po prostu umieścić jako pierwszy.

select:not(:valid) {
  color: #999;
}
<select required>
    <option value="" hidden>Select your option</option>
    <option value="0">First option</option>
    <option value="1">Second option</option>
</select>
 21
Author: Roman Yakoviv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-01 14:30:37

Tutaj zmodyfikowałem odpowiedź Dawida (akceptowana odpowiedź). Na swoją odpowiedź, umieścił atrybut disabled i selected na znaczniku option, ale gdy umieścimy również tag hidden, będzie on wyglądał znacznie lepiej.

Dodając dodatkowy Ukryty atrybut na znaczniku option, zapobiegnie to ponownemu wybraniu opcji " Wybierz swoją opcję "Po wybraniu opcji" Durr".

<select>
    <option value="" disabled selected hidden>Select your option</option>
    <option value="hurr">Durr</option>
</select>
 18
Author: Nawaraj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-01 14:25:34

Oto moje:

select:focus option.holder {
  display: none;
}
<select>
    <option selected="selected" class="holder">Please select</option>
    <option value="1">Option #1</option>
    <option value="2">Option #2</option>

</select>
 16
Author: Will Wang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-01 13:20:58

Widzę oznaki poprawnych odpowiedzi, ale aby to wszystko połączyć, to byłoby moje rozwiązanie:

select {
  color: grey;
}

option {
  color: black;
}

option[default] {
   display: none;
}
<select>
    <option value="" default selected>Select your option</option>
    <option value="hurr">Durr</option>
</select>
 12
Author: user3520445,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-01 13:15:03

Jeśli używasz Angular, zrób tak:

<select>
    <option [ngValue]="undefined"  disabled selected>Select your option</option>
    <option [ngValue]="hurr">Durr</option>
</select>
 9
Author: arun kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-01 14:29:13

To HTML + CSS rozwiązanie zadziałało dla mnie:

form select:invalid {
  color: gray;
}

form select option:first-child {
  color: gray;
}

form select:invalid option:not(:first-child) {
  color: black;
}
<form>
  <select required>
    <option value="">Select Planet...</option>
    <option value="earth">Earth</option>
    <option value="pandora">Pandora</option>
  </select>
</form>
Powodzenia...
 5
Author: Aakash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-25 06:45:09

Inna możliwość w JavaScript:

 $('body').on('change', 'select', function (ev){
    if($(this).find('option:selected').val() == ""){
        $(this).css('color', '#999');
        $(this).children().css('color', 'black');
    }
    else {
        $(this).css('color', 'black');
        $(this).children().css('color', 'black');
    }
});

JSFiddle

 5
Author: Jean-philippe Emond,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-01 13:16:24

Bazując na odpowiedzi MattW , możesz uczynić opcję select placeholder widoczną w rozwijanym menu po dokonaniu prawidłowej selekcji, warunkowo ukrywając ją tylko wtedy, gdy symbol zastępczy pozostaje zaznaczony (a zatem select jest: invalid).

select:required:invalid {
  color: gray;
}
select:invalid > option[value=""][disabled] {
  display: none;
}
option {
  color: black;
}
<select required>
    <option value="" disabled selected>Select something...</option>
    <option value="1">One</option>
    <option value="2">Two</option>
</select>
 5
Author: Matthew Millar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-23 01:49:13

Uwielbiam przyjęte rozwiązanie i działa świetnie bez JavaScript.

Chcę tylko dodać, jak zaadoptowałem tę odpowiedź dla kontrolowanego wyboru komponentu Reactowego , ponieważ zajęło mi to kilka prób rozgryzienia tego. Włączenie react-select i skończenie z tym byłoby naprawdę proste, ale jeśli nie potrzebujesz niesamowitej funkcjonalności, jaką zapewnia to repozytorium, której nie mam dla danego projektu, nie ma potrzeby dodawania więcej kilobajtów do mojego pakietu. Uwaga, react-select obsługuje symbole zastępcze w selekcjach za pomocą złożonego systemu różnych elementów inputs i html.

W Reaccie, dla kontrolowanego komponentu, nie możesz dodać atrybutu selected do swoich opcji. React obsługuje stan select poprzez atrybut value na select, wraz z obsługą zmiany, gdzie wartość powinna pasować do jednego z atrybutów wartości w samych opcjach.

Takie jak na przykład

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

Ponieważ byłoby to niewłaściwe i rzeczywiście rzuciłby błąd, aby dodać atrybut selected do jednej z opcji, co wtedy?

Odpowiedź jest prosta, gdy o tym pomyślisz. Ponieważ chcemy, aby nasz pierwszy option był selected, a także disabled i hidden, musimy zrobić trzy rzeczy:

  1. Dodaj atrybut hidden i disabled do pierwszego zdefiniowanego option.
  2. ustaw wartość pierwszego option jako pusty łańcuch.
  3. Zainicjalizuj wartość select również jako pustą sznurek.
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>

Teraz możesz stylować select jak wskazano powyżej (lub za pomocą className, jeśli wolisz).

select:invalid { color: gray; }
 4
Author: wlh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-01 14:35:50

Input [type="text"] Style Placeholder dla wybranych elementów

Poniższe rozwiązanie symuluje Element Zastępczy, ponieważ odnosi się on do elementu input[type="text"]:

$('.example').change(function () {
  $(this).css('color', $(this).val() === '' ? '#999' : '#555');
});
.example {
  color: #999;
}

.example > option {
  color: #555;
}

.example > option[value=""] {
  color: #999;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<select class="example">
  <option value="">Select Option</option>
  <option>Option 1</option>
  <option>Option 2</option>
  <option>Option 3</option>
</select>
 3
Author: Grant Miller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Chciałem, aby SELECT był szary, dopóki nie zostanie wybrany tak dla tego kawałka HTML:

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

Dodałem definicje CSS:

select { color: grey; }
select:valid { color: black; }

Działa zgodnie z oczekiwaniami w Chrome / Safari i może również w innych przeglądarkach, ale nie sprawdziłem.

 3
Author: fbparis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-01 13:21:51

Oto CSS rozwiązanie, które działa pięknie. Zawartość jest dodawana (i bezwzględnie ustawiana względem kontenera) po elemencie zawierającym (poprzez: after pseudo-class ).

Pobiera swój tekst z atrybutu placeholder, który zdefiniowałem, gdy użyłem dyrektywy (attr (placeholder) ). Innym kluczowym czynnikiem jest pointer-events: none - pozwala to kliknąć tekst zastępczy, aby przejść do select. W przeciwnym razie nie spadnie, jeśli użytkownik kliknie tekst.

Dodaję .empty class myself in my select directive, but normally I find that angular adds / removes .ng-empty for me (zakładam, że to dlatego, że wprowadzam wersję 1.2 Angular w mojej próbce kodu).

(przykład pokazuje również, jak zawijać elementy HTML w AngularJS, aby utworzyć własne niestandardowe wejścia)

var app = angular.module("soDemo", []);
app.controller("soDemoController", function($scope) {
  var vm = {};
  vm.names = [{
      id: 1,
      name: 'Jon'
    },
    {
      id: 2,
      name: 'Joe'
    }, {
      id: 3,
      name: 'Bob'
    }, {
      id: 4,
      name: 'Jane'
    }
  ];
  vm.nameId;
  $scope.vm = vm;
});

app.directive('soSelect', function soSelect() {
  var directive = {
    restrict: 'E',
    require: 'ngModel',
    scope: {
      'valueProperty': '@',
      'displayProperty': '@',
      'modelProperty': '=',
      'source': '=',
    },
    link: link,
    template: getTemplate
  };
  return directive;


  /////////////////////////////////
  function link(scope, element, attrs, ngModelController) {
    init();
    return;


    ///////////// IMPLEMENTATION

    function init() {
      initDataBinding();
    }


    function initDataBinding() {
      ngModelController.$render = function() {
        if (scope.model === ngModelController.$viewValue) return;
        scope.model = ngModelController.$viewValue;
      }

      scope.$watch('model', function(newValue) {
        if (newValue === undefined) {
          element.addClass('empty');
          return;
        }
        element.removeClass('empty');
        ngModelController.$setViewValue(newValue);
      });
    }
  }


  function getTemplate(element, attrs) {
    var attributes = [
      'ng-model="model"',
      'ng-required="true"'
    ];

    if (angular.isDefined(attrs.placeholder)) {
      attributes.push('placeholder="{{placeholder}}"');
    }

    var ngOptions = '';

    if (angular.isDefined(attrs.valueProperty)) {
      ngOptions += 'item.' + attrs.valueProperty + ' as ';
    }

    ngOptions += 'item.' + attrs.displayProperty + ' for item in source';
    ngOptions += '"';
    attributes.push('ng-options="' + ngOptions + '"');

    var html = '<select ' + attributes.join(' ') + '></select>';

    return html;
  }
});
so-select {
  position: relative;
}

so-select select {
  font-family: 'Helvetica';
  display: inline-block;
  height: 24px;
  width: 200px;
  padding: 0 1px;
  font-size: 12px;
  color: #222;
  border: 1px solid #c7c7c7;
  border-radius: 4px;
}

so-select.empty:before {
  font-family: 'Helvetica';
  font-size: 12px;
  content: attr(placeholder);
  position: absolute;
  pointer-events: none;
  left: 6px;
  top: 3px;
  z-index: 0;
  color: #888;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="soDemo" ng-controller="soDemoController">
  <so-select value-property="id" display-property="name" source="vm.names" ng-model="vm.nameId" placeholder="(select name)"></so-select>
</div>
 3
Author: flyer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-01 13:24:49

Nie mogłem uruchomić żadnego z nich, ponieważ dla mnie jest (1) nie jest wymagane i (2) wymaga opcji powrotu do domyślnego wyboru. Więc oto opcja ciężkich rąk, jeśli używasz jQuery:

var $selects = $('select');
$selects.change(function () {
  var option = $('option:default', this);
  if(option && option.is(':selected')) {
    $(this).css('color', '#999');
  }
  else {
    $(this).css('color', '#555');
  }
});

$selects.each(function() {
  $(this).change();
});
option {
    color: #555;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select name="in-op">
    <option default selected>Select Option</option>
    <option>Option 1</option>
    <option>Option 2</option>
    <option>Option 3</option>
</select>
 3
Author: Eric G,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-01 14:11:21

Nie jestem zadowolony z rozwiązań HTML / CSS, więc zdecydowałem się stworzyć niestandardowe select przy użyciu JavaScript.

To jest coś, co pisałem w ciągu ostatnich 30 minut, więc można to jeszcze poprawić.

Wystarczy utworzyć prostą listę z kilkoma atrybutami danych. Kod automatycznie zamienia listę w wybrane rozwijane menu. Dodaje również ukrytą input do przechowywania wybranej wartości, dzięki czemu może być używana w forma.

Wejście:

<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>

Wyjście:

<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>

Tekst elementu, który ma być symbolem zastępczym, jest wyszarzony. Element Zastępczy jest wybierany na wypadek, gdyby użytkownik chciał cofnąć swój wybór. Również przy użyciu CSS można przezwyciężyć wszystkie wady select (np. niemożność stylizacji opcji).

// Helper function to create elements faster/easier
// https://github.com/akinuri/js-lib/blob/master/element.js
var elem = function(tagName, attributes, children, isHTML) {
  let parent;
  if (typeof tagName == "string") {
    parent = document.createElement(tagName);
  } else if (tagName instanceof HTMLElement) {
    parent = tagName;
  }
  if (attributes) {
    for (let attribute in attributes) {
      parent.setAttribute(attribute, attributes[attribute]);
    }
  }
  var isHTML = isHTML || null;
  if (children || children == 0) {
    elem.append(parent, children, isHTML);
  }
  return parent;
};
elem.append = function(parent, children, isHTML) {
  if (parent instanceof HTMLTextAreaElement || parent instanceof HTMLInputElement) {
    if (children instanceof Text || typeof children == "string" || typeof children == "number") {
      parent.value = children;
    } else if (children instanceof Array) {
      children.forEach(function(child) {
        elem.append(parent, child);
      });
    } else if (typeof children == "function") {
      elem.append(parent, children());
    }
  } else {
    if (children instanceof HTMLElement || children instanceof Text) {
      parent.appendChild(children);
    } else if (typeof children == "string" || typeof children == "number") {
      if (isHTML) {
        parent.innerHTML += children;
      } else {
        parent.appendChild(document.createTextNode(children));
      }
    } else if (children instanceof Array) {
      children.forEach(function(child) {
        elem.append(parent, child);
      });
    } else if (typeof children == "function") {
      elem.append(parent, children());
    }
  }
};


// Initialize all selects on the page
$("ul.select").each(function() {
  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": "hidden"});
  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(placeholder, this.children[0]);
  container.appendChild(hidden);
  container.appendChild(selected);
  container.appendChild(this);
  parent.insertBefore(container, refElem);
});

// Update necessary elements with the selected option
$(".ul-select-container ul li").on("click", function() {
  var text     = this.innerText;
  var value    = this.dataset.value || "";
  var selected = this.parentElement.previousElementSibling;
  var hidden   = selected.previousElementSibling;
  hidden.value = selected.dataset.value = value;
  selected.children[0].innerText = text;
  if (this.classList.contains("placeholder")) {
    selected.classList.add("placeholder");
  } else {
    selected.classList.remove("placeholder");
  }
  selected.parentElement.classList.remove("visible");
});

// Open select dropdown
$(".ul-select-container .selected").on("click", function() {
  if (this.parentElement.classList.contains("visible")) {
    this.parentElement.classList.remove("visible");
  } else {
    this.parentElement.classList.add("visible");
  }
});

// Close select when focus is lost
$(document).on("click", function(e) {
  var container = $(e.target).closest(".ul-select-container");
  if (container.length == 0) {
    $(".ul-select-container.visible").removeClass("visible");
  }
});
.ul-select-container {
  width: 200px;
  display: table;
  position: relative;
  margin: 1em 0;
}
.ul-select-container.visible ul {
  display: block;
  padding: 0;
  list-style: none;
  margin: 0;
}
.ul-select-container ul {
  background-color: white;
  border: 1px solid hsla(0, 0%, 60%);
  border-top: none;
  -webkit-user-select: none;
  display: none;
  position: absolute;
  width: 100%;
  z-index: 999;
}
.ul-select-container ul li {
  padding: 2px 5px;
}
.ul-select-container ul li.placeholder {
  opacity: 0.5;
}
.ul-select-container ul li:hover {
  background-color: dodgerblue;
  color: white;
}
.ul-select-container ul li.placeholder:hover {
  background-color: rgba(0, 0, 0, .1);
  color: initial;
}
.ul-select-container .selected {
  background-color: white;
  padding: 3px 10px 4px;
  padding: 2px 5px;
  border: 1px solid hsla(0, 0%, 60%);
  -webkit-user-select: none;
}
.ul-select-container .selected {
  display: flex;
  justify-content: space-between;
}
.ul-select-container .selected.placeholder .text {
  color: rgba(0, 0, 0, .5);
}
.ul-select-container .selected .icon {
  font-size: .7em;
  display: flex;
  align-items: center;
  opacity: 0.8;
}
.ul-select-container:hover .selected {
  border: 1px solid hsla(0, 0%, 30%);
}
.ul-select-container:hover .selected .icon {
  opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<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>

<ul class="select" data-placeholder="Sex" data-name="sex">
  <li data-value="male">Male</li>
  <li data-value="female">Female</li>
</ul>

Update : poprawiłem to (wybór za pomocą klawiszy GÓRA / DÓŁ/enter), uporządkowałem wyjście trochę i zamienił to w przedmiot. Wyjście prądowe:

<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>

Inicjalizacja:

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

Do dalszej analizy: JSFiddle, GitHub (przemianowany).


Update: I am have reapred this again. Zamiast używać listy, możemy po prostu użyć select. W ten sposób będzie działać nawet bez JavaScript (w przypadku niepełnosprawnych).

Wejście:

<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]);

Wyjście:

<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 .

 3
Author: akinuri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-01 14:28:09

Zobacz tę odpowiedź:

<select>
        <option style="display: none;" value="" selected>SelectType</option>
        <option value="1">Type 1</option>
        <option value="2">Type 2</option>
        <option value="3">Type 3</option>
        <option value="4">Type 4</option>
</select>
 3
Author: Jesto .K.J,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-07-02 07:55:44

Możesz ustawić kolor pierwszej opcji na gray, ustawić wyświetlanie na none, ustawić kolor select na gray i dodać do niej detektor zdarzeń input, który ustawia kolor na black.

select > option:not(:first-of-type) {
  color: black;
}
<select style='color:gray' oninput='style.color="black"'>
  <option style='display:none'>
    Choose an option
  </option>
  <option>
    1
  </option>
  <option>
    2
  </option>
  <option>
    3
  </option>
</select>

Korzystanie z API customElement:

class placeholderSelect extends HTMLElement {
  connectedCallback() {
    this.outerHTML = `<select style='color:gray' oninput='style.color="black"'>
  <option style='display:none'>
    ${this.getAttribute('data-placeholder')}
  </option>
  ${this.innerHTML}
</select>`

    Array.from(this.children).forEach(function(el, i) {
      if (i !== 0) {
        el.style.color = 'black'
      }
    })
  }
}

customElements.define('placeholder-select', placeholderSelect)
<placeholder-select data-placeholder='Choose an option'>
  <option>
    1
  </option>
  <option>
    2
  </option>
  <option>
    3
  </option>
</placeholder-select>
 3
Author: GalaxyCat105,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-04 18:29:30

Potrzebujesz walidacji formularza i nowoczesne przeglądarki oferują to od podstaw.

Więc nie musisz uważać, że użytkownik nie może wybrać pola. Ponieważ kiedy to robi, Walidacja przeglądarki powie mu, że jest to zły wybór.

Wbudowana w przeglądarkę funkcja walidacji checkValidity () .

Bootstrap ma również ładny przykład.

HTML

<form class="needs-validation">
  <select required>
    <option value="">Please select an option</option>
    <option value="1">Foo</option>
    <option value="2">Bar</option>
  </select>
<form>

Javascript

form = document.getElementByClassName('needs-validation');
if(form.checkValidity() === true) {
  //form validation succeeded
} else {
  //form validation failed
}
 2
Author: Jurik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-22 10:02:15

Try this it work good for my

<select class="form-control">
    <option value="" readonly="true" hidden="true" selected>Select your option</option>
    <option value="1">Something</option>
    <option value="2">Something else</option>
    <option value="3">Another choice</option>
</select>
 2
Author: Abdulmajeed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-24 11:17:16

Możesz to zrobić bez użycia Javascript używając tylko {[2] } Musisz ustawić domyślną opcję select disabled="" i selected="" i wybierz tag required="". przeglądarka nie pozwala użytkownikowi przesłać formularza bez wybrania opcji.

<form action="" method="POST">
    <select name="in-op" required="">
        <option disabled="" selected="">Select Option</option>
        <option>Option 1</option>
        <option>Option 2</option>
        <option>Option 3</option>
    </select>
    <input type="submit" value="Submit">
</form>
 1
Author: Thusitha Wickramasinghe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-15 15:03:25

W Angular możemy dodać opcję jako symbol zastępczy, który może być ukryty W rozwijanym menu opcji. Możemy nawet dodać niestandardową ikonę rozwijanąjako tło, które zastępuje ikonę rozwijaną przeglądarki.

Sztuczka polega na tym, aby włączyć Element Zastępczy css tylko wtedy, gdy wartość nie jest wybrana

/**Mój Szablon Komponentu*/

 <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>

/**Mój Składnik.TS */

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

/**global.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;
    }
  }
}
 1
Author: Mukundhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-26 12:10:24

Rozwiązanie dla kąta 2

Utwórz etykietę na górze select

<label class="hidden-label" for="IsActive"
    *ngIf="filterIsActive == undefined">Placeholder text</label>
<select class="form-control form-control-sm" type="text" name="filterIsActive"
    [(ngModel)]="filterIsActive" id="IsActive">
    <option value="true">true</option>
    <option value="false">false</option>
</select>

I zastosuj CSS, aby umieścić go na górze

.hidden-label {
    position: absolute;
    margin-top: .34rem;
    margin-left: .56rem;
    font-style: italic;
    pointer-events: none;
}

pointer-events: none umożliwia wyświetlenie opcji wybierz po kliknięciu etykiety, która jest ukryta po wybraniu opcji.

Kątowe html css

 1
Author: edu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-18 12:54:54

Oto mój wkład. Haml + CoffeeScript + SCSS

Haml

=f.collection_select :country_id, [us] + Country.all, :id, :name, {prompt: t('user.country')}, class: 'form-control'

CoffeeScript

  $('select').on 'change', ->
    if $(this).val()
      $(this).css('color', 'black')
    else
      $(this).css('color', 'gray')
  $('select').change()

SCSS

select option {
  color: black;
}

Można używać tylko CSS zmieniając kod serwera i ustawiając tylko Style klas w zależności od bieżącej wartości właściwości, ale ten sposób wydaje się łatwiejszy i czystszy.

$('select').on('change', function() {
  if ($(this).val()) {
    return $(this).css('color', 'black');
  } else {
    return $(this).css('color', 'gray');
  }
});

$('select').change();
    select option {
      color: black;
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select class="form-control" name="user[country_id]" id="user_country_id">
  <option value="">Country</option>
                      <option value="231">United States</option>
                      <option value="1">Andorra</option>
                      <option value="2">Afghanistan</option>
                      <option value="248">Zimbabwe</option></select>

Możesz dodać więcej CSS (select option:first-child), aby utrzymać symbol zastępczy szary, gdy się otworzy, ale nie obchodziło mnie to to.

 1
Author: Chloe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-01 14:16:31