Contenido

CSS Naked Day 2009

26 feb

+ 9

Este año, igual que el anterior el CSS Naked Day tendrá lugar el día 9 de Abril. ¿te apuntas?

Primer problema con Safari4 y WordPress 2.7

25 feb

+ 14

Pues he de decir que Safari4 me ha encantado. Aúna lo que me gusta de Google Chrome (Webkit) y lo que me gusta de Firefox (Firebug). No creo que pueda decir nada nuevo que no se haya dicho yá sobre este navegador. Pero ya me he encontrado con el primer problema a la hora de trabajar con WordPress 2.7 y Safari4 sobre Mac.

safari4_wordpress27

Como podemos ver la caja en la que pondremos la URL y los datos relacionados a ella, aparece debajo del layer oscuro que oscurece el resto de la página. Esto es debido a que esta caja no tiene z-index. Con esto debería solventarse:

.clearlooks2 {
z-index:300000;
}

Pero ahí no acaba, al intentar cerrar la caja, obtenemos un error de tiny_mce que no he podido mirar aún:

TypeError: Result of expression 'na' [undefined] is not an object.

Si alguien descubre algo, que avise.

Actualización

El problema lo produce TinyMCE y ocurre con todas las versiones de este WYSIWYG sobre este navegador, al parecer en la versión de desarrollo del SVN ya lo tienen funcionando y esperan liberarlo con la próxima versión en breve. Así que los usuarios de WordPress tendremos que esperar a una actualización de las tantas que nos tienen acostumbrados :D

NOIE6Day, la iniciativa 2.0

25 feb

+ 97

Bueno, lo primero quiero agradecer a todos los usuarios que se han molestado en plasmar su opinión y ofrecer su granito de arena ( por no decir montaña) a esta iniciativa. Se aprende mucho leyéndolos y se tienen en cuenta cosas que quizás no se tuvieron previamente en consideración.

Muchos de los comentarios apoyan el fondo, pero critican tajantemente la forma.

Estoy de acuerdo en algo que los comentarios me han hecho tener en cuenta, la misión que los desarrolladores web tenemos que cumplir por encima de los estándares web, eliminar barreras a usuarios con discapacidades físicas y tecnológicas

La accesibilidad web es una tarea pendiente y yo he demostrado que debemos tenerla más en cuenta. Por eso creo que debemos hacer una modificación a la iniciativa.

Hablando con Yusef Hassan, un gran profesional y persona me ha estado ayudando a definir mejor la iniciativa que sin duda debe tener en cuenta la accesibilidad por encima de mis caprichos.

¿El día?

Sigue siendo el mismo día, el 18 de Octubre de 2009. Sigue siendo el por el mismo motivo, por que IE7 nació ese día y significó el nacimiento del reemplazo. Pero cambia la duración.

Mi propuesta:

El día 18 de Octubre del 2009a las 00:00 es el día límite

Ese día la iniciativa debería estar implantada en todas web posibles.

¿Como lo hacemos?

Mucho más sencillo que antes, no vamos a privar a los usuarios de que accedan o no al contenido de las páginas web, pero les vamos a eliminar TODOS los estilos CSS cuando el usuario entre con ese navegador (IE6) y añadiremos un mensaje superior informando de que su navegador está anticuado y que hay alternativas mejores.

¿Que ganamos?

Yo no tener que meter hacks en mi código y evitar perder el tiempo en hacer que mis aplicaciones se vean perfectas en IE6. Además, nos obliga a pensar en la semántica del código y en una estructura que permite la lectura del contenido a los que por motivos de fuerza mayor nunca puedan actualizar, haciendo caso a una de las premisas de accesibilidad web más importantes.

¿Que gana el usuario de Internet Explorer 6?

¿Realmente hace falta decirlo? Está claro que además de tener la capacidad de usar las nuevas herramientas que los navegadores modernos ofrecen, tendrán más seguridad en su navegación cotidiana y evitarán problemas como Spyware, y derivados.

¿Que código usamos?

Mucho más sencillo y fácil de usar que el anterior. Necesitaremos una función para detectar el día que lanzaremos la iniciativa.

<?php
function NOIE6() {
  $start = date('U', mktime(-12, 0, 0, 10, 18, 2009));
  $now = time() + date('Z') * -1;
  $isIE6 = eregi("MSIE 6\.[0-9]+", $_SERVER['HTTP_USER_AGENT']);

  if ($isIE6 && ($now >= $start)) return true;
  return false;
}
?>

Esta función devuelve true en caso de que  hayamos pasado la fecha de inicio de la iniciativa. Y nos seguirá devolviendo ese valor siempre que Internet Explorer 6 sea el navegador que visita nuestra página.

Ahora solo nos queda condicionar la salida de las hojas de estilo:

<head>
...
<?php
if ( !NOIE6() ) {
  echo '<link rel="stylesheet" type="text/css" href="styles.css" />';
}
?>
...
</head>

De esta forma, siempre que se cumplan  las condiciones (que pase la fecha y que sea Internet Explorer 6) no nos pintará la los estilos en la página.

¿Y el mensaje?

El mensaje creo que es algo muy subjetivo y que cada uno debería implementar a su gusto y con sus palabras. Así coge un toque más humano y menos enlatado. Pero usaremos los tags condicionales de Internet Explorer 6 para mostrarlo:

<!--[if IE 6]>
<div id="usuarios-ie">
La versión de Internet Explorer que estás utilizando no es recomendada para navegar en Internet.
Te recomendamos que actualices a <a href="http://www.microsoft.com/windows/products/winfamily/ie/default.mspx">una versión más reciente</a> o pruebes otros navegadores como <a href="http://www.mozilla.com" title="Firefox web browser">Firefox</a>, <a href="http://www.opera.com/" title="Opera Browser">Opera</a>, <a href="http://www.apple.com/safari/" title="Apple Safari">Safari</a> o <a href="http://www.google.com/chrome" title="Google Chrome">Chrome</a>
</div>
<![endif]-->

Si usas WordPress es aún más fácil, basta con añadir este código al fichero functions.php de tu theme:

<?php
function noie6($url){
	$start = date('U', mktime(-12, 0, 0, 10, 18, 2009));
  	$now = time() + date('Z') * -1;;
 	$isIE6 = eregi("MSIE 6\.[0-9]+", $_SERVER['HTTP_USER_AGENT']);

  	if ($isIE6 && ($now >= $start))  return "";
  	return $url;
}

add_filter("stylesheet", "noie6");
add_filter("stylesheet_uri", "noie6");
?>

Disculpas

Siento todas las molestias y problemas que haya podido ocasionar. Pido perdón, por dejarme llevar por un momento de rabia y convertir mi cruzada en algo demasiado radical. Y aprovecho para agradecer a todos los que han comentado en la entrada anterior dándome su apoyo y ofreciéndome de forma constructiva soluciones más correctas.

Esto es una iniciativa 2.0 en toda regla.

NOIE6Day, 18 de octubre día sin Internet Explorer 6

24 feb

+ 132

Actualización

Hemos replanteado la iniciativa para hacerla menos radical y no obstructiva.

Os quiero proponer una cosilla. Supongo que por el tema que és recibiré comentarios de apoyo, pero lo importante es ver quien lo lleva a cabo.

Se trata de un NOIE6Day (osea día sin Internet Explorer 6), al igual que tenemos un CSS Naked Day, debemos hacer una protesta hasta que sea inutil criticar a un navegador que no exista.

¿El día?

Según la Wikipedia, Internet Explorer 7.0 nació (lanzamiento) el día 18 de Octubre de 2006. La idea era matar IE6 y dejar paso a una familia de navegadores más modernos (no acabó de cuajar) pero creo que es una buena fecha, no muy cercana que nos permite movilizarnos y que simboliza un cambio por parte de M$.

18 de Octubre

¿Por que?

Por que desde el 25 de agosto del 2004 no se actualiza y está relentizando Internet. Y todo lo que ya conocemos.

¿Como montarlo?

Muy sencillo, simplemente tendremos que añadir este código al inicio de nuestra aplicación,

<?php
// Definimos la función
function NOIE6Day() {
  $start = date('U', mktime(-12, 0, 0, 10, 18, date('Y')));
  $end = date('U', mktime(36, 0, 0, 10, 18, date('Y')));
  $z = date('Z') * -1;
  $now = time() + $z;
  $isIE6 = eregi("MSIE 6\.[0-9]+", $_SERVER['HTTP_USER_AGENT']);

  if ( $isIE6 && ($now >= $start && $now <= $end )) return true;
  return false;
}

// La llamamos
if (NOIE6Day()) {
	die(sprintf('Hoy, día 18 de Octubre del %d es el llamado NOIE6Day. Es un día en el que los usuarios de Internet Explorer 6 no podrán entrar en esta página.
		<br />
		Te recomendamos que actualices a <a href="http://www.microsoft.com/windows/products/winfamily/ie/default.mspx">una versión más reciente</a> o pruebes otros navegadores como <a href="http://www.mozilla.com" title="Firefox web browser">Firefox</a>, <a href="http://www.opera.com/" title="Opera Browser">Opera</a>, <a href="http://www.apple.com/safari/" title="Apple Safari">Safari</a> o <a href="http://www.google.com/chrome" title="Google Chrome">Chrome</a>.
		<br />
		<a href="%s">Más información</a>', date("Y"), $url)
	);
}

?>

está pensado para añadir un fichero noie6day.html en el servidor para informar al usuario de por que estámos dejándole sin su página favorita.

Si alguien más diplomático se anima que me haga llegar una plantilla y la publicaremos para que todos podamos tener algo similar.

Feedback

Espero opiniones, sugerencias  :D

Actualización

Versión .htaccess:
http://www.actualidadtotal.es/htaccess_noie6day.zip
Módulo WordPress:
http://www.actualidadtotal.es/wp_noie6day.zip
Módulo Drupal:
http://www.actualidadtotal.es/drupal_noie6day.zip

Técnicas CSS3 que podemos conseguir con jQuery

24 feb

+ 11

La gente de noupe nos muestra un excelente post en el que podemos ver alguna de las propiedades CSS3 que ya tenemos ganas de tener en nuestras manos y las alternativas jQuery con las que podemos obtenerlas actualmente.

1. border-radius

Quizas es la propiedad más nombrada (despues de opacity) de las que están a punto de llegar. Y me parece lógico ya que las soluciones actuales (sin javascript) son engorrosas y desmesuradas. Con jQuery Canvas Rounded Corner podremos mitigar esas ansias de dispone de esta propiedad.

CSS3

#rounded-box {
-moz-border-radius: 15px;
-webkit-border-radius: 15px;
}

jQuery

$('#rounded-box').corners({ radio: 15, borderSize: 2 });

2. border-image

Otra propiedad muy solicitada por la comunidad de diseñadores. Para usarla actualmente, tendremos que recurrir a jQuery borderImage.js.

CSS3

.button{
	-moz-border-image: url("media/button1.png") 0 5;
	-webkit-border-image: url("media/butto1.png") 0 5;
}

jQuery

$('#buttons a, .button a').borderImage('url("media/button0.png") 0 5', 'media/button1.png', 'media/button2.png')

3.Multiple Backgrounds

Sin duda una propiedad que dará mucho juego y que ofrecerá la posibilidad de dejar de ver el <body /> como una pizarra en la que pintamos. Por el momento tenemos que conformarnos con jQuery MultipleBackground.

CSS3

#multiple-background-box {
background: url(top-bg.gif) top left no-repeat,
url(bottom-bg.gif) bottom left no-repeat,
url(middle-bg.gif) left repeat-y;
padding: 20px;
}

jQuery

$(function(){
  $('.marioBox').add_layer("#A4D3FF");
  $('.marioBox').add_layer("url('/images/mario_floor.gif') no-repeat bottom");
  $('.marioBox').add_layer("url('/images/mario_bush.gif') no-repeat 10px 167px");
  $('.marioBox').add_layer("url('/images/mario_pipe.gif') no-repeat 180px 183px");
  $('.marioBox').add_layer("url('/images/mario_cloud.gif') no-repeat 90px 93px");
  $('.marioBox').add_layer("url('/images/mario_cloud.gif') no-repeat 180px 53px");
  $('.marioBox').add_layer("url('/images/mario_cloud.gif') no-repeat 20px 73px");
  $('.marioBox').add_layer("url('/images/goomba.gif') no-repeat 70px 214px");
  $('.marioBox').add_layer("url('/images/mario.gif') no-repeat 180px 156px");
});

4. Box shadow y text-shadow

Se acabó el usar <div /> flotantes colocados debajo de otro para obtener una sombra, con la llegada de CSS3 esto será cosa del pasado… pero por el momento debemos resignarno y usar DropShadow o Text-Shadow para IE para conseguirlo.

CSS3

h3 { text-shadow: 2px 2px 2px #333; }

jQuery

$("h3").dropShadow({left: 2, top: 2, blur: 1, color: "#03f", swap: true});

5.Opacity

La propiedad CSS3 por excelencia, sin duda es la más mediática de todas las propiedades y con la que se han conseguido maravillas como Lightbox. De ahí que jQuery, sea capaz de usarla nativamente. Aunque plugins como Gradient permite más juego.

CSS3

div.L1 { background:#036; opacity:0.2; width:575px; height:20px; }
div.L2 { background:#036; opacity:0.4; width:575px; height:20px; }
div.L3 { background:#036; opacity:0.6; width:575px; height:20px; }
div.L4 { background:#036; opacity:0.8; width:575px; height:20px; }
div.L5 { background:#036; opacity:1.0; width:575px; height:20px; }

jQuery

$('#main').gradient({
		from:	'fefefe',
		to:		'cddcc3',
		direction:	'horizontal'
	});

HTML5 canvas Cheat Sheet, todo canvas en una hoja

24 feb

+ 1

Jacob Seidelin, conocido por estos lares como mister JSMario y maravillas Javascript varias, nos trae un cheat sheet en la que tenemos todo lo que el elemento <canvas /> puede ofrecernos en el nuevo estandar HTML5. Tenemos la posibilidad de descargarla en PDF o en PNG.

¿Se acabó el soporte a Internet Explorer 6?

24 feb

+ 24

Hoy me ha sorprendido esta iniciativa que Christian publica en Maestros del Web. Se trata de informar a los usuarios que llegan a nuestras páginas con Internet Explorer vean un mensaje de alerta informando de que existen alternativas más modernas y que ofrecen mejores resultados.

Ya hace tiempo que vemos como va cayendo el número de usuarios de IE6 en Internet. Pero aún así lo tenemos en cuenta a la hora de desarrollar nuestras aplicaciones web. Y es que realmente son muchos los motivos por los que IE6 debería dejar de exsitir. Incluso Google incitó a que se dejara de usar.

Así que aNieto2k ya forma parte de esta iniciativa y si entras desde IE6  ( y por un milagro actualiza la CSS) se podrá ver un mensaje en la parte superior de la página que informa que se está usando una versión muy antigua del navegador y que hay otras alternativas más modernas y efectivas.

Código

Usamos el tag condicional para indicar que únicamente debe ser interpretado por Internet Explorer 6.

<!--[if IE 6]>
<div id="usuarios-ie">
La versión de Internet Explorer que estás utilizando no es recomendada para navegar en Internet.
Te recomendamos que actualices a <a href="http://www.microsoft.com/windows/products/winfamily/ie/default.mspx">una versión más reciente</a> o pruebes otros navegadores como <a href="http://www.mozilla.com" title="Firefox web browser">Firefox</a>, <a href="http://www.opera.com/" title="Opera Browser">Opera</a>, <a href="http://www.apple.com/safari/" title="Apple Safari">Safari</a> o <a href="http://www.google.com/chrome" title="Google Chrome">Chrome</a>
</div>
<![endif]-->

Obviamente podeis cambiar el texto y poner lo que querais. Este no es nada más que un ejemplo.

Despues nos quedará darle estilos para que resalte sobre el fondo de la web. A mi, al ser amarillo me viene perfecto con el azul del fondo, así que cada uno revise el código que lo adapte a su web.

#usuarios-ie {font-family: Verdana, Arial, sans-serif; background: #FFFFDE;color:#000; border-bottom: 2px solid #7F0C00;}
#usuarios-ie p {font-size: 1.3em; margin: 0; padding: 5px 0; line-height: 1.5em;}
#usuarios-ie a {text-decoration: underline; font-weight: bold; color: #D64411;}

Lamentablemente, en el ámbito profesiona (no en todo) será dificil cambiar la idea de que IE6 es el navegador por defecto (aunque aún lo és), pero poco a poco debemos ir mostrando gráficos y noticias que hagan que se vayan introduciendo alternativas en la empresa.

Mis jefes tardaron casi 3 años en barajar la idea de que Firefox debería estar soportado…

display:inline-block para todos los navegadores.

22 feb

+ 7

La propiedad CSS display dispone de una buena lista de posible valores ( inline | block | list-item | run-in | inline-block | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | none | inherit) para indicar que tipo de elemento estamos posicionando.  Dos de las más usadas son inline y block .

display:inline

Los elementos inline no generan una nueva línea en el flujo del texto. Los elementos inline son vistos como elementos “internos” subordinados para los hacia arriba elementos de bloque.

Elementos Inline por defecto:

a, abbr, acronym, applet, b, basefont, bdo, big , br, button, cite, code, dfn, em, font, i, img, input, iframe, kbd, label, map, object, q, samp, script, select, small, span, strong, sub, sup, textarea, tt, var.

display:block

Los elementos de bloque generan una nueva línea (renglón) en el flujo del texto

Elementos de bloque por defecto:

address, blockquote, center, dl, dir, div, fieldset, form, h1-6, hr, isindex, menu, noframes, noscript, ol, p, pre, table, ul.

display:inline-block

En la especificación de CSS2.1 se añadió este valor que permite integrar las ventajas de ambas propiedades. Con este valor podemos crear bloques en la misma línea de flujo, haciendo que diseños como rejillas sean posibles.

Actualmente, solo los navegadores modernos lo interpretan, por lo que nos vemos obligados a usar un hack para que todos los navegadores lo “emulen”.

inline-block

En Mozilla Webdev nos muestran un ejemplo de como conseguir que todos los navegadores nos permite obtener diseños como estos sin necesidades usar float en ellos.

inline-block-demo

Código

li {
       width: 200px;
       min-height: 250px;
       border: 1px solid #000;
       display: -moz-inline-stack; /* FF2*/
       display: inline-block;
       vertical-align: top; /* BASELINE CORRECCIÓN*/
       margin: 5px;
       zoom: 1; /* IE7 (hasLayout)*/
       *display: inline; /* IE */
       _height: 250px; /* IE6 */
   }

Parsear URL’s con DOM

21 feb

+ 1

James Padolsey, ha publicado una función que nos permite parsear URL’s usando las propiedades del DOM.

function parseURL(url) {
    var a =  document.createElement('a');
    a.href = url;
    return {
        source: url,
        protocol: a.protocol.replace(':',''),
        host: a.hostname,
        port: a.port,
        query: a.search,
        params: (function(){
            var ret = {},
                seg = a.search.replace(/^\?/,'').split('&'),
                len = seg.length, i = 0, s;
            for (;i<len;i++) {
                if (!seg[i]) { continue; }
                s = seg[i].split('=');
                ret[s[0]] = s[1];
            }
            return ret;
        })(),
        file: (a.pathname.match(/\/([^\/?#]+)$/i) || [,''])[1],
        hash: a.hash.replace('#',''),
        path: a.pathname.replace(/^([^\/])/,'/$1'),
        relative: (a.href.match(/tp:\/\/[^\/]+(.+)/) || [,''])[1],
        segments: a.pathname.replace(/^\//,'').split('/')
    };
}

Con ella podemos obtener una serie de datos sobre las URL’s que queremos parsear. Una solución muy limpia y útil que nos ayudará a mitigar la desaparición de URLParser.

var myURL = parseURL('http://abc.com:8080/dir/index.html?id=255&m=hello#top');

myURL.file;     // = 'index.html'
myURL.hash;     // = 'top'
myURL.host;     // = 'abc.com'
myURL.query;    // = '?id=255&m=hello'
myURL.params;   // = Object = { id: 255, m: hello }
myURL.path;     // = '/dir/index.html'
myURL.segments; // = Array = ['dir', 'index.html']
myURL.port;     // = '8080'
myURL.protocol; // = 'http'
myURL.source;   // = 'http://abc.com:8080/dir/index.html?id=255&m=hello#top'

Esto me recuerda que hace ya tiempo vimos como coger parámetros de la URL con Javascript.

jClass2k, define Class con javascript

21 feb

+ 33

jDeveloper (o Jota) me pasó hace unos días una implementación para conseguir Orientar a Clases nuestros scripts. Me ha encantado por su sencillez y versatilida, nos permite generar Clases con sus respectivos Objetos, extendiendo de Super Clases.

var Class = function(current,previous){
// Comprobamos si tenemos una Class que extender.
      previous = typeof previous == 'undefined' ? {} : previous.prototype;
  // Extendemos con las propiedades de la Class anterior
      for(p in previous){
	// Si no existe la propiedad la añadimos
            if(typeof current[p] == 'undefined') current[p] = previous[p];
	// Si es una función
            else if(typeof previous[p] == 'function'){
	      // añadimos this.parent() a la función de la Class actual.
                  current[p] = (function(tmp){
                                var _parent = function(){
                                    this.parent = _parent.parent;
                                    return tmp.apply(this, arguments);
                                    }
                                    return _parent;
                                })(current[p]);
	// Igualamos this.parent() al método de la Class anterior.
                current[p].parent = previous[p];
            }
        }
	// Construimos el contenedor
        var construct = function(){
          if(this.init) this.init.apply(this,arguments);
        }
	// Le aplicamos los métodos extendidos
        construct.prototype = current;
	// asignamos un constructor
        construct.constructor = Class;
	//Devolvemos el constructor.
        return construct;
    }

Si quitamos todos los comentarios, nos queda un script de 21 líneas que podemos integrar en cualquier código ya que no depende de ningún framework JS.

¿Como lo uso?

Con este script podemos generar Clases, pero ¿como?

var Humano = new Class({
	piernas: 2,
	brazos: 2,
	cabeza: 1,
	init: function(name){
		this.name = name;	
	},
	saludar: function(){
		return "Hola, soy " + this.name;
	}
});

Creamos la Clase Humano que especifica tiene 2 piernas, 2 brazos y una cabeza, además especificamos que el constructor nos solicita un nombre que se le asignará al “Humano“. Como método para testear que funciona he creado saludar() que nos devolverá un saludo cordial personalizado para cada “Humano“.

var Programador = new Class({
	experiencia: 0,
	init: function(name, lenguaje){
		this.parent(name);
		this.lenguaje = lenguaje;
	},
	saludar: function(){
		return this.parent() + " y programo en " + this.lenguaje;
	},
	programar: function(){
		this.experiencia++;
		return "Estoy programando";
	}
},Humano);

La clase Programador extiende de la clase Humano y además le añade experiencia como un valor único de los Programadores. Sobreescribimos los métodos init() y saludar() pero hacemos referencia a los del padre (Class Humano) mediante el uso de this.parent(). Además he añadido un método propio del Programador que obviamente es “programar():D

var Andres = new Programador("Andres", "Javascript");
Andres.saludar();
// --> "Hola, soy Andres y programo en Javascript"

De esta forma creamos un nuevo Objeto llamado Andres y que dispondrá de todos los métodos de Humano y Programador. Incluso podemos hacerlo currar mucho :D

var horas = 24; 
while(horas > 0) {
	console.log(Andres.programar());
	horas--;
}

Optimizaciones en los comentarios.