Jak stylizować menu rozwijane <select> przy użyciu tylko CSS?

1333

Czy istnieje tylko styl CSS, aby stylizować <select>menu rozwijane?

Muszę stylizować <select>formularz tak bardzo, jak to tylko możliwe, bez JavaScript. Jakich właściwości mogę użyć w CSS?

Ten kod musi być zgodny ze wszystkimi głównymi przeglądarkami:

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

Wiem, że mogę to zrobić za pomocą JavaScript: przykład .

I nie mówię o prostej stylizacji. Chcę wiedzieć, co najlepiej możemy zrobić tylko z CSS.

Znalazłem podobne pytania na temat przepełnienia stosu.

I ten na Doctype.com.

Jitendra Vyas
źródło
1
nic nie znaleziono w google tylko rozwiązanie js jest tam
Jitendra Vyas
41
Wydaje mi się, że jest to uzasadnione pytanie, ale odpowiedź brzmi „nie, nie bardzo” lub „nie tak, jak chcesz”. Ale nikt (ani ja) nie jest tego w 100% pewien, to uczucie dwuznaczności pełznie pod skórą czytelnika i kwestionuje zasadność pytania.
ZJR,
1
@Jitendra, wiem o co ci chodzi. Chcielibyśmy, aby Twoje pytanie było bardziej wyraźne. Plus, myślę, że znalazłem to, czego możesz szukać. Jest to eksperymentalne, ale sprawdź to: cappuccino.org/aristo/showcase
jeremyosborne
1
@jeremyosborne - Dzięki za odpowiedź. Wiem, że mogę to zrobić za pomocą javascript. Twój eaxmple link jest oparty na JS. Dlaczego zadałem to pytanie, ponieważ chciałem wiedzieć, czy ktokolwiek wie o tym, co możemy zrobić tylko z css
Jitendra Vyas,
@Jitendra Dziękujemy za aktualizację pytania. Najlepsze, co możesz niezawodnie zrobić z ograniczeniami, które masz (tylko CSS i bez JS) to modyfikacja kroju pisma (czcionki), kolorów tła i pierwszego planu (tekstu), rozmiaru obramowania, wyglądu i kolorów, umiejscowienia i rozmiaru (zazwyczaj za pomocą rodzaju ustawienie za pomocą czcionki). Nawet wtedy prawdopodobnie będziesz musiał zrobić kilka poprawek, aby upewnić się, że wszystko wygląda tak samo we wszystkich przeglądarkach. Chciałbym wiedzieć, że jest lepsza odpowiedź i być może tęsknię za nią, ale nie sądzę.
jeremyosborne,

Odpowiedzi:

1027

Oto trzy rozwiązania:

Rozwiązanie nr 1 - Wygląd: brak - z obejściem programu Internet Explorer 10–11 ( Demo )

-

Aby ukryć domyślny zestaw strzałek appearance: nonena elemencie select, a następnie dodaj własną strzałkę niestandardową za pomocąbackground-image

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

Obsługa przeglądarki:

appearance: nonema bardzo dobrą obsługę przeglądarki ( caniuse ) - z wyjątkiem Internet Explorera 11 (i późniejszych) i Firefox 34 (i późniejszych).

Możemy ulepszyć tę technikę i dodać obsługę przeglądarki Internet Explorer 10 i Internet Explorer 11 poprzez dodanie

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

Jeśli problem dotyczy programu Internet Explorer 9, nie mamy możliwości usunięcia domyślnej strzałki (co oznaczałoby, że mamy teraz dwie strzałki), ale możemy użyć funkcyjnego selektora programu Internet Explorer 9.

Aby przynajmniej cofnąć naszą niestandardową strzałkę - pozostawiając domyślną strzałkę nienaruszoną.

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

Wszyscy razem:

To rozwiązanie jest łatwe i ma dobrą obsługę przeglądarki - ogólnie powinno wystarczyć.


Jeśli konieczna jest obsługa przeglądarki Internet Explorer 9 (i nowsze) i Firefox 34 (i nowsze), czytaj dalej ...

Rozwiązanie nr 2 Obetnij wybrany element, aby ukryć domyślną strzałkę ( wersja demonstracyjna )

-

(Przeczytaj więcej tutaj)

Zawiń selectelement w div o stałej szerokości i overflow:hidden.

Następnie nadaj selectelementowi szerokość około 20 pikseli większą niż div .

W rezultacie domyślna strzałka rozwijana selectelementu zostanie ukryta (ze względu overflow:hiddenna na pojemniku) i możesz umieścić dowolny obraz tła, który chcesz, po prawej stronie div.

Zaletą tego podejścia jest to, że z różnymi przeglądarkami (Internet Explorer 8 i nowsze, WebKit i Gecko ). Jednak wadą tego podejścia jest to, że lista rozwijana opcji wystaje po prawej stronie (o 20 pikseli, które ukryliśmy ... ponieważ elementy opcji przyjmują szerokość wybranego elementu).

Wpisz opis zdjęcia tutaj

[Należy jednak zauważyć, że jeśli niestandardowy element wyboru jest konieczny tylko dla urządzeń mobilnych - powyższy problem nie dotyczy - ze względu na sposób, w jaki każdy telefon natywnie otwiera element wyboru. Dla urządzeń mobilnych może to być najlepsze rozwiązanie.]


Jeśli niestandardowa strzałka jest niezbędna w przeglądarce Firefox - przed wersją 35 - ale nie musisz obsługiwać starych wersji programu Internet Explorer - czytaj dalej ...

Rozwiązanie nr 3 - Użyj pointer-eventswłaściwości ( wersja demonstracyjna )

-

(Przeczytaj więcej tutaj)

Chodzi o to, aby nałożyć element na natywną strzałkę rozwijaną (aby utworzyć naszą niestandardową), a następnie zabronić na nim zdarzeń wskaźnika.

Zaleta: Działa dobrze w WebKit i Gecko. Wygląda również dobrze (bez wystających optionelementów).

Wada: Internet Explorer (Internet Explorer 10 i nowsze) nie obsługuje pointer-events, co oznacza, że ​​nie można kliknąć niestandardowej strzałki. Kolejną (oczywistą) wadą tej metody jest to, że nie można celować w nowy obraz strzałki za pomocą efektu aktywowania lub kursora ręki, ponieważ właśnie na nich wyłączyliśmy zdarzenia wskaźnika!

Jednak za pomocą tej metody można użyć Modernizatora lub komentarzy warunkowych, aby przywrócić Internet Explorera do standardowej wbudowanej strzałki.

Uwaga: Ponieważ Internet Explorer 10 już nie obsługuje conditional comments: jeśli chcesz skorzystać z tego podejścia, prawdopodobnie powinieneś skorzystać z Modernizr . Nadal możliwe jest jednak wykluczenie CSS-a ze wskaźnikami z Internet Explorera 10 za pomocą opisanego tutaj hacka CSS .

Danield
źródło
1
Który z nich jest najlepszy według tych 2 metod?
Jitendra Vyas,
3
To zależy od wymagań projektowych. Jeśli nie masz nic przeciwko rozwijaniu się listy rozwijanej - to jest najlepsze, ponieważ jest to przeglądarka internetowa (wszystkie przeglądarki IMO + IE8 + można uznać za przeglądarkę internetową), ale myślę, że wielu nie zrobi tego. Tak więc w moim powyższym stwierdzeniu miałem na myśli, że podejście nr 2 było najlepsze.
Danield,
4
Również skrzypce, które opublikowałem, wykorzystuje podejście nr 2 z instrukcjami warunkowymi, aby umożliwić IE użycie domyślnej strzałki.
Danield,
3
@AlexisLeclerc Naprawianie div i zaznaczenie tej samej szerokości działa tylko w przeglądarkach -webkit, takich jak Chrome. (ponieważ zawarłem zasadę - wygląd zestawu: brak; ) Jednak to nie działa w innych przeglądarkach, takich jak Firefox
Danield
4
Jeśli mogę zaproponować ulepszenie w podejściu nr 1, osobiście uważam, że brak obramowania lub brak halo selekcji po prawej stronie jest bardzo denerwujący. Zaktualizowałem twoje skrzypce za pomocą czegoś, czego użyłem w moim bieżącym projekcie: jsfiddle.net/YvCHW/1745 . Powiedz mi co myślisz!
Alexis Leclerc
233

Jest to możliwe, ale niestety głównie w przeglądarkach opartych na WebKit w zakresie, w jakim my, jako programiści, wymagamy. Oto przykład stylu CSS zebranego z panelu opcji Chrome za pomocą wbudowanego inspektora narzędzi programistycznych, ulepszonego w celu dopasowania do obecnie obsługiwanych właściwości CSS w większości nowoczesnych przeglądarek:

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

Kiedy uruchomisz ten kod na dowolnej stronie w przeglądarce opartej na WebKit, powinien on zmienić wygląd pola wyboru, usunąć standardową strzałkę systemu operacyjnego i dodać strzałkę PNG, umieścić odstępy przed i po etykiecie, prawie wszystko, co chcesz.

Najważniejszą częścią jest appearancewłaściwość, która zmienia sposób zachowania elementu.

Działa idealnie w prawie wszystkich przeglądarkach opartych na WebKit, w tym także na urządzeniach mobilnych, chociaż Gecko nie obsługuje appearancetak dobrze jak WebKit.

Matthew Morek
źródło
4
Hej, zauważyłem, że wybrane pudełka zaczęły wyglądać zupełnie inaczej niż Firefox 12 (wygląda dużo jak Chrome (mam Maca)) i wydaje się, że FF 12 obsługuje o wiele więcej atrybutów wyglądu.
CWSpear
3
rozwiązanie tylko dla chromu ... Nie zapłaciłbym za to ani mój klient. zobacz odpowiedź @ Dianeld na X-przeglądarkę.
Adrien Be
41
@AdrienBe Moje rozwiązanie zostało zaproponowane prawie 3 lata temu; w tym czasie był to jedyny rozsądny sposób na zmianę stylu wybranych pól bez angażowania bibliotek JavaScript lub wtyczek. Nadal jest opłacalne, jeśli zdecydujesz się usunąć prefiksy, ale działa niezawodnie tylko w przeglądarkach opartych na Webkit (więc Safari, nowa Opera + Android również). W tej chwili mogą istnieć lepsze rozwiązania, więc zamiast dodawać bezsensowne komentarze, po prostu głosuj na rozwiązanie, które uważasz za lepsze, a w przyszłości sprawdź datę „odpowiedzi”. Dzięki.
Matthew Morek
4
@MatthewMorek: było lepsze rozwiązanie, nawet 3 lata temu. Odpowiedź Daniela jest znacznie lepsza w zakresie obsługi w różnych przeglądarkach (obsługuje IE8 i nowsze wersje, WebKit i Gecko). Pytanie brzmiało: „kod musi być zgodny ze wszystkimi głównymi przeglądarkami: Internet Explorer 6,7 i 8, Firefox i Safari”. To wymaganie dotyczące przeglądarki X mogło zostać dodane przez Paula Sweatte w 2013 roku, choć ... przepraszam, jeśli tak jest.
Adrien Be
3
Jeśli dodasz text-indent: 0.01px; text-overflow: "";, będzie działać jeszcze lepiej
Ivan
64

Element wyboru i jego rozwijana funkcja trudne do stylizacji.

atrybuty stylu dla wybranego elementu autorstwa Chrisa Heilmanna potwierdzają to, co powiedział Ryan Dohery w komentarzu do pierwszej odpowiedzi:

„Element select jest częścią systemu operacyjnego, a nie przeglądarki Chrome. Dlatego styl jest bardzo zawodny i niekoniecznie ma sens, aby próbować”.

pavium
źródło
47

Miałem dokładnie ten problem, ale nie mogłem używać obrazów i nie był ograniczony przez obsługę przeglądarki. To powinno być «w ciemno» i ze startu szczęście pracować wszędzie ostatecznie .

Używa warstwowych obróconych warstw tła, aby „wyciąć” strzałkę rozwijaną, ponieważ pseudoelementy nie działałyby dla wybranego elementu.

Edycja: W tej zaktualizowanej wersji używam zmiennych CSS i małego systemu tematycznego.

: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
źródło
5
Wow, to jedno z najfajniejszych rozwiązań, jakie widziałem. Działa dla mnie w najnowszych wersjach Chrome i Safari na Mac. A co z innymi przeglądarkami?
Tintin81
2
Działa dla mnie w Firefoksie z dodatkiem-moz-appearance: none;
Zac
45

Największą niespójnością, jaką zauważyłem podczas stylizowania menu rozwijanych wybranych, jest renderowanie Safari i Google Chrome (Firefox można w pełni dostosować za pomocą CSS). Po przeszukaniu niejasnych głębin Internetu natknąłem się na następujące, które prawie całkowicie rozwiązują moje problemy z WebKit:

Poprawka przeglądarki Safari i Google Chrome :

select {
  -webkit-appearance: none;
}

Spowoduje to jednak usunięcie strzałki rozwijanej. Możesz dodać strzałkę rozwijaną, używając pobliskiego divz tłem, ujemnym marginesem lub absolutnie umieszczonego nad rozwijanym wyborem.

* Więcej informacji i inne zmienne są dostępne we właściwości CSS: -webkit-wygląd .

ioTus
źródło
1
Nie zapomnij dodać potem swojej stylizacji;) Ale bardzo się cieszę, że przeczytałem ten komentarz dzisiaj.
teewuane
1
czy mógłbyś rozwinąć swoje oświadczenie: „Firefox jest w pełni dostosowywalny poprzez CSS”, dla mnie wygląda na to, że firefox nie obsługuje właściwości wygląd ... więc jak to zrobić w Firefox?
Danield,
36

<select>tagi mogą być stylizowane za pomocą CSS, tak jak każdy inny element HTML na stronie HTML renderowanej w przeglądarce. Poniżej znajduje się (zbyt prosty) przykład, który umieści element select na stronie i wyrenderuje tekst opcji na niebiesko.

Przykładowy plik 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>

Przykładowy plik 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
źródło
30
Niesamowite, kiedy po raz pierwszy zobaczyłem „matki” zaangażowane w Internecie, nie będąc niegrzecznym. +1 za to!
BaL
34
Ta odpowiedź nie rozwiązuje tego pytania. Tylko style wybierają dane wejściowe, ale nie rozwijane
Kyborek,
14
Ta odpowiedź całkowicie ignoruje wyzwania związane ze stylizowaniem listy rozwijanej w celu zapewnienia spójności między przeglądarkami. To odpowiedź na bardzo niewielki wysiłek.
BentOnCoding,
18

Wpis na blogu Jak rozwinąć styl CSS, JavaScript nie działa dla mnie, ale w Operze nie działa :

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
źródło
17

Oto wersja, która działa we wszystkich nowoczesnych przeglądarkach. Klawisz używa, appearance:nonektóry usuwa domyślne formatowanie. Ponieważ całe formatowanie zniknęło, musisz dodać z powrotem strzałkę, która wizualnie odróżnia wybór od wejścia.

Przykład roboczy: 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
źródło
16

Dotarłem do twojej sprawy za pomocą Bootstrap . To najprostsze rozwiązanie, które działa:

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>

Uwaga: rzeczy base64 są fa-chevron-downw formacie SVG.

Yajo
źródło
12

W nowoczesnych przeglądarkach stylizacja <select>w CSS jest stosunkowo bezbolesna . Z appearance: nonejedynym Najtrudniejszą częścią jest zastąpienie strzałkę (jeśli to, co chcesz). Oto rozwiązanie wykorzystujące wbudowany data:identyfikator URI z jawnym tekstem SVG:

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>

Reszta stylizacji (obramowania, wypełnienie, kolory itp.) Jest dość prosta.

Działa to we wszystkich przeglądarkach, które właśnie wypróbowałem (Firefox 50, Chrome 55, Edge 38 i Safari 10). Jedna uwaga na temat Firefoksa polega na tym, że jeśli chcesz użyć #znaku w identyfikatorze URI danych (np. fill: #000), Musisz go usunąć ( fill: %23000).

Kevin Christopher Henry
źródło
1
Możesz również zmienić rozmiar pliku SVG za pomocą atrybutu heighti / lub tagu zamiast właściwości CSS . width<svg>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;}
gekon
źródło
Nie można wybrać niczego przy tym w obecnym Chrome.
Witalij Zdanevich,
8

Użyj clipwłaściwości, aby przyciąć ramki i strzałkę selectelementu, a następnie dodaj własne style zastępowania do opakowania:

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

Użyj drugiego wyboru z zerowym kryciem, aby przycisk można kliknąć:

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

Współrzędne różnią się między Webkitem a innymi przeglądarkami, ale zapytanie @media może to obejmować.

Bibliografia

Paul Sweatte
źródło
1
Działa dla mnie dobrze, przynajmniej w chrome: pozycja: absolutna; klip: rect (2px 85px 128px 2px); indeks Z: 2; padding-left: 18px; padding-right: 18px; margines: 7px auto; kolor: # 555; rozmiar czcionki: dziedziczony; kolor tła: przezroczysty;
BrianFreud
1
Znalazłem przycinanie strzałki tylko połowa działa w IE7, ponieważ nie masz kontroli nad ramką zaznaczenia.
CpILL
1
Dodano funkcję kliknięcia w ramach powiązanego pytania
Paul Sweatte
1
@PaulSweatte, wow, to twój 20. nekromanta ! Gratulacje. Pokonałeś także wszystkie moje zapytania o złotą odznakę nekromanty .
Nemo
8

Niestandardowe Wybierz style CSS

Testowany w Internet Explorerze (10 i 11), Edge, Firefox i 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
źródło
Nieco bardziej elastyczny (ale nie testowany we wszystkich przeglądarkach):background-position: right 15px center, right 10px center;
Robin Stewart
5

Bardzo dobrym przykładem, który wykorzystuje :afteri :beforedo robienia sztuczek, jest Styling Select Box z CSS3 | CSSDeck

Ahmad Ajmi
źródło
1
Tak, ale wymaganie było zgodne z programem Internet Explorer 6,7 i 8
Jitendra Vyas
2
Tak To nie jest kompatybilne z IE, ale uwielbiałem dzielić się tym, którzy szukają nowoczesnego rozwiązania.
Ahmad Ajmi
5

Edycja tego elementu nie jest zalecana, ale jeśli chcesz spróbować, działa jak każdy inny element HTML.

Edytuj przykład:

/* 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
źródło
2
@MikkoP: czy sugerując zmiany, proszę podać bardziej opisowe podsumowanie edycji? „Ulepszona wiadomość” nie jest bardzo pomocnym podsumowaniem wysokiego poziomu dla naszych recenzentów. Dzięki.
Jean-François Corbett,
1
@ Jean-FrançoisCorbett Postaram się sprecyzować :)
MikkoP,
1
nie można stylizować elementów opcjonalnych (patrz odpowiedź SO: stackoverflow.com/a/7208814/703717 )
Danield,
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;
}

Używa koloru tła dla wybranych elementów i usunąłem obraz.

Szczęściarz
źródło
4

Tak. Możesz stylizować dowolny element HTML według jego nazwy, na przykład:

select {
  font-weight: bold;
}

Oczywiście możesz również użyć klasy CSS, aby ją stylizować, jak każdy inny element:

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

<style type="text/css">
  .important {
    font-weight: bold;
  }
</style>
Dave Ward
źródło
6
nie mówię o tym chcę zmienić strzałkę listy rozwijanej na coś innego
Jitendra Vyas
5
Nie można stylizować strzałki rozwijanej do innego obrazu, jest on kontrolowany przez system operacyjny. Jeśli naprawdę potrzebujesz, najlepiej jest użyć widgetu rozwijanego DHTML.
Ryan Doherty,
3
Możesz zmieniać właściwości CSS tylko poprzez CSS. Możesz zmienić jego margines, wypełnienie, właściwości czcionki, kolor tła itp. Jeśli chcesz, aby wyglądał zupełnie inaczej, po prostu musisz zastąpić go grafiką w czasie wykonywania za pomocą JavaScript (co nie jest złym rozwiązaniem, jeśli zostanie wykonane dobrze ).
Dave Ward,
4

Oto rozwiązanie oparte na moich ulubionych pomysłach z tej dyskusji. Pozwala to na stylizowanie elementu <select> bezpośrednio, bez dodatkowych znaczników.

Działa Internet Explorer 10 (i nowsze wersje) z bezpieczną rezerwą dla Internet Explorera 8/9. Jednym z zastrzeżeń dla tych przeglądarek jest to, że obraz tła musi być ustawiony i być wystarczająco mały, aby ukryć się za natywną kontrolą rozwijania.

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
źródło
3

Jest prosty sposób.

Sprawdź to skrzypce i wybacz mi overstyling: https://jsfiddle.net/dkellner/7ac9us70/

Sztuczka: jak tylko tag <select> otrzyma właściwość o nazwie „size”, będzie się zachowywał jak lista o stałej wysokości i nagle, z jakiegoś powodu, pozwoli ci nadać mu styl. Mówiąc ściśle, ustalona lista jest efektem ubocznym - ale pomaga nam bardziej, ponieważ używamy jej do „rozwijanego wyglądu”.

Minimalny przykład:

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

(dla uproszczenia zrobiłem to z jQuery - ale możesz zrobić to samo bez tego)

Notatki dodatkowe

  • To rozwiązanie daje więcej niż tylko opcję wyboru: wartość można również edytować ręcznie. Użyj właściwości tylko do odczytu, jeśli wolisz domyślny sposób ograniczonego wyboru.

  • Aby zmaksymalizować możliwości stylizacji, znaczniki <optgroup> nie znajdują się wokół ich dzieci, są przenoszone przed nimi. Jest celowy, wizualnie wyraźniejszy i chętnie pracują w ten sposób, nie martw się.

  • Javascript: tak, wiem, że OP powiedział „nie Javascript”, ale zrozumiałem to, proszę, nie przejmuj się wtyczkami , co jest w porządku. Nie potrzebujesz do tego żadnych bibliotek. Nawet jQuery, jak powiedziałem, to tylko dla przejrzystości przykładu.

dkellner
źródło
2

Możesz także dodać styl aktywowania do menu rozwijanego.

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>


źródło
2

Trzecia metoda w odpowiedzi Danielda może zostać ulepszona do pracy z efektami najechania myszą i innymi zdarzeniami myszy. Upewnij się tylko, że element „przycisku” pojawia się zaraz po elemencie select w znaczniku. Następnie celuj za pomocą selektora + CSS:

HTML:

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

CSS:

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

To jednak pokaże efekt najechania kursorem w dowolnym miejscu nad elementem wyboru, a nie tylko nad „przyciskiem”.

Używam tej metody w połączeniu z Angularem (ponieważ i tak mój projekt jest aplikacją Angular), aby objąć cały element select i pozwolić Angularowi wyświetlić tekst wybranej opcji w elemencie „button”. W takim przypadku doskonale ma sens, że efekt najechania na kursor ma zastosowanie, gdy najedziesz kursorem w dowolnym miejscu nad zaznaczeniem.

Nie działa jednak bez JavaScript, więc jeśli chcesz to zrobić, a Twoja strona musi działać bez JavaScript, powinieneś upewnić się, że twój skrypt dodaje elementy i klasy niezbędne do rozszerzenia. W ten sposób przeglądarka bez JavaScriptu otrzyma zwykły, niestylowany wybór, zamiast stylowej plakietki, która nie aktualizuje się poprawnie.

Adrian Schmidt
źródło
1
Chciałbym poznać przyczynę jakichkolwiek negatywnych opinii, więc mogę wiedzieć, jak poprawić! 🙂
Adrian Schmidt
1

Rozwiązanie tylko CSS i HTML

Wydaje się być kompatybilny z Chrome, Firefox i Internet Explorer 11. Ale proszę zostawić swoją opinię na temat innych przeglądarek internetowych.

Jak sugeruje odpowiedź Danielda , zawijam mój wybór w div (nawet dwa div dla kompatybilności z przeglądarkami x), aby uzyskać oczekiwane zachowanie.

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

Zwróć uwagę na dwa opakowania div.

Zwróć także uwagę na dodatkowy div dodany, aby umieścić przycisk strzałki w dół, gdziekolwiek chcesz (absolutnie ustawiony), tutaj umieszczamy go po lewej stronie.

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
źródło