problème avec <select> et: après avec CSS dans WebKit

123

Je voudrais ajouter du style sur une boîte de sélection avec le pseudo: après (pour styliser ma boîte de sélection avec 2 parties et sans images). Voici le HTML:

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

Et ça ne marche pas. Je ne sais pas pourquoi et je n'ai pas trouvé la réponse dans les spécifications du W3C. Voici le 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;
}

Alors est-ce normal ou y a-t-il une astuce?

Nicolas Merouze
la source
J'imagine que cela ne serait pas, ne devrait pas être possible, sinon cela rendrait trop facile le changement du contenu des formulaires. Imaginez un simple morceau de CSS modifiant le prix d'affichage de quelque chose. Il pourrait être montré comme moins cher qu'il ne l'est vraiment, incitant les gens à acheter quelque chose pour plus que prévu. (Ou bien sûr, si quelqu'un a accès au CSS d'une page / usertylesheet, alors ils pourraient probablement faire la même chose d'une autre manière…)
Synetech
22
@Synetech - Ceci est incorrect, l'auteur de la page doit avoir un contrôle complet sur tous les aspects du style de page. Les fabricants de navigateurs qui tentent d'empêcher le style de certains éléments parce qu'ils pourraient être utilisés pour tromper les utilisateurs ne seront pas efficaces car il existe un nombre presque illimité de façons de tromper le système ou de produire des faux positifs.
Jonathan Cross
1
Possible duplication des pseudo éléments et de la balise SELECT
Tessa

Réponses:

132

Je n'ai pas vérifié cela de manière approfondie, mais j'ai l'impression que ce n'est pas (encore?) Possible, en raison de la manière dont les selectéléments sont générés par le système d'exploitation sur lequel le navigateur fonctionne, plutôt que par le navigateur lui-même.

David dit de réintégrer Monica
la source
62
Nous sommes en 2019 maintenant et c'est toujours la même chose
Placido
40
C'est 2020 maintenant et c'est toujours la même chose
Joeri Minnekeer
3
Si j'avais vu votre commentaire sur ce post vieux de 10 ans il y a une heure, je me serais économisé une heure de mon temps. : C
ericek111
66

Je cherchais la même chose car le fond de ma sélection est le même que la couleur de la flèche. Comme mentionné précédemment, il est encore impossible d'ajouter quoi que ce soit en utilisant: before ou: after sur un élément select. Ma solution a été de créer un élément wrapper sur lequel j'ai ajouté ce qui suit: avant le code.

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

Et c'est ma sélection

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

J'ai utilisé FontAwesome.io pour ma nouvelle flèche, mais vous pouvez utiliser tout ce que vous voulez. Ce n'est évidemment pas une solution parfaite, mais en fonction de vos besoins, cela peut suffire.

sroy
la source
4
C'est visuellement parfait. Mais vous ne pouvez pas cliquer sur cette icône et sélectionner l'élément ne s'ouvrira pas: / Des suggestions?
Schovi
11
événements de pointeur: aucun; devrait prendre soin de cela. Il y a eu un problème avec mon code ci-dessus. Je changerai tout sass ci-dessus en css pour supprimer toute confusion.
sroy
Le pseudo-sélecteur (avant vs après) est-il important?
eddiegroves
Vous pouvez utiliser l'un ou l'autre
sroy
2
C'est une excellente solution, mais lors de sa mise en œuvre, j'ai trouvé que pour une raison quelconque: avant travaillé et PAS: après. Je ne sais pas pourquoi.
Lee Probert
32

D'après mon expérience, cela ne fonctionne tout simplement pas, à moins que vous ne souhaitiez emballer votre emballage <select>dans un emballage. Mais ce que vous pouvez faire à la place est d'utiliser l'image de fond SVG. Par exemple

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

Faites juste attention au bon encodage d'URL grâce à IE. Vous devez utiliser charset=utf8(pas seulement utf8), n'utilisez pas de guillemets (") pour délimiter les valeurs d'attribut SVG, utilisez plutôt des apostrophes (') pour vous simplifier la vie. Encodez l'URL s (% 3E). Au cas où vous auriez à imprimer tous les caractères non ASCII dont vous disposez pour obtenir leur représentation UTF-8 (par exemple BabelMap peut vous aider avec cela) et ensuite fournir cette représentation sous forme codée en URL - par exemple pour ▾ ( U+25BEBLACK DOWN-POINTING SMALL TRIANGLE) La représentation UTF-8 est \xE2\x96\xBEqui est %E2%96%BEquand URL-encodé.

Đonny
la source
1
Ceci est une solution agréable et élégante
JosFabre
1
C'est une solution fantastique, simple et élégante qui ne nécessite aucun HTML supplémentaire, ce qui est exactement ce que je recherchais! Merci! Cela devrait être la réponse choisie par l'OMI.
KyleFarris
15

Cet article peut aider http://bavotasan.com/2011/style-select-box-using-only-css/

Il utilise un div extérieur avec une classe pour résoudre ce problème.

<div class="styled-select">
  <select>
    <option>Here is the first option</option>
    <option>The second option</option>
  </select>
</div>
Glauber Ramos
la source
13

Face au même problème. Cela pourrait probablement être une solution:

<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 {
    ...
}
Ivan
la source
Pouvez-vous ajouter les styles requis pour placer l'étiquette au-dessus de l'élément sélectionné?
bafromca
7

Cette solution est similaire à celle de sroy, mais avec un triangle css au lieu de la police Web:

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

LarS
la source
6

Et si la modification du balisage n'est pas une option?

Voici une solution qui n'a pas d'exigences pour un wrapper: il utilise un SVG dans une image d'arrière-plan. Vous devrez peut-être utiliser un décodeur d'entité HTML pour comprendre comment modifier la couleur de remplissage.

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

Pincé de CSS-Tricks .

Dominic Hurr
la source
C'est une belle astuce. Super ennuyeux que nous ne pouvons toujours pas
styliser les
5

C'est une solution moderne que j'ai concoctée en utilisant font-awesome . Les extensions de fournisseur ont été omises par souci de concision.

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

Si votre élément de sélection a une couleur d'arrière-plan définie, cela ne fonctionnera pas car cet extrait de code place essentiellement l'icône Chevron derrière l'élément de sélection (pour permettre de cliquer sur le dessus de l'icône pour toujours lancer l'action de sélection).

Cependant, vous pouvez styliser l'encapsuleur de sélection à la même taille que l'élément de sélection et styliser son arrière-plan pour obtenir le même effet.

Découvrez mon CodePen pour une démonstration de travail qui montre ce morceau de code sur une boîte de sélection à la fois sombre et claire en utilisant une étiquette régulière et une étiquette «espace réservé» et d'autres styles nettoyés tels que les bordures et les largeurs.

PS C'est une réponse que j'avais postée à une autre question en double plus tôt cette année.

Tessa
la source
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>

Insted de styliser la sélection pourquoi ne pas ajouter un div en dehors de la sélection.

et style ensuite en 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;
}
mouton noir
la source