#328 Twitter Bootstrap Basics
- Download:
- source codeProject Files in Zip (52.1 KB)
- mp4Full Size H.264 Video (32.3 MB)
- m4vSmaller H.264 Video (14.4 MB)
- webmFull Size VP8 Video (14.4 MB)
- ogvFull Size Theora Video (35.7 MB)
Twitter Bootstrap nos ayuda a escribir más deprisa aplicaciones web de aspecto resultón y viene con una combinación de CSS y JavaScript que sirven para hacer layouts, navegaciones y formularios, e incluso incluye soporte para implementar diseños adaptativos. Por ejemplo, si visitamos la página de Bootstrap y cambiamos el ancho del navegador, podremos ver que cambia la disposición de los elementos en pantalla para ajustarse al nuevo tamaño. Esto puede mejorar mucho la experiencia de uso de aplicaciones web en dispositivos móviles.
Merece la pena dedicarle un tiempo a explorar el sitio de Twitter Bootstrap y estudiar todo lo que hace, pero en este episodio nos vamos a centrar en su uso dentro de una aplicación Rails. Una opción es descargar el fichero CSS y JavaScript haciendo clic en el botón de descarga y luego mover los ficheros correspondientes al directorio /app/assets
pero no sería esta la mejor manera de hacerlo si usamos Rails. Twitter boostrap está escrito con LESS, que es un preprocesador de CSS similar al que usa Rails (SASS).
Para sacar todo el provecho a la flexibilidad de Twitter Boostrap lo mejor es utilizar un lenguaje dinámico como LESS, en lugar de utilizar la salida estática que éste genera. Para que LESS funcione con Rails tenemos que recurrir a varias gemas de Ruby. Hay varias gemas disponibles que integran Boostrap con Rails. En este episodio vamos a usar la gema twitter-bootstrap-rails pero más adelante mencionaremos algunas alternativas. Escogemos esta gema porque trabaja directamente con LESS y ofrece varios generadores que nos ayudarán a ponernos en marcha. Pero no nos anticipamos tanto, porque todavía no tenemos ni una aplicación Rails con la que trabajar.
Cómo añadir Bootstrap a una nueva aplicación Rails
Vamos a empezar con una nueva aplicación que llamaremos store
, y para la que vamos a generar el andamiaje necesario para un modelo Product
, y así tendremos algo de lo que partir.
$ rails new store $ cd store $ rails g scaffold product name price:decimal --skip-stylesheets $ rake db:migrate
Obsérvese que hemos utilizado la opción --skip-stylesheets
porque queremos utilizar las CSS de Bootstrap en lugar de la que sería generada automáticamente. También hemos migrado la base de datos de forma que se cree la tabla de productos. A continuación se muestra el aspecto que tiene la página generada; no es muy atractivo porque todavía no hemos aplicado los estilos. Ha llegado pues el momento de incluir Twitter Bootstrap.
El primer paso es añadir la gema twitter-bootstrap-rails
al grupo assets
en el Gemfile
. La gema sólo hará falta en este grupo porque sólo se usa con el conducto de estáticos. En producción sólo usaremos dichos estáticos por lo que no será necesaria.
# Gems used only for assets and not required # in production environments by default. group :assets do gem 'sass-rails', '~> 3.2.3' gem 'coffee-rails', '~> 3.2.1' # See https://github.com/sstephenson/execjs#readme for more supported runtimes # gem 'therubyracer' gem 'uglifier', '>= 1.0.3' gem 'twitter-bootstrap-rails' end
A continuación tenemos que lanzar bundle
para instalar twitter-bootstrap-rails
así como sus dependencias, entre las cuales están libv8
y less-rails
, que permiten a nuestra aplicacón interpretar la sintaxis LESS. Ahora que tenemos Bootstrap instalado, podemos ejecutar su generador para terminar el proceso de instalación.
$ rails g bootstrap:install insert app/assets/javascripts/application.js create app/assets/javascripts/bootstrap.js.coffee create app/assets/stylesheets/bootstrap_and_overrides.css.less gsub app/assets/stylesheets/application.css gsub app/assets/stylesheets/application.css
Esto coloca Bootstrap bajo el directorio /app/assets
. Uno de los ficheros clave generados es bootstrap_and_overrides.css.less
Este fichero carga Bootstrap y es un sitio ideal para personalizar los estilos de forma que se ajusten a nuestra aplicación. Tras reiniciar el servidor y recargar la página veremos que empieza a tener mejor aspecto, aunque todavía queda mucho por hacer.
Mejoras de maquetación
Vamos a centrarnos primero en el layout de la aplicación. La gema twitter-bootstrap-rails
incorpora un generador bootstrap:layout
que genera un fichero de layout que nosotros no vamos a usar. En vez de eso seguiremos los pasos necesarios para cambiar nuestro layout de forma que nos hagamos una mejor idea del funcionamiento de Twitter Bootstrap.
Existen dos tipos de layouts, fijos y fluidos. Un layout fijo tiene un ancho de píxeles específicos, mientras que uno que sea fluido se expandirá según el tamaño de la ventana del navegador. Para escoger entre uno y otro tipo de layout debemos especificar container
o container-fluid
en la clase del div
. Nosotros preferimos usar uno fijo para nuestro ejemplo por lo que creamos un div
con clase container
al body
del fichero de layout.
<!DOCTYPE html> <html> <head> <title>Store</title> <%= stylesheet_link_tag "application", :media => "all" %> <%= javascript_include_tag "application" %> <%= csrf_meta_tags %> </head> <body> <div class="container"> <%= yield %> </div> </body> </html>
Twitter Bootstrap utiliza un sistema de retícula de 12 columnas, por lo que es muy sencillo implementar diseños basados en columnas simplemente especificando el ancho de cada columna. El layout es adaptativo, por lo que si se reduce el ancho de la ventana del navegador la distribución cambiará de forma acorde. Supongamos que queremos una barra lateral en nuestro diseño y queremos que ocupe el 25% del ancho de la página. Podemos hacerlo modificando así el fichero de layout:
<div class="container"> <div class="row"> <div class="span9"><%= yield %></div> <div class="span3"> <h2>About Us</h2> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> </div> </div> </div>
Cuando recarguemos la página veremos nuestro nuevo layout de dos columnas.
Cómo incorporar una barra de navegación
A continuación vamos a añadir una barra de navegación en la parte superior de la página con algunos enlaces para navegar por el sitio. La sección de componentes de la documentación describe las diferentes opciones de navegación que Twitter Bootstrap permite, incluyendo una barra de navegación. Dicha barra se puede personalizar de acuerdo a nuestras necesidades, y podemos añadir enlaces, menús desplegables, campos de búsqueda, etcétera. Hay muchos ejemplos en la documentación acerca de cómo añadir cada tipo de elemento. Añadiremos nuestra barra de navegación en la parte superior de la página.
<div class="navbar navbar-fixed-top"> <div class="navbar-inner"> <div class="container"> <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </a> <a class="brand" href="#">Some Store</a> <div class="nav-collapse"> <ul class="nav"> <li><%= link_to "Browse Products", products_path %></li> <li><%= link_to "Price List" %></li> <li><%= link_to "Contact Us" %></li> <li><%= link_to "Cart" %></li> </ul> </div> </div> </div> </div>
Nuestra navegación tiene una sección para el nombre de la marca y varios enlaces de relleno. La sección superior es interesante porque controla el comportamiento colapsable cuando el navegador cambia de tamaño. Podemos ver nuestra barra de navegación recargando la página.
Nótese que vemos la versión colapsada de la navegación porque el ancho de la ventana del navegador es de 800px, lo que significa que no es lo suficientemente ancha como para que veamos la versión completa. Si hacemos la ventana más ancha sí que veremos la navegación.
Pero al hacerlo veremos un problema. La parte superior de la página quedará tapada por la barra de navegación. Se trata de un efecto colateral de utilizar una barra de navegación fija, la documentación indica que si queremos evitar este efecto debemos añadir por lo menos 40 píxeles de padding en la parte superior del elemento body
entre la CSS de Bootstrap y la CSS adaptativa. Lo haremos dentro del fichero CSS bootstrap_and_overrides
, que incluye los ficheros bootstrap
y responsive
, y la documentación dice que el padding debe añadirse entre los dos.
@import "twitter/bootstrap/bootstrap"; body { padding-top: 60px; } @import "twitter/bootstrap/responsive"; // Set the correct sprite paths @iconSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings.png'); @iconWhiteSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings-white.png'); // Your custom LESS stylesheets goes here // // Since bootstrap was imported above you have access to its mixins which // you may use and inherit here // // If you'd like to override bootstrap's own variables, you can do so here as well // See http://twitter.github.com/bootstrap/less.html for their names and documentation // // Example: // @linkColor: #ff0000;
Si ahora recargamos la página veremos que la parte superior ya no queda escondida detrás de la barra de navegación.
Ajustes finales en la cabecera
Con el fichero de layout de nuestra aplicación prácticamente acabado todavía nos quedan un par de cosas que añadir en el encabezado para asegurarnos de que funciona en todas partes.
<head> <title>Store</title> <!--[if lt IE 9]> <script src="http://html5shim.googlecode/svn/trunk/html5.js" type="text/javascript"></script> <![endif]--> <%= stylesheet_link_tag "application", :media => "all" %> <%= javascript_include_tag "application" %> <%= csrf_meta_tags %> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head>
El primer fragmento de código mejora el soporte HTML5 en versiones anteriores de Internet Explorer. La segunda es una etiqueta meta
que fija el comportamiento de diseño adaptativo para los dispositivos móviles.
Mejoras en las vistas
¿Y qué hay del resto de vistas de nuestras aplicación? Twitter Bootstrap permite mejorar el aspecto del resto de páginas generadas automáticamente que tenemos. Primero añadiremos un par de registros en la tabla de productos para tener algo de contenido con el que trabajar.
A continuación vamos a usar Twitter Bootstrap para mejorar el aspecto de esta página. En lugar de ver cada cambio de forma manual utilizaremos uno de los generadores que proporciona la gema. Este generador se llama themed
y está preparado para funcionar sobre el scaffold así que tan sólo le tenemos que pasar el nombre que queramos usar, así como la opción -f
para que sobreescriba los ficheros que ya estaban generados.
$ rails g bootstrap:themed products -f
La página de productos tendrá ahora un aspecto mucho mejor. La tabla queda mucho más clara y los enlaces de edición y borrado tienen ya aspecto de botones en lugar de texto plano.
Hemos aplicado otros cambios similares en las páginas para ver y editar un único producto. Podemos ver el código fuente de estas plantillas para ver cómo funcionan.
<h1>Products</h1> <table class="table table-striped"> <thead> <tr> <th>ID</th> <th>Name</th> <th>Created at</th> <th>Actions</th> </tr> </thead> <tbody> <% @products.each do |product| %> <tr> <td><%= product.id %></td> <td><%= link_to product.name, product_path(product) %></td> <td><%= product.created_at %></td> <td> <%= link_to 'Edit', edit_product_path(product), :class => 'btn btn-mini' %> <%= link_to 'Destroy', product_path(product), :method => :delete, :confirm => 'Are you sure?', :class => 'btn btn-mini btn-danger' %> </td> </tr> <% end %> </tbody> </table> <%= link_to 'New', new_product_path, :class => 'btn btn-primary' %>
Vemos que se han añadido un par de clases de CSS en la tabla que muestra los productos. Igualmente se han añadido clases en los enlaces de edición y borrado para mejorar su aspecto. El mayor cambio es que se ha hecho sobre el parcial que contiene el formulario de creación o edición de producto.
<%= form_for @product, :html => { :class => 'form-horizontal' } do |f| %> <fieldset> <legend><%= controller.action_name.capitalize %> Product</legend> <div class="control-group"> <%= f.label :name, :class => 'control-label' %> <div class="controls"> <%= f.text_field :name, :class => 'text_field' %> </div> </div> <div class="control-group"> <%= f.label :price, :class => 'control-label' %> <div class="controls"> <%= f.text_field :price, :class => 'text_field' %> </div> </div> <div class="form-actions"> <%= f.submit nil, :class => 'btn btn-primary' %> <%= link_to 'Cancel', products_path, :class => 'btn' %> </div> </fieldset> <% end %>
No ha habido cambios significativos con respecto al código generado habitualmente, así que sirve como ejemplo de cómo se puede embellecer un formulario con Twitter Bootstrap.
Ya hemos terminado este episodio, y nos quedan por mencionar algunas alternativas a la gema twitter-bootstrap-rails
. Hay una lista de ellas en este artículo de Ruby Source que explica el funcionamiento de Twitter Bootstrap y enumera las diversas opciones y gemas para integrarlo con Rails.