Uninstallme

Desarrollo front-end, estándares web, accesibilidad y más

Reseteado de margin y padding en CSS: un término medio

Por kcmr, el 31 de diciembre de 2009 en CSS, Personal

Etiquetas: , ,

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.

Captura de los estilos interpretados para un elemento OPTION en Firebug

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.

Información relacionada y opiniones variadas

Sin comentarios

Lazy Load de imágenes con Mootools

Por kcmr, el 30 de diciembre de 2009 en Javascript, Utilidades

La técnica “Lazy Load” consiste en detener la carga inicial de imágenes u otros elementos hasta que están en el área visible de la pantalla, momento en que se cargan con un efecto fade in (aparición suave).

Es ideal para páginas con galerías lineales de imágenes, en las que la carga de imágenes a petición (al hacer scroll) puede reducir considerablemente el tiempo inicial de carga de la página.

Existe un plugin para jQuery y también uno para Prototype, pero no acababa de encontrar uno que funcionara exactamente igual para Mootools, aunque existe uno, así que me he decidido a hacerlo basándome en el de Prototype.

Es un script bastante sencillo que no contempla otras opciones como ancho y alto mínimo de las imágenes o extensión (gif, jpg, etc). Su funcionamiento se basa en reemplazar el atributo src de las imágenes que no están en el área visible de la pantalla por el de una imagen de peso muy reducido (43 bytes) y utilizar el atributo src original cuando esta imagen pasa a estar en el área visible de la pantalla. La posición de la imagen se detecta con el evento scroll de la página.

Para saber si la imagen está en el área visible de la pantalla he utilizado el método explicado en otro post para hacer lo mismo con Prototype.

Archivos requeridos

Uso

Se inicializa con el evento ‘domready’ del objeto window. En la demo se utilizan todas las imágenes, pero se podría utilizar cualquier selector, sólo las imágenes con una determinada clase, o las imágenes que estén dentro de una capa, etc.

window.addEvent('domready', function(){
   $$('img').each(function(el){
      new Kcmr.MooLazyLoad(el);
   });
});

Como única opción se puede pasar la ruta a la imagen de 1x1px que se utiliza como sustitución de la imagen original. La ruta por defecto es “images/blank.gif”

Ejemplo con otros selectores y ruta personalizada a la imagen de sustitución:

window.addEvent('domready', function(){
   $$('.clase img.clase').each(function(el){
      new Kcmr.MooLazyLoad(el, {
         blank: 'directorio/imagen.gif'
      });
   });
});

Demo y descarga

Sin comentarios

Detectar suavizado de fuentes con javascript

Por kcmr, el 6 de diciembre de 2009 en Buenas ideas, CSS, Javascript

Etiquetas: , , ,

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.

Información relacionada (@font-face)

Bulletproof @font-face syntax
La mejor forma de utilizar @font-face.
Existe una traducción al español en CSSBlog
Font Squirrel
Kits de fuentes para usar mediante @font-face
@font-face generator
Nos permite subir una fuente y descargar el paquete completo para usar mediante @font-face
TTF to EOT Font Converter
Para convertir fuentes TrueType a OpenType (EOT), el formato usado por Internet Explorer

3 Comentarios

MySQL por línea de comandos en Mac

Por kcmr, el 17 de noviembre de 2009 en Cajón de sastre, Mac

Etiquetas:

Hace un tiempo publicaba un método para poder utilizar comandos SQL desde la consola de Windows, que consiste en añadir el directorio de MySQL a las variables de entorno del sistema.

En Mac se puede conseguir escribiendo lo siguiente en la consola:


Machine:~ user$ sudo su
Password: (tu contraseña...)
sh-3.2# echo '/usr/local/mysql/bin' >> /etc/paths.d/mysql
sh-3.2#
exit

La primera vez que hice esto funcionó, pero después de la actualización a Snow Leopard (realmente no sé si tiene algo que ver) me he encontrado con la sorpresa de que el directorio /usr/local/mysql no existe:
/usr/local/mysql no such file or directory

Para los que utilicen MAMP y se hayan encontrado con este mismo problema, esta solución es la que me ha funcionado (utilizar el directorio de MAMP):


sh-3.2# echo '/Applications/MAMP/Library/bin/mysql' >> /etc/paths.d/mysql

Sin comentarios

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:

Captura de imágenes redimensionadas en Explorer 7

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;
      }
   }
});

2 Comentarios

Max-width para Internet Explorer 6 sólo con CSS

Por kcmr, el 21 de octubre de 2009 en Buenas ideas, CSS

Etiquetas: ,

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;}
  • El alto de los bloques con el margen negativo debe ser una unidad. No funciona un porcentaje o el valor auto.
  • El margen negativo es igual a la mitad del ancho máximo del bloque contenedor, que no se declara en ningún otro sitio.

Existen otras soluciones para conseguir un ancho máximo en IE 6, basadas en Javascript o en el uso de expresiones propietarias de Microsoft.

5 Comentarios

Acceso a un virtual host en Mac desde Windows con Parallels

Por kcmr, el 6 de septiembre de 2009 en Mac

Etiquetas: , , ,

Parallels es el mejor sistema de virtualización de los que he probado hasta ahora, que la verdad, tampoco han sido muchos: Virtual Box y Virtual PC de Microsoft.

Gracias al “modo coherencia” de Parallels, para abrir un archivo que tengamos en Mac en una aplicación de Windows, basta con arrastrar y soltar. Así de sencillo.

Ahora bien, cuando necesitamos usar un virtual host para algún proyecto y tenemos que acceder a él desde Windows, la cosa se complica un poco.

Este sería el caso de las aplicaciones web que usan rutas absolutas para vincular hojas de estilo, scripts, imágenes…, de manera que no nos sirve utilizar la dirección IP para acceder a ellas.

Necesitamos instalar Rinetd, concrétamente una versión modificada para Windows que podemos descargar en esta página.

Descomprimimos el archivo en C y modificamos el archivo rinetd.conf con los datos correspondientes a nuestro equipo. La segunda IP que aparece en la captura es la de nuestro equipo. Podemos encontrarla en Preferencias del Sistema > Compartir.
Si estamos utilizando MAMP y no hemos cambiado los puertos por defecto de MAMP, en lugar del puerto 80 tendríamos que usar el 8888.

Ejemplo de configuración de Rinetd.conf

Ejemplo de configuración de Rinetd.conf

Después instalamos WAMP en Windows y creamos el virtual host que necesitemos usar en el archivo httpd-vhosts.conf, que se encuentra en wamp\bin\apache\apacheX(*)\conf\extra
* X se corresponde a la versión de Apache

Configuración del virtual host en Windows

Configuración del virtual host en Windows

En el archivo hosts de Windows, añadimos el virtual host que acabamos de crear (línea destacada en la captura). En Windows XP este archivo está en C:\WINDOWS\System32\drivers\etc

Configuración del archivo hosts de Windows

Configuración del archivo hosts de Windows

Iniciamos WAMP o reiniciamos si estaba iniciado y ejecutamos Rinetd mediante la consola de Windows escribiendo:
C:\rinetd\rinetd.exe -c C:\rinetd\rinetd.conf

Captura de la consola de Windows

Captura de la consola de Windows

No veremos ningún mensaje en la consola, es lo normal. La dejamos abierta y ya podemos acceder a nuestro virtual host en Mac.

Internet Explorer accediento a un Virtual Host en Mac

Internet Explorer accediento a un virtual host en Mac

La principal ayuda para llegar a esta solución: Access a local Mac server from Windows in Parallels

Sin comentarios

Ejemplo de Javascript Multiidioma

Por kcmr, el 1 de septiembre de 2009 en Javascript

Cuando tenemos un sitio en varios idiomas en el que estamos añadiendo atributos como ALT o TITLE a imágenes o enlaces, lo ideal es proporcionar esos literales en todos los idiomas del sitio y usar los correspondientes al idioma según el valor del atributo xml:lang o lang de la etiqueta HTML.

Para estos casos es útil crear un objeto en el que almacenamos todos los literales según el código del idioma.

Mediante una función que devuelva el valor del atributo xml:lang o lang del tag HTML, estableceremos el idioma del sitio y los literales a usar.

Ejemplo completo usando Mootools:

var MiClase = new Class({
  Implements: Options,
  // literales a usar
  options: {
    literales: {
      ES: {
        titleMostrar: 'Mostrar álbum',
        titleOcultar: 'Ocultar álbum'
      },
      EN: {
        titleMostrar: 'Show album',
        titleOcultar: 'Hide album'
      }
    }
  },
  initialize: function(element, options){
    this.setOptions(options);
    this.element = element;
    ...
    // llamamos a la función encargada de obtener el valor del atributo lang del tag HTML
    this.getDocumentLang();
    // según el valor de this.lang (devuelto por la función anterior) asociamos los literales de uno u otro idioma a una propiedad "literales" de nuestra clase "MiClase"
    this.lang == 'es' ? this.literales = this.options.literales.ES : this.literales = this.options.literales.EN;
  },
  getDocumentLang: function(){
    // obtengo el valor de xml:lang o de lang si xml:lang no se ha usado en el HTML
    this.lang = $$('html')[0].get('xml:lang') || $$('html')[0].get('lang');
    if(!this.lang) this.lang = 'es'; // idioma por defecto si no se ha declarado el idioma principal del documento
    return this.lang;
  },
  // uso de la propiedad literales en otras funciones
  funcionEjemplo: function(){
    var miElemento = ...;
    miElemento.set('title', this.literales.titleMostrar);
  }
});

En el caso de más de dos idiomas, en lugar del condicional usado dentro del método initialize en el ejemplo anterior, podríamos usar una estructura switch case.
Ejemplo:

initialize: function(element, options){
  ...
  this.getDocumentLang();
  switch(this.lang){
    case 'es':
      this.literales = this.options.literales.ES;
      break;
    case 'en':
      this.literales = this.options.literales.EN;
      break;
    case 'fr':
      this.literales = this.options.literales.FR;
      break;
    default:
      this.literales = this.options.literales.ES;
  }
}

1 Comentario

Cuidadín con pulvillarrac@gmail.com

Por kcmr, el 31 de agosto de 2009 en Wordpress

Un pequeño aviso para los que usan WordPress: si se os registra un usuario con email pulvillarrac@gmail.com, borradlo inmediatamente.

También recomiendan cambiar todas las contraseñas de los usuarios administradores. Yo además he deshabilitado el registro de usuarios. (Administración > Opciones > General > Desmarcar “cualquiera puede registrarse”)

No sé que puede llegar a hacer este usuario, pero su registro me ha parecido bastante raro. Primero, no solicito el registro para comentar ni tengo ningún enlace a la página de registro por ninguna parte, por lo que es un usuario que conoce bien WordPress. Segundo, y esto ha sido lo alarmante, se ha registrado a la vez en dos blogs con dominio de mi propiedad y temática no relacionada…

Buscando su email en Google he encontrado esta página con entradas recientes en Twitter comentando el registro de este usuario.

4 Comentarios

Usar PHP en archivos Javascript

Por kcmr, el 29 de agosto de 2009 en Javascript

La forma más sencilla de acceder a alguna variable de PHP desde Javascript, es colocar el Javascript en el código HTML.

Ejemplo:


<script type="text/javascript">
    var flashvars = {
        file: "<php echo get_settings('home'); ?>/archivo.xml"
    }
</script>

Afortunadamente existe otro método para poder mantener el Javascript en un archivo independiente en el que podamos acceder a variables PHP.

Para poder hacer esto necesitamos servir los archivos Javascript como PHP.

El primer paso es renombrar el archivo Javascript para que su extensión sea .php. Lo podemos dejar como nombrearchivo.js.php para facilitar su identificación.

Dentro del archivo Javascript, al comienzo, necesitamos indicar que el contenido del archivo es de tipo Javascript:


<?php
Header("content-type: application/x-javascript");
?>

Podemos pasar las variables PHP que necesitemos como parámetro en la url:


<script type="text/javascript" src="js/nombrearchivo.js.php?url=<?php get_settings('home'); ?>"></script>

De esta forma podemos acceder a ellas mediante $_GET en el archivo Javascript:


<?php
Header("content-type: aplication/x-javascript");

$variablePHP = $_GET['url'];
echo "var variableJS = '" .$variablePHP. "';\n";
?>

// inicio del código javascript
var flashvars = {
    file: variableJS + "/archivo.xml"
}

Usando este método también podemos reducir un poco el tamaño de los archivos Javascript encerrando los bloques de comentarios entre etiquetas PHP.

Más información: External JavaScript and PHP

2 Comentarios