Sugerencia rápida:elementos de formulario de estilo con pseudoselectores

Desde que se inventó CSS, los desarrolladores web de todo el mundo han deseado una forma de diseñar los controles integrados del navegador. Esto es sencillo para elementos simples como botones y entradas de texto, pero difícil para algunos de los elementos más complejos como select y range . En este consejo rápido, le mostraremos cómo hacerlo.

¿Por qué pseudoselectores?

Todavía no existe una forma estándar de personalizar la apariencia de los elementos integrados del navegador. Por ejemplo, la entrada de búsqueda muestra una pequeña "x" que puede presionar para cancelar su búsqueda. Esto se implementa internamente como un elemento separado, pero no se puede alcanzar con CSS normal. Los fabricantes de navegadores se han dado cuenta y han agregado selectores específicos de proveedores que puede usar. Para esa "x", el selector a usar es input[type=search]::-webkit-search-cancel-button .

Hay una lista enorme de los selectores conocidos aquí. Todos los navegadores proporcionan algunos selectores para personalizar elementos integrados, pero la mala noticia es que el soporte está en todas partes. Esperemos que en el futuro haya un estándar que aporte consistencia a este lío. Sin embargo, por ahora, tenemos que apuntar a cada navegador individualmente.

Si usa Google Chrome, hay una manera fácil de averiguar qué selector se supone que debe usar. Después de habilitar la compatibilidad con Shadow DOM, puede ver la estructura interna de los elementos integrados del navegador. Aquí se explica cómo hacerlo, tal como se extrae de nuestro artículo Consejos y trucos de Chrome DevTools:

Abra las herramientas de desarrollo y vaya a Configuración. Allí, en General , en Elementos marca Mostrar agente de usuario shadow DOM. Ahora, cuando inspeccione los elementos, verá su #shadow-root. Cuando selecciona un elemento en #shadow-root, en la pestaña Estilos verá qué selectores utiliza la hoja de estilo del agente de usuario para aplicarles estilo. La mayoría de las veces este es el selector que estás buscando.

Tenga en cuenta que la mayoría de los siguientes experimentos solo funcionan en Chrome y Safari. Firefox e IE no son compatibles con muchos de los pseudoselectores que son necesarios para personalizar los elementos integrados, por lo que muestran las versiones normales. Algún día, cuando tengamos estándares establecidos, las personalizaciones como estas funcionarán en todas partes.

1. Casillas de verificación

No hay mucho que puedas hacer con las casillas de verificación en CSS, además de darles un ancho y alto. Pero Chrome y Safari admiten :before y :after pseudo elementos en las entradas, para que pueda divertirse. Tenga en cuenta que la marca de verificación está hecha completamente con CSS e incluso está animada con una transición gradual.

Configurando -webkit-appearance a none , evitamos que se aplique el estilo de navegador predeterminado, lo que deja las puertas abiertas a nuestro CSS personalizado. También gracias al em unidades, hicimos la escala de la casilla de verificación con el tamaño de fuente de su padre. Intenta aumentarlo.

body {
    font: 13px sans-serif;
    color:#444;
}

label {
    padding: 10px;
    display: block;
}

input[type=checkbox].styled {
    -webkit-appearance: none;
    height: 1em;
    position: relative;
    background-color: #276FF4;
    width: 1em;
    border-radius: 3px;
    outline: none;
    font-size: 16px;
    /* try this: */
    /* font-size: 36px; */
    vertical-align: middle;
    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
}

input[type=checkbox].styled:active {
    box-shadow: 0 0 0.8em rgba(0, 0, 0, 0.2) inset;
}

input[type=checkbox].styled:before,
input[type=checkbox].styled:after {
    content: '';
    background-color: inherit;
    position: absolute;
    transition: 0.1s background-color;
}

input[type=checkbox].styled:after {
    width: 0.19em;
    height: 0.65em;
    -webkit-transform: rotate(36deg) translate(0.52em, -0.16em);
}

input[type=checkbox].styled:before {
    width: 0.2em;
    height: 0.4em;
    -webkit-transform: rotate(-58deg) translate(-0.2em, 0.48em);
}

/* We use the checked selector to make the pseudo elements visible */

input[type=checkbox].styled:checked:after,
input[type=checkbox].styled:checked:before {
    background-color: #fff;
}
<label>
    <input type="checkbox" /> Regular Checkbox
</label>

<label>
    <input type="checkbox" class="styled" />
    Styled Checkbox
</label>

2. Botones de opción

Podemos usar la misma técnica en los botones de opción. Aquí es más simple, ya que no necesitamos hacer una marca de verificación en CSS. Esto todavía solo funciona en Chrome y Safari. Otros navegadores muestran el botón de opción normal.

body {
    font: 13px sans-serif;
    color:#444;
}

label {
    padding: 10px;
    display: block;
}

input[type=radio].styled {
    -webkit-appearance: none;
    height: 1em;
    position: relative;
    background-color: #276FF4;
    width: 1em;
    border-radius: 50%;
    outline: none;
    font-size: 14px;
    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
}

input[type=radio].styled:checked:before {
    content: '';
    height: 0.4em;
    width: 0.4em;
    background-color: #FFF;
    position: absolute;
    border-radius: 50%;
    top: 0.3em;
    left: 0.3em;
}
<label>
    <input type="radio" name="test" /> Regular Radio
</label>

<label>
    <input type="radio" class="styled" name="test" /> Styled Radio
</label>

3. Seleccionar elementos

El elemento de selección es notoriamente difícil de diseñar con CSS. Incluso hoy estamos limitados a lo que podemos cambiar. Para personalizar la flecha hacia abajo, podemos usar una imagen de fondo y un poco de relleno. Para la lista desplegable, puede especificar un tamaño de fuente y un fondo en los elementos de opción, pero no mucho más.

body {
    font: 13px sans-serif;
    color:#444;
}

label {
    padding: 10px;
    display: block;
}

select.styled {
    -webkit-appearance: none;
    -moz-appearance: none;
    -ms-appearance: none;
    appearance: none;
    border: 1px solid #aaa;
    padding: 2px 15px 2px 5px;
    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAAICAQAAACxSAwfAAAAUklEQVQY02P4z0AMRGZGMaShwCisyhITmb8huMzfEhOxKvuvsGAh208Ik+3ngoX/FbBbClcIUcSAw21QhXxfIIrwKAMpfNsEUYRXGVCEFc6CQwBqq4CCCtU4VgAAAABJRU5ErkJggg==), linear-gradient(#EDEDED, #EDEDED 38%, #DEDEDE);
    background-position: right center;
    background-repeat: no-repeat;
    border-radius: 2px;
    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
    color: #333;
}

/* Required to disable the default IE styles */
select.styled::-ms-expand {
    display: none;
}

select.styled:hover {
    border-color: #909090;
}

/* You have limited control on the drop down list. Uncomment this: */
/* select.styled option{
    background-color:green;
    color:#fff;
    font-size:20px;
} */
<label>
    <select>
        <option>Cheeze</option>
        <option>Bacon</option>
        <option>Pasta</option>
        <option>Pizza</option>
        <option>Ice Cream</option>
    </select> Regular Select
</label>

<label>
    <select class="styled">
        <option>Cheeze</option>
        <option>Bacon</option>
        <option>Pasta</option>
        <option>Pizza</option>
        <option>Ice Cream</option>
    </select> Styled Select
</label>

4. Elementos de rango

El rango es uno de los elementos de formulario más nuevos compatibles con los navegadores. También es uno de los más personalizables. Chrome, Safari y Firefox nos brindan una gran cantidad de pseudoselectores de CSS que podemos usar para diseñar partes específicas del elemento. Incluso IE tiene soporte para algunos, aunque no los hemos implementado en nuestro ejemplo. Consulte esta lista para saber qué hay disponible.

body {
    font: 13px sans-serif;
    color:#444;
}

label {
    padding: 10px;
    display: block;
}

input[type=range].styled {
    -webkit-appearance: none;
    outline: 0;
    width: 300px;
    transition: 0.2s;
}

/* Chrome */

input[type=range].styled::-webkit-slider-runnable-track {
    height: 2px;
    background: #9DA0A6;
    border: none;
    border-radius: 3px;
}

input[type=range].styled::-webkit-slider-thumb {
    -webkit-appearance: none;
    height: 16px;
    width: 16px;
    border-radius: 50%;
    background: #FFF;
    margin-top: -7px;
    vertical-align: middle;
    border: 5px solid #276FF4;
    transition: 0.15s;
}

input[type=range].styled::-webkit-slider-thumb:active {
    height: 20px;
    width: 20px;
    margin-top: -9px;
}

/* Firefox */

input[type=range].styled::-moz-range-track {
    height: 2px;
    background: #9DA0A6;
    border: none;
    border-radius: 3px;
}

input[type=range].styled::-moz-range-progress {
    background: #276FF4;
}

input[type=range].styled::-moz-range-thumb {
    height: 16px;
    width: 16px;
    border-radius: 50%;
    background: #FFF;
    margin-top: -7px;
    vertical-align: middle;
    border: 5px solid #276FF4;
    transition: 0.15s;
    box-sizing: border-box;
}

input[type=range].styled::-moz-range-thumb:active {
    height: 20px;
    width: 20px;
    margin-top: -9px;
}

input[type=range].styled::-moz-focus-outer {
    border: 0;
}
<label>
    <input type="range" /> Regular Range
</label>

<label>
    <input type="range" class="styled" /> Styled Range
</label>

5. Barras de progreso

El elemento de progreso también nos brinda una gran capacidad de personalización. Aunque para un elemento simple como este, podría anidar fácilmente dos divs y crear su propia versión.

body {
    font: 13px sans-serif;
    color:#444;
}

label {
    padding: 10px;
    display: block;
}

progress.styled {
    margin-top: 15px;
    width: 200px;
    height: 12px;
    background-color: #ddd;
    border: none;
}

/* Chrome */

progress.styled::-webkit-progress-bar {
    background-color: #ddd;
}

progress.styled::-webkit-progress-value {
    background-color: #266FF4;
}

/* Firefox */

progress.styled::-moz-progress-bar {
    background-color: #266FF4;
}
<label>
    <progress value="22" max="100"></progress> Regular Progress
</label>

<label>
    <progress value="22" max="100" class="styled"></progress> Styled Progress
</label>

Conclusión

Es genial que finalmente podamos modificar los controles integrados del navegador, pero aún queda un largo camino por recorrer en términos de estandarización. Google Chrome es un claro líder aquí, y si escribe aplicaciones o extensiones de Chrome, puede continuar y usar todo lo que mostramos aquí. Pero si desea una compatibilidad constante entre navegadores, la mejor solución sigue siendo confiar en las bibliotecas de JavaScript y los complementos de jQuery como Chosen.