Crear una tabla HTML con cabecera fija, usando CSS3

Si bien los elementos table suenan a cosa del pasado, a aquellos tiempos en los que todo se hacía con tablas y de vez en cuando algo de flash o similar, todavía siguen utilizándose tablas en el mundo de la programación y diseño web, ya no como elemento central y básico de la maquetación, pero sí para por ejemplo presentar datos en ese formato de filas/columnas.

Si tenemos una tabla muy larga la solución tradicional ha sido siempre la paginación, que con el tiempo fue sustituída por elementos que van insertando nuevas filas de forma asíncrona mientras hacemos scroll. En estos casos puede pasar que hayamos bajado mucho, la cabecera ya no esté visible y no tengamos muy claro a qué corresponde cada columna. Una solución podría ser repetir la cabecera cada x filas, pero se puede hacer visualmente incómodo. Otra posibilidad es hacer fijas estas cabeceras de forma que siempre estén visibles en pantalla y bajen mientras hacemos scroll.

Parece que lo lo lógico sería que pudiésemos hacer fijos los elementos thead o tr, ya que queremos que toda la línea quede fijada, pero aunque nos parezca lo elemental no será posible. Para fijar un elemento de esta forma tenemos que ponerle position:relative y esta característica no se aplica a esos elementos, esto implica que tendremos que usarlo obligatoriamente sobre las celdas, sobre los elementos th o td.

Supongamos que tenemos una tabla como esta (bueno, con cientos de registros para que tenga sentido la cabecera fija):

<table>
  <thead>
    <tr>
       <th>Nombre</th>
       <th>Edad</th>
       <th>Salario</th>
       <th>Rango</th>
       <th>Area</th>
     </tr>
    </thead>
   <tbody>
    <tr>
       <td>Manuela Z.</td>
       <td>43</td>
       <td>24000</td>
       <td>Analista</td>
       <td>Big Data</td>
     </tr>
  </tbody>
</table>

Si queremos fijar la cabecera el CSS, lo más básico posible, sería tal que así:

table {
  position: relative;
  border-collapse: collapse; 
}
th, td {
  padding: 6%;
}

th {  
  position: sticky;
  top: 0; 
}

Hay tres puntos clave en ese CSS: el position:relative de la tabla, el position:sticky del elemento th y la posición top:0 también del elemento th. De esta forma le decimos que todas las celdas de la cabecera se queden fijas en la parte superior de la tabla, así al bajar el scroll estas bajarán con él.

Añadir un PDF a un sitio web usando una etiqueta de HTML5

Existen varias formas de insertar un PDF dentro de un sitio web, una de ellas es usar alguna de estas etiquetas:

  • embed
  • object
  • iframe

Antaño solo teníamos la opción de usar la etiqueta iframe, dado que embed y object se añadieron para la especificación HTML5. En todo caso el procedimiento con las tres es el mismo: ponemos la URL del fichero PDF como valor del atributo src y definimos el tamaño mediante los atributos width y height:

<!--Ejemplos varios-->
<iframe src="http://rutaamipdf/fichero.pdf" width="95%" height="100%"></iframe>

<embed src="http://rutaamipdf/fichero.pdf" width="95%" height="100%"></embed>

<object src="http://rutaamipdf/fichero.pdf" width="95%" height="100%"></object>

¿Problemas? Pues sí, que con este método dependemos de que el navegador que está usando el usuario tenga incorporado algún visualizador de PDF. En algunos casos tiene que ser mediante un plugin externo, como en Chrome, en otros ya viene incluído por defecto en el propio navegador.

Creando una tabla con los bordes redondos con CSS3

¿Cómo puede redondear los bordes de una tabla con CSS? Ponerle bordes al objeto table o al tr no va a funcionar, hay que hacerlo sobre el primer o el último td de la fila.

table { border-collapse: separate; }
td { border: solid 1px #000; }
/*PARA LA PRIMERA FILA TIENES DOS OPCIONES*/
/*Así sería la cosa
si has empezado con un tr
*/
tr:first-child td:first-child { border-top-left-radius: 10px; }
tr:first-child td:last-child { border-top-right-radius: 10px; }
tr:first-child td:only-child { border-top-right-radius: 10px;
border-top-left-radius: 10px; }
/*si en lugar de eso has usado la etiquetas thead y th es más
sencillo todavía*/
th:first-child { border-top-left-radius: 10px; }
th:last-child { border-top-right-radius: 10px; }
th:only-child { border-top-right-radius: 10px;
border-top-left-radius: 10px; }

/*Y ASÍ PONEMOS EL PIE*/
tr:last-child td:first-child { border-bottom-left-radius: 10px; }
tr:last-child td:last-child { border-bottom-right-radius: 10px; }
tr:last-child td:only-child { border-bottom-right-radius: 10px;border-bottom-left-radius: 10px; }

Centrando verticalmente elementos de bloque en CSS

Si bien centrar elementos horizontalmente no suele suponer un problema cuando trabajamos con CSS, el hacerlo verticalmente es mucho más puñetero. Desde que se jubilaron las engorrosas tablas, que todo hay que decirlo para el tema del centrado eran bastante cómodas, son muchos los que llevan buscando una solución. Con los elementos inline la cosa no es tan pesada, pero con los elementos de bloque puede tonarse desquiciante.

Si trabajamos con navegadores modernos, con total soporte de CSS3, la solución nos llega de la mano de Flexbox con unas pocas líneas. Basta con definir la alineación usando esta propiedad en el elemento contenedor como podéis ver en este fiddle:

.contenedor {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

Con flexbox la alineación vertical es tan simple como en las viejas tablas. Pero ¿y si no podemos contar con flexbox?… el horror, el horror… Bueno, no tanto, también hay una solución. En este caso lo primero será definir la posición del contenedor como relativa, y el elemento a centrar de forma absoluta, situado en la mitad de la altura del padre y a su vez desplazando su eje Y otro 50% (suena más rollo de lo que es, la idea es poner el borde superior en la mitad del contenedor y luego desplazarlo la mitad de su propia altura de forma que el centro del elemento queda en el centro del contenedor, viendo el código a continuación se entiende, y podéis ver el resultado en un fiddle)

.contenerdor {
  position: relative;
}
.elementoACentrar {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}

Listo, dos métodos para alinear verticalmente un elemento de bloque en CSS que te pueden ahorrar mucho tiempo.

Cinco generadores de Lorem Ipsum muy curiosos

Todo el que esté en los mundillos de la programación o el diseño sabe lo que es el lorem ipsum, un texto de prueba de impresión que se supone que procede del siglo XVI. Pululando por la red hay muchos generadores de texto aleatorio curiosos y divertidos y aquí me he decidido a recopilar los cinco mejores (bueno, realmente son los cinco que más gracia me han hecho):

  • Cthuvian Ipsum Generator: Para fanáticos de H.P. Lovecraft y su saga de Cthulhu, este generador os dará unas líneas que os acercarán a las simas de la locura primigenia.
  • Zombie Ipsum: Para los amantes de los no muertos también hay un generador cargado de referencias al género zombie, tanto al cine como a la televisión o los comics.
  • Doctor Ipsum: El Doctor Who también tiene un generador, en este caso además nos permitirá elegir qué encarnación del personaje queremos que hable.
  • Samuel L. Ipsum: El más badass de los generadores, homenajeando a grandes personajes de Samuel L. Jackson. No es muy variado, la verdad, pero tiene su gracia
  • Trollem Ipsum: Elige entre fanboy de Apple, Microsoft, Blackberry o de Android y consigue un texto con sus tópicos «argumentos» fanáticos. Ojo, saca textos cortitos.

En su momento había encontrado un Dalek Generator perfecto para aquellos enganchados al Dr. Who, pero parece que han retirado la web, que antes estaba alojada en esta dirección. Una pena, porque era claramente top. Había originalmente también un generador de conversaciones aleatorias de El Gran Lebowski pero al repasar el artículo me encontré con que ya no existía.

En fin, ahí os queda esta pequeña lista de recursos, para hacer los prototipados un poco menos tediosos.

Instalando Google Web Designer en Linux

Hará cosa de un año Google nos sorprendió con una herramienta de diseño web en fase beta: Google Web Designer. Un editor WYSIWYG muy potente, gratuito (al menos de momento), orientado hacia diseñadores, pensado para sacar todo el jugo de HTML5 y CSS3 (diseño responsivo, animaciones, aceleración 3D) y a su vez ser sencillo. Y, al igual que hicieron con Google Drive, se olvidaron de los usuarios de Linux.

Google-Web-Designer

Lo curioso es que se preguntó al director de proyecto alguna vez que qué pasaba con los Linuxeros y la respuesta fue más sorprendente: sí existía una versión para linux que además se usaba internamente en la empresa, pero tenía diferencias respecto a la que salió para Mac y Windows, por lo que no la sacaban. Al final, tras mucha presión por la comunidad, anunciaron que sí sacarían la versión para Linux.

Y ya la tenemos.

¿Cómo la instalamos? Sencillo: Vamos a la web del proyecto y desde allí descargamos el archivo .deb que mejor vaya con la distribución de Linux con la que trabajemos, lo ejecutamos con nuestro instalador de paquetes y… listo. Ya está, todo muy fácil… ¿o no?

Pues voy a ser jodón, pero no. Si fuera tan fácil no haría una entrada en el blog. Resulta que de momento hay un bug con la carga del idioma, si vuestro sistema no está en inglés Google Web Designer sólo muestra una ventana negra y no carga, no funciona. Por suerte por los foros oficiales ya existe una solución, que os obligará a tirar de consola (hasta que no salga una actualización/parche al menos)

#Lo primero es cargarnos la configuración por defecto tecleando:
sudo rm -r .local/share/google-web-designer

#y ya podemos lanzar web designer desde la consola, forzando que lo haga en inglés, con el siguiente comando
LANGUAGE=en_US google-webdesigner

Ahora sí, con esto ya tenéis funcionando Google Web Designer en vuestro equipo con Linux. Esperemos que dentro de poco la gente de Mountain View se apure a sacar o traducciones o al menos un parche que evite este molesto bug.

Meta etiquetas de Apple para hacer que una web parezca un app para iPhone o iPad

Aunque ya sabéis que le tengo alergia a los iCacharros, y sobre todo a sus fanáticos seguidores, hay que reconocer que Apple de vez en cuando saca cosillas interesantes. Una de ellas es la meta etiqueta viewport de la que ya hablamos en el pasado, pero no es la única meta equita que se sacó de la manga Apple para el diseño web móvil. Y es que dando uso a sus etiquetas podemos hacer que una web aparezca en pantalla como si fuera un app nativa, que se le pueda hacer un acceso directo desde el menú de aplicacione con un icono… todo esto mediante una serie de etiquetas.

Para conseguir que al abrir la web esta se vea sin ningún marco del navegador en pantalla hay que usar la siguiente etiqueta en la cabecera de la web, gracias a la cual lograremos ese aspecto app-like:

<meta name="apple-mobile-web-app-capable" content="yes" />

Sigamos ¿cómo escogemos un icono? Bueno, realmente necesitamos dos iconos, uno para la versión normal y otro para la versión con pantalla de alta densidad (o como reza su nombre comercial «retina display«). El primero ha de ser de 57*57px y la siguiente de 114*114px, la propiedad href apuntará a donde tengáis guardada la imagen:

<link rel="apple-touch-icon" href="img/icons/icono5757.png">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="img/icons/icono114114.png">

Es posible que al abrir la web/app os salga durante unos segundos una imagen en blanco mientras esta carga (muy posible), algo que queda «feo» pero que tiene también solución: podéis definir una imagen que se muestre durante esta carga, una startup-image:

<link rel="apple-touch-startup-image" href="img/loading.png">

Y finalmente, existe una posibilidad de modificar mínimamente la barra de estado de Apple en la parte superior. No es que tengáis mucho con lo que jugar, no es que haya mucha opción, pero algo se puede ir apañando, pudiendo elegir entre el color por defecto, el negro o un efecto traslúcido.

<!--Por defecto-->
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<!--negro-->
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<!--traslúcido-->
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">

Y con estas opciones podréis hacer que vuestra web parezca un app para dispositivos Apple. La he probado en el curro (web PHP+Javascript) en un proyecto y el resultado fue satisfactorio. La pena es que no haya algo así para Windows Phone y Android.

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.

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.

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.