проблема з <select> і: after з CSS у WebKit


123

Я хотів би додати деякий стиль у вікно вибору з псевдо: after (для стилістики мого вибору з 2 частин та без зображень). Ось HTML:

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

І це не працює. Я не знаю, чому я не знайшов відповіді в специфікаціях W3C. Ось 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;
}

Так це нормально чи є хитрість?


Я думаю, що це не було б, не могло б бути можливо, інакше було б надто легко змінювати зміст форм. Уявіть простий шматочок CSS, який змінює ціну дисплея на щось. Це можна показати як дешевше, ніж є насправді, обманюючи людей купувати щось більше, ніж вони очікували. (Або звичайно, якщо хтось має доступ до CSS сторінки / userstylesheet, він, ймовірно, може зробити те ж саме і іншими способами…)
Synetech

22
@Synetech - Це неправильно, автор сторінки повинен мати повний контроль над усіма аспектами стилізації сторінки. Виробники браузерів, які намагаються запобігти стилізації певних елементів, оскільки вони можуть бути використані для введення в оману користувачів, не будуть ефективними, оскільки існує майже необмежена кількість способів підманути систему або створити помилкові позитиви.
Джонатан Хрест

Відповіді:


132

Я ще не перевіряв це ретельно, але мені здається, що це неможливо (поки що?) Через те, як selectгенеруються елементи ОС, на якій працює браузер, а не сам браузер.


62
Зараз 2019 рік, і все одно
Placido

40
Зараз 2020 рік, і все одно
Joeri Minnekeer

3
Якби я бачив ваш коментар до цього 10-річного допису годину тому, я би заощадив собі годину свого часу. : C
ericek111

66

Я шукав те саме, оскільки фон мого вибору такий самий, як і колір стрілки. Як вже було сказано раніше, поки що неможливо додати щось, використовуючи: до або: після на обраному елементі. Моє рішення полягало в створенні обгорткового елемента, до якого я додав наступне: перед кодом.

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

І це мій вибір

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

Я використовував FontAwesome.io для своєї нової стрілки, але ви можете використовувати все, що завгодно. Очевидно, це не ідеальне рішення, але залежно від ваших потреб це може бути достатньо.


4
Це візуально ідеально. Але ви не можете натиснути цю піктограму і вибрати елемент, який не буде відкрито: / Будь-які пропозиції?
Шові

11
покажчик-події: немає; повинні подбати про це. Вище була проблема з моїм кодом. Я зміню будь-який sass вище на css, щоб видалити будь-яку плутанину.
sroy

Чи має значення, який псевдоселектор (до vs після) використовується?
eddiegroves

Ви можете скористатись тим чи іншим
sroy

2
Це чудове рішення, але, реалізуючи його, я виявив, що чомусь: раніше працював, а НЕ: після. Я не знаю чому.
Лі Пробер

31

На мій досвід, це просто не спрацьовує, якщо ви не готові загорнути його <select>в якусь обгортку. Але замість цього можна використовувати фоновий образ SVG. Напр

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

Будьте обережні з правильним кодуванням URL через IE. Ви повинні використовувати charset=utf8(не просто utf8), не використовувати подвійні лапки (") для розмежування значень атрибутів SVG, використовуйте апострофи (") замість того, щоб спростити своє життя. URL-кодуйте s (% 3E). будь-які символи, що не належать до ASCII, вам потрібно отримати їх представлення UTF-8 (наприклад, BabelMap може допомогти вам у цьому), а потім надати це представлення у формі, кодованій URL-адресою - наприклад, для ACK ( U+25BEЧОРНЕ ВНИМАННЯ-ВКАЗАННЯ МАЛЬКОГО ТРІАНГУ) Представлення UTF-8 є \xE2\x96\xBEщо %E2%96%BEколи кодується URL.


1
Це приємне та елегантне рішення
JosFabre

1
Це фантастичне, просте та елегантне рішення, яке не потребує додаткового HTML, саме те, що я шукав! Дякую! Це має бути обраною відповіддю ІМО.
KyleFarris


13

Зіткнувся з тією ж проблемою. Можливо, це може бути рішенням:

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

Чи можете ви додати стилі, необхідні для того, щоб ярлик знаходився над елементом вибору?
bafromca

7

Це рішення схоже на рішення у sroy, але з трикутником css замість веб-шрифту:

.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

Що робити, якщо зміна розмітки не є варіантом?

Ось рішення, яке не потребує обгортки: воно використовує SVG у фоновому зображенні. Можливо, вам потрібно буде використовувати декодер HTML-сутності, щоб зрозуміти, як змінити колір заливки.

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

Виявлено з CSS-трюків .


Це приємний трюк. Супер прикро, що ми все ще не можемо
вибрати

5

Це сучасне рішення, яке я приготував, використовуючи приголомшливий шрифт . Розширення постачальника для стислості опущені.

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

Якщо ваш елемент вибору має визначений колір фону, він не працюватиме, оскільки цей фрагмент по суті розміщує піктограму "Шеврон" за елементом вибору (щоб дозволити натискання на верхню частину піктограми все-таки ініціювати дію вибору).

Однак ви можете стилювати обгортку вибору до того ж розміру, що й елемент вибору, та стилювати його фон, щоб досягти однакового ефекту.

Ознайомтеся з моїм CodePen на робочій демонстрації, яка показує цей біт коду як у темному, так і світлому тематичному вікні вибору за допомогою звичайної мітки та мітки «заповнювача» та інших очищених стилів, таких як рамки та ширини.

PS Це відповідь, яку я опублікував на інше, повторне запитання на початку цього року.


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>

На основі стилю вибору, чому ви не додаєте поділ поза вибором.

і стиль тоді в 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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.