web-dev-qa-db-fra.com

Comment styliser un menu déroulant <select> avec CSS uniquement?

Existe-t-il un moyen uniquement CSS de styliser un menu déroulant <select>?

J'ai besoin de dénommer une forme <select> autant que possible, sans JavaScript. Quelles sont les propriétés que je peux utiliser pour le faire en CSS?

Ce code doit être compatible avec tous les principaux navigateurs:

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

Je sais que je peux le faire avec JavaScript: Exemple .

Et je ne parle pas de style simple. Je veux savoir ce que nous pouvons faire de mieux avec CSS uniquement.

J'ai trouvé questions similaires sur Stack Overflow.

Et celui-ci sur Doctype.com.

1214
Jitendra Vyas

Voici 3 solutions:

Solution n ° 1 - apparence: aucune - avec la solution ie10-11 ( Demo )

Pour masquer la flèche par défaut, définissez appearance: none sur l'élément sélectionné, puis ajoutez votre propre flèche personnalisée avec background-image

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

Prise en charge du navigateur:

appearance: none supporte très bien le navigateur ( caniuse ) - à l'exception de ie11- et de firefox 34-

Nous pouvons améliorer cette technique et ajouter le support pour ie10 et ie11 en ajoutant

select::-ms-expand { 
    display: none; /* hide the default arrow in ie10 and ie11 */
}

Si ie9 est un problème - nous n'avons aucun moyen de supprimer la flèche par défaut (ce qui voudrait dire que nous aurions maintenant deux flèches), mais nous pourrions utiliser un sélecteur funky ie9 pour au moins annuler notre flèche personnalisée - en laissant le bouton de sélection par défaut intact.

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

Tous ensemble:

select {
  margin: 50px;
  width: 150px;
  padding: 5px 35px 5px 5px;
  font-size: 16px;
  border: 1px solid #ccc;
  height: 34px;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background: url(http://www.stackoverflow.com/favicon.ico) 96% / 15% no-repeat #eee;
}


/* CAUTION: IE hackery ahead */


select::-ms-expand { 
    display: none; /* remove default arrow in IE 10 and 11 */
}

/* target Internet Explorer 9 to undo the custom arrow */
@media screen and (min-width:0\0) {
    select {
        background:none\9;
        padding: 5px\9;
    }
}
<select>
  <option>Apples</option>
  <option selected>Pineapples</option>
  <option>Chocklate</option>
  <option>Pancakes</option>
</select>

Cette solution est simple et prend en charge les navigateurs. Elle devrait généralement suffire.


Si la prise en charge des navigateurs pour IE9 et Firefox 34 est nécessaire, continuez à lire ...

Solution n ° 2: tronquez l'élément select pour masquer la flèche par défaut ( démo )

(Lire la suite ici)

Enveloppez l'élément select dans un div avec un largeur fixe et overflow:hidden.

Donnez ensuite à l'élément select une largeur d'environ 20 pixels plus grand que le div.

Le résultat est que la flèche déroulante par défaut de l'élément select sera masquée (en raison du overflow:hidden du conteneur), et vous pouvez placer n'importe quelle image d'arrière-plan sur le côté droit- côté de la div.

L’avantage de cette approche est qu’il s’agit d’un multi-navigateur (Internet Explorer 8 et versions ultérieures, WebKit , et Gecko ). Cependant, le désavantage de cette approche est que la liste déroulante des options dépasse du côté droit (par les 20 pixels que nous avons cachés). .. car les éléments d’option prennent la largeur de l’élément select).

enter image description here

[Il convient toutefois de noter que si l'élément de sélection personnalisé est nécessaire uniquement pour les appareils MOBILES, le problème ci-dessus ne s'applique pas - en raison de la manière dont chaque téléphone ouvre en mode natif l'élément select. Donc, pour le mobile, cela peut être la meilleure solution.]

.styled select {
  background: transparent;
  width: 150px;
  font-size: 16px;
  border: 1px solid #ccc;
  height: 34px;
}
.styled {
  margin: 50px;
  width: 120px;
  height: 34px;
  border: 1px solid #111;
  border-radius: 3px;
  overflow: hidden;
  background: url(http://www.stackoverflow.com/favicon.ico) 96% / 20% no-repeat #eee;
}
<div class="styled">
  <select>
    <option>Pineapples</option>
    <option selected>Apples</option>
    <option>Chocklate</option>
    <option>Pancakes</option>
  </select>
</div>

Si la flèche personnalisée est nécessaire sur Firefox - avant Version 35 - mais vous n'avez pas besoin de supporter les anciennes versions de IE - continuez à lire ...

Solution n ° 3 - Utilisez la propriété pointer-events (( Demo )

(Lire la suite ici)

L'idée ici est de superposer un élément sur la flèche déroulante native (pour créer notre élément personnalisé), puis d'interdire les événements de pointeur sur celui-ci.

Avantage: fonctionne bien dans WebKit et Gecko. Ça a l'air bien aussi (pas de saillie option éléments)

Inconvénient: Internet Explorer (IE10 et ultérieur) ne prend pas en charge pointer-events, ce qui signifie que vous ne pouvez pas cliquer sur la flèche personnalisée. En outre, un autre inconvénient (évident) de cette méthode est que vous ne pouvez pas cibler votre nouvelle image de flèche avec un effet de survol ou un curseur de main, car nous venons de désactiver les événements de pointeur sur celles-ci!

Cependant, avec cette méthode, vous pouvez utiliser Modernizer ou des commentaires conditionnels pour que Internet Explorer revienne à la flèche intégrée standard.

NB: Etant donné qu'Internet Explorer 10 ne supporte plus conditional comments: Si vous voulez utiliser cette approche, vous devriez probablement utiliser Modernizr . Cependant, il est toujours possible d'exclure les événements de pointeur CSS de Internet Explorer 10 avec un hack CSS décrit ici .

.notIE {
  position: relative;
  display: inline-block;
}
select {
  display: inline-block;
  height: 30px;
  width: 150px;
  outline: none;
  color: #74646e;
  border: 1px solid #C8BFC4;
  border-radius: 4px;
  box-shadow: inset 1px 1px 2px #ddd8dc;
  background: #fff;
}
/* Select arrow styling */

.notIE .fancyArrow {
  width: 23px;
  height: 28px;
  position: absolute;
  display: inline-block;
  top: 1px;
  right: 3px;
  background: url(http://www.stackoverflow.com/favicon.ico) right / 90% no-repeat #fff;
  pointer-events: none;
}
/*target Internet Explorer 9 and Internet Explorer 10:*/

@media screen and (min-width: 0\0) {
  .notIE .fancyArrow {
    display: none;
  }
}
<!--[if !IE]> -->
<div class="notIE">
  <!-- <![endif]-->
  <span class="fancyArrow"></span>
  <select>
    <option>Apples</option>
    <option selected>Pineapples</option>
    <option>Chocklate</option>
    <option>Pancakes</option>
  </select>
  <!--[if !IE]> -->
</div>
<!-- <![endif]-->
953
Danield

C'est possible, mais malheureusement principalement dans les navigateurs Webkit, dans la mesure où nous en avons besoin, en tant que développeurs. Voici l'exemple de style CSS recueilli à partir du panneau d'options Chrome via un inspecteur intégré d'outils de développement, amélioré pour correspondre aux propriétés CSS actuellement prises en charge dans la plupart des navigateurs modernes:

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 Fx (3.6 to 15) */
    background-image: url(../images/select-arrow.png), -ms-linear-gradient(top, #E5E5E5, #F4F4F4); /* For pre-releases of IE 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;
}

Lorsque vous exécutez ce code sur n’importe quelle page d’un navigateur Webkit, il doit changer l’aspect de la zone de sélection, supprimer la flèche standard du système d’exploitation, ajouter une flèche au format PNG, mettre un espacement avant et après le libellé, comme vous le souhaitez.

La partie la plus importante est la propriété appearance, qui modifie le comportement de l'élément.

Cela fonctionne parfaitement dans presque tous les navigateurs Webkit, y compris les navigateurs mobiles, bien que Gecko ne supporte pas appearance ainsi que Webkit, semble-t-il.

228
Matthew Morek

L'élément select et sa fonctionnalité de liste déroulante sont difficiles à styler.

Les attributs de style pour l'élément select de Chris Heilmann confirme ce que Ryan Dohery a dit dans un commentaire à la première réponse:

"L'élément select fait partie du système d'exploitation, pas le chrome du navigateur. Par conséquent, il est très peu fiable en matière de style et il n'est pas nécessairement logique d'essayer de toute façon."

58
pavium

La plus grande incohérence que j'ai constatée lors de la sélection des styles dans les listes déroulantes est Safari et Google Chrome. rendu (Firefox est entièrement personnalisable via CSS). Après quelques recherches dans les profondeurs obscures d'Internet, je trouvai ce qui suit, ce qui résout presque complètement mes scrupules avec WebKit:

Safari et Google Chrome correctif :

select {
  -webkit-appearance: none;
}

Cela supprime toutefois la flèche déroulante. Vous pouvez ajouter une flèche de liste déroulante en utilisant un div voisin avec un arrière-plan, une marge négative ou une position absolue par rapport à la liste déroulante sélectionnée.

* Plus d'informations et d'autres variables sont disponibles dans propriété CSS: -webkit-apparence.

41
ioTus

Les balises <select> peuvent être stylées via CSS, comme tout élément HTML d'une page HTML rendue dans un navigateur. Vous trouverez ci-dessous un exemple (trop simple) qui positionnera un élément sélectionné sur la page et affichera le texte des options en bleu.

Exemple de fichier HTML (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>

Exemple de fichier 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;
}
34
jeremyosborne

J'ai eu ce problème, sauf que je ne pouvais pas utiliser d'images et que le support du navigateur ne me limitait pas. Cela devrait être "à la carte" et avec de la chance commencer à travailler partout éventuellement .

Il utilise des calques d'arrière-plan en rotation pour "découper" une flèche déroulante, car les pseudo-éléments ne fonctionneraient pas pour l'élément sélectionné.

Edit: Dans cette version mise à jour, j'utilise des variables CSS et un système de thématisation minuscule.

: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>
30
Henrik

Voici une version qui fonctionne dans tous les navigateurs modernes. La clé utilise appearance:none qui supprime le formatage par défaut. Puisque toute la mise en forme a disparu, vous devez rajouter la flèche qui différencie visuellement la sélection à partir de l'entrée.

Exemple de travail: 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>
15
Eric

Le blog Comment faire pour que le style de formulaire CSS ne comporte pas de JavaScript fonctionne pour moi, mais il échoue dans Opera si:

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

Je suis arrivé à votre cas en utilisant Bootstrap . C'est la solution la plus simple qui fonctionne:

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

Remarque: le contenu base64 est fa-chevron-down en SVG.

11
Yajo
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;}
9
gecko

Dans les navigateurs modernes, il est relativement simple de nommer le <select> en CSS. Avec appearance: none, le seul problème est de remplacer la flèche (si c'est ce que vous voulez). Voici une solution qui utilise un URI data: en ligne avec SVG en texte brut:

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>

Le reste du style (bordures, rembourrages, couleurs, etc.) est assez simple.

Cela fonctionne dans tous les navigateurs que je viens d'essayer (Firefox 50, Chrome 55, Edge 38 et Safari 10). Une remarque à propos de Firefox est que si vous souhaitez utiliser le caractère # dans l'URI des données (par exemple, fill: #000), vous devez l'échapper (fill: %23000).

9

Utilisez la propriété clip pour rogner les bordures et la flèche de l'élément select, puis ajoutez vos propres styles de remplacement au wrapper:

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

Utilisez une deuxième sélection avec une opacité nulle pour rendre le bouton cliquable:

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

Les coordonnées diffèrent entre Webkit et les autres navigateurs, mais une @ requête multimédia peut couvrir cela.

Références

7
Paul Sweatte

Modifier cet élément n'est pas recommandé, mais si vous voulez essayer, c'est comme n'importe quel autre élément HTML.

Exemple de modification:

/*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>
4
Homar

Oui. Vous pouvez styler n'importe quel élément HTML avec son nom de balise, comme ceci:

select {
  font-weight: bold;
}

Bien sûr, vous pouvez également utiliser une classe CSS pour la styler, comme n'importe quel autre élément:

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

<style type="text/css">
  .important {
    font-weight: bold;
  }
</style>
4
Dave Ward

Un très bel exemple qui utilise :after et :before pour faire le tour est dans Styling Select Box with CSS3 | CSSDeck

4
Ahmad Ajmi

À partir d'Internet Explorer 10, vous pouvez utiliser le sélecteur de pseudo-éléments ::-ms-expand pour styler et masquer l'élément de flèche déroulante.

_select::-ms-expand {
    display:none;
    /* or visibility: hidden; to keep it's space/hitbox */
}
_

Le style restant doit être similaire à celui des autres navigateurs.

Voici un fork de base de jsfiddle de Danield qui applique le support pour IE1

3
Richard Szalay

Voici une solution basée sur mes idées préférées de cette discussion. Cela permet de styler directement un élément sans aucun balisage supplémentaire.

Fonctionne avec IE10 + avec un repli sûr pour IE8/9. Un inconvénient pour ces navigateurs est que l'image d'arrière-plan doit être positionnée et suffisamment petite pour se cacher derrière le contrôle de développement natif.

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 IE10+
// IE 8/9 get dafault arrow which covers caret image
// as long as caret image is small than and positioned
// behind default arrow
select::-ms-expand {
    display: none;
}

Codepen

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

3
ralgh
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;
}

Cela utilise une couleur de fond pour certains éléments et j'ai enlevé l'image.

3
Lucky

Vous devriez certainement le faire comme dans Styling select, optgroup et options avec CSS. À bien des égards, la couleur d'arrière-plan et la couleur sont exactement ce dont vous auriez besoin pour styliser les options, et non la totalité de la sélection.

3
Otvazhnii

Il IS un moyen de styliser les balises SELECT.

S'il y a un paramètre "taille" dans la balise, presque tous les CSS s'appliqueront. En utilisant cette astuce, j'ai créé un violon qui est pratiquement équivalent à une balise select normale, plus la valeur peut être modifiée manuellement comme une ComboBox dans les langages visuels (à moins que vous ne mettiez en lecture seule dans la balise d’entrée).

Voici donc un exemple minimal pour comprendre le principe de base:
(vous aurez besoin de jQuery pour le mécanisme de clic) :

<style>

    /* only these 2 lines are truly required */
    .stylish span {position:relative;}
    .stylish select {position:absolute;left:0px;display:none}

    /* now you can style the hell out of them */
    .stylish input    { ... }
    .stylish select   { ... }
    .stylish option   { ... }
    .stylish optgroup { ... }

</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="gandalf">Gandalf</option>
            <option value="harry">Harry Potter</option>
            <option value="jon">Jon Snow</option>

            <optgroup label="Comics"></optgroup>
            <option value="tony">Tony Stark</option>
            <option value="steve">Steven Rogers</option>
            <option value="natasha">Natasha Romanova</option>

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

Voici le violon avec quelques autres styles: https://jsfiddle.net/dkellner/7ac9us70/

(Il est bien entendu surdimensionné, juste pour démontrer les possibilités.)

Notez que les balises n'encapsulent pas les options appartenant à elles comme elles le devraient normalement; oui c'est intentionnel, c'est pour le style. (La manière bien éduquée serait beaucoup moins stylée.) Et oui, elles fonctionnent parfaitement bien de cette façon.

Avant que quiconque souligne la partie NO-JS: Je connais la question qui dit "pas de Javascript". Pour moi, cela ressemble plus à s'il vous plaît ne vous embêtez pas avec les plugins, je sais qu'ils peuvent le faire, mais j'ai besoin de la manière native . Compris, pas de plugins, pas de scripts supplémentaires inclus, seulement ce qui rentre dans le tag "onclick". La seule dépendance est jQuery, pour éviter la folie native "document.parentNode.getElementsByTagName". Mais ça peut marcher comme ça. Donc oui, il s’agit d’une balise select native avec un style natif et des gestionnaires onclick. Ce n'est clairement pas "une solution Javascript".

Prendre plaisir!

2
dkellner

Une solution CSS & HTML uniquement

Je semble compatible avec Chrome, Firefox et IE11. Mais s'il vous plaît laissez vos commentaires concernant les autres navigateurs Web.

Comme suggéré par la réponse de @Danield, j’enveloppe ma sélection dans un div (même deux divs pour la compatibilité avec le navigateur x) afin d’obtenir le comportement attendu.

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

Remarquez les 2 wrappers div. Remarquez également le supplément supplémentaire ajouté pour placer le bouton en forme de flèche vers le bas où vous le souhaitez (positionné absolument), nous le mettons ici à gauche.

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 hidding the default-provided browser arrow */
    padding-left: 13px;
    margin-left: 0;
    border: none;
    background: none;
    /* margin-top & margin-bottom must be set since some browser 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;
}
0
Adrien Be

Personnaliser Sélectionner les styles CSS

Testé dans IE (10, 11), Edge, FF, 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>
0
Roko C. Buljan

Vous pouvez également ajouter un style de survol au menu déroulant.

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

La troisième méthode de la réponse de Danield ( --- (https://stackoverflow.com/a/13968900/280972 ) peut être améliorée pour fonctionner avec les effets de survol et les autres événements de souris. Assurez-vous simplement que l'élément "button" vient juste après l'élément select dans le balisage. Puis ciblez-le avec le sélecteur + css:

HTML:

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

CSS:

.select-input:hover+.select-button {
    [hover styles here]
}

Cela montrera toutefois l'effet de survol lors du survol n'importe où sur l'élément sélectionné, pas seulement sur le "bouton".

J'utilise cette méthode en combinaison avec Angular (car mon projet est de toute façon une application angulaire), pour couvrir tout l'élément select et laisser Angular afficher le texte de l'option sélectionnée dans l'élément "button". Dans ce cas, il est parfaitement logique que l’effet de survol s’applique lorsque vous survolez la sélection. Toutefois, cela ne fonctionne pas sans JavaScript. Par conséquent, si vous souhaitez le faire et que votre site doit fonctionner sans JavaScript, vous devez vous assurer que votre script ajoute les éléments et les classes nécessaires à l'amélioration. De cette façon, un navigateur sans JavaScript obtiendra simplement un badge normal, non stylé, au lieu d’un badge stylé qui ne se met pas à jour correctement.

0
Adrian Schmidt