¿Cómo hago un marcador de posición para un cuadro 'select'?


1542

Estoy usando marcadores de posición para las entradas de texto, que está funcionando bien. Pero también me gustaría usar un marcador de posición para mis cajas de selección. Por supuesto, solo puedo usar este código:

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

Pero el 'Seleccione su opción' está en negro en lugar de gris claro. Entonces, mi solución podría estar basada en CSS. jQuery también está bien.

Esto solo hace que la opción sea gris en el menú desplegable (así que después de hacer clic en la flecha):

option:first {
    color: #999;
}

La pregunta es: ¿cómo crean las personas los marcadores de posición en las cajas de selección? Pero ya ha sido respondido, saludos.

Y usar esto da como resultado que el valor seleccionado siempre sea gris (incluso después de seleccionar una opción real):

select {
    color: #999;
}

1
En caso de que alguien lea esto, publiqué una solución más común para los navegadores modernos con la validación integrada del navegador. Bienvenido al año 2020;)
Jurik

Respuestas:


2974

Un no CSS - sin respuesta JavaScript / jQuery:

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


134
Firefox (10) no muestra una opción deshabilitada como la selección predeterminada (marcador de posición). Muestra el siguiente por defecto, en este caso "Durr".
jarnoan

53
Por lo general, agrego tanto deshabilitado como seleccionado. Parece trabajar en FF también.
nilskp

11
<select> <option value="" disabled selected>Select your option</option> </select>
kolypto

183
La razón por la que esta no es la respuesta correcta es porque (creo) el autor de la pregunta quiere que la selección sea gris hasta que se haya seleccionado otro valor. Esta respuesta hace que la opción sea gris en el menú desplegable; pero no el elemento select.
Bill

22
seleccione {opción [deshabilitado] {display: none; }}
Dimael Vértigo

822

Me topé con esta pregunta, y esto es lo que funciona en Firefox y Chrome (al 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>

La opción Desactivado detiene la <option>selección con el mouse y el teclado, mientras que el solo uso 'display:none'permite al usuario seleccionar a través de las flechas del teclado. El 'display:none'estilo solo hace que el cuadro de lista se vea 'agradable'.

Nota: el uso de un valueatributo vacío en la opción "marcador de posición" permite la validación (atributo requerido) para evitar tener el "marcador de posición", por lo que si la opción no se cambia, pero es obligatorio, el navegador debe solicitar al usuario que elija una opción de la lista.

Actualización (julio de 2015):

Se confirma que este método funciona en los siguientes navegadores:

  • Google Chrome - v.43.0.2357.132
  • Mozilla Firefox - v.39.0
  • Safari - v.8.0.7 (el marcador de posición es visible en el menú desplegable, pero no es seleccionable)
  • Microsoft Internet Explorer - v.11 (el marcador de posición es visible en el menú desplegable pero no se puede seleccionar)
  • Project Spartan - v.15.10130 (el marcador de posición es visible en el menú desplegable, pero no es seleccionable)

Actualización (octubre de 2015):

Quité el style="display: none"favor de HTML5 atributo hiddenque tiene un amplio apoyo. El hiddenelemento tiene rasgos similares display: nonea los de Safari, Internet Explorer (Project Spartan necesita verificación) donde optionestá visible en el menú desplegable, pero no es seleccionable.

Actualización (enero de 2016):

Cuando el selectelemento está required, permite el uso de la :invalidpseudoclase CSS que le permite diseñar el selectelemento cuando está en su estado de "marcador de posición". :invalidfunciona aquí debido al valor vacío en el marcador de posición option.

Una vez que se ha establecido un valor, :invalidse eliminará la pseudoclase. Opcionalmente, también puede usar :validsi lo desea.

La mayoría de los navegadores admiten esta pseudoclase. Internet Explorer 10 y posterior. Esto funciona mejor con selectelementos de estilo personalizados ; en algunos casos, es decir (Mac en Chrome / Safari), deberá cambiar la apariencia predeterminada del selectcuadro para que se muestren ciertos estilos, es decir, background-colory color. Puede encontrar algunos ejemplos y más sobre compatibilidad en developer.mozilla.org .

Apariencia de elemento nativo Mac en Chrome:

Seleccione el cuadro Mac nativo en Chrome

Usando el elemento de borde alterado Mac en Chrome:

Cuadro de selección alterado Mac en Chrome


55
@jaacob En los navegadores que he probado, el estilo 'display: none' oculta el "Por favor, elija" de la lista, lo que hace que se vea mejor.
William Isted

38
Es importante tener en cuenta que una opción deshabilitada no se puede volver a seleccionar: si la selección es obligatoria, está bien, pero no si la selección es opcional.
Robert Mark Bram

2
Explorer11 ignora el display:noneestilo.
T30

1
Felicitaciones a @MattW por trabajar :invalidmucho antes que yo.
William Isted

3
También puede agregar una regla para "restablecer" colorlas opciones en los navegadores compatibles como en este violín . Esto ayudaría a reforzar que el discapacitado optiones un marcador de posición. (Editar: veo que MattW ya ha cubierto esto en su respuesta)
Shaggy

251

Para un campo obligatorio, existe una solución de CSS puro en los 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>


77
Increíble: fue la respuesta en la parte inferior (sin votos positivos aún) que fue la más simple, y en realidad funciona perfectamente. ¡Gracias! Esperemos que esta respuesta llegue a la cima.
Dan Nissenbaum,

2
@DanNissenbaum Llegué muy tarde al juego, además de que necesita requiredfuncionar, por lo que no sirve de nada si quieres que el campo sea opcional.
MattW

1
Por otro lado, el :requiredselector no es compatible con IE8 y versiones inferiores. El :invalidselector no es compatible con IE9 y versiones posteriores. quirksmode.org/css/selectors
Matt Wagner

44
¿Ninguna solución para una selección no requerida?
user3494047

1
@ user3494047 no con este enfoque: la requiredcondición es la que hace que el navegador aplique la :invalidpseudoclase cuando se selecciona el marcador de posición. [value=""]no funcionará como reemplazo porque lo que se actualiza mediante la interacción del usuario es la propiedad del valor , pero esa sintaxis CSS se refiere a un atributo (inexistente) .
MattW

105

Algo como esto:

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

Ejemplo de trabajo: http://jsfiddle.net/Zmf6t/


8
Esto es exactamente lo que hice recientemente. pero agregué un controlador de teclado para que el cambio también ocurra cuando se selecciona una opción a través del teclado (usando las flechas o atajos de letras) jsfiddle.net/Zmf6t/131
Radu

esto me puso en el camino correcto ... sin embargo, hice el valor = "" (nada entre las comillas) de modo que cuando se hizo clic en el botón de envío, todavía no pudo validar la primera opción y aparecerá una ventana emergente del navegador que le informará para seleccionar una opción ... gracias @Albireo
Craig Wayne

¿Por qué llamó explícitamente la función de cambio?
Foreever

@Foreever porque configuré la clase CSS en el controlador de eventos de cambio de la selección, por lo que si no genera manualmente el evento cuando se construye el control, el estilo no se aplica (se aplicará solo cuando el usuario cambie manualmente el valor).
Albireo

Esto no funciona en JQeury 3.4.1
geobudex

45

Acabo de agregar un atributo oculto en un me optiongusta a continuación. Está funcionando bien para mí.

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


2
Solo para el registro, esto no funciona para mí (Chrome en Win10).
Chris Rae

Pero no puedes desarmarlo. Terminas eligiendo uno, pero no puedes restablecerlo en caso de que cambies de opinión.
Thielicious

¡Si! Pero dentro del formulario, el usuario tiene que seleccionar cualquiera de esas opciones. Si no es un campo obligatorio, elimine el atributo oculto.
Ajithkumar S

35

La solución a continuación también funciona en Firefox, sin 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>


26

Tuve el mismo problema y mientras buscaba me encontré con esta pregunta, y después de encontrar una buena solución para mí, me gustaría compartirla con ustedes en caso de que alguien pueda beneficiarse de ella.

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

Después de que el cliente realiza la primera selección, no hay necesidad de color gris, por lo que el código JavaScript elimina la clase place_holder.

Gracias a @ user1096901, como solución alternativa para el navegador Internet Explorer, puede agregar la place_holderclase nuevamente en caso de que la primera opción se seleccione nuevamente :)


2
En algunos navegadores todavía puede seleccionar la pantalla: ninguna opción, porque no está oculta.
Srneczek

La solución para esto es agregar nuevamente la clase "place_holder" en caso de que se seleccione la primera opción :)
rramiii

23

No hay necesidad de JavaScript o CSS, solo tres 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>

No muestra la opción en absoluto; solo establece el valor de la opción como el predeterminado.

Sin embargo, si simplemente no le gusta un marcador de posición que sea del mismo color que el resto , puede arreglarlo en línea de esta manera:

<!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, puede separar las funciones y al menos el CSS de la selección en archivos separados.

Nota: la función de carga corrige un error de actualización.


Esto no funciona si la opción oculta es la única
Eridanis

pero ¿por qué tendrías un menú desplegable con una sola opción?
Jacob Schneider

Tengo una ventana emergente con pestañas y el menú desplegable de tab3 toma la entrada de tab2, que se muestra. Su respuesta es buena y este es un caso de esquina, pero hubiera esperado que el valor predeterminado se mostrara como la primera opción, en su lugar, aparece un menú desplegable en blanco. Ver aquí: jsfiddle.net/n66L7sza
Eridanis

Ese es un buen punto, en cuyo caso puede escanear la longitud del menú desplegable, si es cero, luego elimine el atributo oculto
Jacob Schneider,

Esto no parece funcionar correctamente en Google Chrome 65.0.3325.181 en MacOS, no muestra la entrada oculta y elige la que está debajo.
Jamie H

19

El usuario no debe ver el marcador de posición en las opciones seleccionadas. Sugiero usar el hiddenatributo para la opción de marcador de posición, y no necesita el selectedatributo para esta opción. Puedes ponerlo como el primero.

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>


2
o select:invalidtambién es válido.
elquimista

2
Recomiendo este, ya que no presenta el texto del marcador de posición en la lista, al menos en Chrome.
JoeRaid

Tenga en cuenta que el estilo no funciona sinrequired
akmalhakimi1991

18

Aquí he modificado la respuesta de David (respuesta aceptada). En su respuesta, puso el atributo desactivado y seleccionado en la optionetiqueta, pero cuando también ponemos una etiqueta oculta, se verá mucho mejor.

Al agregar un atributo oculto adicional en la optionetiqueta, evitará que la opción "Seleccione su opción" se vuelva a seleccionar después de seleccionar la opción "Durr".

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


Gracias por la actualización, pero la respuesta aún no explica por qué se ve diferente. Por ejemplo, esta respuesta evita que la opción "Seleccione su opción" se vuelva a seleccionar después de seleccionar la opción "Durr" . ¿Qué atributo causa este comportamiento?
bgran

16

Aquí esta el mio:

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>


Simplemente podría agregar <option value="" selected disabled>Please select</option>como la primera opción.
sstauross

No hace que el marcador de posición sea gris claro.
Chloe

12

Veo signos de respuestas correctas, pero para reunirlo todo, esta sería mi solución:

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>


8
Durrestá en gris después de seleccionarlo. Esto obliga a que el cuadro de selección cerrado sea gris siempre.
Chloe

9

Si está utilizando Angular, haga lo siguiente:

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


Puede agregar el hiddenatributo para que esa opción no se muestre al abrir select. Pero gracias de todos modos por esa respuesta, funcionó para mí.
dcg

5

Esta HTML + CSSsolución funcionó para mí:

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>

Buena suerte...


No parece funcionar en JQuery 3.4.1
geobudex

5

Otra posibilidad en 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


4

Me encanta la solución aceptada , y funciona muy bien sin JavaScript.

Solo quiero agregar cómo adopté esta respuesta para un componente React de selección controlada , porque me tomó algunos intentos descubrirlo. Sería realmente simple incorporarlo react-selecty terminar con él, pero a menos que necesite la sorprendente funcionalidad que proporciona este repositorio, que no necesito para el proyecto en cuestión, no es necesario agregar más kilobytes a mi paquete. Nota, react-selectse encarga de marcadores de posición en selecciona a través de un complejo sistema de distintos inputsy htmlelementos.

En React, para un componente controlado , no puede agregar el selectedatributo a sus opciones. React maneja el estado de la selección a través de un valueatributo sobre selectsí mismo, junto con un controlador de cambio, donde el valor debe coincidir con uno de los atributos de valor dentro de las propias opciones.

Como por ejemplo

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

Dado que sería incorrecto y, de hecho, arrojaría un error al agregar el selectedatributo a una de las opciones, ¿entonces qué?

La respuesta es simple una vez que lo piensas. Dado que queremos que nuestro primero optionsea selectedtan bueno como disabledy hidden, debemos hacer tres cosas:

  1. Agregue el atributo hiddeny disabledal primero definido option.
  2. Establezca el valor de la primera optioncomo una cadena vacía.
  3. Inicialice el valor de selectque también sea una cadena vacía.
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>

Ahora puede diseñar la selección como se indicó anteriormente (o mediante un classNamesi lo prefiere).

select:invalid { color: gray; }

3

[type="text"]Marcador de posición de estilo de entrada para elementos seleccionados

La siguiente solución simula un marcador de posición en relación con un 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>


3

Quería que SELECT fuera gris hasta que fuera seleccionado, por lo que para este fragmento de HTML:

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

He agregado estas definiciones CSS:

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

Funciona como se esperaba en Chrome / Safari y quizás también en otros navegadores, pero no lo he comprobado.


3

Aquí hay una solución CSS que funciona muy bien. El contenido se agrega (y se posiciona absolutamente en relación con el contenedor) después del elemento contenedor (a través de: después de la pseudoclase ).

Obtiene su texto del atributo de marcador de posición que definí donde utilicé la directiva ( attr (marcador de posición) ). Otro factor clave son los eventos de puntero: ninguno : esto permite que los clics en el texto del marcador de posición pasen a la selección. De lo contrario, no se desplegará si el usuario hace clic en el texto.

Agrego la clase .empty en mi directiva select, pero normalmente encuentro que angular agrega / elimina .ng-empty para mí (supongo que es porque estoy inyectando la versión 1.2 de Angular en mi muestra de código).

(El ejemplo también muestra cómo envolver elementos HTML en AngularJS para crear sus propias 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>


3

No pude hacer que ninguno de estos funcione actualmente, porque para mí no es (1) obligatorio y (2) necesito la opción de volver al valor predeterminado seleccionable. Así que aquí hay una opción de mano dura si está utilizando 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>


Gracias, esto fue lo mejor para mí, como dijiste ... se requiere el elemento select.
Mousa Alfhaily

3

No estoy contento con soluciones HTML / CSS solamente, así que decidí crear una personalizada selectusando JavaScript.

Esto es algo que he escrito en los últimos 30 minutos, por lo que se puede mejorar aún más.

Todo lo que tiene que hacer es crear una lista simple con pocos atributos de datos. El código convierte automáticamente la lista en un menú desplegable seleccionable. También agrega un oculto inputpara mantener el valor seleccionado, por lo que se puede usar en un formulario.

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>

Salida:

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

El texto del elemento que se supone que es un marcador de posición está atenuado. El marcador de posición es seleccionable, en caso de que el usuario quiera revertir su elección. También utilizando CSS, selectse pueden superar todos los inconvenientes de (por ejemplo, la incapacidad del estilo de las opciones).


Actualización : he mejorado esto (selección usando las teclas arriba / abajo / enter), ordené un poco la salida y la convertí en un objeto. Salida de corriente:

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

Inicializacion:

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

Para un examen más detallado: JSFiddle , GitHub (renombrado).


Actualización: he vuelto a escribir esto de nuevo. En lugar de usar una lista, podemos usar una selección. De esta manera funcionará incluso sin JavaScript (en caso de que esté deshabilitado).

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

Salida:

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


2

Necesita validación de formularios y los navegadores modernos ofrecen esto desde cero.

Por lo tanto, no necesita tener cuidado de que el usuario no pueda seleccionar el campo. Porque cuando lo está haciendo, la validación del navegador le dirá que esta es una selección incorrecta.

El navegador integrado en la función de validación checkValidity () .

Bootstrap también tiene un buen ejemplo.

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
}

1

Puede hacer esto sin usar Javascriptutilizando sólo HTMLes necesario seleccionar la opción por defecto conjunto disabled=""y selected=""y seleccione la etiqueta required="".navegador no permite al usuario enviar el formulario sin seleccionar una opción.

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

Esto hace que todo el elemento de selección se atenúe hasta que se elija una opción, lo que provoca un comportamiento potencialmente no deseado.
wickedchild

1

En Angular podemos agregar una opción como marcador de posición que se puede ocultar en el menú desplegable de opciones. Incluso podemos agregar un icono desplegable personalizado como fondo que reemplace el icono desplegable del navegador .

El truco es habilitar el marcador de posición css solo cuando el valor no está seleccionado

/ ** Mi plantilla 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>

/ ** My Component.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

Solución para Angular 2

Crear una etiqueta en la parte superior de la selección

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

y aplica CSS para colocarlo encima

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

pointer-events: none le permite mostrar la selección cuando hace clic en la etiqueta, que se oculta cuando selecciona una opción.


1

Aquí está mi contribución. 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;
}

Es posible usar solo CSS cambiando el código del servidor y solo configurando los estilos de clase dependiendo del valor actual de la propiedad, pero de esta manera parece más fácil y limpio.

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

Puede agregar más CSS ( select option:first-child) para mantener el marcador de posición gris cuando se abre, pero eso no me importó.


1

Prueba esto para un cambio:

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

1

Aquí hay un ejemplo práctico de cómo lograr esto con JavaScript puro que maneja las opciones de color después del primer clic:

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

1

Sobre la base de la respuesta de MattW , puede hacer que la opción de selección de marcador de posición sea visible en el menú desplegable después de que se haya realizado una selección válida, ocultándola condicionalmente solo mientras el marcador de posición permanezca seleccionado (y la selección por lo tanto no es vá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>


0

Según la respuesta de Albireo , esta versión no utiliza jQuery y la especificidad de CSS es mejor.

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>

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.