Desarrollo front-end, estándares web, accesibilidad y más
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.
Por kcmr, el 9 de abril de 2009 en Accesibilidad, Buenas ideas, Utilidades
Etiquetas: Accesibilidad, bookmarklets, legibilidad, tipografía, Usabilidad
Yo también me he sumado a esta iniciativa de dejar la web en pelotas, que pretende promover el correcto uso de Estándares Web y marcado semántico. Es el CSS Naked Day.
Me tengo que decir eso de “bueno, un día es un día” para tener la conciencia más tranquila, ya que aunque todo permanece perfectamente utilizable y comprensible sin estilos, la verdad sea dicha… resulta bastante incómodo de leer.
Una buena forma de superarlo, sobretodo cuando tenemos verdadero interés en leer algo, cosa que debe de ocurrir sólo durante un 5% del tiempo en que navegamos, es utilizar un bookmarket que aplica los estilos necesarios para mejorar la legibilidad a la parte de la página que contiene el contenido relevante, ocultando todos los demás elementos que pueden distraer la lectura, como banners, menús de navegación, etc. Se trata de Readability. En su web podemos elegir el estilo que más nos gusta entre varias opciones y una vez configurado, añadir el marcador al navegador.
Es un bookmarklet bastante útil y cómodo, no sólo para superar el día de hoy, sino para cuando nos encontramos con un tamaño de texto diminuto o longitud excesiva de líneas, dos cosas que dificultan y hacen poco apetecible la lectura.
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 14 de marzo de 2009 en Javascript
Etiquetas: Javascript
Esta es la sintaxis del operador ternario, que equivale a una estructura de control de flujo if / else:
condicion ? instrucción si se cumple : instrucción si no se cumple;
Usando un ejemplo de código real podría ser así:
hasClassName(capa, clase) ? removeClassName(capa, clase) : addClassName(capa, clase);
Que para mayor legibilidad, si las instrucciones son muy largas, se puede separar en varias líneas:
hasClassName(capa, clase)
? removeClassName(capa, clase)
: addClassName(capa, clase);
Hasta ahora, siempre que había tenido que usar varias instrucciones en una condición, había abandonado el operador ternario en favor de una estructura if / else:
if(condicion){
hazAlgo();
yHazOtraCosa();
}
else{
hazUnaCosa();
hazOtraCosaMas();
}
Mediante el operador ternario podemos incluir varias instrucciones usando funciones anónimas:
condicion
? (function(){ hazAlgo(); hazOtraCosa();})()
: (function(){ hazUnaCosa(); hazOtraCosaMas();})();
Usando un ejemplo de código real, podría ser así:
hasClassName(capa, clase)
? (function(){ removeClassName(capa, clase); enlace.title = 'Ocultar';})()
: (function(){ addClassName(capa, clase); enlace.title = 'Mostrar';})();
Por kcmr, el 3 de marzo de 2009 en Accesibilidad, Buenas ideas, Navegadores
Etiquetas: Accesibilidad, flash
Sí Flash ya es de por sí bastante problemático en cuanto a accesibilidad se refiere, en Firefox tiene una dificultad añadida: no se puede acceder a su contenido mediante teclado. Para navegar por los elementos de un flash en Firefox necesitamos clicar el flash. Una vez que hemos entrado ya no podemos salir usando el teclado, la tabulación queda atrapada en el flash. La buena noticia es que si hemos podido entrar en el flash, se supone que sólo hemos podido hacerlo mediante ratón, por lo que también se supone que también podremos salir del flash usando el ratón, a no ser que justamente decida fallar en ese preciso momento. En cualquier caso, este comportamiento de Flash en Firefox hace que sea dependiente de dispositivo.
No ocurre lo mismo en Internet Explorer, en el que sí podemos entrar y salir del Flash mediante teclado. Podemos imitar el comportamiento de Flash en Internet Explorer mediante Javascript y Actionscript. En el siguiente ejemplo tenemos un flash al que podemos acceder mediante teclado en Firefox, navegar por sus elementos y salir de él.
Para conseguir esto se han seguido los siguientes pasos:
<param name="allowScriptAccess" value="always" />
// primer elemento navegable
bot_1.onKillFocus = function(newFocus){
if(newFocus == bot_3){
ExternalInterface.call('AccesibleFlash.desenfocaObject', 'test');
}
}
// último elemento navegable
bot_3.onKillFocus = function(newFocus){
if(newFocus != bot_2){
ExternalInterface.call('AccesibleFlash.desenfocaObject', 'test');
}
}
Descargar todos los archivos del ejemplo, incluido el .fla, en formato .zip
Una buena parte del “cómo conseguirlo” surgió de una cabeza inquieta de mi antiguo curro y creo, que hasta aquí puedo y debo leer.
Por kcmr, el 16 de febrero de 2009 en Javascript
Etiquetas: framework javascript, Javascript, mootools
Como los amantes de jQuery sabrán, para acceder a cada uno de los elementos de un HTMLCollection con este framework no necesitamos utilizar un bucle for o un método each(), ya que la iteración se hace de forma implícita.
Ejemplo con jQuery:
$('a.clase').bind('click', function(ev){
ev.preventDefault();
alert('Hola mundo');
})
Hoy descubro vía The Blueprint, que Mootools también permite hacer esta iteración implícita característica de jQuery, de manera que podríamos resumir el primer ejemplo de código en el que se usa el método each(), en el segundo ejemplo algo más corto usando la iteración implícita.
Usando each() con Mootools:
$$('a.clase').each(function(el){
el.addEvent('click', function(ev){
ev.stop();
alert('Hola mundo');
})
})
Usando la iteración implícita:
$$('a.clase').addEvent('click', function(ev){
ev.stop();
alert('Hola mundo')
})
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.
Por kcmr, el 8 de febrero de 2009 en Accesibilidad, Cajón de sastre, HTML
Etiquetas: Accesibilidad, curiosidades
Si no teníamos suficiente con el típico debate sobre usar uno o varios encabezados de primer nivel, ahora tenemos otro para la colección: ¿H1 para el título principal de la página o para el logo del sitio?
La cosa llega al extremo de tener su propia web, en la que podemos ver los argumentos y votos dados a través de Twitter (me temo que nunca participaré.)
De momento va ganando la opinión de usar H1 para el título principal de la página. Yo comienzo a pensar que da un poco igual mientras se hayan hecho otras cosas bien, como usar un título (elemento <title>) descriptivo y una jerarquía de encabezados con sentido.
Por kcmr, el 8 de febrero de 2009 en HTML
Etiquetas: custom dtd, HTML, wai-aria
En muchas ocasiones nos habrá tocado encontrarnos con la necesidad de usar atributos desaprobados por el W3C, que hacen que nuestros documentos no validen. Este es el caso del atributo autocomplete en campos de formulario, el atributo target para enlaces en XHTML estricto o los atributos de WAI-ARIA.
Podemos solucionar el problema de la validación mediante el uso de una DTD personalizada. Reciéntemente han sido varios los sitios que han propuesto el uso de una DTD personalizada para validar documentos que usan atributos de WAI-ARIA. En todos estos casos se usaba una DTD externa. Para usar una DTD externa sólo necesitamos descargar una DTD original de XHTML y modificarla añadiendo los atributos que deseemos para determinados elementos. Después necesitaremos hacer referencia a esta DTD, alojada en un dominio público, en el DOCTYPE del documento HTML.
Ejemplo:
<!DOCTYPE html SYSTEM
"http://dominio.com/dtd/xhtml1-custom.dtd">
Existe otra opción que consiste en modificar una DTD de forma interna, en el propio documento XHTML, sin necesidad de necesitar un documento DTD alojado en el servidor.
En el siguiente ejemplo modificamos la dtd de XHTMl transicional, para añadir el atributo autocomplete a elementos input:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
[
<!ATTLIST input autocomplete (off) #IMPLIED>
]
>
En esta línea <!ATTLIST input autocomplete (off) #IMPLIED> estamos diciendo que al elemento input se le añade un nuevo atributo (autocomplete), cuyo valor será off. #IMPLIED indica que su uso es opcional.
De la misma forma podríamos añadir el atributo target para los enlaces en XHTML estricto. Por cierto, una práctica nada recomendable.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
[
<!ATTLIST a target (_blank|_parent|_search|_self|_top) #IMPLIED>
]
>
Y añadir atributos WAI-ARIA a determinados elementos HTML sin necesidad de usar Javascript. En este caso añadimos el atributo aria-required con el valor true para elementos input.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
[
<!ATTLIST input aria-required (true) #IMPLIED>
]
>
Esta técnica tiene un pequeño problema, y es que, en el navegador nos aparecen unos caracteres al principio del documento ]>
En este ejemplo, que usa XTHML estricto e incluye la ampliación del DTD para admitir, tanto el atributo autocomplete, como el atributo target en enlaces y aria-required en elementos input, se puede ver el problema de los caracteres al principio del documento.
La solución elegante consiste simplemente en servir el documento como application/xhtml+xml, con la extensión .xhtml. El problema de este método es que Internet Explorer no acepta este Content-type e intentará guardar el documento. Ver ejemplo de XHTML servido como application/xhtml+xml.
La solución sucia pero eficaz, consiste en utilizar CSS para ocultar los caracteres no deseados. Podemos hacerlo de varias formas, esta es la que yo he elegido después de varias opciones:
html{text-indent: -99999em; line-height: 0;}
body *{text-indent: 0; line-height: normal;}
Ver ejemplo de XHTML estricto servido como text/html (aceptado por Internet Explorer) con los estilos anteriores.
La verdad es que lo he publicado como una opción a tener en cuenta en casos extremos (el plan B), y me parece, más que nada, una forma de engañar a los validadores, que se debería usar con moderación y en ocasiones muy puntuales. En los ejemplos expuestos se han usado atributos de uso común, pero sería peligroso que cada uno decidiera usar atributos de su propia cosecha. Recomiendo echarle un vistazo a lo que opina el W3C sobre las DTD personalizadas, simplemente “no utilice DTDs personalizadas“.