problem z <select> i: after z CSS w WebKit


124

Chciałbym dodać styl do pola wyboru za pomocą pseudo: after (aby nadać styl mojemu polu wyboru z 2 częściami i bez obrazów). Oto kod HTML:

<select name="">
  <option value="">Test</option>
</select>

I to nie działa. Nie wiem dlaczego i nie znalazłem odpowiedzi w specyfikacji W3C. Oto CSS:

select {
  -webkit-appearance: none;
  background: black;
  border: none;
  border-radius: 0;
  color: white;
}

select:after {
  content: " ";
  display: inline-block;
  width: 24px; height: 24px;
  background: blue;
}

Czy to normalne, czy jest jakaś sztuczka?


Wyobrażam sobie, że to nie będzie, nie powinno być możliwe, w przeciwnym razie byłoby to uczynić go zbyt łatwo zmienić zawartość formularzy. Wyobraź sobie prosty kawałek CSS zmieniający cenę wyświetlania czegoś. Można to pokazać jako tańsze niż w rzeczywistości, nakłaniając ludzi do zakupu czegoś za więcej, niż się spodziewali. (Lub oczywiście, jeśli ktoś ma dostęp do CSS strony / arkusza stylów użytkownika, prawdopodobnie mógłby zrobić to samo w inny sposób…)
Synetech

22
@Synetech - to nieprawda, autor strony powinien mieć pełną kontrolę nad wszystkimi aspektami stylizacji strony. Producenci przeglądarek próbujący zapobiec stylizowaniu niektórych elementów, ponieważ mogą być wykorzystywane do wprowadzania użytkowników w błąd, nie będą skuteczni, ponieważ istnieje prawie nieograniczona liczba sposobów na oszukanie systemu lub wygenerowanie fałszywych alarmów.
Jonathan Cross,

1
Możliwy duplikat pseudoelementów i tagu SELECT
Tessa

Odpowiedzi:


133

Nie sprawdzałem tego dokładnie, ale mam wrażenie, że nie jest to (jeszcze?) Możliwe, ze względu na sposób, w jaki selectelementy są generowane przez system operacyjny, na którym działa przeglądarka, a nie przez samą przeglądarkę.


63
Jest teraz 2019 i nadal jest tak samo
Placido

41
Teraz jest rok 2020 i nadal jest tak samo
Joeri Minnekeer

3
Gdybym widział Twój komentarz do tego 10-letniego postu godzinę temu, zaoszczędziłbym sobie godzinę swojego czasu. : C
ericek111

66

Szukałem tego samego, ponieważ tło mojego zaznaczenia jest takie samo jak kolor strzałki. Jak wspomniano wcześniej, nie można jeszcze dodać niczego za pomocą: before lub: after na wybranym elemencie. Moim rozwiązaniem było utworzenie elementu wrapper, na którym dodałem: przed kodem.

.select-wrapper {
    position: relative;
}

.select-wrapper:before {
    content: '\f0d7';
    font-family: FontAwesome;
    color: #fff;
    display: inline-block;
    position: absolute;
    right: 20px;
    top: 15px;
    pointer-events: none;
}

I to mój wybór

select {
    box-sizing: border-box;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    width: 100%;
    padding: 10px 20px;
    background: #000;
    color: #fff;
    border: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
}

select::-ms-expand {
    display: none;
}

Użyłem FontAwesome.io do mojej nowej strzały, ale możesz użyć wszystkiego, co chcesz. Oczywiście nie jest to idealne rozwiązanie, ale w zależności od potrzeb może wystarczyć.


4
To jest wizualnie idealne. Ale nie możesz kliknąć tej ikony i wybrać element nie zostanie otwarty: / Jakieś sugestie?
Schovi

11
zdarzenia wskaźnikowe: brak; Powinien się tym zająć. Wystąpił problem z moim kodem powyżej. Zmienię dowolny sass powyżej na css, aby usunąć wszelkie nieporozumienia.
sroy

Czy ma znaczenie, który pseudo selektor (przed czy po) jest używany?
eddiegroves

Możesz użyć jednego lub drugiego
sroy

2
To świetne rozwiązanie, ale wdrażając je stwierdziłem, że z jakiegoś powodu: przed działaniem i NIE: po. Nie wiem dlaczego.
Lee Probert

32

Z mojego doświadczenia wynika, że ​​po prostu nie działa, chyba że zechcesz zawinąć go <select>w jakieś opakowanie. Ale zamiast tego możesz użyć obrazu tła SVG. Na przykład

    .archive .options select.opt {
    -moz-appearance: none;
    -webkit-appearance: none;
    padding-right: 1.25EM;
    appearance: none;
    position: relative;
    background-color: transparent;
    background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1.1' height='10px' width='15px'%3E%3Ctext x='0' y='10' fill='gray'%3E%E2%96%BE%3C/text%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-size: 1.5EM 1EM;
    background-position: right center;
    background-clip: border-box;
    -moz-background-clip: border-box;
    -webkit-background-clip: border-box;
}

    .archive .options select.opt::-ms-expand {
        display: none;
    }

Tylko uważaj na prawidłowe kodowanie adresów URL ze względu na IE. Musisz używać charset=utf8(nie tylko utf8), nie używać podwójnych cudzysłowów (") do oddzielania wartości atrybutów SVG, zamiast tego użyj apostrofów ('), aby uprościć sobie życie. Kodowanie adresów URL (% 3E). Na wypadek, gdybyś musiał drukować wszelkie znaki spoza ASCII, które musisz uzyskać, aby uzyskać ich reprezentację UTF-8 (np. BabelMap może ci w tym pomóc), a następnie podać tę reprezentację w postaci zakodowanej w adresie URL - np. dla ▾ ( U+25BECZARNY MAŁY TRÓJKĄT WSKAZUJĄCY W DÓŁ) Reprezentacja UTF-8 jest \xE2\x96\xBEczyli w %E2%96%BEprzypadku zakodowania adresu URL.


1
To ładne i eleganckie rozwiązanie
JosFabre

1
To fantastyczne, proste i eleganckie rozwiązanie, które nie wymaga dodatkowego kodu HTML, a właśnie tego szukałem! Dzięki! To powinna być wybrana odpowiedź IMO.
KyleFarris


13

W obliczu tego samego problemu. Prawdopodobnie mogłoby to być rozwiązanie:

<select id="select-1">
    <option>One</option>
    <option>Two</option>
    <option>Three</option>
</select>
<label for="select-1"></label>

#select-1 {
    ...
}

#select-1 + label:after {
    ...
}

Czy możesz dodać style wymagane, aby etykieta znajdowała się nad wybranym elementem?
bafromca

7

To rozwiązanie jest podobne do tego z sroy, ale z trójkątem CSS zamiast czcionki internetowej:

.select-wrapper {
  position: relative;
  width: 200px;
}
.select-wrapper:after {
  content: "";
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 6px solid #666;
  position: absolute;
  right: 8px;
  top: 8px;
  pointer-events: none;
}
select {
  background: #eee;
  border: 0 !important;
  border-radius: 0;
  -webkit-appearance:none;
  -moz-appearance:none;
  appearance:none;
  text-indent: 0.01px;
  text-overflow: "";
  font-size: inherit;
  line-height: inherit;
  width: 100%;
}
select::-ms-expand {
  display: none;
}
<div class="select-wrapper">
  <select>
    <option value="1">option 1</option>
    <option value="2">option 2</option>
    <option value="3">option 3</option>
  </select>
</div>


6

A jeśli modyfikowanie znaczników nie wchodzi w grę?

Oto rozwiązanie, które nie ma wymagań dotyczących opakowania: wykorzystuje plik SVG w obrazie tła. Może być konieczne użycie dekodera encji HTML, aby zrozumieć, jak zmienić kolor wypełnienia.

-moz-appearance: none;
-webkit-appearance: none;
appearance: none;

background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23000000%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E');
background-repeat: no-repeat;
background-position: right .7em top 50%;
background-size: .65em auto;

Ściągnięte z CSS-Tricks .


To niezła sztuczka. Bardzo denerwujące, że nadal nie możemy stylizować
selekcji

5

To nowoczesne rozwiązanie, które stworzyłem używając font-awesome . Rozszerzenia dostawców zostały pominięte ze względu na zwięzłość.

HTML

<fieldset>
    <label for="color">Select Color</label>
    <div class="select-wrapper">
        <select id="color">
            <option>Red</option>
            <option>Blue</option>
            <option>Yellow</option>
        </select>
        <i class="fa fa-chevron-down"></i>
    </div>
</fieldset>

SCSS

fieldset {
    .select-wrapper {
        position: relative;

        select {
            appearance: none;
            position: relative;
            z-index: 1;
            background: transparent;

            + i {
                position: absolute;
                top: 40%;
                right: 15px;
            }
        }
    }

Jeśli wybrany element ma zdefiniowany kolor tła, to nie zadziała, ponieważ ten fragment zasadniczo umieszcza ikonę Chevron za wybranym elementem (aby umożliwić kliknięcie na górze ikony, aby nadal zainicjować akcję zaznaczania).

Możesz jednak nadać styl opakowaniom typu select taki sam rozmiar jak element zaznaczenia i stylizować jego tło, aby uzyskać ten sam efekt.

Sprawdź mój CodePen, aby zobaczyć działające demo, które pokazuje ten fragment kodu zarówno na ciemnym, jak i jasnym polu wyboru przy użyciu zwykłej etykiety i etykiety „zastępczej” oraz innych wyczyszczonych stylów, takich jak obramowanie i szerokość.

PS To jest odpowiedź, którą wysłałem na inne, zduplikowane pytanie na początku tego roku.


1
<div class="select">
<select name="you_are" id="dropdown" class="selection">
<option value="0" disabled selected>Select</option>
<option value="1">Student</option>
<option value="2">Full-time Job</option>
<option value="2">Part-time Job</option>
<option value="3">Job-Seeker</option>
<option value="4">Nothing Yet</option>
</select>
</div>

Zamiast stylizacji select, dlaczego nie dodajesz elementu div poza zaznaczeniem.

a następnie styl w CSS

.select{
    width: 100%;
    height: 45px;
    position: relative;
}
.select::after{
    content: '\f0d7';
    position: absolute;
    top: 0px;
    right: 10px;
    font-family: 'Font Awesome 5 Free';
    font-weight: 900;
    color: #0b660b;
    font-size: 45px;
    z-index: 2;

}
#dropdown{
    -webkit-appearance: button;
       -moz-appearance: button;
            appearance: button;
            height: 45px;
            width: 100%;
        outline: none;
        border: none;
        border-bottom: 2px solid #0b660b;
        font-size: 20px;
        background-color: #0b660b23;
        box-sizing: border-box;
        padding-left: 10px;
        padding-right: 10px;
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.