problema con <select> y: después con CSS en WebKit


123

Me gustaría agregar algo de estilo en un cuadro de selección con el pseudo: after (para diseñar mi cuadro de selección con 2 partes y sin imágenes). Aquí está el HTML:

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

Y no funciona. No sé por qué y no encontré la respuesta en las especificaciones del W3C. Aquí está el 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;
}

Entonces, ¿es normal o hay un truco?


Me imagino que esto no sería posible, no debería ser posible, de lo contrario sería demasiado fácil cambiar el contenido de los formularios. Imagínese un poco de CSS cambiando el precio de visualización por algo. Podría mostrarse más barato de lo que realmente es, engañando a las personas para que compren algo por más de lo esperado. (Por supuesto, si alguien tiene acceso al CSS de una página / hoja de estilo de usuario, probablemente podría hacer lo mismo de otras formas ...)
Synetech

22
@Synetech: esto es incorrecto, el autor de la página debe tener control total sobre todos los aspectos del estilo de la página. Los fabricantes de navegadores que intentan evitar el estilo de ciertos elementos porque podrían usarse para engañar a los usuarios no serán efectivos, ya que hay un número casi ilimitado de formas de engañar al sistema o producir falsos positivos.
Jonathan Cross

1
Posible duplicado de pseudo elementos y etiqueta SELECT
Tessa

Respuestas:


132

No lo he verificado ampliamente, pero tengo la impresión de que esto no es (¿todavía?) Posible, debido a la forma en que los selectelementos son generados por el sistema operativo en el que se ejecuta el navegador, en lugar del navegador en sí.


62
Es 2019 ahora y sigue siendo el mismo
Plácido

40
Es 2020 ahora y sigue siendo el mismo
Joeri Minnekeer

3
Si hubiera visto su comentario sobre esta publicación de hace 10 años hace una hora, me habría ahorrado una hora de mi tiempo. : C
ericek111

66

Estaba buscando lo mismo ya que el fondo de mi selección es el mismo que el color de la flecha. Como se mencionó anteriormente, aún es imposible agregar algo usando: before o: after en un elemento seleccionado. Mi solución fue crear un elemento contenedor en el que agregué lo siguiente: antes del código.

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

Y esta mi selecta

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

He usado FontAwesome.io para mi nueva flecha, pero puedes usar lo que quieras. Obviamente, esta no es una solución perfecta, pero dependiendo de sus necesidades, puede ser suficiente.


4
Esto es visualmente perfecto. Pero no puede hacer clic en ese icono y el elemento seleccionado no se abrirá: / ¿Alguna sugerencia?
Schovi

11
eventos de puntero: ninguno; debería encargarme de eso. Hubo un problema con mi código anterior. Cambiaré cualquier sass anterior a css para eliminar cualquier confusión.
sroy

¿Importa qué pseudo selector (antes o después) se usa?
eddiegroves

Puede usar uno u otro
sroy

2
Esta es una gran solución, pero al implementarla descubrí que por alguna razón: antes funcionó y NO: después. No sé por qué.
Lee Probert

32

En mi experiencia, simplemente no funciona, a menos que esté dispuesto a envolverlo <select>en algún envoltorio. Pero lo que puede hacer en su lugar es usar SVG de imagen de fondo. P.ej

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

Solo tenga cuidado con la codificación de URL adecuada debido a IE. Debe usar charset=utf8(no solo utf8), no use comillas dobles (") para delimitar los valores de los atributos SVG, use apóstrofos (') en su lugar para simplificar su vida. URL-encode s (% 3E). En caso de que tenga que imprimir cualquier carácter que no sea ASCII tiene que obtener su representación UTF-8 (por ejemplo, BabelMap puede ayudarlo con eso) y luego proporcionar esa representación en forma codificada en URL, por ejemplo, para ▾ ( U+25BENEGRO DOWN-POINTING PEQUEÑO TRIÁNGULO) La representación UTF-8 es \xE2\x96\xBEque es %E2%96%BEcuando está codificado en URL.


1
Esta es una solución agradable y elegante
JosFabre

1
Esta es una solución fantástica, simple y elegante que no requiere HTML adicional, ¡que es exactamente lo que estaba buscando! ¡Gracias! Esta debería ser la respuesta elegida en mi opinión.
KyleFarris


13

Enfrentó el mismo problema. Probablemente podría ser una solución:

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

¿Puede agregar los estilos requeridos para que la etiqueta se asiente sobre el elemento seleccionado?
bafromca

7

Esta solución es similar a la de sroy, pero con triángulo css en lugar de fuente 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>


6

¿Qué pasa si modificar el marcado no es una opción?

Aquí hay una solución que no tiene requisitos para un contenedor: usa un SVG en una imagen de fondo. Puede que necesite utilizar un decodificador de entidad HTML para comprender cómo cambiar el color de relleno.

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

Pellizcado de CSS-Tricks .


Este es un buen truco. Súper molesto que todavía no podamos
diseñar

5

Esta es una solución moderna que inventé usando font-awesome . Las extensiones del proveedor se han omitido por brevedad.

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 su elemento seleccionado tiene un color de fondo definido, entonces esto no funcionará ya que este fragmento esencialmente coloca el ícono de Chevron detrás del elemento de selección (para permitir hacer clic en la parte superior del ícono para iniciar la acción de selección).

Sin embargo, puede diseñar el contenedor de selección con el mismo tamaño que el elemento de selección y diseñar su fondo para lograr el mismo efecto.

Consulte mi CodePen para ver una demostración funcional que muestra este fragmento de código en un cuadro de selección de temática oscura y clara utilizando una etiqueta regular y una etiqueta de "marcador de posición" y otros estilos limpios como bordes y anchos.

PD: Esta es una respuesta que había publicado a otra pregunta duplicada a principios de este año.


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>

En lugar de diseñar la selección, ¿por qué no agrega un div fuera de la selección?

y estilo luego 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;
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.