Delirios de un Informático

Funciones personalizadas para Less mediante Grunt

Less dispone de muchas funciones nativas, pero hay ocasiones en las que resultaría útil disponer de funciones personalizadas porque los mixins tampoco son suficientes. Por ejemplo, puede ser útil comprobar si existe un archivo, leer su contenido o ejecutar una herramienta externa para obtener los valores.

Para estos casos, es posible añadir nuevas funciones a Less mediante Grunt y el plugin grunt-contrib-less mediante la opción customFunctions, con lo que tendremos toda la potencia de Node.js a nuestra disposición para realizar todo que se nos ocurra.

Este sería el contenido de un Gruntfile.js de ejemplo:

module.exports = function(grunt) {
    grunt.loadNpmTasks('grunt-contrib-less');

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        less: {
            options: {
                customFunctions: require('./functions.js'),
                sourceMap: false
            },
            build: {
                src: 'test.less',
                dest: 'test.css'
            }
        }
    });

    grunt.registerTask('default', ['less']);
};

Como se puede ver, utilizo un require('./functions.js') para almacenar en un archivo todas las funciones, que deben exportarse del siguiente modo:

exports.test = function(less, arg1, arg2) {
    // código personalizado
}

Cada función se exporta con un nombre que será el utilizado en Less:

body {
  background-color: test('test.jpg', #FFFFFF);
}

Hay que tener en cuenta los siguientes aspectos:

  • El primer argumento recibido por la función es una instancia del compilador Less
  • El resto de argumentos son los que se especifiquen en Less
  • Cada argumento es un objeto con las siguientes propiedades (entre otras):
    • value: valor especificado en Less
    • quote: entrecomillado usado para convertir el valor
    • escaped: indica si se aplicarán caracteres de escape en el valor
  • Cualquiera de las propiedades puede modificarse para que el compilador las utilice
  • El entrecomillado será el especificado en Less: ‘, ” o ninguno si se usa un color o cualquier otro valor CSS
  • El valor de retorno de la función puede ser un objeto como el recibido como argumento o una cadena que se mostrará tal cual

El único problema que no he logrado solventar es poder acceder a las variables definidas en el punto en el que se llama a la función. Sería muy útil poder acceder a las variables, añadirlas y modificarlas, pero por lo que he podido comprobar la instancia de Less recibida por la función no da acceso a ellas.

Mejorando Internet Explorer

Comentaba ayer lo frustrante de intentar usar pseudoclases hover en Internet Explorer. Curioseando un poco más di con una serie de scripts y trucos ¿recopilados? ¿programados? por Dean Edwards agrupados en un paquete llamado IE7. Añade soporte completo para CSS 2 y parte de CSS 3 ( selectores, atributos, pseudoclases…), soporte para transparencias de PNG ( incluso para las imágenes usadas como fondos con CSS ) y muchas cosas más que se pueden comprobar con ejemplos.

El paquete tiene una instalación muy sencilla y está licenciado con Creative Commons.

Escuchando Alan Parsons Project – The gold bug en el disco Turn of a friendly card
.

Pseudoclase hover en Internet Explorer

Llevo unos dias peleando con Internet Explorer y su incompatibilidad con los estándares. Una de las cousas que me frustran a la hora de diseñar algo visible es la carencia de la pseudoclase hover para todo lo que no sea un enlace.

Para solucionarlo hay un método ( bastante cutre, sí ) que consiste en forzar un cambio de clase en el evento onmouseover, de modo que se simula el efecto. En este artículo de A List Apart muestran cómo hacerlo con listas para generar menús desplegables. Un sencillo código JavaScript soluciona el problema….

Cambiar estilos CSS con JavaScript

Una de las ideas que tenía a la hora de programar esta bitácora era la de poner a disposición de los visitantes varios estilos CSS. El problema era aplicar el estilo sin tener que recargar la página completamente. La solución la encontré en Javascript.
Javascript nos permite cambiar las propiedades de un objeto usando la sintaxis objeto.propiedad=valor así que cambiando la propiedad href de la etiqueta <link> que enlaza los archivos CSS el estilo especificado se cargará.
Primero, crearemos un enlace al estilo CSS por defecto asignándole un identificador :
<link href="css/defecto.css" rel="stylesheet" type="text/css" id="estilo">
Despues crearemos en Javascript la función que cambiará el estilo. Funciona pasándole como único argumento el nombre o ruta completa del archivo CSS a mostrar. Usaremos la propiedad getElementById() para identificar el objeto:
function estilo(arquivo) {
    document.getElementById('estilo').href=arquivo;
}

Y finalmente sólo tendremos que llamar a la función desde un enlace o botón pasándole como argumento el nombre o ruta del arquivo CSS que queramos mostrar:
<input type="buton" value="Cambiar Estilo" onClick="estilo('azul.css');">
Podeis comprobar el funcionamento del script en la sección Opciones del menú de la derecha.