sábado, 27 de julio de 2013

Bootstrap 3 y el marcado semántico

Probablemente estés ya hasta las narices de Bootstrap. Artículos y artículos, herramientas que lo usan o generan código compatible, y lo peor de todo... muchas webs con lo que yo llamo "pestuzo Bootstrap", que no se molestan casi ni en cambiar el estilo que trae por defecto, así que son todas igualicas. Por otra parte, también es posible que no lo hayas usado jamás e incluso que ni sepas lo que es.

Acaba de salir la primera release candidate de la versión 3 de Bootstrap, una versión que imagino que puede ser polémica (igual es por eso que la han sacado un Sábado veraniego casi de Agosto), así que aprovecho la ocasión para escribir este artículo. Empezaré contando qué es Bootstrap y qué tiene de bueno, sobre todo para los que no lo conozcáis aún (¿en qué cueva os habéis metido?). Incidiré en cosas que no me gustaron de su planteamiento general, especialmente contaré cómo se puede ir más allá y mejorar la separación entre contenido y presentación, haciendo nuestro código más semántico. Finalmente, aprovecharé que llevo varias semanas usando Bootstrap 3 para contar qué puedes esperar de esta versión y por qué tiene algunos cambios realmente interesantes para el futuro, junto a otros frustrantes para los que ya estaban usando la versión 2.

¿Por qué Bootstrap?

No hay nada que haga a uno sentirse más como un perro apaleado que programar el front de una web. Desde los primeros años de la web, se ha maltratado sistemáticamente todo lo que tenía que ver con su programación, casi siempre por motivos comerciales. Primero la guerra entre Microsoft y Netscape hizo que cada uno usara el JavaScript que le daba la gana. Luego la guerra entre Microsoft y... el resto del mundo, hizo... que en general Micro$oft interpretara cualquier posible estándar de la web como le diera la gana. Programar JavaScript y CSS significaba, básicamente, perder días y días pegándose en dura batalla con los navegadores, fundamentalmente con todas y cada una de las versiones de IE, ya que era con diferencia el navegador más utilizado y encima ninguna versión era igual a la anterior (ni tampoco se acogía a los estándares).

de html5code.com
Perdón, ¿estoy hablando en pasado?. Me temo que eso aún no ha acabado. Internet Explorer 8, aún uno de los navegadores más usados, sigue haciendo lo que le da la gana con muchas cosas. No he probado aún lo suficiente IE9 para saber si también es así, aunque algo he oído de que avanza bastante respecto a las versiones anteriores en cuanto a su estandarización pero todavía no acaba de cuajar. ¿Quizá IE10?.

Los estándares intentan moverse, modernizarse. No es normal que después de tanta guerra estemos casi en el mismo punto que hace 20 años. Se crea HTML5, sí... y después de varios años, todavía es una "candidate recommendation" y cada navegador implementa las partes que quiere. CSS3... más o menos lo mismo, con la coña de que tiene partes aprobadas y otras que aún no.

El precio de todo esto es enorme. Hacer una aplicación web es muchísimo más costoso de lo que debería, y la web avanza mucho más lentamente de lo que sería normal.

Como ocurre a menudo, las soluciones las ha ido proporcionando la propia comunidad. No necesitamos estándares de iure, tengamos estándares de facto. Así, especialmente en el campo del JavaScript fueron surgiendo librerías que encapsulaban las diferencias entre los navegadores, fundamentalmente en el acceso a DOM: MooTools, Prototype... y sobre todo la que finalmente parece que se alzó como la ganadora, jQuery.

Sin embargo, la revolución real está ocurriendo ahora mismo. En cuestión de estos últimos meses. En estos momentos, Internet Explorer ya no es el rey, y está en un declive cada vez mayor. Y ahora están saliendo productos que crean una capa por encima de HTML-CSS-JavaScript. Productos con una pinta estupenda, y que facilitan la programación del front. Entre ellos, seguramente el más popular ahora mismo sea Bootstrap.

Primera impresión

La primera impresión es muy buena. Bootstrap utiliza un curioso sistema para facilitar muchísimo el diseño de la web. Lo que predica es lo siguiente: utiliza HTML5 estándar para hacer la web, y coloca estratégicamente determinados "class" en cada elemento para conseguir:
  • Un sencillo pero potente sistema de layout, basado en filas y columnas.
  • Varios componentes prediseñados. Algunos de ellos, con código JavaScript listo para hacer que esos componentes sean dinámicos, sin que tengas que hacer nada de primeras. Así tendremos botones, pestañas, menús con varios niveles, componentes de paginación... un gran número de elementos que HTML no incorpora, pero que se utilizan habitualmente como interfaz de usuario en muchas webs.
Este es un ejemplo de código HTML (de Bootstrap 2). Obsérvense los distintos class que tiene:

<div class="container">
   <!-- Main hero unit for a primary marketing message or call to action -->
   <div class="hero-unit">
     <h1>Hello, world!</h1>
     <p>This is a template for a simple marketing or informational website. It includes a large callout called the hero unit and three supporting pieces of content. Use it as a starting point to create something more unique.</p>
     <p><a href="#" class="btn btn-primary btn-large">Learn more »</a></p>
   </div>

   <!-- Example row of columns -->
   <div class="row">
     <div class="span4">
       <h2>Heading</h2>
       <p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p>
       <p><a class="btn" href="#">View details »</a></p>
     </div>
     <div class="span4">
       <h2>Heading</h2>
       <p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p>
       <p><a class="btn" href="#">View details »</a></p>
    </div>
     <div class="span4">
       <h2>Heading</h2>
       <p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
       <p><a class="btn" href="#">View details »</a></p>
     </div>
   </div>
</div> <!-- /container -->

Hacer una web con este sistema es realmente fácil, y aunque no toques apenas nada la web ya te quedará con una pinta bastante decente.

La distribución "normal" de Bootstrap trae un fichero .js y un fichero .css. Para personalizar los estilos, se supone que hay que añadir más reglas CSS, o al menos eso es a lo que parece que te invita.

Sin embargo, aunque esta es la forma de programar que propone Bootstrap, lo cierto es que no nos deberíamos conformar con eso. Eso sí, me gustaría recalcar que es una forma muy interesante y rápida por ejemplo para crear prototipos de una web. Pero si estamos haciendo algo serio podemos exigir más.

Personalizando con LESS

Modificar directamente el CSS tiene un problema, y es que estamos perdiendo una de las ventajas más importantes que realmente tiene Bootstrap, y es que está hecho en LESS. De hecho, Bootstrap se puede considerar una librería de LESS unida a otra de JavaScript.

LESS es un lenguaje que se construye sobre CSS, añadiendo características muy cómodas, fundamentalmente:

  • Anidamiento de reglas, que mejora mucho la legibilidad y te facilita el que haya un orden dentro del fichero (los ficheros CSS tienden naturalmente al caos más absoluto)
  • Variables: puedes meter valores comunes como colores, tamaños de padding, etc. en variables, y utilizarlas luego en otras reglas
  • Funciones y operaciones: también puedes crear valores que resulten de aplicar una operación sobre otro valor, como por ejemplo poner un color que sea un 20% más oscuro que otro (el cual puede estar, por ejemplo, en una variable).
  • Mixins: esto es lo más importante que aporta LESS. Los mixins son conjuntos de reglas que puedes usar en distintos sitios. Es decir, permite crear componentes reutilizables de CSS.

La librería LESS de Bootstrap está en general bien diseñada. Hay un fichero "variables.less" que tiene un montón de variables con las que se pueden controlar y personalizar muchísimos aspectos de la presentación por defecto: colores, fuentes, espaciados de márgenes y paddings... Otro fichero, "mixins.less" contiene un montón de mixins muy útiles de propósito general.

El resto de ficheros .less están dedicados a componentes o partes específicas: botones, tablas, barras de navegación, etc. En ellos se encuentran los estilos por defecto para todos estos tipos de elementos, junto a opciones de presentación de cada uno según sus clases.

Imagino que Bootstrap no incluye los ficheros LESS en la distribución normal porque intenta facilitar al máximo el que cualquiera pueda usarlo. Es decir, trata a los usuarios como idiotas. En mi opinión esta es un arma de doble filo, porque lo que está consiguiendo con ello es que mucha gente personalice muy poco lo que viene por defecto, consiguiendo así el efecto "pestuzo Bootstrap" que hay en tantas y tantas webs, y que comentaba al principio del artículo.

Créeme, trabaja directamente utilizando los ficheros .less, y creando otros less propios que redefinan las variables y pongan tus estilos. Es mucho más cómodo y a la vez mucho más potente (salvo que seas un idiota, claro).

Marcado semántico en Bootstrap

Hace muchos, muchos años, en una galaxia muy, muy lejana, el layout de las páginas se definía directamente dentro del propio HTML usando tablas. Entonces surgió la creación de layouts con CSS, la que se ha venido usando desde entonces. Lo cierto es que esta forma de crear los layouts era un coñazo integral porque cada versión de Internet Explorer interpretaba (y sigue interpretando) las propiedades CSS, y especialmente las que permiten formar layouts, como le daba la gana. A pesar de esto acabó triunfando, y una de las grandes ventajas que defendía el layout por CSS es que gracias a él se podía separar el contenido, la información que queremos mostrar, de la presentación de ese contenido. Se trataba de hacer marcado semántico, dentro de lo posible.

de coding.smashingmagazine.com
¿Cuál es el problema de la forma de hacer layouts que propone Bootstrap?. Pues precisamente esto, que volvemos a mezclar dentro del HTML el layout de la página con el contenido, aunque sea en forma de .class. Pues para eso volvemos a las tablas, ¿no?...

Es prácticamente imposible que el contenido de tu página sea semántico puro y no piense un poco en el layout. Ahí están los div, que sobre todo sirven para agrupar cosas que imaginas que pondrás luego juntas en el layout. Pero sí pienso que es bueno intentar separarlo lo máximo posible.

En mi caso es fundamental esta separación. Trabajo en un producto reutilizable, que se instala en varios clientes y que en cada uno puede cambiar la presentación. Tengo que intentar evitar al máximo el que tenga que modificar el HTML cuando lo único que necesite sea cambiar aspectos de presentación. Aparte de eso, aunque tu producto no sea reutilizable, pienso que en general es una buena práctica.

¿Entonces?. ¿Pasamos de Bootstrap?. No es necesario. Como ya he comentado antes, BS está basado en LESS. Y esa precisamente va a ser la solución.

Al principio descargué la última versión oficial de BS, la 2.3.2. Algunos de los class de Bootstrap se pueden considerar realmente semánticos: este div va a ser una barra de menú, o un elemento de paginación... Pero otros son claramente de presentación, como por ejemplo si un botón va a ser grande o pequeño, o si una barra de botones se va a poner alineada a la izquierda o a la derecha.

En seguida me di cuenta de que para la mayor parte de los casos, no era realmente necesario poner los class dentro del HTML, aprovechando las capacidades de LESS. Así, por ejemplo, si quiero que los botones de un formulario sean pequeños, no necesito poner el HTML así:

<form class="form-login">
   (...)
   <button type="button" class="btn btn-small">Ver cambios</button>
</form>


sino que puedo hacer esto otro:

<form class="form-login">
   (...)
   <button type="button" class="btn">Ver cambios</button>
</form>


y luego en el .less:

.form-login {
   .btn {
      .btn-small;
   }
}

Alegría, saltos, fiesta... pero espera... esto no ocurre para todos los casos. O mejor dicho, había un caso fundamental en el que esto no funcionaba: precisamente, el sistema de grid para el layout.

Escondidos entre los .less de Bootstrap encontré unos mixins que me podían ayudar: makeRow y makeColumn. Sin embargo, no funcionaban bien. No era lo mismo poner los class que usar estos mixins. Mi gozo en un pozo.

Cuando estaba pensando alternativas, encontré que estaba en desarrollo una versión 3. Miro los cambios y ¡bingo!, han cambiado enterito el sistema de grid. Ahora el sistema de grid es mobile-first, y no diferencia entre "filas fluid y no fluid", todas son fluidas. También han cambiado el nombre de los class.

Vuelvo a hacer la prueba y, esta vez sí, compruebo que funciona. Esto es un ejemplo de un grid en Bootstrap hecho con marcado semántico:

<div class="wrapper">
  <div class="content-main">...</div>
  <div class="content-secondary">...</div>
</div>

Y su LESS:
.wrapper {
  .make-row();
}
.content-main {
  .make-column(8);
}
.content-secondary {
  .make-column(3);
  .make-column-offset(1);
}

De hecho, aunque hasta hace poco no estaba y yo tuve que llegar a ello a base de hacer arqueología en el código, estos mixins y la forma de usarlos ya aparecen dentro de la propia documentación del sistema de grid (bueno, a mi me ha servido para copiar el ejemplo...).

No sólo esto, sino que la librería LESS está realmente mejor diseñada. No es sólo el sistema de grids, en general todos los componentes están mucho más basados en mixins, es mucho más fácil hacer marcado semántico ahora que en la versión 2.

Así que sí, querido lector, te lo puedo decir: se puede hacer marcado semántico con Bootstrap.

Bootstrap 3: qué más me voy a encontrar

Si ya eras usuario de Bootstrap 2, tengo una noticia realmente mala para ti: no es sólo que tu código anterior no sea compatible. Es que ha cambiado un montón, muchas veces en cosas muy pequeñas.

Lo primero que te vas a encontrar es que ha cambiado el aspecto por defecto. El diseño actual pretende ser más "aséptico", menos intrusivo. Los botones y otros elementos no tienen detalles como gradientes, es un diseño más plano, más "metro". Esto es fácil de ver, basta conque vayas a la página principal de Bootstrap, porque lo que se está mostrando ahí ya es la versión 3.

Lo segundo que te vas a encontrar es que han cambiado el nombre de un montón de clases y variables. La intención es hacer los nombres más homogéneos, y en verdad lo han conseguido. Pero olvídate de que tu código funcione con ellos, claro. Los más obvios son los del sistema de layout, cuando antes se ponían las columnas con elementos como "span3" y las filas muchas veces con "row-fluid", ahora hay que utilizar cosas como "col-3" o "col-lg-3", y las filas van siempre con "row". Pero hay que decir que no se han cortado nada, han cambiado muchísimos nombres.

En cuanto a los formularios, ahora los componentes ocupan por defecto el 100% del ancho disponible, y han cambiado por completo la forma de agrupar campos.

de soyouwanna.com
Los iconos también se han rediseñado por completo, ahora se dibujan con una fuente (es decir, son glyphicons). Bueno, y han cambiado los nombres de los class, claro.

Han desaparecido muchas opciones de presentación de los distintos elementos, muchos "-inverse" por ejemplo, y muchas formas de agrupar tipos de elementos. También han desaparecido elementos enteritos, como los thumbnails. A cambio, aparecen otros nuevos como los panels y los list groups.

Si además pretendes que tu código sea compatible con IE7 o Firefox 3.6, ni intentes actualizarte: BS3 ha dejado de ser compatible con ellos.

Pero bueno, lo mejor es que chequees tú mismo la gran lista oficial de cambios realizados para la versión 3.

Habrá que ver a partir de ahora qué harán todas esas webs que generan código Bootstrap de forma gráfica, o que venden temas ya prediseñados, y que al fin y al cabo pueden considerarse una de las ventajas de usar Bootstrap: su popularidad. ¿Se actualizarán?, ¿no se actualizarán?, ¿se mantendrán compatibles con las dos versiones? (posiblemente la mejor opción). Algunas de ellas son estas:


En definitiva, si eras usuario de Bootstrap 2, actualizar tu HTML a BS3 no será nada sencillo. A pesar de eso, opino que los cambios en general son para mejor, la librería está mejor organizada, es mucho más fácil hacer HTML más semántico, los nombres son más homogéneos, y se han eliminado muchas opciones que eran quizá demasiado intrusivas.

Aunque bah! la verdad es que todo eso me importa un pimiento. Como no llegué a usar nunca la versión 2, lo único que realmente quería es que me dejara hacer marcado semántico, y ahora... ¡se puede!.

12 comentarios:

  1. Hola Andrés. Soy diseñador gráfico con nivel básico-medio de frontend. Voy a empezar una web y me había decidido ha usar por primera vez, un framework y un prepocesador. Después de mucho leer, me había decidio por 320andup que es mobile-first y permite Less, pero resulta que hoy va y sacan Bootstrap 3, que te voy a contar. Nunca he usado un framework pero gracias al imparable Jesús con su curso gratuito intensivo (http://www.youtube.com/watch?v=Ybsv0BSdP64) me veo capaz a montarlo en Bootstrap y luego ajustar el diseño al gusto.

    Ante la nueva versión me asalta un duda ¿Puedo empezar el proyecto con la 2.3.2 estable y cuando salga la 3 final cambiar los .js? ¿o empiezo directamente con la 3 RC1? ¿cuando salga la final podré actualizar los .js y listo o no es tan fácil?

    Muchas gracias.

    Saludos,
    David

    ResponderEliminar
    Respuestas
    1. Hola, David.

      De 320andup no te puedo hablar, no la conozco. Es posible que Bootstrap no sea el mejor framework de este estilo, se habla también muy bien de Foundation, por ejemplo. Pero BS es el más popular, y eso da puntos, y dudo que los que sean mejor que él sean mucho mejores.

      En cuanto a tu pregunta, yo iría directamente a la versión 3 RC1. Yo llevo más de un mes usando versiones 3 nightly, anteriores a la RC1, y en general me han funcionado bastante bien. Cuando salga la final no creo que haya que cambiar gran cosa, seguramente sólo actualizando los less y js te siga funcionando todo. Sin embargo, si empiezas con la 2 vas a tener que rehacer luego todo, y en tu cabeza vas a tener un lío entre las cosas que tiene la 2 y las que tiene la 3, y los nombres distintos que les ponen a lo mismo. Yo creo que estás en el momento ideal para empezar con la 3.

      Ah, también te aconsejo que te empapes bien en LESS y todas sus posibilidades. Puede marcar la diferencia entre hacer "código que funciona" o "código bien hecho".

      Un saludo!

      Eliminar
  2. Excelente artículo. Mil disculpas Andrés, ahora que he terminado de leer todo el artículo veo que la respuesta a mi primera pregunta estaba en el mismo.

    Pero ahora me pregunto, si esta RC1 viene sin los archivos less entiendo que vendrán en la versión final pero ¿y mientras? entiendo que los anteriores que sí tengo de la 2.3.2 no sirven por los grandes cambios en el marcado.

    Si empiezo el proyecto con la 3 pierdo toda la ventaja de less si edito directamente el CSS.

    ¿Alguna sugerencia?

    Muchas gracias por todo.

    ResponderEliminar
    Respuestas
    1. Puedes descargar directamente los fuentes del github:

      https://github.com/twbs/bootstrap/tree/3.0.0-wip

      A la derecha verás un botón en el que pone "Download ZIP", ahí va todo.

      (por cierto, no estoy muy seguro que la distribución de la versión 2 incluya los LESS, me suena que tampoco... cosas tontas de los autores)

      Eliminar
    2. Ahhh, ahora sí que viene todo. En la página oficial se descarga un archivo bs-v3.0.0-rc1-dist.zip que sólo contiene los js y css. Esa versión wip de github sí que tiene todo.

      Voy a dormir que mañana me toca mucho Less para empezar con buen pie!

      Mil gracias de nuevo! Feliz noche y que disfrutes lo que queda de fin de semana.

      David

      Eliminar
  3. hola una consulta estoy utilizando bst3 pero como hago para que tanto el footr y el encabesado in cluido el menu se mantenga para todas las paginas en dreanwevaer se usa plantillas region editables en bootstrapa como se hace

    ResponderEliminar
    Respuestas
    1. Hola, anónimo. Bootstrap no genera ni gestiona HTML, sólo es una librería de LESS/CSS y Javascript, para lo que quieres tendrías que complementarlo con alguna otra tecnología que permita incluir trozos de HTML dentro de otros, como PHP, o usar algún editor WYSIWYG que te dé esta opción.

      Eliminar
  4. deacarge el framework bootstrap 3 y no me quiere funcionar y en cuanto a los requisitos de hardware los cumple todos, me hace falta saber por que no me funciona

    ResponderEliminar
    Respuestas
    1. Hola, anónimo. Prueba con los ejemplos que vienen en la web. Puede que no hayas puesto los ficheros en los directorios correctos.

      Eliminar
  5. Hola Andrés.

    Yo también ando peleándome con Bootstrap y el marcado semántico.

    Si bien Less soluciona muchas cosas, veo algunas ocasiones en las que no alcanza. Por ejemplo, con .btn-group. Para poder usar esto, has de usar las clases .btn-group y .btn en el html. No alcanza con heredar esas clases en Less, ya que en el framework está escrito tal que así:

    .btn-group .btn {...}

    Entonces para que funcione, has de tener esas clases en el HTML sí o sí.

    La solución que yo encuentro para usar estas clases sin tocar el HTML, es asignarselas desde jQuery. ¿A ti se te ocurre algo?

    ResponderEliminar
    Respuestas
    1. Hola, SunTzu.

      Sí, puedes probar a usar :extend, una característica de LESS que está desde su versión 1.4 y que con "all" sí crea una herencia completa no sólo de los estilos de un elemento sino también de sus derivados. Yo la uso para casos de ese estilo, y hasta ahora me ha funcionado para todos los casos que he probado. Más información:

      http://lesscss.org/#-extend

      Eliminar
    2. Es una solución muy buena. Mejora mucho el marcado semántico.
      Pero al menos en mi caso, lo mejora, siguiendo con el ejemplo, al no tener que usar .btn-group. Aunque sí que hay que darles la clase .btn a los elementos de dentro.

      Muchas gracias por la info :)

      Eliminar

cookie consent