#334 Compass & CSS Sprites
- Download:
- source codeProject Files in Zip (102 KB)
- mp4Full Size H.264 Video (33.2 MB)
- m4vSmaller H.264 Video (14.2 MB)
- webmFull Size VP8 Video (14.2 MB)
- ogvFull Size Theora Video (36.1 MB)
Compass hace que sea mucho más fácil generar hojas de estilos con SASS incorporando mixins útiles, funciones, etc, y la nueva gema CompassRails permite la integración directa de Compass con el conducto de estáticos de Rails. A continuación se muestra una versión simplificada del diseño del sitio de Railscasts. Vamos a usar Compass para mejorar los estilos de la web pero manteniendo el mismo aspecto.
Para añadir Compass a una aplicación Rails tan sólo tenemos que añadir la gema CompassRails al grupo assets
del Gemfile
y luego ejecutar bundle
.
# 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 'compass-rails' end gem 'jquery-rails'
Lo siguiente que haremos será renombrar nuestro fichero application.css
a application.css.scss
, que hará que pase a ser un fichero interpretado por SASS. Es necesario que hagamos esto para poder tener un lugar desde el que cargar Compass que esté compartido entre todos los ficheros SASS de nuestra aplicación. Sprockets no da esta funcionalidad por lo que eliminaremos su manifiesto y en su lugar utilizaremos SASS para importar los ficheros necesarios. Nuestra aplicación ya tiene un fichero llamado layout.css.scss
por lo que lo importaremos, así como el fichero compass
.
@import "compass"; @import "layout";
Tendremos que reiniciar el servidor porque hemos acabado de añadir una gema a la aplicación. Al recargar la página veremos que tiene el mismo aspecto que antes, lo cual es bueno. La única diferencia es que ahora ya podemos utilizar Compass para mejorar nuestro código SASS.
Uso de Compass en nuestra aplicación
Como ya hemos añadido el fichero compass
a la aplicación tenemos acceso automáticamente a toda la funconalidad de Compass, que nos facilitará el trabajo con CSS3, pudiendo añadir funcionalidades de CSS sin tener que especificar prefijos específicos para cada navegador cuando usemos gradientes, sombras o bordes redondeados La aplicación de Railscasts utiliza un gradiente. Los gradientes están documentados en la sección de imágenes de la documentación de Compass. Así que usando Compass vamos a mejorar el código de estilos de la barra de navegación, que se encuentra en el fichero layout
.
#nav_bar { position: relative; padding: 8px 100px; margin-bottom: 15px; border-top: solid 1px #FFF; border-bottom: solid 3px #DE9F00; background-color: #333; background-image: -webkit-linear-gradient(#5c5c5c, #111111); background-image: -moz-linear-gradient(#5c5c5c, #111111); background-image: -ms-linear-gradient(#5c5c5c, #111111); background-image: linear-gradient(#5c5c5c, #111111); .nav { float: right; padding-top: 2px; li { padding-left: 25px; font-size: 14px; color: #BBB; a { color: #FFF; } } } }
En este fichero definimos los gradientes cuatro veces porque tenemos que tener en cuenta los diferentes prefijos específicos para cada navegador. Con Compass no tendremos que hacerlo, tan sólo tenemos que utilizar una línea de código:
@include background-image(linear-gradient(#5c5c5c, #111111));
Con esta línea Compass generará todos los prefijos que necesitamos y al recargar la página veremos que tiene el mismo aspecto pero si examinamos la CSS generada veremos todo el código que Compass ha escrito por nosotros:
/* line 69, ../../app/assets/stylesheets/layout.css.scss */ #nav_bar { position: relative; padding: 8px 100px; margin-bottom: 15px; border-top: solid 1px #FFF; border-bottom: solid 3px #DE9F00; background-color: #333; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #5c5c5c), color-stop(100%, #111111)); background-image: -webkit-linear-gradient(#5c5c5c, #111111); background-image: -moz-linear-gradient(#5c5c5c, #111111); background-image: -o-linear-gradient(#5c5c5c, #111111); background-image: -ms-linear-gradient(#5c5c5c, #111111); background-image: linear-gradient(#5c5c5c, #111111); }
Uso de Sprites en CSS
Si todo lo que buscamos en Compass son este tipo de comodidades en el uso de CSS3, nos podría bastar con Bourbon tal y como vimos en el episode 330. Pero Compass va mucho más allá, incluyendo sprites en CSS. El uso de sprites en CSS es una técnica que combina varias imágenes en una más grande y usar reglas CSS para mostrar sólo una parte de dicha imagen. En nuestra página tenemos una fila de iconos que nos permiten suscribirnos a Railscasts de varias maneras, cada uno de estos iconos tiene una imagen separada lo que quiere decir que se lanza una petición HTTP diferente por cada uno. Es buena práctica reducir este número de peticiones, por lo que si somos capaces de fusionar todas estas imágenes en una sola podríamos utilizar CSS para mostrar cada icono escogiendo una sección de esta imagen.
Por supuesto la implementación manual de esta técnica es bastante costosa, pero con Compass se puede hacer múy fácilmente. Ahora mismo estamos cargando los iconos mediante background-image
.
#subscribe { position: absolute; bottom: 10px; right: 100px; li { position: relative; margin-left: 8px; font-size: 12px; } a { display: block; width: 34px; height: 34px; } .itunes { background-image: image-url("icons/itunes.png"); } .twitter { background-image: image-url("icons/twitter.png"); } .facebook { background-image: image-url("icons/facebook.png"); } .rss { background-image: image-url("icons/rss.png"); } }
Primero tendremos que combinar todas las imágenes que queremos combinar y ponerlas en el mismo directorio. Las nuestras ya están en /app/assets/images/icons
por lo que no tendremos que hacerlo. Podemos cargar las imágenes en Compass invocando @import
y pasándole la ruta.
@import "icons/*.png";
Con esto cargaremos todas las imágenes de dicho directorio y generaremos una única imagen sprite con todos ellos. Esto se puede hacer de varias maneras, la más manual es modifiando la llamada a background-image
para cada icono.
.itunes { @include icons-sprite(itunes); } .twitter { @include icons-sprite(twitter); } .facebook { @include icons-sprite(facebook); } .rss { @include icons-sprite(rss) }
Nuevamente la página sigue teniendo el mismo aspecto cuando la recargamos pero los iconos se encuentran ahora en la misma imagen de forma que se descargan todos con una única peticón.
Pero Compass viene con una forma todavía más cómoda de hacerlo. En lugar de cargar los sprites individualmente podemos hacerlo todo automáticamente mediante Compass, pudiendo eliminar el CSS de las cuatro clases que representan los iconos e incluyendo la siguiente línea:
@import "icons/*.png"; @include all-icons-sprites;
Esto generará automáticamente una clase CSS para cada imagen. Claro está que tendremos que cambiar el marcado HTML para que haga referencia a estas clases. Cada icono se muestra en una lista de la siguiente manera:
<ul id="subscribe" class="horizontal"> <li><a class="itunes" href="/itunes"></a></li> <li><a class="twitter" href="/twitter"></a></li> <li><a class="facebook" href="/facebook"></a></li> <li><a class="rss" href="/rss"></a></li> </ul>
Tan solo tenemos que preceder el nombre de clase con el directorio, en nuestro caso icons
y un guión:
<ul id="subscribe" class="horizontal"> <li><a class="icons-itunes" href="/itunes"></a></li> <li><a class="icons-twitter" href="/twitter"></a></li> <li><a class="icons-facebook" href="/facebook"></a></li> <li><a class="icons-rss" href="/rss"></a></li> </ul>
La página tiene el mismo aspecto que antes pero la CSS generada referencia a una única imagen y utiliza background-position
para mostrar la parte relevante de cada icono.
/* line 66, icons/*.png */ .icons-sprite, .icons-facebook, .icons-itunes, .icons-rss, .icons-twitter { background: url(/assets/icons-s1286bd1660.png) no-repeat; } /* line 60, ../../../.rvm/gems/ruby-1.9.3-p125/gems/compass-0.12.1/frameworks/compass/stylesheets/compass/utilities/sprites/_base.scss */ .icons-facebook { background-position: 0 -102px; }
Podemos encontrar más información acerca de el uso de sprites en el tutorial de Compass.
Listas horizontales simples
La documentación de Compass es bastante buena y es recomendable dedicar un tiempo a repasar las sección de Ayuda y Referencia para hacernos una idea de lo que podemos hacer con Compass. Hay muchas funciones de utilidad, una de las cuales hace que sea mucho más fácil generar listas horizontales. Las listas con frecuencia se usan para mostrar menús de navegación y podemos utilizar el mixin horizontal-list
para simplificarlas. El sitio de Railscasts tiene una clase .horizontal
que hace justo eso y su código SASS tiene el siguiente aspecto:
ul.horizontal { list-style: none; margin: 0; padding: 0; li { margin: 0; padding: 0; float: left; } }
Podemos cambiarlo por una llamada al mixin.
`` /app/assets/stylesheets/layout.css.scss ul.horizontal { @include horizontal-list; }<p>Con este marcado mucho más simple las listas horizontales se seguirán mostrando de forma horizontal, aunque puede ser que tengamos que ajustar un poco los márgenes y el <em>padding</em> de forma individual.</p> <h3><em>Reset</em> de hoja de estilos con Compass</h3> <p>Los navegadores vienen con valores por defecto diferentes para el tamaño y el espaciado de diversos elementos, pero mediante Compass podemos ajustar todo a cero para que podamos construir nuestros estilos de forma consistente entre los diferentes navegadores. Para usarlo sólo tenemos que importar <code>reset</code> a nuestro fichero <code>application.css.scss</code>.</p> ``` /app/assets/stylesheets/application.css.scss @import "compass"; @import "compass/reset"; @import "layout";
Esta es una de las escasas directivas de Compas que inserta CSS en nuestro layout por lo que deberemos tenerlo en cuenta, y veremos que el texto “Welcome” que se encuentra en un elemento h1
aparece ahora con menor tamaño.
En general la mayoría de nuestras páginas acabarán con peor aspecto tras aplicar este reset porque la mayoría de los diseños dependen hasta cierto punto de los estilos por defecto que incorporan los navegadores. Pero una vez que hayamos puesto a cero todos los estilos por defecto podemos empezar a construir nuestros propios estilos de forma consistente e independiente de l navegador. Por ejemplo podemos declarar qué aspecto queremos que tengan los elementos h1
.
h1 { font-size: 28px; font-weight: bold; margin: 18px 0; }
Veremos que nuestra página tiene el mismo aspecto que antes.
Este tipo de ajustes de CSS no siempre sirven, pero deben tenerse en cuenta cuando necesitamos que el diseño sea consistente en todos los navegadores. Hay otras alternativas al reset que hace Compass, como por ejemplo normalize.css. Éste define valores por defecto mucho más parecidos a los que vienen con los navegadores con lo que no tendremos que definir todos los elementos desde cero.
Más información
Con esto terminamos este episodio. Hay varias funcionalidades que no hemos cubierto, por lo que conviene repasar el sitio web de Compass para recabar más información. Una de las partes que no hemos visto es el módulo de Blueprint, que es un framework CSS completo que sirve para construir diseños basados en retículas. También merece la pena leer el README de CompassRails para ver otras formas posibles de integrar Compass con Rails. También incluye información útil para los que estén utilizando versiones antiguas de Rails.
Compass ofrece mucha funcionalidad, pero también es muy modular, lo que quiere decir que tan sólo tenemos que incluir las partes que necesitemos en nuestra aplicación.