¿Cómo puedo diseñar un menú desplegable <select> con solo CSS?

1333

¿Hay una forma solo de CSS para diseñar un <select>menú desplegable?

Necesito diseñar un <select>formulario tanto como sea humanamente posible, sin ningún tipo de JavaScript. ¿Cuáles son las propiedades que puedo usar para hacerlo en CSS?

Este código debe ser compatible con todos los principales navegadores:

  • Internet Explorer 6, 7 y 8
  • Firefox
  • Safari

Sé que puedo hacerlo con JavaScript: Ejemplo .

Y no estoy hablando de un estilo simple. Quiero saber qué es lo mejor que podemos hacer solo con CSS.

Encontré preguntas similares en Stack Overflow.

Y este en Doctype.com.

Jitendra Vyas
fuente
1
no hay mucho encontrado en google, solo la solución js está allí
Jitendra Vyas
41
Siento que es una pregunta legítima, pero la respuesta es "no, no realmente" o "no de la manera que usted lo quiere". Pero nadie (ni yo) está 100% seguro de ello, este sentimiento de ambigüedad se esconde debajo de la piel del lector y se cuestiona la legitimidad de la pregunta.
ZJR
1
@Jitendra, sé a qué te refieres. Nos encantaría que hicieras tu pregunta más explícita. Además, creo que encontré lo que podrías estar buscando. Esto es experimental, pero échale un vistazo: cappuccino.org/aristo/showcase
jeremyosborne
1
@ jeremyosborne - Gracias por responder. Sé que puedo hacerlo con javascript. su enlace de ejemplo está basado en JS. ¿Por qué hice esta pregunta porque quería saber? ¿Hay alguien allí que sepa qué podemos hacer mejor con CSS
Jitendra Vyas
@Jitendra Gracias por actualizar tu pregunta. Lo mejor que puede hacer de manera confiable con las restricciones que tiene (solo CSS y sin JS) es modificar el tipo de letra (fuente), los colores de fondo y primer plano (texto), el tamaño del borde, la apariencia y los colores, la ubicación y el tamaño (generalmente a través del tipo configuración a través de la fuente). Incluso entonces, es probable que necesite hacer algunos ajustes para asegurarse de que las cosas se vean igual en todos los navegadores. Ojalá supiera una respuesta mejor que esa, y tal vez haya una que me haya perdido, pero no lo creo.
jeremyosborne

Respuestas:

1028

Aquí hay tres soluciones:

Solución # 1 - apariencia: ninguna - con Internet Explorer 10 - 11 solución alternativa ( Demo )

-

Para ocultar la flecha predeterminada establecida appearance: noneen el elemento de selección, luego agregue su propia flecha personalizada conbackground-image

select {
   -webkit-appearance: none;
   -moz-appearance: none;
   appearance: none;       /* Remove default arrow */
   background-image: url(...);   /* Add custom arrow */
}

Soporte de navegador:

appearance: nonetiene muy buena compatibilidad con el navegador ( caniuse ), excepto Internet Explorer 11 (y posterior) y Firefox 34 (y posterior).

Podemos mejorar esta técnica y agregar soporte para Internet Explorer 10 e Internet Explorer 11 agregando

select::-ms-expand {
    display: none; /* Hide the default arrow in Internet Explorer 10 and Internet Explorer 11 */
}

Si Internet Explorer 9 es una preocupación, no tenemos forma de eliminar la flecha predeterminada (lo que significaría que ahora tendríamos dos flechas), pero podríamos usar un selector de Internet Explorer 9 original.

Al menos para deshacer nuestra flecha personalizada, dejando intacta la flecha de selección predeterminada.

/* Target Internet Explorer 9 to undo the custom arrow */
@media screen and (min-width:0\0) {
    select {
        background-image:none\9;
        padding: 5px\9;
    }
}

Todos juntos:

Esta solución es fácil y tiene un buen soporte para el navegador, generalmente debería ser suficiente.


Si es necesario el soporte del navegador para Internet Explorer 9 (y posterior) y Firefox 34 (y posterior), siga leyendo ...

Solución # 2 Truncar el elemento de selección para ocultar la flecha predeterminada ( demo )

-

(Leer más aquí)

Envuelva el selectelemento en un div con un ancho fijo y overflow:hidden.

Luego dele al selectelemento un ancho de aproximadamente 20 píxeles mayor que el div .

El resultado es que la flecha desplegable predeterminada del selectelemento estará oculta (debido a que está overflow:hiddenen el contenedor), y puede colocar cualquier imagen de fondo que desee en el lado derecho del div.

La ventaja de este enfoque es que es un navegador cruzado (Internet Explorer 8 y posterior, WebKit y Gecko ). Sin embargo, la desventaja de este enfoque es que el menú desplegable de opciones sobresale en el lado derecho (por los 20 píxeles que ocultamos ... porque los elementos de opción toman el ancho del elemento seleccionado).

Ingrese la descripción de la imagen aquí

[Sin embargo, debe tenerse en cuenta que si el elemento de selección personalizado es necesario solo para dispositivos móviles, entonces el problema anterior no se aplica, debido a la forma en que cada teléfono abre de forma nativa el elemento de selección. Entonces, para dispositivos móviles, esta puede ser la mejor solución.]


Si la flecha personalizada es necesaria en Firefox, antes de la Versión 35 , pero no necesita admitir versiones antiguas de Internet Explorer, siga leyendo ...

Solución # 3 - Use la pointer-eventspropiedad ( demo )

-

(Leer más aquí)

La idea aquí es superponer un elemento sobre la flecha desplegable nativa (para crear uno personalizado) y luego no permitir eventos de puntero en él.

Ventaja: Funciona bien en WebKit y Gecko. También se ve bien (sin optionelementos sobresalientes ).

Desventaja: Internet Explorer (Internet Explorer 10 y versiones anteriores) no es compatible pointer-events, lo que significa que no puede hacer clic en la flecha personalizada. Además, otra desventaja (obvia) con este método es que no puede orientar su nueva imagen de flecha con un efecto de desplazamiento o cursor de mano, ¡porque acabamos de deshabilitar los eventos de puntero en ellos!

Sin embargo, con este método puede usar Modernizer o comentarios condicionales para hacer que Internet Explorer vuelva al estándar integrado en la flecha.

NB: Siendo que Internet Explorer 10 ya no es compatible conditional comments: si desea utilizar este enfoque, probablemente debería utilizar Modernizr . Sin embargo, aún es posible excluir el CSS de puntero-eventos de Internet Explorer 10 con un hack CSS descrito aquí .

Danield
fuente
1
¿Cuál es el mejor según usted de estos 2 métodos?
Jitendra Vyas
3
Depende de los requisitos de diseño. Si está de acuerdo con que el menú desplegable sobresalga, entonces eso es lo mejor porque es cross browser (IMO allbrowsers + IE8 + podría considerarse cross-browser) pero creo que para muchos, esto no funcionará. Entonces, en realidad en mi declaración anterior, quise decir que el enfoque n. ° 2 fue el mejor.
Danield
44
Además, el violín que publiqué utiliza el enfoque # 2 con declaraciones condicionales para permitir que IE use su flecha predeterminada.
Danield
3
@AlexisLeclerc La fijación de la división y selección al mismo ancho solo funciona en navegadores web como Chrome. (porque incluí la regla - webkit-apariencia: ninguno; ) Sin embargo, esto no funciona en otros navegadores como
Firefox
44
Si puedo proponer una mejora para el Enfoque n. ° 1, personalmente considero que la falta de borde o la falta de halo de selección en el lado derecho es muy molesta. Actualicé su violín con algo que usé en mi proyecto actual: jsfiddle.net/YvCHW/1745 . ¡Dime que piensas!
Alexis Leclerc
233

Es posible, pero desafortunadamente principalmente en navegadores basados ​​en WebKit en la medida en que nosotros, como desarrolladores, lo requerimos. Este es el ejemplo del estilo CSS recopilado del panel de opciones de Chrome a través del inspector de herramientas de desarrollador incorporado, mejorado para que coincida con las propiedades CSS actualmente compatibles en la mayoría de los navegadores modernos:

select {
    -webkit-appearance: button;
    -moz-appearance: button;
    -webkit-user-select: none;
    -moz-user-select: none;
    -webkit-padding-end: 20px;
    -moz-padding-end: 20px;
    -webkit-padding-start: 2px;
    -moz-padding-start: 2px;
    background-color: #F07575; /* Fallback color if gradients are not supported */
    background-image: url(../images/select-arrow.png), -webkit-linear-gradient(top, #E5E5E5, #F4F4F4); /* For Chrome and Safari */
    background-image: url(../images/select-arrow.png), -moz-linear-gradient(top, #E5E5E5, #F4F4F4); /* For old Firefox (3.6 to 15) */
    background-image: url(../images/select-arrow.png), -ms-linear-gradient(top, #E5E5E5, #F4F4F4); /* For pre-releases of Internet Explorer  10*/
    background-image: url(../images/select-arrow.png), -o-linear-gradient(top, #E5E5E5, #F4F4F4); /* For old Opera (11.1 to 12.0) */
    background-image: url(../images/select-arrow.png), linear-gradient(to bottom, #E5E5E5, #F4F4F4); /* Standard syntax; must be last */
    background-position: center right;
    background-repeat: no-repeat;
    border: 1px solid #AAA;
    border-radius: 2px;
    box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
    color: #555;
    font-size: inherit;
    margin: 0;
    overflow: hidden;
    padding-top: 2px;
    padding-bottom: 2px;
    text-overflow: ellipsis;
    white-space: nowrap;
}

Cuando ejecuta este código en cualquier página dentro de un navegador basado en WebKit, debe cambiar la apariencia del cuadro de selección, eliminar la flecha estándar del sistema operativo y agregar una flecha PNG, poner algo de espacio antes y después de la etiqueta, casi todo lo que desee.

La parte más importante es la appearancepropiedad, que cambia el comportamiento del elemento.

Funciona perfectamente en casi todos los navegadores basados ​​en WebKit, incluidos los móviles, aunque parece que Gecko no es appearancetan compatible como WebKit.

Matthew Morek
fuente
44
Hola, noté que los cuadros de selección comenzaron a verse muy diferentes a partir de Firefox 12 (se parece MUCHO a Chrome (tengo una Mac)), y parece que FF 12 admite muchos más atributos de apariencia.
CWSpear
3
una solución solo para Chrome ... No pagaría por esto, ni mi cliente. vea la respuesta de @ Dianeld para una solución de x-browser.
Adrien Be
41
@AdrienBe Mi solución fue propuesta hace casi 3 años; en ese momento era la única forma razonable de cambiar el estilo de los cuadros de selección sin involucrar libs o complementos de JavaScript. Todavía es viable si decide eliminar los atributos prefijados, pero funciona de manera confiable solo en los navegadores basados ​​en Webkit (por lo tanto, Safari, la nueva Opera + Android también). En este momento, quizás haya mejores soluciones, así que en lugar de agregar comentarios sin sentido, simplemente vote por la solución que considere mejor y en el futuro verifique la fecha de "respuesta". Gracias.
Matthew Morek
44
@MatthewMorek: había una solución mejor, incluso hace 3 años. La respuesta de Daniel es mucho mejor con respecto a la compatibilidad entre navegadores (es compatible con IE8 y posterior, WebKit y Gecko). La pregunta fue "el código debe ser compatible con todos los principales navegadores: Internet Explorer 6,7 y 8, Firefox y Safari". Sin embargo, este requisito del navegador x puede haber sido agregado por Paul Sweatte en 2013 ... perdón si es el caso.
Adrien Be
3
Si agrega text-indent: 0.01px; text-overflow: "";, funcionará aún mejor
Ivan
64

El elemento de selección y su función desplegable son difíciles de diseñar.

Los atributos de estilo para el elemento seleccionado de Chris Heilmann confirman lo que Ryan Dohery dijo en un comentario a la primera respuesta:

"El elemento select es parte del sistema operativo, no el navegador Chrome. Por lo tanto, no es muy confiable para el estilo, y no tiene necesariamente sentido intentarlo de todos modos".

pavium
fuente
47

Tuve este problema exacto, excepto que no podía usar imágenes y no estaba limitado por el soporte del navegador. Esto debería ser "según las especificaciones" y con suerte comenzará a funcionar en todas partes eventualmente .

Utiliza capas de fondo rotadas en capas para «cortar» una flecha desplegable, ya que los pseudoelementos no funcionarían para el elemento seleccionado.

Editar: en esta versión actualizada estoy usando variables CSS y un pequeño sistema de temas.

:root {
  --radius: 2px;
  --baseFg: dimgray;
  --baseBg: white;
  --accentFg: #006fc2;
  --accentBg: #bae1ff;
}

.theme-pink {
  --radius: 2em;
  --baseFg: #c70062;
  --baseBg: #ffe3f1;
  --accentFg: #c70062;
  --accentBg: #ffaad4;
}

.theme-construction {
  --radius: 0;
  --baseFg: white;
  --baseBg: black;
  --accentFg: black;
  --accentBg: orange;
}

select {
  font: 400 12px/1.3 sans-serif;
  -webkit-appearance: none;
  appearance: none;
  color: var(--baseFg);
  border: 1px solid var(--baseFg);
  line-height: 1;
  outline: 0;
  padding: 0.65em 2.5em 0.55em 0.75em;
  border-radius: var(--radius);
  background-color: var(--baseBg);
  background-image: linear-gradient(var(--baseFg), var(--baseFg)),
    linear-gradient(-135deg, transparent 50%, var(--accentBg) 50%),
    linear-gradient(-225deg, transparent 50%, var(--accentBg) 50%),
    linear-gradient(var(--accentBg) 42%, var(--accentFg) 42%);
  background-repeat: no-repeat, no-repeat, no-repeat, no-repeat;
  background-size: 1px 100%, 20px 22px, 20px 22px, 20px 100%;
  background-position: right 20px center, right bottom, right bottom, right bottom;   
}

select:hover {
  background-image: linear-gradient(var(--accentFg), var(--accentFg)),
    linear-gradient(-135deg, transparent 50%, var(--accentFg) 50%),
    linear-gradient(-225deg, transparent 50%, var(--accentFg) 50%),
    linear-gradient(var(--accentFg) 42%, var(--accentBg) 42%);
}

select:active {
  background-image: linear-gradient(var(--accentFg), var(--accentFg)),
    linear-gradient(-135deg, transparent 50%, var(--accentFg) 50%),
    linear-gradient(-225deg, transparent 50%, var(--accentFg) 50%),
    linear-gradient(var(--accentFg) 42%, var(--accentBg) 42%);
  color: var(--accentBg);
  border-color: var(--accentFg);
  background-color: var(--accentFg);
}
<select>
  <option>So many options</option>
  <option>...</option>
</select>

<select class="theme-pink">
  <option>So many options</option>
  <option>...</option>
</select>

<select class="theme-construction">
  <option>So many options</option>
  <option>...</option>
</select>

Henrik
fuente
55
Wow, esta es una de las mejores soluciones que he visto. A mí me funciona en las últimas versiones de Chrome y Safari en Mac. ¿Qué hay de otros navegadores?
Tintin81
2
Funciona para mí en Firefox con la adición de-moz-appearance: none;
Zac
45

La mayor inconsistencia que he notado al diseñar los menús desplegables seleccionados es Safari y Google Chrome (Firefox es totalmente personalizable a través de CSS). Después de buscar a través de oscuras profundidades de Internet, me encontré con lo siguiente, que resuelve casi por completo mis dudas con WebKit:

Safari y solución de Google Chrome :

select {
  -webkit-appearance: none;
}

Sin embargo, esto elimina la flecha desplegable. Puede agregar una flecha desplegable usando una cercana divcon un fondo, margen negativo o absolutamente posicionada sobre el menú desplegable de selección.

* Más información y otras variables están disponibles en la propiedad CSS: -webkit-apariencia .

ioTus
fuente
1
No olvides agregar tu estilo después de eso;) Pero estoy muy contento de haber leído este comentario hoy.
teewuane
1
¿podría explicar su afirmación: "Firefox es totalmente personalizable a través de CSS" para mí parece que Firefox no admite la propiedad de apariencia ... entonces, ¿cómo se haría esto en Firefox?
Danield
36

<select>Las etiquetas se pueden diseñar a través de CSS como cualquier otro elemento HTML en una página HTML representada en un navegador. A continuación se muestra un ejemplo (demasiado simple) que posicionará un elemento seleccionado en la página y mostrará el texto de las opciones en azul.

Archivo HTML de ejemplo (selectExample.html):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
  <title>Select Styling</title>
  <link href="selectExample.css" rel="stylesheet">
</head>
<body>
<select id="styledSelect" class="blueText">
  <option value="apple">Apple</option>
  <option value="orange">Orange</option>
  <option value="cherry">Cherry</option>
</select>
</body>
</html>

Ejemplo de archivo CSS (selectExample.css):

/* All select elements on page */
select {
  position: relative;
}

/* Style by class. Effects the text of the contained options. */
.blueText {
  color: #0000FF;
}

/* Style by id. Effects position of the select drop down. */
#styledSelect {
  left: 100px;
}
jeremyosborne
fuente
30
Increíble, la primera vez que vi "madres" involucradas en Internet sin que fuera grosero. +1 por eso!
BaL
34
Esta respuesta no resuelve esta pregunta. Solo
aplica
14
Esta respuesta ignora totalmente los desafíos de diseñar una lista desplegable para la coherencia entre navegadores. Esta es una respuesta de muy bajo esfuerzo.
BentOnCoding
18

La publicación del blog Cómo usar el estilo desplegable del formulario CSS no JavaScript funciona para mí, pero falla en Opera :

select {
  border: 0 none;
  color: #FFFFFF;
  background: transparent;
  font-size: 20px;
  font-weight: bold;
  padding: 2px 10px;
  width: 378px;
  *width: 350px;
  *background: #58B14C;
}

#mainselection {
  overflow: hidden;
  width: 350px;
  -moz-border-radius: 9px 9px 9px 9px;
  -webkit-border-radius: 9px 9px 9px 9px;
  border-radius: 9px 9px 9px 9px;
  box-shadow: 1px 1px 11px #330033;
  background: url("arrow.gif") no-repeat scroll 319px 5px #58B14C;
}
<div id="mainselection">
  <select>
    <option>Select an Option</option>
    <option>Option 1</option>
    <option>Option 2</option>
  </select>
</div>

Daniel
fuente
17

Aquí hay una versión que funciona en todos los navegadores modernos. Se usa la clave appearance:noneque elimina el formato predeterminado. Como todo el formato ha desaparecido, debe volver a agregar en la flecha que diferencia visualmente la selección de la entrada.

Ejemplo de trabajo: https://jsfiddle.net/gs2q1c7p/

select:not([multiple]) {
    -webkit-appearance: none;
    -moz-appearance: none;
    background-position: right 50%;
    background-repeat: no-repeat;
    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAMCAYAAABSgIzaAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDZFNDEwNjlGNzFEMTFFMkJEQ0VDRTM1N0RCMzMyMkIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDZFNDEwNkFGNzFEMTFFMkJEQ0VDRTM1N0RCMzMyMkIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0NkU0MTA2N0Y3MUQxMUUyQkRDRUNFMzU3REIzMzIyQiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0NkU0MTA2OEY3MUQxMUUyQkRDRUNFMzU3REIzMzIyQiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PuGsgwQAAAA5SURBVHjaYvz//z8DOYCJgUxAf42MQIzTk0D/M+KzkRGPoQSdykiKJrBGpOhgJFYTWNEIiEeAAAMAzNENEOH+do8AAAAASUVORK5CYII=);
    padding: .5em;
    padding-right: 1.5em
}

#mySelect {
    border-radius: 0
}
<select id="mySelect">
    <option>Option 1</option>
    <option>Option 2</option>
</select>

Eric
fuente
16

Llegué a tu caso usando Bootstrap . Esta es la solución más simple que funciona:

select.form-control {
    -moz-appearance: none;
    -webkit-appearance: none;
    appearance: none;
    background-position: right center;
    background-repeat: no-repeat;
    background-size: 1ex;
    background-origin: content-box;
    background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0ic3ZnMiIKICAgdmlld0JveD0iMCAwIDM1Ljk3MDk4MyAyMy4wOTE1MTgiCiAgIGhlaWdodD0iNi41MTY5Mzk2bW0iCiAgIHdpZHRoPSIxMC4xNTE4MTFtbSI+CiAgPGRlZnMKICAgICBpZD0iZGVmczQiIC8+CiAgPG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhNyI+CiAgICA8cmRmOlJERj4KICAgICAgPGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPgogICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz4KICAgICAgICA8ZGM6dGl0bGU+PC9kYzp0aXRsZT4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGcKICAgICB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjAyLjAxNDUxLC00MDcuMTIyMjUpIgogICAgIGlkPSJsYXllcjEiPgogICAgPHRleHQKICAgICAgIGlkPSJ0ZXh0MzMzNiIKICAgICAgIHk9IjYyOS41MDUwNyIKICAgICAgIHg9IjI5MS40Mjg1NiIKICAgICAgIHN0eWxlPSJmb250LXN0eWxlOm5vcm1hbDtmb250LXdlaWdodDpub3JtYWw7Zm9udC1zaXplOjQwcHg7bGluZS1oZWlnaHQ6MTI1JTtmb250LWZhbWlseTpzYW5zLXNlcmlmO2xldHRlci1zcGFjaW5nOjBweDt3b3JkLXNwYWNpbmc6MHB4O2ZpbGw6IzAwMDAwMDtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZTtzdHJva2Utd2lkdGg6MXB4O3N0cm9rZS1saW5lY2FwOmJ1dHQ7c3Ryb2tlLWxpbmVqb2luOm1pdGVyO3N0cm9rZS1vcGFjaXR5OjEiCiAgICAgICB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4KICAgICAgICAgeT0iNjI5LjUwNTA3IgogICAgICAgICB4PSIyOTEuNDI4NTYiCiAgICAgICAgIGlkPSJ0c3BhbjMzMzgiPjwvdHNwYW4+PC90ZXh0PgogICAgPGcKICAgICAgIGlkPSJ0ZXh0MzM0MCIKICAgICAgIHN0eWxlPSJmb250LXN0eWxlOm5vcm1hbDtmb250LXZhcmlhbnQ6bm9ybWFsO2ZvbnQtd2VpZ2h0Om5vcm1hbDtmb250LXN0cmV0Y2g6bm9ybWFsO2ZvbnQtc2l6ZTo0MHB4O2xpbmUtaGVpZ2h0OjEyNSU7Zm9udC1mYW1pbHk6Rm9udEF3ZXNvbWU7LWlua3NjYXBlLWZvbnQtc3BlY2lmaWNhdGlvbjpGb250QXdlc29tZTtsZXR0ZXItc3BhY2luZzowcHg7d29yZC1zcGFjaW5nOjBweDtmaWxsOiMwMDAwMDA7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjFweDtzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjptaXRlcjtzdHJva2Utb3BhY2l0eToxIj4KICAgICAgPHBhdGgKICAgICAgICAgaWQ9InBhdGgzMzQ1IgogICAgICAgICBzdHlsZT0iZmlsbDojMzMzMzMzO2ZpbGwtb3BhY2l0eToxIgogICAgICAgICBkPSJtIDIzNy41NjY5Niw0MTMuMjU1MDcgYyAwLjU1ODA0LC0wLjU1ODA0IDAuNTU4MDQsLTEuNDczMjIgMCwtMi4wMzEyNSBsIC0zLjcwNTM1LC0zLjY4MzA0IGMgLTAuNTU4MDQsLTAuNTU4MDQgLTEuNDUwOSwtMC41NTgwNCAtMi4wMDg5MywwIEwgMjIwLDQxOS4zOTM0NiAyMDguMTQ3MzIsNDA3LjU0MDc4IGMgLTAuNTU4MDMsLTAuNTU4MDQgLTEuNDUwODksLTAuNTU4MDQgLTIuMDA4OTMsMCBsIC0zLjcwNTM1LDMuNjgzMDQgYyAtMC41NTgwNCwwLjU1ODAzIC0wLjU1ODA0LDEuNDczMjEgMCwyLjAzMTI1IGwgMTYuNTYyNSwxNi41NDAxNyBjIDAuNTU4MDMsMC41NTgwNCAxLjQ1MDg5LDAuNTU4MDQgMi4wMDg5MiwwIGwgMTYuNTYyNSwtMTYuNTQwMTcgeiIgLz4KICAgIDwvZz4KICA8L2c+Cjwvc3ZnPgo=");
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<section class="container">
  <form class="form-horizontal">
    <select class="form-control">
      <option>One</option>
      <option>Two</option>
    </select>
  </form>
</section>

Nota: el material base64 está fa-chevron-downen SVG.

Yajo
fuente
12

En los navegadores modernos es relativamente sencillo diseñar el estilo <select>en CSS. Con appearance: nonela única parte difícil está reemplazando la flecha (si eso es lo que quiere). Aquí hay una solución que usa un data:URI en línea con SVG de texto plano:

select {
  -moz-appearance: none;
  -webkit-appearance: none;
  appearance: none;
  
  background-repeat: no-repeat;
  background-size: 0.5em auto;
  background-position: right 0.25em center;
  padding-right: 1em;
  
  background-image: url("data:image/svg+xml;charset=utf-8, \
    <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 40'> \
      <polygon points='0,0 60,0 30,40' style='fill:black;'/> \
    </svg>");
}
<select>
  <option>Option 1</option>
  <option>Option 2</option>
</select>

<select style="font-size: 2rem;">
  <option>Option 1</option>
  <option>Option 2</option>
</select>

El resto del estilo (bordes, relleno, colores, etc.) es bastante sencillo.

Esto funciona en todos los navegadores que acabo de probar (Firefox 50, Chrome 55, Edge 38 y Safari 10). Una nota sobre Firefox es que si desea utilizar el #carácter en el URI de datos (p fill: #000. Ej. ) Debe escapar de él ( fill: %23000).

Kevin Christopher Henry
fuente
1
También puede dimensionar el SVG con el atributo heighty / o widthen la <svg>etiqueta, en lugar de la propiedad CSS background-size.
gitaarik
10
select  {
    outline: 0;
    overflow: hidden;
    height: 30px;
    background: #2c343c;
    color: #747a80;
    border: #2c343c;
    padding: 5px 3px 5px 10px;
    -moz-border-radius: 6px;
    -webkit-border-radius: 6px;
    border-radius: 10px;
}

select option {border: 1px solid #000; background: #010;}
geco
fuente
No se puede seleccionar nada con eso con Chrome actual.
Vitaly Zdanevich
9

Seleccionar estilos CSS personalizados

Probado en Internet Explorer (10 y 11), Edge, Firefox y Chrome

select::-ms-expand {
  display: none;
}
select {
  display: inline-block;
  box-sizing: border-box;
  padding: 0.5em 2em 0.5em 0.5em;
  border: 1px solid #eee;
  font: inherit;
  line-height: inherit;
  -webkit-appearance: none;
  -moz-appearance: none;
  -ms-appearance: none;
  appearance: none;
  background-repeat: no-repeat;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 15px top 1em, right 10px top 1em;
  background-size: 5px 5px, 5px 5px;
}
<select name="">
  <option value="">Lorem</option>
  <option value="">Lorem Ipsum</option>
</select>

<select name="" disabled>
  <option value="">Disabled</option>
</select>

<select name="" style="color:red;">
  <option value="">Color!</option>
  <option value="">Lorem Ipsum</option>
</select>

Roko C. Buljan
fuente
Ligeramente más adaptable (pero no probado en todos los navegadores):background-position: right 15px center, right 10px center;
Robin Stewart
8

Use la clippropiedad para recortar los bordes y la flecha del selectelemento, luego agregue sus propios estilos de reemplazo al contenedor:

    <!DOCTYPE html>
    <html>
      <head>
        <style>
          select { position: absolute; clip:rect(2px 49px 19px 2px); z-index:2; }
          body > span { display:block; position: relative; width: 64px; height: 21px; border: 2px solid green;  background: url(http://www.stackoverflow.com/favicon.ico) right 1px no-repeat; }
        </style>
      </head>
      <span>
        <select>
          <option value="">Alpha</option>
          <option value="">Beta</option>
          <option value="">Charlie</option>
        </select>
      </span>
    </html>

Use una segunda selección con opacidad cero para hacer clic en el botón:

    <!DOCTYPE html>
    <html>
      <head>
        <style>
          #real { position: absolute; clip:rect(2px 51px 19px 2px); z-index:2; }
          #fake { position: absolute; opacity: 0; }
    
          body > span { display:block; position: relative; width: 64px; height: 21px; background: url(http://www.stackoverflow.com/favicon.ico) right 1px no-repeat; }
        </style>
      </head>
      <span>
        <select id="real">
          <option value="">Alpha</option>
          <option value="">Beta</option>
          <option value="">Charlie</option>
        </select>
        <select id="fake">
          <option value="">Alpha</option>
          <option value="">Beta</option>
          <option value="">Charlie</option>
        </select>
      </span>
    </html>

Las coordenadas difieren entre Webkit y otros navegadores, pero una consulta @media puede cubrir eso.

Referencias

Paul Sweatte
fuente
1
Funcionando bien para mí, al menos en cromo: posición: absoluta; clip: rect (2px 85px 128px 2px); índice z: 2; relleno-izquierda: 18px; relleno derecho: 18px; margen: 7px automático; color: # 555; tamaño de fuente: heredar; color de fondo: transparente;
BrianFreud
1
Descubrí que recortar la flecha solo funciona a medias en IE7 ya que no tienes control sobre el borde de la selección.
CpILL
1
Se agregó la funcionalidad de clic como parte de una pregunta relacionada
Paul Sweatte
1
@PaulSweatte, ¡este es tu vigésimo nigromante ! Felicidades También superó todas mis consultas para obtener una insignia de nigromante de oro .
Nemo
5

Un ejemplo muy bueno que usa :aftery :beforepara hacer el truco es en Styling Select Box con CSS3 | CSSDeck

Ahmad Ajmi
fuente
1
Sí, pero el requisito en cuestión era compatible con Internet Explorer 6,7 y 8
Jitendra Vyas
2
Sí, no es compatible con IE, pero me encantó compartir para cualquiera que buscara una solución moderna como la que estaba buscando.
Ahmad Ajmi
5

No se recomienda editar este elemento, pero si quieres probarlo es como cualquier otro elemento HTML.

Editar ejemplo:

/* Edit select */
select {
    /* CSS style here */
}

/* Edit option */
option {
    /* CSS style here */
}

/* Edit selected option */
/* element  attr    attr value */
option[selected="selected"] {
    /* CSS style here */
}
<select>
    <option >Something #1</option>
    <option selected="selected">Something #2</option>
    <option >Something #3</option>
</select>
Homar
fuente
2
@MikkoP: al sugerir ediciones, ¿podría proporcionar un resumen de edición más descriptivo? "Mejorar el mensaje" no es muy útil como resumen de alto nivel para los revisores. Gracias.
Jean-François Corbett
1
@ Jean-FrançoisCorbett Intentaré ser más específico :)
MikkoP
1
no puede
diseñar
4
label {
    position: relative;
    display: inline-block;
}
select {
    display: inline-block;
    padding: 4px 3px 5px 5px;
    width: 150px;
    outline: none;
    color: black;
    border: 1px solid #C8BFC4;
    border-radius: 4px;
    box-shadow: inset 1px 1px 2px #ddd8dc;
    background-color: lightblue;
}

Esto usa un color de fondo para los elementos seleccionados y eliminé la imagen.

Suerte
fuente
4

Si. Puede diseñar cualquier elemento HTML con su nombre de etiqueta, como este:

select {
  font-weight: bold;
}

Por supuesto, también puede usar una clase CSS para darle estilo, como cualquier otro elemento:

<select class="important">
  <option>Important Option</option>
  <option>Another Important Option</option>
</select>

<style type="text/css">
  .important {
    font-weight: bold;
  }
</style>
Dave Ward
fuente
66
No estoy hablando acerca de como esto quiero cambiar flecha de la derecha a otra cosa
Jitendra Vyas
55
No puede diseñar la flecha desplegable a otra imagen, está controlada por el sistema operativo. Si realmente lo necesita, su mejor opción es utilizar un widget desplegable DHTML.
Ryan Doherty
3
Solo puede cambiar las propiedades CSS a través de CSS. Puede cambiar su margen, relleno, propiedades de fuente, color de fondo, etc. Si desea que se vea completamente diferente, básicamente debe reemplazarlo con gráficos en tiempo de ejecución a través de JavaScript (que no es una solución terrible si se hace bien )
Dave Ward, el
4

Aquí hay una solución basada en mis ideas favoritas de esta discusión. Esto permite diseñar un elemento <select> directamente sin ningún marcado adicional.

Funciona Internet Explorer 10 (y posterior) con un respaldo seguro para Internet Explorer 8/9. Una advertencia para estos navegadores es que la imagen de fondo debe estar posicionada y ser lo suficientemente pequeña como para esconderse detrás del control de expansión nativo.

HTML

<select name='options'>
  <option value='option-1'>Option 1</option>
  <option value='option-2'>Option 2</option>
  <option value='option-3'>Option 3</option>
</select>

SCSS

body {
  padding: 4em 40%;
  text-align: center;
}

select {
  $bg-color: lightcyan;
  $text-color: black;
  appearance: none; // Using -prefix-free http://leaverou.github.io/prefixfree/
  background: {
    color: $bg-color;
    image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/1255/caret--down-15.png");
    position: right;
    repeat: no-repeat;
  }
  border: {
    color: mix($bg-color, black, 80%);
    radius: .2em;
    style: solid;
    width: 1px;
    right-color: mix($bg-color, black, 60%);
    bottom-color: mix($bg-color, black, 60%);
  }
  color: $text-color;
  padding: .33em .5em;
  width: 100%;
}

// Removes default arrow for Internet Explorer 10 (and later)
// Internet Explorer 8/9 gets the default arrow which covers the caret
// image as long as the caret image is smaller than and positioned
// behind the default arrow
select::-ms-expand {
    display: none;
}

CodePen

http://codepen.io/ralgh/pen/gpgbGx

ralgh
fuente
3

Hay una manera fácil

Comprueba este violín y perdóname el exceso de estilo: https://jsfiddle.net/dkellner/7ac9us70/

El truco detrás: tan pronto como la etiqueta <select> obtenga una propiedad llamada "tamaño", se comportará como una lista de altura fija y, de repente, por alguna razón, le permite darle un estilo increíble. Ahora, estrictamente hablando, la lista fija es un efecto secundario, pero solo nos ayuda más porque la usamos para el "aspecto desplegable".

Un ejemplo mínimo:

<style>

    .stylish span   {position:relative;}
    .stylish select {position:absolute;left:0px;display:none}

</style>
...
<div class="stylish">
    <label> Choose your superhero: </label>
    <span>
        <input onclick="$(this).closest('div').find('select').slideToggle(110)"><br>
        <select size=15 onclick="$(this).hide().closest('div').find('input').val($(this).find('option:selected').text());">

            <optgroup label="Fantasy"></optgroup>
            <option value="1">  Gandalf        </option>
            <option value="2">  Harry Potter   </option>
            <option value="3">  Jon Snow       </option>

            <!-- ... and so on -->

        </select>
    </span>
</div>

(para simplificar, lo hice con jQuery, pero puedes hacer lo mismo sin él)

Notas al margen

  • Esta solución le ofrece más que solo una selección: el valor también se puede editar manualmente. Utilice la propiedad de solo lectura si prefiere la forma predeterminada de selección restringida.

  • Para maximizar las posibilidades de estilo, las etiquetas <optgroup> no están alrededor de sus hijos, se mueven antes que ellos. Es intencional, es visualmente más claro y están felices de trabajar así, no se preocupe.

  • Javascripts: sí, sé que el OP dijo "no Javascript" pero lo entendí como por favor no se moleste con los complementos , lo cual está bien. No necesitas ninguna biblioteca para esta. Ni siquiera jQuery, como dije, es solo por la claridad del ejemplo.

dkellner
fuente
2

Definitivamente deberías hacerlo como en Styling select, optgroup y options with CSS . En muchos sentidos, el color de fondo y el color son exactamente lo que normalmente necesitaría para diseñar las opciones, no la selección completa.

Otvazhnii
fuente
2

También puede agregar un estilo de desplazamiento al menú desplegable.

select {position:relative; float:left; width:21.4%; height:34px; background:#f9f9e0; border:1px solid #41533f; padding:0px 10px 0px 10px; color:#41533f; margin:-10px 0px 0px 20px; background: transparent; font-size: 12px; -webkit-appearance: none; -moz-appearance: none; appearance: none; background: url(https://alt-fit.com/images/global/select-button.png) 100% / 15% no-repeat #f9f9e0;}
select:hover {background: url(https://alt-fit.com/images/global/select-button.png) 100% / 15% no-repeat #fff;}
<html>
<head>
</head>
<body>
<select name="type" class="select"><option style="color:#41533f;" value="Select option">Select option</option>
<option value="Option 1">Option 1</option>
<option value="Option 2">Option 2</option>
<option value="Option 3">Option 3</option>
</select>
</body>
</html>


fuente
2

El tercer método en la respuesta de Danield se puede mejorar para trabajar con efectos de desplazamiento y otros eventos del mouse. Solo asegúrese de que el elemento "botón" viene justo después del elemento de selección en el marcado. Luego apunte con el selector + CSS:

HTML:

<select class="select-input">...</select>
<div class="select-button"></div>

CSS:

.select-input:hover+.select-button {
    <Hover styles here>
}

Sin embargo, esto mostrará el efecto de desplazamiento al pasar el cursor sobre cualquier lugar sobre el elemento de selección, no solo sobre el "botón".

Estoy usando este método en combinación con Angular (dado que mi proyecto es una aplicación Angular de todos modos), para cubrir todo el elemento de selección y dejar que Angular muestre el texto de la opción seleccionada en el elemento "botón". En este caso, tiene mucho sentido que el efecto de desplazamiento se aplique al pasar el cursor sobre cualquier lugar de la selección.

Sin embargo, no funciona sin JavaScript, por lo que si desea hacer esto, y su sitio tiene que funcionar sin JavaScript, debe asegurarse de que su script agregue los elementos y clases necesarios para la mejora. De esa manera, un navegador sin JavaScript simplemente obtendrá una selección normal, sin estilo, en lugar de una insignia con estilo que no se actualiza correctamente.

Adrian Schmidt
fuente
1
Me encantaría saber el motivo de cualquier voto negativo, ¡para saber cómo mejorar! 🙂
Adrian Schmidt
1

Una solución única para CSS y HTML

Parece compatible con Chrome, Firefox e Internet Explorer 11. Pero deje sus comentarios con respecto a otros navegadores web.

Como sugiere la respuesta de Danield, envuelvo mi selección en un div (incluso dos divs para compatibilidad con x-browser) para obtener el comportamiento esperado.

Ver http://jsfiddle.net/bjap2/

HTML:

<div class="sort-options-wrapper">
    <div class="sort-options-wrapper-2">
        <select class="sort-options">
                <option value="choiceOne">choiceOne</option>
                <option value="choiceOne">choiceThree</option>
                <option value="choiceOne">choiceFour</option>
                <option value="choiceFiveLongTestPurpose">choiceFiveLongTestPurpose</option>
        </select>
    </div>
    <div class="search-select-arrow-down"></div>
</div>

Observe los dos envoltorios div.

También observe el div extra agregado para colocar el botón de flecha hacia abajo donde desee (posicionado absolutamente), aquí lo colocamos a la izquierda.

CSS

.sort-options-wrapper {
    display: inline-block;
    position: relative;
    border: 1px solid #83837F;
}

/* This second wrapper is needed for x-browser compatibility */
.sort-options-wrapper-2 {
    overflow: hidden;
}

select {
    margin-right: -19px; /* That's what is hiding the default-provided browser arrow */
    padding-left: 13px;
    margin-left: 0;
    border: none;
    background: none;

    /* margin-top & margin-bottom must be set since some
       browsers have default values for select elements */
    margin-bottom: 1px;
    margin-top: 1px;
}

select:focus {
    outline: none; /* Removing default browsers outline on focus */
}
.search-select-arrow-down {
    position: absolute;
    height: 10px;
    width: 12px;
    background: url(http://i.imgur.com/pHIYN06.png) scroll no-repeat 2px 0px;
    left: 1px;
    top: 5px;
}
Adrien Be
fuente