Gozos y quebrantos. Apariencia y pseudo elementos privativos

La apariencia de los elementos de la interfaz de usuario (IU). Cómo modificarla con CSS y la propiedad appearance y los pseudoelementos privativos de FF, Chrome e IE que intervienen

Gozos y quebrantos. Apariencia y pseudo elementos privativos

Por Kseso ✎ 3

El grupo de las propiedades appearance son utilizadas por los navegadores para lograr que una serie de elementos se presenten de idéntica forma y sean fácilmente reconocidos como tales por el usuario con independencia de dónde los encuentre.

Y en alguno de ellos, a su vez, se puede observar que los componen varias partes o piezas. Como en este input tipo rango

Que dependiendo de tu navegador y SO lo verás de determinada forma.

La apariencia

La apariencia la define el SO de la máquina y su IU (interfaz de usuario). Así un checkbox o una barra de scroll lucen igual a priori con independencia de la página que visites. Excepto que las haya alterado exprofeso el realizador de la página.

Y esto, de entrada, es bueno... hasta que deja de serlo. Ya sea porque su estética choca con tu diseño o porque alguna particularidad de esa apariencia por defecto causa algún destrozo.

Estos estilos en grupo por defecto son aplicados por la propiedad appearance y por un grupo de valores. Su sintaxis es la habitual:

elemento { appearance: valor; } /* Necesita prefijos privativos */

El ejemplo más común es anular los estilos de los campos de los inputs especialmente en Chrome y "hermanos", con la extendida declaración -webkit-appearance: none;. Pero no sólo en webkit. Firefox también ofrece y soporta esta posibilidad. Desconozco si IE en su última versión también.

input { -webkit-appearance: none; -moz-appearance: none; }

Y si nos sirve para quitar el maquillaje también es util para lo contrario. Ofrece la posibilidad de hacer que un elemento cualquiera del Html se muestre como otro, por ejemplo con sólo esa declaración:

span.button { -webkit-appearance: button; -moz-appearance: button; } Soy un span y me presento y hago como un "button"

Como ya es norma entre los navegadores, para desgracia, no hay uniformidad ni en el nombre de los valores, ni en las particularidades que pueden alterarse ni en el soporte por cada versión en cada navegador.

Como las relaciones son amplias no te las transcribo. Puedes consultarlas tú:

  1. Las propiedades "-moz-appearance" en la pág. Mozilla Developer
  2. Las propiedades "-webkit-appearance"

El soporte

Que nadie piense que estas propiedades son "novedad". Vienen desde antiguo como puedes ver en el soporte que le dan:

Chrome
Todas las versiones.
Android
Todas las versiones
IOS
Todas las versiones
Safari
3.0 +
Firefox
Todas las versiones

El Quebranto

Chrome: desalineación en input search
Chrome: desalineación en input search

Me encontraba estilizando una serie de elementos, entre ellos un campo de búsqueda, y todo iba como la seda. Hasta que en un momento y por cuestión estética cambié la alineación del texto de la izquierda a la derecha y pasé a verlo en Chrome.

La sorpresa fue ese espacio extra a la derecha del campo de búsqueda. Pese a tener declarado el -webkit-appearance: none;. Y por más bordes, márgenes y paddings a cero o negativos y todas las perrerías Css que se me ocurrían ahí seguía. Como una lapa.

El primer paso fue fijarme en la "x" que Chrome añade para limpiar con un click lo escrito en este input. Pero no recordaba ni su nombre, ni si era un atributo de los nuevos de Html5 o qué. Y el hecho de haber anulado la apariencia me descolocaba un poco más. Tras un tuit, en una pequeña conversación con Raúl Santaella aka @rausantaella me dio la más que suficiente información y me puso tras la pista.

Como bien apuntó Raúl es un pseudoelemento. Webkit lo llama ::-webkit-search-cancel-button. Así que identificado el causante ya era fácil enmendarlo. Un simple display: none arreglaría el problema. Pero...

::-webkit-search-cancel-button controlado a voluntad
search-cancel-button controlado

Si eso hubiese hecho este artículo no existiría. Porque tampoco es cuestión de sacrificar una característica y función del navegador por muy privativa de él que sea por una cuestión méramente estética. Ya conoces la advertencia: "no toques mi configuración ni las funciones de mi navegador".

Así que el siguiente paso era anular su efecto mientras "duerma" y que "despierte" cuando se necesite. Para este particular al ser un pseudoelemento de nada sirve atacarlo por la apariencia (-webkit-appearance) en el input, que ya estaba declarada.
Tras unos intentos fallidos o que funcionaron sólo a medias (se mostraba al :focus pero perdía funcionalidad) este es el css final para que no afecte a la alineación a la derecha pero que se muestre y funcione cuando se utilice el buscador:

#q::-webkit-search-cancel-button { position: absolute;/* Sale del flujo */ } #q:focus::-webkit-search-cancel-button, #q:active::-webkit-search-cancel-button { position: relative;/* De nuevo en su lugar * }

Del quebranto al gozo

El paso siguiente como es lógico es adaptar este elemento al diseño de cada cual. Si no te gusta esa "x" que por defecto le es propia, una vez leído lo anterior, ya resulta sencillo. Sólo es cuestión de cambiarla vía css. Recuerda que estamos tratando con un pseudoelemento, así que es obligado declarar la propiedad content, aunque sea con un valor vacío.

Por defecto la × aparece al escribir

La × visible y personalizada

Icono de Papelera

Texto en vez de icono

Quizás el detalle más significativo del Css que lo hace posible y que tienes abajo (es editable para que puedas jugar con él directamente) sea el encadenado de pseudoelementos ::-webkit-search-cancel-button:after

Si recuerdas, esto no funciona con los pseudoelementos "oficiales".

/*Estilos editables */

Este ejemplo último y una explicación más detallada la puedes encontrar en el artículo de David Calhoun en su blog.

Hasta el infinito (casi) y más allá

Input range estilizado
Input range estilizado

¿Recuerdas el input de rango del inicio del artículo y que mencionaba que alguno de estos elementos está hechos de varias piezas? Más exactamente son pseudoelementos. Así que sólo es cuestión de conocer cómo los llama cada navegador y qué permite modificar para hacer que luzcan a tu antojo o necesidades.
A la derecha tienes cómo luciría en IE10 tras estos estilos:

::-ms-fill-lower { background: orange; } ::-ms-fill-upper { background: green; } ::-ms-thumb { background: red; } ::-ms-ticks-after { display: block; color: blue; } ::-ms-ticks-before { display: block; color: black; } ::-ms-track { padding: 20px 0; } ::-ms-tooltip { display: none; } /* sólo display y visibility */

Casi todos los pseudoelementos disponibles

El problema de meterte en este campo es, como apuntaba antes, la disparidad entre navegadores y sus versiones. No existe uniformidad. Cada cual los llama como estima oportuno y cada cual ha creado y soporta los que le place.

Así que no es nada práctico pretender tenerlos en la cabeza. Para evitarte ese trabajo hay quien ya lo ha realizado por ti recopilándolos y escribiendo artículos divulgativos. Aquí para terminar una recopilación de algunos de estos trabajos

Recursos y lecturas

  1. Lista de Todos los pseudoelementos WEBKIT en github de @angelinamagnum. (@paul_irish la amplió hackeando el código base generado por Webkit)
  2. Mozilla CSS Extensions Artículo en MDN
  3. Listado de los prefijos -ms- y pseudoelementos en Triden Internet explorer también juega.
  4. Styling Form Controls Using Pseudo Classes Una guía en la wiki de WebKit
  5. Wufoo’s Current State of HTML Forms Artículo en Wufoo
  6. Lista de pseudoelementos para el control de formularios. Artículo de @tjvantoll

Disclaimer final ;-)

@rausantaella
@rausantaella
"culpable"
No era mi intención al inicio del artículo que fuese tan extenso. Quizás sea que inconcientemente haya querido redimirme por estos 13 días sin publicar nada. De todas formas, siempre podemos decir que la culpa de tanto rollo es de @rausantaella. Si se hubiera estado calladito este artículo sería totalmente distinto, si es que era. Así que ¡ala! ahí te dejo su tuitter para que se lo agradezcas, por instigador :-D

Ramajero Argonauta, Enredique Amanuense de CSS.
#impoCSSible inside
Dicen que, en español, EsCss es el mejor blog de CSS. Posíblemente exageren.
@Kseso EsCss Don Kseso Kseso

Comentarios: 3

  1. Firefox 22.0 no admite el input type range, lo muestra como un type text y tampoco muestra el span como un botón. Esto del type text, es HTML5, ¿no?

    ResponderEliminar
  2. No entendia nada hasta que lo vi con Chrome :P

    ResponderEliminar
  3. Muy muy interesante lectura!

    Gracias!!

    ResponderEliminar

EsCss RSS del Blog RSSS Comentarios Humans.txt ᛯ Diseno por Kseso SiteMap