Diferencia entre display:none y visibility:hidden en CSS

A la hora de ocultar elementos html desde el css tenemos dos posibilidades: las propiedades display  y visibility. Ambas nos permiten definirlas para que un elemento no se muestre en nuestra página. En caso de display definiéndola como display:none y en caso de visibility como visibility:hidden. Muchos son los inconscientes que los usan de manera indistinta, con fatídicas consecuencias para sus maquetaciones porque ambas propiedades tienen diferencias. Veamos cuales:

  • La propiedad visibility:hidden oculta un elemento de la vista del usuario, pero respetando el espacio que ocupaba. Imagina que tienes tres cuadrados y ocultas el del medio con esta propiedad, ¿ok? Lo que ocurriría es que el cuadrado desaparecería, dejando ver lo que haya de fondo, y los cuadrados 1 y 3 seguirían en la misma posición. Con visibility:hidden todas las cajas css siguen en su sitio.
  • La propiedad display:none no sólo oculta, sino que quita el elemento del flujo lógico de la maquetación. Imagina el mismo caso de los cuadrados, en este supuesto en cambio el tercer cuadrado se desplazaría hacia la izquieda, ocupando el espacio que antes ocupaba el 2. Es decir, cuando usas display:none todas las cajas se recolocan como si la caja oculta no existiera.

Por tanto, a la hora de usar una propiedad u otra ten en cuenta estos comportamientos por el bien de tu maquetación.

Convertir un objeto SimpleXMLElement en un array

Toda la mañana peleando con un API que debería devolverme un array de PHP pero que, cosas de la vida, me devuelve un SimpleXMLElement. Cosillas del PHP y de tener que integrar aplicaciones externas a un proyecto usando sus APIs propias (y, en muchos casos, chapuceras). Tras mucho romperme la cabeza (cosa mala) llegué a la conclusión de que con aquello no había dios que trabajara (o sí, pero necesitaría unos días para aprender a manejarlo) y que mejor me sería pasarlo todo a un array y manipularlo a gusto. Tocó búsqueda por stack overflow y google y aparecieron muchas soluciones.

La mayoría son un truquito tal que así, recorriendo el XML y almacenando sus elementos en un array:

/*Siendo $xml el objeto SimpleXML*/
function xml2array($xml) {
  $arr = array();
  foreach ($xml as $element) {
    $tag = $element->getName();
    $e = get_object_vars($element);
    if (!empty($e)) {
      $arr[$tag] = $element instanceof SimpleXMLElement ? xml2array($element) : $e;
    }
    else {
      $arr[$tag] = trim($element);
    }
  }
  return $arr;
}

Esa es la solución propuesta por php.net, que funciona, sin duda. Pero he visto otra más simple y cortita en Book of Zeus donde lo solucionan con una sola línea:

$xml = json_decode(json_encode((array) simplexml_load_string($string)), 1);

Funciona, lo que no tengo claro es cual cargará menos tu servidor a nivel de rendimiento (eso de codificar como JSON y luego descodificar… mmmmmm, pero a saber). Yo me he decantado por la segunda, que hace el código más legible.

jQueryNumeric: Fuerza al usuario a introducir sólo números.

Llevo unos días sin escribir nada por aquí, cierto es. Me alegra ver que por otra parte el número de lecturas no decae. Hoy he decidido hacerme un hueco en la hora de comer para comentar este plugin de jQuery. Lo podéis descargar de aquí e incorporarlo libremente a vuestros proyectos, junto al framework jQuery, indispensable para su funcionamiento.

Una vez insertado sólo tenéis que utilizar el método numeric() sobre los campos de usuario que queráis que no acepten números. Este primer ejemplo muestra su funcionamiento para permitir sólo la entrada de enteros:

$("#input").numeric();

¿Y para floats? (es decir, números reales)… pues metiende una cadena con el separador como parámetro (en el ejemplo una coma, por mantener el formato latino):

$("#input").numeric(",");

Ojo, esto bloquea el teclado sobre el campo del formulario. Es decir, si os hacen la gracia de copiar y pegar algo sí lo tragará, así que una expresión regular para comprobar el formato, como la del ejemplo, no estaría mal. Por aquello de evitar fallos en el envío del formulario:

/[0-9\.,]+/.test()

Y con esto, liquidamos el consejo javascript del día.

Datepicker fácil en tu web

¿Necesitas un «datepicker»? Con esto quiero decir necesitas introducir un calendario en un formulario web, a día de hoy hay muchos sencillos métodos para hacerlo. Pero estas son las dos más fáciles:

  • Campo date en HTML5: Un campo del formulario definido como de tipo date ya te arregla en gran parte el problema. Tiene el handicap de que cada navegador te saca el calendario con el formato que le da la gana
    <input type="date"/>
  • Calendario datepicker con jQueryUI: Esta opción incluye más opciones de personalización. Lo primero es descargar la librería jQuery y lo siguiente bajar los componentes de jQueryUI necesarios, incluyendo sus estilos. Luego para implantarlo debes cargar las dos librerías en la cabecera del documento, usar un campo input normal (en el ejemplo se llamará #calendario) y un script como el siguiente:
    <script>
    	$(function() {
    		$( "#calendario" ).datepicker({
    			changeMonth: true,
    			changeYear: true
    		});
    	});
    	</script>
    
    <div class="ejemplo">
    
    <p>Date: <input type="text" id="calendario"></p>
    
    </div>
    

En fin, para el caso del jQueryUI tienes muchos más ejemplos en la propia página con las distintas opciones.

Librería para usar MD5 y SHA 1 en Javascript

En fin, me he quedado sin ordenador el fin de semana… pero todavía me apaño para dejar una minientrada.

Hemos hablado ya en el pasado de criptografía y de algoritmos de hash e incluso de cómo usarlos en C o en Java así que hoy nos toca verlo desde otro ángulo. A la hora de usar estos algoritmos de resumen en una web, para almacenar una contraseña por ejemplo, nos podemos encontrar con la duda ¿encripto en el lado del servidor o en el del cliente? En fin, en el lado del servidor no tiene mucha ciencia ya que desde PHP 4 existen funciones MD5 y SHA1 de forma nativa. Pero ¿y si queremos hacerlo en el cliente?. Encriptar en el servidor implica que el mensaje viaje en texto plano desde el equipo hasta él. En cambio encriptando en el cliente esta ya saldrá encriptada del equipo.

Podría tirarme el moco y hacerme el pro copiando aquí un chorretón de código enorme, pero realmente os daré dos opciones:

  • PHP.js: Se trata de una librería libre de javascript que aporta a este lenguaje todas (o gran parte) de las existentes para PHP. Podéis descargarla desde la web oficial del proyecto, donde además podréis personalizar la librería eligiendo las funciones que os interesen (coged sólo lo justo, para aligerar la carga).
  • JSHASH: Esta otra , bajo licencia BSD, está en versión beta y se orienta totalmente al uso de  algoritmos de reducción (incluye además de las dos citadas sha256 y sha512). La recomiendan en varios blogs como muy fiable. Podéis descargarla de aquí, donde también hay tutoriales sobre su utilización.

En fin, con esto ya tenéis dos opciones para generar hashes con facilidad y sin romperos mucho la cabeza.

Diseño responsivo con media queries de CSS3

Siguiendo con los artículos de Web Designer wall, continuamos con el tema de las media queries de CSS3, en este caso con otra traducción/explicación de uno de sus artículos.

En este artículo comienza repitiendo lo que ya hablamos en la otra entrada sobre media queries, que el diseño responsivo a día de hoy cobra mayor imortancia por la variedad de resoluciones que pueden usar los usuarios, y que por tanto el aspecto tiene que adaptarse a la ventana. El ejemplo del resultado que se busca conseguir es este.

El conceto, como diría Manquiña (el conceto es el conceto), es el siguiente: La página tiene un contenedor de tamaño fijo (980px) optimizado par una resolución mayor de 1024 px. La media query se utiliza para saber si el tamaño es menor de 980px, en cuyo caso se pasa a un diseño fluido. Y si el caso es que es menor de 650px entonces, directamente se convierte en un diseño con una sola columna.

El marcado HTML es el siguiente, donde se ha creado un contenedor pagewrapper que envuelve cabecera, cuerpo y pie:

<div id="pagewrap">

	<header id="header">

		<hgroup>
			<h1 id="site-logo">Demo</h1>
			<h2 id="site-description">Site Description</h2>
		</hgroup>

		<nav>
			<ul id="main-nav">
				<li><a href="#">Home</a></li>
			</ul>
		</nav>

		<form id="searchform">
			<input type="search">
		</form>

	</header>
	
	<div id="content">

		<article class="post">
			blog post
		</article>

	</div>
	
	<aside id="sidebar">

		<section class="widget">
			 widget
		</section>
						
	</aside>

	<footer id="footer">
		footer
	</footer>
	
</div>

Como hemos comentado miles de veces, el marcado HTML5 no se lleva bien con las veriones de IE anteriores al 9, pero puedes solucionarlo introduciendo esta línea en la cabecera, que enlazan con una librería de javascript que subsanará el problema:

<!--[if lt IE 9]>
	<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

Tras esto toca comenzar con el css, y lo primero es resetar todos los elementos de HTML5 a elementos de bloque:

article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { 
    display: block;
}

Y tras esto toca la estructura principal del css. El contenedor principal ha sido fijado en 980px, el header tiene una altura fija de 160px, el contente un ancho de 600px flotado a la izquierda y el sidebar, flotado a la derecha, de 280px.:

#pagewrap {
	width: 980px;
	margin: 0 auto;
}

#header {
	height: 160px;
}

#content {
	width: 600px;
	float: left;
}

#sidebar {
	width: 280px;
	float: right;
}

#footer {
	clear: both;
}

Todo esto, así de momento, daría lugar a un diseño estático tal que el de esta demo. Ahora toca la parte divertida: CSS3 Media Queries. Como el HTML5, CSS3 tampoco es que furrule muy bien en IE pre-9, así que de nuevo habrá que tirar de una librería de .js para solventar el problema.

<!--[if lt IE 9]>
	<script src="http://css3-mediaqueries-js.googlecode.com/svn/trunk/css3-mediaqueries.js"></script>
<![endif]-->

La idea es hacer un css externo con las media queries, introduciéndolo en el documento tal que así

<link href="media-queries.css" rel="stylesheet" type="text/css">

Luego vendrán las siguientes líneas para cuando la ventana donde visualicemos sea menor de 980px se aplicarán las siguientes reglas:

  • El contenedor principal se resetea al 95%
  • El contenedor de contenido pasa al 60%
  • El contenedor lateral pasa al 30%

El usar el % hace los contenidos fluídos:

@media screen and (max-width: 980px) {

	#pagewrap {
		width: 95%;
	}

	#content {
		width: 60%;
		padding: 3% 4%;
	}

	#sidebar {
		width: 30%;
	}
	#sidebar .widget {
		padding: 8% 7%;
		margin-bottom: 10px;
	}

}

Luego tocará hacer el media query para tamaños menores de 650px, con una única columna:

  • header = resetear la altura a auto
  • searchform = lo mandamos a una posición absoluta, a 5px del borde superior
  • main-nav = se reseta su posición a estatic
  • site-logo = lo mismo
  • site-description = lo mismo también
  • content = devolvemos el ancho a auto
  • sidebar = ponemos el ancho al 100% y quitamos la propiedad de flotado
@media screen and (max-width: 650px) {

	#header {
		height: auto;
	}

	#searchform {
		position: absolute;
		top: 5px;
		right: 0;
	}

	#main-nav {
		position: static;
	}

	#site-logo {
		margin: 15px 100px 5px 0;
		position: static;
	}

	#site-description {
		margin: 0 0 15px;
		position: static;
	}

	#content {
		width: auto;
		float: none;
		margin: 20px 0;
	}

	#sidebar {
		width: 100%;
		float: none;
		margin: 0;
	}

}

Finalmente tenemos la versión para menos de 480px, pensada para el iPhone. Implica evitar el zoom que automáticamente hace Safari sobre el texto y toquetear el menú de navegación principal:

@media screen and (max-width: 480px) {

	html {
		-webkit-text-size-adjust: none;
	}

	#main-nav a {
		font-size: 90%;
		padding: 10px 8px;
	}

}

Ahora toca el truquito para imágenes flexibles, con un pequeño hack para que funcione en IE8 (el width: auto\9; de la línea final):

img {
	max-width: 100%;
	height: auto;
	width: auto\9; /* ie8 */
}

Con los vídeos va igual, menos para Safari, dode max-width no va con vídeos (con fotos sí, extraño). Finalmente, y siguiendo con el iPhone de los huevos, toca metar una meta-tag de escala inicial, ya que el iPhone tiende a modificar las páginas para adaptarlas a la pantalla del dispositivo:

<meta name="viewport" content="width=device-width; initial-scale=1.0">

Y con esto está el tutorial terminado, en el artículo citado podrás encontrar además todo el código y las imágenes de la página de ejemplo. Un placer el haberos traducido esto, y todavía me queda al menos una tercera entrada sobre diseño responsivo. Esta semana creo que la cosa va a andar chunga para conectarme mucho rato, así que igual tarda hasta el viernes o sábado. O igual lo puedo hacer mañana, a saber. En todo caso, un saludo.

CSS3 Media Queries

La verdad es que no hace mucho Web designer Wall me ha salvado el culo en el tema del diseño responsivo (hacer que una web se adapte al tamaño de la ventana). Tras mucho tiempo rompiéndome la cabeza, tirando de jQuery y Javascript con pirulas cosa mala para lograr modificar el tamaño del texto, las posiciones de las imágenes… un coñazo y además ineficiente y poco compatible entre navegadores (menos mal que para móviles jQueryMobile me safaba muchas veces), pues tras mucho tiempo, como te iba diciendo, me encuentro este artículo, que ya tiene un par de años y me quedo como «coño, así es más fácil«. La siguiente explicación es una medio traducción/adaptación/explicación del tema, ya que se que en muchos casos lo que buscáis en este blog es una explicación en castellano de algo que ya hay en inglés. Espero que os sirva de ayuda.

Bueno, empezando desde un principio ¿por qué es importante el diseño responsivo? Porque los tiempos en los que el usuario visualizaba webs en su ordenador, con un rango de pantallas que solía oscilar entre las 14 y las 20 pulgadas en el 90% de los casos, ya pasó, es una reliquia de la década pasada, como MySpace, las PDA’s o que en la liga de fútbol española pueda ganar algo un equipo que no sea Madrid o Barcelona. Ahora te puedes encontrar desde el que usa una tele con una definición de 2560px al que lo ve en su teléfono móvil con una de 320px. Los tamaños fijos son un coñazo, y el usar porcentajes para todo… no siempre funciona, porque el tamaño de la fuente o las imágenes no se adaptan, y a veces hay que usar posicionamientos absolutos y te da la risa. CSS2 permitía diferenciar entre una hoja de estilos para la impresión y otra para la presentación en pantalla. CSS3 nos permite ir más allá, nos permite conocer el tamaño de la ventana/pantalla del dispositivo y aplicar un estilo diferente para cada pantalla. Voy a aprovecharme del artículo antes citado y enlazarte aquí con un ejemplo donde verás cómo funciona esto.

Visto esto, aquí tienes la explicación del cómo se hace, sacada del mismo artículo:

Max Width
En este caso el css se aplicará si trabajamos con una resolución de un máximo de 600 pixeles:

@media screen and (max-width: 600px) {
  .class {
    background: #ccc;
  }
}

Si quieres enlazarlo a una archivo CSS distinto, puedes hacerlo poniendo esta línea en la cabecera del documento:

<link rel="stylesheet" media="screen and (max-width: 600px)" href="small.css" />

Min Width
Al contrario que en el ejemplo de arriba, en este caso se especificará un tamaño mínimo para utilizar este estilo (en este caso, se aplicará a toda las resoluciones mayores de 900px).

@media screen and (min-width: 900px) {
  .class {
    background: #666;
  }
}

Media Queries múltiples
Tienes también la opción de utilizar dos valores a la vez, máximo y mínimo, para que el estilo se aplique a los comprendidos entre esos valores. En este caso, entre 600 y 900 px.

@media screen and (min-width: 600px) and (max-width: 900px) {
  .class {
    background: #333;
  }
}

Max device
Finalmente está la opción de adaptarlo a la máxima resolución del dispositivo. Los ejemplos anteriores hacen referencia al tamaño de la ventana/area de visualización, mientras que este se referiría a la resolución máxima que pueda mostrar el teléfono/ordenador/tableta en cuestión.

@media screen and (max-device-width: 480px) {
  .class {
    background: #000;
  }
}

En el artículo original arriba referenciado podéis encontrar también código para adaptarlo específicamente para iPad y iPhone4. No tiene mucha ciencia, podréis ver los ejemplos de código pinchando allí, además hay páginas de ejemplo al final.

Lo interesante está en uno de los puntos finales, donde comentan que, como siempre, va a haber problemas con Explorer. Bueno, no hay que ser 100% injusto con Microsoft, en principio Explorer 9 va bien, pero en las versiones anteriores la cosa ya no va por ningún lado. Dan varias soluciones, pero yo recomiendo la del plugin de jQuery para hacer furrular las media queries, que está en este ejemplo. Hay varios artículos más sobre diseño responsivo en esta página, así que intentaré próximamente meter un par de estas medio traducciones.

Menú desplegable con jQuery

Write less, es la idea de jQuery. Usando este framework para Javascript puedes lograr resultados vistosos y mejorar la usabilidad de tu web. En este caso vamos a hacer un menú desplegable usando jQuery, que se abra cuando lo «sobrevolemos» con el ratón. Mi primera experiencia con menús desplegables fue en una empresa (no diré cual, no queda bien hablar mal de los jefes) que querían un menú desplegable en la página (era un menú de sólo dos opciones, por lo que no le veía mucho sentido a hacerlo así, pero eran paranoias del jefe).

Lo primero es descargar jQuery desde su página oficial e incluirlo en la cabecera de la página. Luego insertar el marcado html del menú tal que así:

        <ul class="dropdown">  
            <li class="active">Listado: <span>Ejemplos</span></li>  
            <li class="first"><a href="#">Ej 1</a></li>  
            <li><a href="#">Ej 2</a></li>  
            <li><a href="#">Ej 3</a></li>  
            <li class="last"><a href="#">Ej...</a></li>  
        </ul>  

En fin, lo siguiente son los estilos del menú, el css. En el marcado ya dimos a la lista la clase dropdown, lo que nos simplificará mucho ahora el aplicar estilos en el css.

  
ul.dropdown{  
    width: 250px;  
    border: 1px double #000;  
    border-radius: 5px;  
    -moz-border-radius: 5px;  
    -webkit-border-radius: 5px;  
    background: #1a1a1a;  
    margin-top: 2em;  
}  
ul.dropdown li{  
    display: none;  
    font-size: 12px;  
}  
ul.dropdown li.active{  
    display: block;  
    color: #8c8c8c;  
    font-size: 14px;  
    padding: 12px;  
    color: #555;  
    border-top: 1px solid #313131;  
    border-radius: 4px;  
    -moz-border-radius: 4px;  
    -webkit-border-radius: 4px;  
}  
ul.dropdown li.active span{  
    padding-right: 24px;  
    color: #8c8c8c;  
}  
ul.dropdown li a{  
    display: block;  
    text-decoration: none;  
    padding: 8px 8px 8px 10px;  
    background: #1e1e1e;  
    border-bottom: 1px solid #171717;  
}  
ul.dropdown li.last a{  
    border:0;  
}  
ul.dropdown li.first a{  
    border-top: 3px solid #131313;  
}  
ul.dropdown li a:hover{  
    background: #232323;  
    color: #fff;  
    padding-left: 11px;  
}  

Marcado listo, estilos listos. Falta sólo la funcionalidad, el código javascript que haga furrular todo esto. De momento toda la lista está oculta menos el elemento de la clase active, por lo que tenemos que hacer que se muestre el resto cuando pasemos el ratón por encima, desaparezca cuando lo saquemos y además sea un código reutilizable. Aquí tenemos el procedimiento:


//variable global para almacenar el menú 
var menu = $("ul.dropdown");  
  
//captura de eventos  
$(this.document).ready(function(){  
    menu.mouseover(function(){  
        mostrar($(this).find("li"));  
    });  
    menu.mouseout(function(){  
        ocultar($(this));  
    });  
})  
  
//función que muestra los elementos del menú  
function mostrar(e){  
    e.show();  
}  
//función que los oculta
function ocultar(e){  
    e.find("li").hide();  
    e.find("li.active").show();  
}  

Y con esto ya tienes un menú desplegable chulo chulo que poner en tu web.

Ejemplos varios de canvas (html5)

Canvas es, probablemente, el elemento más potente de HTML5. Mayormente nos da una funcionalidad similar a las animaciones flash en una parte de la pantalla, pero utilizando javascript. En principio es para un contexto 2D pero ya hay una librería (three.js) que te permite utilizar gráficos 3D (de momento no soportada por todos los navegadores). En los primeros manuales de HTML5 que cayeron en mis manos este elemento venía muy mal explicado, te decían que se podía «dibujar» usando javascript… y ale, vía.

Para utilizar canvas en tu web debes incluir una etiqueta canvas, que por defecto será invisible y tendrá un tamaño de 300*150 px. Luego, en javascript, debes inicializar un contexto tal que así:

var ctx = document.querySelector('canvas').getContext('2d');

Tras haber definido un contexto bidimensional, podemos empezar a dibujar. El API da la posibilidad de utilizar rectángulos, arcos, círculos… El siguiente código dibujaría un rectángulo, con un reborde más oscuro:

ctx.fillStyle='rgb(0, 255, 0)';
ctx.fillRect(10,20,50,50);
ctx.strokeStyle='rgb(0,182,0)'
ctx.lineWidth=5;
ctx.strokeRect(9,19,52,52);

En fin, esto es lo más básico, pero tienes múltiples opciones: degradados, imágenes complejas, animaciones, interactividad… En lugar de currarme un tutorial más complejo te remito a varios enlaces para que veas la pontencia de Canvas:

Bueno, con estos ejemplos ya puedes ver más o menos la potencia de este elemento y tener varios tutoriales para iniciarte en la creación de aplicaciones con canvas.

Formularios HTML5 con jQueryMobile

Tras la iniciación a la maquetación con jQueryMobile que publiqué ayer, toca complementarla con una introducción a los formularios.

Como es habitual en todo formulario HTML, los campos estarán encerrados entre etiquetas form, con su action y su method definidos. Existen varios tipos de controles, que son mas que suficientes para poder crear formularios complejos, que puedes consultar aquí.

Una de las opciones que nos reporta jQueryMobile es la de poder crear formularios «mini», con una versión más pequeña de sus controles para facilitar la visualización en las pantallas de los móviles. Para ello debemos añadir el atributo data-mini=”true” en el controlgroup.

El atributo placeholder (del que también hablamos en este blog) juega un papel importante aquí. Si quieres ocultar la etiqueta label por motivos de accesibilidad pero que los lectores de pantalla puedan leerla, podras servirte de la clase ui-hidden-accessible y, con el atributo placeholder, usar el elemento de formulario con la etiqueta dentro.

Para deshabilitar un elemento del formulario usaremos el atributo disabled. En el caso de que necesitemos aplicar el estilo disabled a un elemento que no sea un control de formulario, podemos utilizar la clase ui-disabled sobre el elemento.

Ahora un ejemplo de un formulario con las etiquetas como placeholder y controles mini, para ilustrar lo explicado.

<form action="procesar.php" method="post" id="formEjemplo">
    <div data-role="fieldcontain">
        <fieldset data-role="controlgroup" data-mini="true">
            <legend>Login ejemplo:</legend>
            <label for="user" class="ui-hidden-accessible">Usero:</label>
            <input type="text" name="user" id="user" value="" placeholder="User" />
            <label for="password" class="ui-hidden-accessible">Usuario:</label>
            <input type="password" name="password" id="password" value="" placeholder="password" />
        </fieldset>
    </div>
</form>

Si usas un contenedor para controles de formularios (que es un elemento de jQueryMobile) y quieres ocultar la etiqueta y usar el texto placeholder, tienes que ocultarla en los atributos del div con class=»ui-hide-label» en lugar de en los del label, como en este ejemplo:

<div data-role="fieldcontain" class="ui-hide-label">
    <label for="user">Usero:</label>
    <input type="text" name="user" id="user" value="" placeholder="User" />
</div>

Y con esto ya puedes empezar a hacer tus formularios optimizados para móviles.