Desarrollo frontend, estándares web, accesibilidad y más
Por kcmr, el 21 de Marzo de 2010 en CSS, Navegadores
Etiquetas:@font-face, internet explorer, legibilidad
Cada vez son más los sitios que usan @font-face y por fin parece que el abanico de fuentes disponibles en páginas web deja de estar limitado a Arial, Verdana, Georgia y poco más. De todos los métodos que se han usado durante años para utilizar fuentes que no son de sistema, @font-face es sin duda el más accesible, pero ¡cómo no!, la cosa no podía ser tan fácil. Una vez más es Internet Explorer el que tenía que causar algún problema.
Cuando el suavizado de fuentes mediante ClearType está habilitado en Windows o el suavizado de fuentes está desactivado por completo, Internet Explorer muestra algunas fuentes embebidas mediante @font-face con un aspecto pixelado. Si el tamaño de fuente es pequeño se empeora la legibilidad.

Suavizado de texto desactivado

Suavizado de texto mediante ClearType
Este problema no ocurre cuando está activado el suavizado estándar.

Suavizado de texto estándar de Windows
Este efecto pixelado se puede corregir mediante una técnica algo sucia. Consiste en la utilización de un filtro CSS para desactivar el suavizado de texto. Funciona porque Internet Explorer no aplica el suavizado de texto mediante ClearType a los elementos con filtros CSS propietarios.
Código CSS:
.suavizado{ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=hIEfix.png,sizingMethod=crop);
min-height: 0;
color: green;}
Utilizando este filtro el resultado es el que se puede ver en las siguientes capturas:

Suavizado de texto desactivado. Texto verde con filtro CSS

Suavizado mediante ClearType. Texto verde con filtro CSS.
Sin embargo esta técnica tiene otro problema, y es que al hacer zoom para aumentar el tamaño de fuente, aparecen bordes negros alrededor de la fuente que nuevamente dificultan su legibilidad. Eso sí, sobre fondo negro no se aprecia este fallo, pero sobre fondo blanco nos encontramos con este aspecto:

Zoom sobre texto con filtro CSS. Legibilidad empeorada.
Si decidimos utilizar esta técnica sería recomendable ofrecer también un método para desactivarla a petición del usuario, por ejemplo mediante la adición o eliminación de una clase CSS a los elementos afectados.
Quizá con Internet Explorer 9 tengamos más suerte.
Más información en Smoother @font-face embedding in IE 7 & 8
Por kcmr, el 9 de Febrero de 2010 en CSS, Utilidades
LESS es una extensión de CSS escrita en Ruby que permite utilizar variables, operaciones, reglas anidadas y mezclas con paso de parámetros que se comportan como funciones.
De todas sus posibilidades, las dos que me resultan más interesantes y que voy a comentar son el uso de variables y las operaciones.
En Mac OS X, que ya tiene instalado ruby y ruby-gems, es tan sencillo como escribir esta línea en la consola:
$ sudo gem install less
En Windows y Linux hay que instalar primero ruby y ruby-gems.
Una vez instalado podemos utilizar LESS escribiendo nuestro CSS en un archivo .less tal y como lo haríamos con un archivo .css, con la diferencia de que es necesario compilarlo.
Para compilar un archivo .less escribimos lo siguiente en la consola:
lessc style.less style.css
Si no se especifica el archivo de destino, se creará uno con el mismo nombre pero con la extensión .css. Es decir, la siguiente línea generaría un archivo style.css
lessc style.less
Afortunadamente, no es necesario compilar el archivo manualmente cada vez que hacemos cambios, ya que es posible detectar los cambios en el archivo .less y compilar automáticamente. Para hacer esto utilizamos la instrucción –watch sobre el archivo que queremos compilar:
lessc style.less --watch
Sobre las ventajas del uso de variables en CSS sobran las explicaciones. A todos nos gustaría poder definir unas variables para colores de enlaces, texto, encabezados, fondos, etc. y poder usarlas cuando sea necesario sin tener que rebuscarlas en la CSS. También a la hora de hacer un cambio global resulta mucho más cómodo cambiar solamente el valor de una variable que todas las coincidencias. (Sí, conozco el buscar y reemplazar).
Para mí, el uso de variables no es su punto más fuerte, ya que se pueden usar varibles en CSS mediante PHP u otro lenguaje o incluso creando atajos de teclado personalizados en tu editor de texto, de manera que cada vez que tecleas, por ejemplo, colorLink seguido de tabulador, se escribe un color hexadecimal definido previamente. Esta última opción se puede usar con Coda (Mac).
Lo que más me ha gustado de LESS es la posibilidad de realizar operaciones, algo que ahorra bastante trabajo cuando se utilizan diseños elásticos.
En los diseños elásticos, una unidad es relativa al elemento al que se refiere. Por ejemplo, si tenemos un encabezado de 20px de tamaño de fuente, con un margen inferior de 7px, esos 7px deben calcularse respecto a los 20 del encabezado, de manera que tenemos que hacer una división (7 / 20).
h2{font-size: 2em; margin-bottom: .35em;}
Con LESS podemos escribir esta división en la CSS.
h2{font-size: 2em; margin-bottom: 7 / 20em;}
Se añade el em al 20 para conservar la unidad de medida. De otra forma el resultado sería 0.35 en vez de 0.35em;
Además de ahorrarnos la operación, ya sea mediante calculadora o cabeza (siempre supone un esfuerzo), podemos ver inmediatamente qué unidad en píxeles estamos manejando en cada momento, es decir, nos ahorramos la multiplicación correspondiente o la ojeada al Firebug.
Si escribimos algo como h2 a, h3 a, h4 a{font-weight: normal;} el resultado al compilar es
h2 a{font-weight: normal;}
h3 a{font-weight: normal;}
h4 a{font-weight: normal;}
Al compilar, cada declaración se escribe en una línea dando lugar a archivos más pesados.
Simplemente, no funcionan. Las variables en LESS van precedidas del signo arroba.
#fff se convierte en white.
Estos inconvenientes se pueden solucionar con la ayuda de alguna herramienta de compresión como Clean CSS, que permite agrupar selectores, eliminar saltos de línea, utilizar las formas cortas de códigos de color, etc.
Otra herramienta útil es MinifyMe, una aplicación en Adobe AIR que se limita a eliminar comentarios y dejar todo el código en una sola línea. También sirve para comprimir Javascript.
Más información sobre uso e instalación en la documentación oficial de LESS
Aprovechando las vacaciones estoy preparando un nuevo diseño para este blog (que en algún momento estará listo) y de paso he recuestionado algunas de mis prácticas de CSS. Le ha tocado al método para establecer en 0 el margen y relleno de todos los elementos.
Son muchos los que apuestan por el método utilizado en la CSS Reset de Eric Meyer en lugar del selector universal asterisco, al que suelen acusar de requerir un rendimiento excesivo para el navegador. Otro de los argumentos para evitar este selector es su efecto sobre elementos de formulario. Cito a Eric Meyer sobre esta cuestión:
This is why so many people zero out their padding and margins on everything by way of the universal selector. That’s a good start, but it does unfortunately mean that all elements will have their padding and margin zeroed, including form elements like textareas and text inputs. In some browsers, these styles will be ignored. In others, there will be no apparent effect. Still others might have the look of their inputs altered.
Después de hacer unas pruebas incluyendo todos los elementos de formulario que se me han ocurrido, he comprobado que Firefox aplica un padding-right y padding-left a los elementos OPTION que queda anulado al usar el selector asterisco, mientras que el resto de navegadores sigue mostrando ese espacio, por lo que en este caso el selector universal no ayuda a eliminar diferencias entre navegadores sino todo lo contrario.

Aunque es cierto que es un “derroche” aplicar margin y padding 0 a todos los elementos, incluso a los que por defecto no lo tienen, la regla del asterisco es facilísima de recordar y ocupa menos bytes que la tira de elementos HTML utilizados en la CSS Reset de Eric Meyer. Por otra parte, en cuanto al rendimiento, yo estoy en el punto de “si no lo veo no lo creo” y creo que en cualquier caso, tiene que ser imperceptible para el usuario final.
A pesar de estas ventajas me he decidido a probar el Reset de Eric Meyer.
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td{ margin: 0; padding: 0; font-size: 100%; }
No ha sido hasta este momento cuando he podido observar un efecto que no había visto usando el selector universal. En el HTML cargo las CSS en este orden: reset, 960.css (sistema de retícula de 960.gs) y por último la CSS específica de la página.
<link rel="stylesheet" type="text/css" media="screen" href="css/base.css" /> <link rel="stylesheet" type="text/css" media="screen" href="css/960.css" /> <link rel="stylesheet" type="text/css" media="screen" href="css/style.css" />
Al cargar la página, durante unos segundos me aparecía el contenido de forma lineal, lo que quiere decir que por alguna razón se estaba retrasando la carga de 960.css, que define la anchura y posicionamiento de los bloques. Logicamente le he echado la culpa al Reset de Eric Meyer, que ha sido la única modificación hecha en mi CSS inicial, aunque la verdad es que no puedo demostrarlo.
Si observamos los elementos HTML incluidos en el Reset de Eric Meyer, vemos que hay unos cuantos que no tienen margen ni relleno, como SPAN, A, SMALL, etc., por lo que podemos prescindir tranquilamente de ellos.
En Perishable Press hay un post dedicado a las múltiples técnicas de reseteado que podemos usar, en el que aparece una versión reducida del Reset de Eric Meyer bastante aceptable. Al final he decidido quedarme con una combinación, ni tan escasa como la que sólo aplica el margen y relleno a los elementos HTML y BODY, ni tan amplia como la versión completa de Eric Meyer.
html, body, p, ul, ol, li, dl, dt, dd, h1, h2, h3, h4, h5, h6, th, td, pre, blockquote,
form, fieldset, legend, input, select, textarea, button{ margin: 0; padding: 0; font-size: 100%; }
La razón por la que añado el font-size: 100%, es porque algunos elementos de formulario no heredan el tamaño de fuente del body, como tampoco heredan la familia tipográfica.
Lo he probado en un par de proyectos en los que había usado el asterisco y no he observado ningún cambio, así que, hasta que no me encuentre con ningún inconveniente me voy a quedar con esta lista de selectores en lugar del asterisco.
Por kcmr, el 6 de Diciembre de 2009 en Buenas ideas, CSS, Javascript
Etiquetas:@font-face, fuentes, ie, windows
En User Agent Man han publicado un script para detectar el suavizado de fuentes en el navegador. Si el suavizado de fuentes está activado, se añade una clase al elemento html que permite usar unas u otras fuentes en la CSS dependiendo de esta característica.
Este script es especialmente útil para utilizar fuentes embebidas mediante @font-face, ya que la calidad del resultado depende muchísimo de si el suavizado de fuentes está o no habilitado en el SO del usuario. También es útil a la hora de decantarse por unas u otras fuentes de sistema, como por ejemplo, la Lucida Sans Unicode, que sin suavizado resulta de mala legibilidad en Windows.
Por kcmr, el 5 de Noviembre de 2009 en Buenas ideas, CSS, Navegadores
Etiquetas:CSS, ie, IE 6, int, internet explorer
Cuando forzamos el tamaño de una imagen mediante CSS reduciendo su ancho o alto original, nos encontramos con que Internet Explorer hace cosas feas. A falta de palabras para describirlo, nada mejor que una captura:

Imágenes redimensionadas en Explorer 7
En el blog de ZURB, que por cierto, me encanta, nos muestran un pequeño truco para suavizar las imágenes en Internet Explorer entre otras técnicas para mejorar la presentación visual en varios navegadores
img{-ms-interpolation-mode: bicubic;}
Este método no funciona en Internet Explorer 6, para el que proponen usar algo un poco más sucio que lo anterior:
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader (src='/path/to/image.jpg', sizingMethod='scale');
Afortunadamente, Internet Explorer 8 no tiene este problema.
Demo suavizado de imágenes (sólo para IE 7)
Actualización: script para aplicar el filtro a las imágenes redimensionadas
En este comentario proponen el uso de un pequeño script en jQuery para detectar si una imagen está redimensionada y en ese caso aplicarle el estilo correspondiente para IE 7 y el filtro para IE 6. De esta forma evitamos tener código no válido en la CSS y aplicamos estos estilos sólo a las imágenes que lo requieran. Ya que el código no aparece muy bien formateado en los comentarios, lo pego aquí.
Gracias por la aportación!
jQuery.each($('img'), function() {
ancho_forzado = $(this).width();
img = new Image();
img.src = $(this).attr('src');
ancho_real = img.width;
if (ancho_forzado != ancho_real) {
if ($.browser.version.substr(0,1) == '7') {
this.style.msInterpolationMode = "bicubic";
} else if ($.browser.version.substr(0,1) == '6') {
$(this).attr('width', ancho_forzado);
this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + img.src + "', sizingMethod='scale')",
this.runtimeStyle.paddingTop = this.height,
this.runtimeStyle.height = 0;
}
}
});
Por kcmr, el 21 de Octubre de 2009 en Buenas ideas, CSS
En CSSPlay han publicado un método basado sólo en CSS válido, para emular el funcionamiento de la propiedad max-width de CSS en Internet Explorer 6.
Esta propiedad es útil para fijar un ancho máximo de página (bloque contenedor) en diseños fluidos, evitando que los bloques de texto sean demasiado largos y dificulten su lectura.
La solución quizá llega un poco tarde ahora que, ¡por fin!, el porcentaje de uso de IE 6 es menor que el de sus hermanos mayores, IE 7 y 8, y poco a poco vamos dejando de dar soporte (teniendo siempre en cuenta aquello de la degradación elegante) a este navegador.
La técnica varía según la alineación de página que se use. Para un contenedor centrado de 960 pixeles de ancho máximo, el código HTML y CSS a usar sería similar a este:
HTML
<div class="leftpad"></div> <div class="rightpad"></div> <div id="contenedor"> ... bla bla bla ... </div>
CSS
.leftpad{
width: 50%; float: left;
margin-right: -480px; height: 1px;
}
.rightpad{
width: 50%; float: right;
margin-left: -480px; height: 1px;
}
#contenedor{overflow: hidden;}
* html #contenedor{float: left;}
Existen otras soluciones para conseguir un ancho máximo en IE 6, basadas en Javascript o en el uso de expresiones propietarias de Microsoft.
Caso típico: lista centrada de enlaces al pie de página separados por barras u otro elemento.
Enlaces centrados en el pie de página
Para que la lista aparezca centrada necesitamos que los elementos de lista se muestren en línea en vez de en bloque.
ul{text-align: center;}
li{display: inline; padding: 0 6px 0 5px; background: url(../img/separador.gif) 100% 50% no-repeat;}
Problema típico: la separación entre ítems no es igual en distintos navegadores, básicamente, entre Explorer y el resto.

Distinta separación entre elementos de lista en Explorer
Solución (muy vieja): evitar la separación (saltos de línea) entre los elementos de lista en el HTML.
<ul><li><a href="#">Lorem ipsum</a></li><li><a href="#">Sit amet</a></li><li><a href="#">Consectetuer</a></li></ul>
Se puede mejorar un poco la legibilidad del código y evitar tener toda la lista en una línea de esta forma:
<ul><li
><a href="#">Lorem ipsum</a></li
><li><a href="#">Sit amet</a></li
><li><a href="#">Consectetuer</a></li
></ul>
El resultado de usar esta técnica:

Misma separación entre elementos de lista en todos los navegadores
Demo.
Visto en CSS:Inline list, entre otras cosas muuuy interesantes.
En el blog de Anieto2K aparecía hace un par de días la sentencia tajante: “No uses @import“. Y sí, después de comprobar que tiene más inconvenientes que ventajas, la sentencia no es ninguna barbaridad.
Yo también uso usaba esta técnica, que vi por primera vez en la web del W3C, donde todavía la siguen usando, y la verdad es que nunca me había dado por comprobar en qué orden cargaban los archivos. Efectivamente, usando @import dentro de una CSS, la carga de los archivos no se corresponde con el orden en que se llaman desde el HTML provocando que los script carguen antes que las hojas de estilo, etc.
Dejo aquí una captura del orden de carga de archivos tomada de la web del W3C, en la que se puede ver como home-import.css no se carga en el orden que cabría esperar, aunque como comenta Anieto, tiene toda su lógica que el orden sea el que es al usar este método.

Captura del orden de carga de archivos del W3C
El uso de @import dentro de etiquetas <style> en el HTML se utilizaba anteriormente para esconder hojas de estilo a Netscape 4, que no entendía @import, de manera que, opcionalmente se podía proporcionar una CSS con estilos básicos para este navegador mediante <link> y otra con estilos “avanzados” para los demás mediante <style> y @import. Esta técnica, cuando no se proporcionaba una CSS alternativa mediante <link>, tenía el inconveniente del instante de contenido sin estilo en Internet Explorer. Existe otra técnica con la misma finalidad que no plantea ese inconveniente, basada en especificar “all” como valor para el atributo media de la etiqueta <link> o una combinación de varios medios, ya que Netscape 4 sólo entendía el valor “screen”:
<link rel="stylesheet" type="text/css" href="css/style.css" media="screen, projection" />
A día de hoy, Netscape 4 es un navegador completamente muerto, por lo que estas técnicas también pueden pasar a la historia con él.
En cuanto a @import dentro de la CSS, me parecía una buena forma de enlazar a una sola hoja de estilo en el HTML, pero visto lo visto, también podemos decirle adiós.
Después de ver el “cómo se hizo” de los botones de las aplicaciones de Google (Google Reader, Gmail, Google Docs), y porque me aburría un poco, me he animado a hacer algo parecido manteniendo como objetivo no usar imágenes de fondo.
Ventajas:
Inconvenientes:
Antes de añadir el script para Explorer 6, tuve la oportunidad de experimentar lo que parece ser oooootro bug de este navegador. Si presionamos F5 teniendo el cursor sobre un botón, aparecen los estilos para el estado :hover. Curioso.
Demo botones con brillo sin imágenes
Para botones con fuente Tahoma a 11 píxeles:
/* generales boton */
.boton{ text-decoration: none; border: 0; cursor: pointer; }
button.boton{ outline: none; background: none; white-space: nowrap; overflow: visible;}
.boton span.brillo span{ font: bold 1.1em tahoma, arial, sans-serif; color: #fff; display: block; text-align: center; padding: 0 .9090em; min-width: 5.6363em; top: -.5454em; position: relative; }
* html .boton span.brillo span{ width: 5.6363em; white-space: nowrap; } /* emulacion de la propiedad min-width para Explorer 6 */
.boton span.borde-h{ display: block; float: left; }
.boton span.borde-v{ cursor: pointer; padding: 1px 0 0 1px; position: relative; margin-left: -1px; margin-right: -1px; display: block; float: left;}
.boton span.brillo{ display: block; }
Para un botón de un determinado color, en este caso verde:
/* verde */
.boton-a span.borde-h{ border: 1px solid #718a0a; border-left: 0; border-right: 0; }
.boton-a span.borde-v{ background: #defd0e; border: 1px solid #718a0a; border-top: 0; border-bottom: 0; }
.boton-a span.brillo{ border-top: 10px solid #b4ce0c; background: #95b60d; }
.boton-a:hover span.borde-h, .boton-a span.hover{ border-color: #526407;}
.boton-a:hover span.borde-v, .boton-a .hover span.borde-v{ background: #c7e30d; border-color: #526407;}
.boton-a:hover span.brillo, .boton-a .hover span.brillo{ border-top-color: #a4bc0b; background: #79940b;}
Por kcmr, el 15 de Febrero de 2009 en CSS, Cajón de sastre, Javascript
Etiquetas:fuentes, Javascript, tipografía
He encontrado este script para detectar si una fuente está disponible en un determinado navegador, que nos puede sacar de más de un apuro, por ejemplo, cuando decidimos correr el riesgo de usar Arial Narrow como fuente “casi de sistema”.
En la web no dejan claro el modo de uso. Para detectar una fuente en concreto, en este caso la Arial Narrow, se podría usar el siguiente código añadido al script:
function testFont(){
var inst = new Detector();
if(!(inst.test('Arial Narrow')[3])) // si la fuente no está disponible...
{
// añadimos una clase al body
document.body.className = 'nonarrow';
}
}
En la CSS tendríamos que añadir las reglas alternativas para los navegadores que no tienen la fuente disponible:
#menu{font-family: "Arial Narrow", arial, tahoma, helvetica, sans-serif; font-size: 1.3em;}
body.nonarrow #menu{font-size: 1.2em; word-spacing: -1px;} /* arréglelo como pueda */
Para los que usen jQuery acabo de descubrir otra solución basada sólo en Javascript.