Como faço para criar um espaço reservado para uma caixa 'selecionar'?

1542

Estou usando espaços reservados para entradas de texto que estão funcionando bem. Mas eu gostaria de usar um espaço reservado para minhas caixas de seleção também. Claro que posso apenas usar este código:

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

Mas a opção "Selecione sua opção" está em preto em vez de cinza claro. Portanto, minha solução pode ser baseada em CSS. jQuery também está bem.

Isso só torna a opção cinza no menu suspenso (então, depois de clicar na seta):

option:first {
    color: #999;
}

A pergunta é: como as pessoas criam espaços reservados nas caixas de seleção? Mas já foi respondido, aplausos.

E usar isso resulta no valor selecionado sempre em cinza (mesmo depois de selecionar uma opção real):

select {
    color: #999;
}
Thomas
fonte
1
Apenas no caso de alguém ler isso - publiquei uma solução mais comum para navegadores modernos com validação incorporada no navegador. Bem-vindo ao ano 2020;)
Jurik em 22/01

Respostas:

2974

Uma resposta não CSS - sem JavaScript / jQuery:

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

David
fonte
134
O Firefox (10) não mostra uma opção desabilitada como a seleção padrão (espaço reservado). Ele mostra o próximo por padrão, neste caso "Durr".
jarnoan
53
Normalmente, adiciono desativado e selecionado. Parece funcionar também em FF.
Nilskp 21/05
11
<select> <option value="" disabled selected>Select your option</option> </select>
Kolypto
183
A razão pela qual essa não é a resposta correta é porque (acredito) o solicitante deseja que a seleção fique cinza até que outro valor seja selecionado. Esta resposta torna a opção cinza no menu suspenso; mas não o elemento select.
Bill
22
selecione {opção [desabilitada] {display: none; }}
Dimael Vertigo 11/11
822

Eu me deparei com essa pergunta, e aqui está o que funciona no Firefox e Chrome (pelo menos):

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

A opção Desativado interrompe a <option>seleção com o mouse e o teclado, enquanto o simples uso 'display:none'permite ao usuário ainda selecionar através das setas do teclado. O 'display:none'estilo apenas faz a caixa de listagem parecer 'legal'.

Nota: O uso de um valueatributo vazio na opção "espaço reservado" permite que a validação (atributo obrigatório) contenha o "espaço reservado"; portanto, se a opção não for alterada, mas necessária, o navegador deverá solicitar ao usuário que escolha uma opção da lista.

Atualização (julho de 2015):

Este método é confirmado trabalhando nos seguintes navegadores:

  • Google Chrome - v.43.0.2357.132
  • Mozilla Firefox - v.39.0
  • Safari - v.8.0.7 (o espaço reservado é visível no menu suspenso, mas não é selecionável)
  • Microsoft Internet Explorer - v.11 (o espaço reservado é visível no menu suspenso, mas não é selecionável)
  • Projeto Spartan - v.15.10130 (o espaço reservado é visível no menu suspenso, mas não é selecionável)

Atualização (outubro de 2015):

Eu removi o style="display: none"favor do atributo HTML5, hiddenque tem amplo suporte. O hiddenelemento possui características semelhantes às display: nonedo Safari, Internet Explorer, (o Project Spartan precisa de verificação), onde optioné visível no menu suspenso, mas não é selecionável.

Atualização (janeiro de 2016):

Quando o selectelemento está, requiredele permite o uso da :invalidpseudo-classe CSS, que permite estilizar o selectelemento no estado "espaço reservado". :invalidfunciona aqui por causa do valor vazio no espaço reservado option.

Depois que um valor for definido, a :invalidpseudo-classe será descartada. Opcionalmente, você também pode usar, :validse desejar.

A maioria dos navegadores suporta essa pseudo classe. Internet Explorer 10 e posterior. Isso funciona melhor com selectelementos de estilo personalizado ; em alguns casos, ou seja, (Mac no Chrome / Safari), você precisará alterar a aparência padrão da selectcaixa para que certos estilos sejam exibidos, background-colore color. Você pode encontrar alguns exemplos e mais sobre compatibilidade em developer.mozilla.org .

Aparência do elemento nativo Mac no Chrome:

Marque a caixa Mac nativo no Chrome

Usando o elemento de borda alterado Mac no Chrome:

Caixa de seleção alterada Mac no Chrome

William Isted
fonte
5
@jaacob Nos navegadores que testei, o estilo 'display: none' oculta o "Por favor, escolha" da lista, o que apenas o torna mais agradável.
William Isted
38
Importante observar que uma opção desabilitada não pode ser selecionada novamente: se a seleção for obrigatória, tudo bem - mas não se a seleção for opcional.
22812 Robert
2
Explorer11 ignora o display:noneestilo.
T30
1
Parabéns ao @MattW por trabalhar :invalidmuito antes de mim.
William isTed
3
Você também pode adicionar uma regra para "redefinir" coloras opções nos navegadores de suporte, como neste violino . Isso ajudaria a reforçar que os desmotivados optionsão um espaço reservado. (Edit: Eu vejo MattW já cobriu este em sua resposta)
Shaggy
251

Para um campo obrigatório, há uma solução de CSS puro nos navegadores modernos:

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>

MattW
fonte
7
Incrível - foi a resposta na parte inferior (ainda sem votos positivos) que foi a mais simples e, na verdade, funciona perfeitamente. Obrigado! Esperemos que esta resposta chegue ao topo.
Dan Nissenbaum
2
@ DanNissenbaum Eu estava muito atrasado para o jogo, além disso, ele precisa requiredfuncionar, por isso não adianta se você quiser que o campo seja opcional.
MattW
1
Como um aparte, o :requiredseletor não é suportado no IE8 e abaixo. O :invalidseletor não é suportado no IE9 e abaixo. Quirksmode.org/css/selectors
Matt Wagner
4
Não há solução para uma seleção não necessária?
user3494047
1
@ user3494047 não com esta abordagem - é a requiredcondição que faz com que o navegador aplique a :invalidpseudo-classe quando o espaço reservado é selecionado. [value=""]não funcionará como um substituto, porque o que é atualizado pela interação do usuário é a propriedade value , mas a sintaxe CSS se refere a um atributo (inexistente) .
MattW
105

Algo assim:

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

Exemplo de trabalho: http://jsfiddle.net/Zmf6t/

Albireo
fonte
8
Foi exatamente isso que fiz recentemente. mas eu adicionei um manipulador de keyup modo que a mudança também ocorre quando uma opção é selecionada através do teclado (usando as setas ou atalhos carta) jsfiddle.net/Zmf6t/131
Radu
isso me colocou no caminho certo ... no entanto, eu fiz o valor = "" (nada entre as aspas) para que quando o botão enviar foi clicado, ele ainda não conseguiu validar a primeira opção e um pop-up do navegador apareceria informando você para selecionar uma opção ... obrigado @Albireo
Craig Wayne
Por que você chamou a função de alteração explicitamente.
foreever
@ Antes, porque eu defino a classe CSS no manipulador de eventos de alteração do select, portanto, se você não aumentar manualmente o evento quando o controle for criado, o estilo não será aplicado (ele será aplicado apenas quando o usuário alterar manualmente o valor).
Albireo
Isso não está funcionando no JQeury 3.4.1
geobudex
45

Acabei de adicionar um atributo oculto em um optionlike abaixo. Está funcionando bem pra mim.

<select>
  <option hidden>Sex</option>
  <option>Male</option>
  <option>Female</option>
</select>

Ajithkumar S
fonte
2
Apenas para constar, isso não funciona para mim (Chrome no Win10).
Chris Rae
Mas você não pode desfazê-lo. Você acaba escolhendo um, mas não pode redefinir caso mude de idéia.
Thielicious 18/08/19
sim! Mas de qualquer maneira, dentro do formulário, o usuário deve selecionar qualquer uma dessas opções. Se não for um campo obrigatório, remova o atributo oculto.
Ajithkumar S
35

A solução abaixo também funciona no Firefox, sem 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>

Dani-Br
fonte
26

Eu tive o mesmo problema e, durante a pesquisa, me deparei com essa pergunta e, depois de encontrar uma boa solução para mim, gostaria de compartilhá-la com vocês, caso alguém possa se beneficiar.

Aqui está:

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

Depois que o cliente faz a primeira seleção, não há necessidade de cor cinza, portanto o código JavaScript remove a classe place_holder.

Graças a @ user1096901, como solução alternativa para o navegador Internet Explorer, você pode adicionar a place_holderclasse novamente caso a primeira opção seja selecionada novamente :)

rramiii
fonte
2
Em alguns navegadores, ele ainda pode selecionar a tela: nenhuma opção, porque não está oculta.
Srneczek
A solução para este é adicionar "place_holder" classe novamente caso primeira opção é selecionada :)
rramiii
23

Não há necessidade de JavaScript ou CSS, apenas três atributos:

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

Não mostra a opção; apenas define o valor da opção como padrão.

No entanto, se você não gostar de um espaço reservado da mesma cor que o restante , poderá corrigi-lo da seguinte maneira:

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

Obviamente, você pode separar as funções e pelo menos o CSS do select em arquivos separados.

Nota: a função onload corrige um bug de atualização.

Jacob Schneider
fonte
Isso não funciona se a opção escondida é o único
Eridanis
mas por que você teria um menu suspenso com apenas uma opção?
Jacob Schneider
Eu tenho um pop-up com guias e o menu suspenso da guia3 recebe a entrada da guia2, que é exibida. Sua resposta é boa e esse é um caso de canto, mas eu esperava que o valor padrão fosse exibido como a primeira opção; em vez disso, você recebe um menu suspenso em branco. Veja aqui: jsfiddle.net/n66L7sza
Eridanis
Esse é um ponto bom, caso em que você poderia fazer a varredura do comprimento da suspenso, se for zero, em seguida, remover o atributo oculto
Jacob Schneider
Isso não parece funcionar corretamente no Google Chrome 65.0.3325.181 no MacOS, não mostra a entrada oculta e escolhe a que está abaixo.
21318 Jamie H
19

O usuário não deve ver o espaço reservado nas opções selecionadas. Sugiro usar o hiddenatributo para a opção de espaço reservado e você não precisa do selectedatributo para esta opção. Você pode colocá-lo como o primeiro.

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>

Roman Yakoviv
fonte
2
ou select:invalidtambém é válido.
Elquimista 18/10/19
2
Eu recomendo este, pois ele não apresenta o texto do espaço reservado na lista, pelo menos no Chrome.
JoeRaid 2/19/19
Note que o estilo não funciona semrequired
akmalhakimi1991
18

Aqui eu modifiquei a resposta de David (resposta aceita). Em sua resposta, ele colocou o atributo desativado e selecionado na optiontag, mas quando também colocamos a tag oculta, ela ficará muito melhor.

Ao adicionar um atributo oculto extra na optiontag, impedirá que a opção "Selecione sua opção" seja re-selecionada após a seleção da opção "Durr".

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

Nawaraj
fonte
Obrigado pela atualização, mas a resposta ainda não explica por que parece diferente. Por exemplo, esta resposta impede que a opção "Selecione sua opção" seja re-selecionada após a seleção da opção "Durr" . Qual atributo causa esse comportamento?
Bgran 6/05/19
16

Aqui é minha:

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>

Will Wang
fonte
Você pode apenas adicionar <option value="" selected disabled>Please select</option>como a primeira opção.
precisa saber é o seguinte
Não deixa o espaço reservado cinza claro.
Chloe
12

Vejo sinais de respostas corretas, mas, para reunir tudo, essa seria a minha solução:

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>

user3520445
fonte
8
Durrfica cinza depois que você o seleciona. Isso força a caixa de seleção fechada a ficar sempre cinza.
Chloe
9

Se você estiver usando Angular, vá assim:

<select>
    <option [ngValue]="undefined"  disabled selected>Select your option</option>
    <option [ngValue]="hurr">Durr</option>
</select>

Arun Kumar
fonte
Você pode adicionar o hiddenatributo para que a opção não seja exibida ao abrir o select. Mas, de qualquer forma, obrigado por essa resposta, funcionou para mim.
DCG
5

Esta HTML + CSSsolução funcionou para mim:

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>

Boa sorte...

Akash
fonte
Parece não funcionar no JQuery 3.4.1
geobudex em 09/02
5

Outra possibilidade em 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

Jean-philippe Emond
fonte
4

Adoro a solução aceita e funciona muito bem sem JavaScript.

Eu só quero adicionar como eu adotei essa resposta para um componente de reação com seleção controlada , porque demorei algumas tentativas para descobrir. Seria muito simples de incorporar react-selecte terminar com ele, mas, a menos que você precise da incrível funcionalidade que este repositório fornece, o que não é necessário para o projeto em questão, não há necessidade de adicionar mais kilobytes ao meu pacote. Observe que react-selectmanipula espaços reservados em selects através de um sistema complexo de vários inputse htmlelementos.

No React, para um componente controlado , você não pode adicionar o selectedatributo às suas opções. O React manipula o estado da seleção por meio de um valueatributo sobre selectele mesmo, junto com um manipulador de alterações, em que o valor deve corresponder a um dos atributos de valor nas próprias opções.

Por exemplo, por exemplo

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

Como seria impróprio e, de fato, geraria um erro para adicionar o selectedatributo a uma das opções, o que então?

A resposta é simples quando você pensa sobre isso. Como queremos que o nosso primeiro optionseja selectedtão bom quanto disablede hidden, precisamos fazer três coisas:

  1. Adicione o atributo hiddene disabledao primeiro definido option.
  2. Defina o valor do primeiro optioncomo uma sequência vazia.
  3. Inicialize o valor de selectpara também ser uma sequência vazia.
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>

Agora você pode estilizar a seleção conforme indicado acima (ou via a, classNamese preferir).

select:invalid { color: gray; }
wlh
fonte
3

Espaço [type="text"]reservado para o estilo de entrada para elementos selecionados

A solução a seguir simula um espaço reservado no que se refere a um input[type="text"]elemento:

$('.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>

Grant Miller
fonte
3

Eu queria que o SELECT fosse cinza até ser selecionado, para este trecho de HTML:

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

Eu adicionei estas definições de CSS:

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

Funciona como esperado no Chrome / Safari e talvez também em outros navegadores, mas eu não verifiquei.

fbparis
fonte
3

Aqui está uma solução CSS que funciona lindamente. O conteúdo é adicionado (e absolutamente posicionado em relação ao contêiner) após o elemento que contém ( via: after pseudo-class ).

Ele obtém seu texto do atributo placeholder que eu defini onde usei a diretiva ( attr (placeholder) ). Outro fator importante são os eventos do ponteiro: nenhum - isso permite que cliques no texto do espaço reservado passem para a seleção. Caso contrário, não será suspenso se o usuário clicar no texto.

Eu mesmo adicionei a classe .empty na minha diretiva select, mas normalmente acho que o angular adiciona / remove .ng-vazio para mim (suponho que seja porque estou injetando a versão 1.2 do Angular no meu exemplo de código).

(A amostra também demonstra como agrupar elementos HTML no AngularJS para criar suas próprias entradas personalizadas)

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>

folheto
fonte
3

Não consegui fazer com que nenhum deles funcione atualmente, porque para mim não é (1) necessário e (2) precisa da opção para retornar ao padrão selecionável. Então, aqui está uma opção pesada, se você estiver usando o 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>

Eric G
fonte
Obrigado, este foi o melhor para mim, como você disse ... o elemento select é necessário.
Mousa Alfhaily #: 20113
3

Não estou satisfeito com soluções somente HTML / CSS, por isso decidi criar um personalizado selectusando JavaScript.

Isso é algo que escrevi nos últimos 30 minutos, portanto, pode ser melhorado ainda mais.

Tudo que você precisa fazer é criar uma lista simples com poucos atributos de dados. O código transforma automaticamente a lista em um menu suspenso selecionável. Ele também adiciona um oculto inputpara armazenar o valor selecionado, para que possa ser usado em um formulário.

Entrada:

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

Resultado:

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

O texto do item que deveria ser um espaço reservado fica acinzentado. O espaço reservado é selecionável, caso o usuário deseje reverter sua escolha. Também usando CSS, todas as desvantagens de selectpodem ser superadas (por exemplo, incapacidade de definir o estilo das opções).


Atualização : melhorei isso (seleção usando as teclas para cima / para baixo / enter), arrumei a saída um pouco e transformei isso em um objeto. Saída atual:

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

Inicialização:

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

Para um exame mais aprofundado: JSFiddle , GitHub (renomeado).


Atualização: reescrevi isso novamente. Em vez de usar uma lista, podemos apenas usar um select. Dessa forma, ele funcionará mesmo sem JavaScript (caso esteja desativado).

Entrada:

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

Resultado:

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

akinuri
fonte
2

Você precisa da validação do formulário e os navegadores modernos oferecem isso do zero.

Portanto, você não precisa cuidar para que o usuário não possa selecionar o campo. Porque quando ele está fazendo isso, a validação do navegador diz a ele que esta é uma seleção errada.

O navegador embutido na função de validação checkValidity () .

O Bootstrap também tem um bom exemplo.

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
}
Jurik
fonte
1

Você pode fazer isso sem usar Javascriptusando apenas HTMLVocê precisa opção de selecção conjunto padrão de disabled=""e selected=""e selecione tag required="".navegador não permitem que o usuário enviar o formulário sem selecionar uma opção.

<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>
Assim é Wickramasinghe
fonte
Isso faz com que todo o elemento de seleção fique acinzentado até que uma opção seja escolhida, causando um comportamento potencialmente indesejado.
Wickedchild 11/11
1

Em Angular , podemos adicionar uma opção como espaço reservado que pode ser ocultada no menu suspenso. Podemos até adicionar um ícone suspenso personalizado como plano de fundo que substitui o ícone suspenso do navegador .

O truque é ativar o espaço reservado css somente quando o valor não estiver selecionado

/ ** Meu modelo de componente * /

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

/ ** Meu componente.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;
    }
  }
}
Mukundhan
fonte
1

Solução para Angular 2

Crie um rótulo em cima da seleção

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

e aplique CSS para colocá-lo em cima

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

pointer-events: none permite exibir a seleção quando você clica no rótulo, que fica oculto quando você seleciona uma opção.

edu
fonte
1

Aqui está a minha contribuição. 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;
}

É possível usar apenas CSS alterando o código do servidor e definindo apenas os estilos de classe, dependendo do valor atual da propriedade, mas dessa maneira parece mais fácil e limpo.

$('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>

Você pode adicionar mais CSS ( select option:first-child) para manter o espaço reservado em cinza quando for aberto, mas não me importei com isso.

Chloe
fonte
1

Tente isso para variar:

$("select").css("color", "#757575");
$(document).on("change", "select", function(){
    if ($(this).val() != "") {
        $(this).css("color", "");
    } 
    else {
        $(this).css("color", "#757575");
    }
});
Jordan Lipana
fonte
1

Aqui está um exemplo prático de como conseguir isso com JavaScript puro que lida com a cor das opções após o primeiro clique:

<!DOCTYPE html>
<html>
  <head>
    <style>
      #myselect {
        color: gray;
      }
    </style>
  </head>

  <body>
    <select id="myselect">
      <option disabled selected>Choose Item
      </option>

      <option>Item 1
      </option>

      <option>Item 2
      </option>

      <option>Item 3
      </option>
    </select>

    <script>
      // Add event listener to change color in the first click
      document.getElementById("myselect").addEventListener("click", setColor)
      function setColor()
      {
        var combo = document.getElementById("myselect");
        combo.style.color = 'red';
        // Remove Event Listener after the color is changed at the first click
        combo.removeEventListener("click", setColor);
      }
    </script>
  </body>
</html>
jonathana
fonte
1

Com base na resposta de MattW , você pode tornar a opção selecionar espaço reservado visível no menu suspenso após a seleção válida, ocultando-a condicionalmente apenas enquanto o espaço reservado permanece selecionado (e a seleção é, portanto, inválida).

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>

Matthew Millar
fonte
0

Com base na resposta de Albireo , esta versão não usa jQuery e a especificidade do CSS é melhor.

const triggerEvent = (el, eventName) => {
  let event = document.createEvent('HTMLEvents')
  event.initEvent(eventName, true, false)
  el.dispatchEvent(event)
}

let select = document.querySelector('.placeholder-select')
select.addEventListener('change', (e) => {
  e.target.classList[e.target.value == 0 ? 'add' : 'remove']('empty')
})
triggerEvent(select, 'change')
.placeholder-select option {
  color: #000000;
}
.placeholder-select option:first-child {
  color: #444444;
  font-style: italic;
  font-weight: bold;
}
.placeholder-select.empty {
  color: #7F7F7F;
}
<select class="placeholder-select">
  <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>

Mr. Polywhirl
fonte