Un completo curso de diseño gráfico, ilustración, diseño web y tipografía.

Puertas correderas con CSS, parte 2

Una técnica para crear menús a medida con solapas o pestañas

por Douglas Bowman

Las puertas correderas en CSS (Parte I) introducía una nueva técnica para crear impresionantes elementos de interfaz con un código simple, basado en texto y semántico. En esta segunda parte, llevaremos la técnica aún más lejos. Si no has leído todavía la Parte I, deberías leerla ahora.

Aquí, nos ocuparemos de un nuevo escenario en el que no se destaca ningua solapa, combinaremos la técnica de Puertas Correderas con un cambio de imagen, proporcionaremos una solución para la región activa en IE/Win, y sugeriremos un método alternativo para seleccionar las solapas. Nos saltaremos un repaso básico de la técnica (ver la Parte I para ésto) y reanudaremos la experimentación allí donde la dejamos.

Sin solapa activa

En la Parte I, no tuvimos en cuenta los casos en los que puede que no haya una solapa “activa o actual” que se destaque. Por ejemplo, un proceso de registro, o páginas que contienen texto legal, puede que no encajen en ninguna de las secciones representadas por las solapas. si ninguna de las solapas se ha dotado de estilo como solapa “activa” la regla que añade un valor de 1px de espaciado adicional para la parte inferior, no se utilizará. Así, las solapas acabarán tapando la línea que va por la parte inferior de las solapas.

Si añadimos un borde de 1px en la parte inferior de todas las solapas “no activas” y a continuación eliminando el borde inferior en el caso de que exista una solapa “activa” tendremos una solución fácil:

#header li {
  float:left;
  background:url("left.gif")
    no-repeat left top;
  margin:0;
  padding:0 0 0 9px;
  border-bottom:1px solid #765;
  }
#header #current {
  background-image:url("left_on.gif");
  border-width:0;
  }

Cuando dejamos fuera una solapa activa, los efectos en la hoja de estilo pueden verse en el Ejemplo 7.

Cambios de imagen individuales

Con la intención de simplificar, intencionadamente dejamos de lado el tema de los cambios de imagen al pasar el ratón, tipo rollover en la Parte I. Ahora que tenemos la técnica básica bajo control podemos empezar a combinarla con otras para extender su utilidad y comportamiento.

Hasta hace poco, introducir cualquier tipo de efecto de rollover, fuera con JavaScript o con CSS significaba crear dos juegos de imágenes: uno para el estdo normal, otro para el estado de activación al pasar el ratón. Para evitar el retraso causado por la descarga sucesiva de la imagen correspondiente al segundo estado, existían numerosos métodos para “precargar” las imágenes requeridas en el caché del navegador. Petr Stanicek (conocido como “Pixy”) nos muestra en su artículo “Fast Rollovers, No Preload Needed” cómo combinar ambos estados (normal y hover) en una sola imagen, eliminando la necesidad de precargar.

Para nuestro ejemplo, colocamos dos imágenes una encima de otra para combinar los estados normal y hover en una sola imagen nueva. Hacemos lo mismo para la imagen de la derecha. Lo que era antes una imagen de 150 pixels de alto, ahora tiene el doble, 300 pixels. Terminamos con left_both.gif yright_both.gif. Con estas nuevas imágenes, podemos aprovechar la propiedad de CSS background-position para hacer visible la porción apropiada de la imagen que combina ambos estados cuando el usuario pasa el ratón sobre una solapa:

[Doble imagen que muestra una u otra parte en función del estado activo o no.]

Cambiamos a esas nuevas imágenes para los elementos de la lista y las anclas, manteniendo la misma posición:

#header li {
  float:left;
  background:url("left_both.gif")
    no-repeat left top;
  margin:0;
  padding:0 0 0 9px;
  border-bottom:1px solid #765;
  }
#header a {
  float:left;
  display:block;
  background:url("right_both.gif")
    no-repeat right top;
  padding:5px 15px 4px 6px;
  text-decoration:none;
  font-weight:bold;
  color:#765;
  }

Cuando usamos la propiedad background-position, debemos especificar dos valores, horizontal y vertical, y deben especificarse en ese orden. NO podemos combinar palabras clave (left, right, top, etc.) como lo hacemos con la longitud o valores de porcentaje. Así que al especificar las posiciones para el estado activado hover evitamos las palabras clave. Utilizamos un 0% para la imagen izquierda para colocar su borde izquierdo contra la parte izquierda de la abrtura, y un 100% para la imagen derecha para que haga lo opuesto.

Dado que conocemos exactamente dónde comienza el estado diferente en la nueva imagen, podemos colocar en posición verticalemente las imágenes de fondo en un valor de píxeles preciso. Los 150 pixeles de la parte superior de estas imágenes tienen el estado normal, y los 150 píxeles inferiores, tienen el estado hover. Así que tanto en la imagen izquierda como en la derecha, simplemente desplazamos las imágenes de fondo hacia arriba utilizando un valor negativo de 150px. También doblamos en los selectores para la primera regla para tener que especificar el color del texto sólo una vez:

#header li:hover, #header li:hover a {
  background-position:0% -150px;
  color:#333;
  }
#header li:hover a {
  background-position:100% -150px;
  }

Podemos utilizar la misma imagen con los estados combiados para la solapa activa. En lugar de especificar una nueva imagen como hacíamos previamente, podemos utilizar las mismas posiciones cambiadas en el fondo que hemos utilizado para los estados hover:

#header #current {
  background-position:0% -150px;
  border-width:0;
  }
#header #current a {
  background-position:100% -150px;
  padding-bottom:5px;
  color:#333;
  }

Implementar rollovers es así de simple. Puedes verlos en acción en el Ejemplo 8. Hemos rebajado el número total de imágenes empleadas de cinco (2 izquierdas, 2 derechas, and 1 fondo detrás de las solapas) a tres (1 izquierda, 1 derecha, 1 fondo), y hemos eliminado la necesidad de efectuar una precarga de imágenes.

Si hasta ahora has ido probando nuestra labor en Internet Explorer (Win o Mac), sin duda habrás notado que los efectos de rollover tal como los hemos implementado, no funcioinan. IE sólo aplica la pseudo-clase :hover a elementos de enlace, y a nada más. Para poder cambiar las imágenes de esta técnica de Puertas Correderas, necesitaríamos insertar un elemento adicional (tal como un span) dentro del ancla, y mover todas nuestras reglas de estilo un elemento hacia dentro (los ítems de lista se mueven al ancla, las reglas de las anclas se mueven al span).

No entraremos en detalle en los ajustes necesarios para que ambas imágenes puedan cambiar para proporcionar este efecto en IE. Pero para demostrar que es posible, podemos ver estos cambios demostrados en el Ejemplo 8a. Como verás, mover los papeles de cada elemento también elimina el pequeño espacio muerto que mencioné en la Parte I, porque el ancla ahora contiene la solapa entera.

Los rollovers son a menudo (más o menos) un efecto decorativo. Algunos pueden decidir que el código adicional necesario no merece la pena para hacer que los rollovers funcionen en Internet Explorer. Otros decidirán que los spans extra son un pequeño sacrificio para hacer que funcionen en todos los navegadores más populares y para eliminar el espacio muerto en los ejemplos anteriores. Insertar o no este código extra depende de tí.

Arreglo de la región clicable.

Como pasaba en el caso de los ejemplos de la Parte I, los enlaces de navegación se pueden convertir en elementos de nivel de bloque y se les puede dar un espacioado extra para aumentar la región clicable del enlace. La región visual se rellena a menudo con un color de fondo (o con una imagen de fondo en nuestro caso), lo que implica que el usuario puede hacer clic donde sea dentro de esta región, no sólo en los contenidos del enlace. En la mayoría de navegadores, cuando un elemento de ancla se cambia a elemento de bloque (vía CSS) y se aplica espaciado adicional a este ancla, las regiones visual y clicable se extienden juntas para cubrir los contenidos y el espaciado del enlace. Desafortunadamente, IE/Win sólo extiende la región visual, confinando la parte clicable en los contenidos del ancla, y sin incluir su espaciado:

[diferencia entre área visual y área clicable en IE /Win]

En la Parte I (y justo después del ejemplo 8a, más arriba), mencionamos de pasada que había un pequeño espacio muerto en la parte izquierda de las imágenes transparentes de las esquinas. También comentamos la manera de eliminar este espacio muerto. Sin embargo, la Parte I no tenía en cuenta la limitación del “área clicable” en IE/Win. Este navegador (versión 6.0 y anteriores) padece diversos “bugs” en su implementación de CSS. Uno de estos fallos produce problemas indebidos — y a veces no reconocidos — en la usabilidad y accesibilidad de la navegación dotada de estilo con CSS.

Si se especifica tanto el ancho como el alto para el ancla hará que también IE expanda mágicamente la región clicable. Pero al hacerlo inhibiremis el tamaño flexible de nuestra abertura para los otros navegadores. Para nuestro ejemplo de solapas, podrías pensar que se puede recurrir al uso de las unidades “ems” para especificar el alto o el ancho. Esto haría que el tamaño de las solapas estaría basado en el tamaño de fuente, ya heredado, del texto que hay dentro. pero especificar un alto para el ancla hace que IE/Win se vuelva majara. Y a menos que estemos usando una fuente monoespaciada para el texto de la solapas, especificar un ancho en ems hará las solapas inconsistentes con el texto de dentro a medida que se cambia su tamaño. (por no mencionar lo difícil que es determinar un ancho apropiado para cada texto, y después re-especificar su ancho cada vez que la solapa cambia.)

Afortundamente, podemos explotar un fallo diferente en la implementación de CSS de IE/Win, que fuerza la expansión de la región clicable en este navegador, sin necesidad de adjudicar un ancho arbitrario. Todo lo que necesitamos es especificar un pequeño ancho para el ancla. La mayoría de navegadores reconocen — y aplican — la propiedad de ancho para un elemento de nivel de bloque, incluso si los contenidos del elemento no caben en ese ancho. El elemento se encogerá al ancho especificado, incluso si esto hace que el texto se extienda más allá de los bordes del elemento. Pero IE/Win sólo encogerá el elemento hasta el ancho de la la línea más larga de texto sin salto de línea.

Así que incluso si especificamos un ancho minúsculo para el ancla (como .1em), IE/Win todavía permitirá que el ancla sea tan ancha como el texto que contiene dentro. Al mismo tiempo, IE también extenderá el área clicable hasta llenar la solapa completa:

#header a {
  float:left;
  display:block;
  width:.1em;
  background:url("right.gif")
    no-repeat right top;
  padding:5px 15px 4px 6px;
  text-decoration:none;
  font-weight:bold;
  color:#765;
  }

Todo esto no tiene sentido, ya que dos conceptos funcionan de forma opuesta. Pero funciona, y arregla la región clicable para IE/Win. Debemos recordar que otros navegadores cumplen con la especificación de ancho, y realmente intentarán encoger el ancho para cada solapa a .1em + espaciado (padding). Por suerte, IE/Win (6.0 y anteriores) tampoco entiende los selectores hijos en CSS — así que podemos utilizar uno para recuperar el ancho del ancla a su valor normal, “auto” para los demás navegadores, permitiendo que las solapas se expandan y contraigan como deben:

#header > ul a {width:auto;}

El Ejemplo 9 arregla el problema de la región clicable en IE/Win, y los lamentables trucos para arreglar IE deberían ser invisibles para todos los demás navegadores.

Identificar las solapas

Todos los ejemplos en la Parte I utilizan un ID aplicado a elementos individuales de una lista para alterar la apariencia de la solapa “actual”. El resultado de mover los ID de un elemento de la lista a otro es un concepto fácil de entender para alguien que ha empezado hace poco con las CSS. Pero hay un sistema alternativo de identificar la solapa actual, más eficiente en muchos casos, aunque añada algo más de código.

En lugar de utilizar un solo id="current" para identificar la solapa actual en el código, podemos aplicar IDs únicos a cada ítem, así:

<div id="header">
  <ul>
    <li id="nav-home"><a href="#">Home</a>

		</li>
    <li id="nav-news"><a href="#">News</a>
		</li>
    <li id="nav-products"><a href="#">Products</a>

		</li>
    <li id="nav-about"><a href="#">About</a>
		</li>
    <li id="nav-contact"><a href="#">Contact</a>

		</li>
  </ul>
</div>

También aplicamos un ID a un elemento contenedor más grande(como body). El valor de ID corresponde a una sección en la que esta página encaja. Este valor de ID para body puede emplearse también para añadir estilos específicos de la sección a otras porciones de la página. Con los ID en ambos lugares, podemos alterar la apariencia de una cierta solapa si cumple los requisitos de selectores descendientes. En lugar de utilizar #current como parte de nuestro selector, utilizaremos combinaciones de body y de los elementos de la lista para establecer las condiciones que harán que una solapa se considere la “actual”:

#home #nav-home, #news #nav-news,
#products #nav-products, 
#about #nav-about,
#contact #nav-contact {
  background-position:0% -150px;
  border-width:0;
  }
#home #nav-home a, 
#news #nav-news a,
#products #nav-products a, 
#about #nav-about a,
#contact #nav-contact a {
  background-position:100% -150px;
  color:#333;
  padding-bottom:5px;
  }

El Ejemplo 10 muestra el efecto de aplicar id="news" al body, y el Ejemplo 10a muestra qué ocurre cuando el body utiliza id="products". {La navegación de A List Apart utiliza el id en body de la misma manera. – Ed.}

Notas adicionales

Tapas de caja: Puedes tener módulos extensibles en las páginas que dibujan una caja alrededor de un encabezado y su contenido. Asumiendo que utilizas un contenedor, (como un div) que contiene el encabezado y contenido de un módulo, ya tienes los dos elementos para cada imagen de fondo(div y encabezado). En este caso, seguramente querrás disponer la imagen estrecha a la derecha, como se muestra en el Ejemplo 2. Esto te dará completo control al punto de partida izquierdo del texto de encabezado. Haz que la parte inferior de cada imagen se funda con el color de fondo de la caja contenedora para que parezca que se mezclan en una unidad única.

Moverse lateralmente: Si puedes predeterminar aproximadamente el alto de un elemento de la interfaz (o si creas una imagen suficientemente grande para acomodar la expansión ertical) puedes hacer que la “abertura” se abra lateralmente, utilizando una imagen para la parte superior y otra para la parte inferior (en vez de izquierda y derecha). Recuerda tener en cuenta el salto de línea del texto que ocurrirá con un ancho muy pequeño en el navegador o con tamaños de texto muy grandes.

Parpadeo en IE: Si ves un parpadeo en las imágenes cuando se pasa sobre las solapas en IE/Win, comprueba la configuración del caché para archivos temporales (Tools > Internet Options > General tab > Settings). Puede que hayas cambiado el valor por defecto para asegurarte de que siempre ves la versión más nueva de la página que visitas. IE/Win tiene problemas para mantener una imagen fija en las anclas si has especificado “Cada visita a la página” para los archivos temporales. El valor por defecto es “Automaticático”, lo que permite al navegador recuperar instantáneamente la imágen del caché, evitando el parpadeo. La mayoría de usuarios no cambian esta configuración; probablemente, ni siquiera sepan que existe.

Solapas con múltiples palabras: Puede darse el caso a menudo de que necesites un texto de más de una palabra para una solapa, y probablemente querrás añadir una declaración de white-space:nowrap; a la regla del ancla, para prevenir que el texto salte de línea en algunos navegadores.

Pueden darse otros problemas, alteraciones y variaciones de esta técnica, que ya existen o se acumulen con el tiempo. Pero nos detendremos aquí por ahora. Esperamos haber llenado el vacío y resuelto algunas dudas que podrían plantearse acerca de la utilidad y extensibilidad de las Puertas correderas. Hacia adelante y hacia arriba.

Este artículo tiene una primera parte en la que se explican más técnicas relacionadas.

Fundador y director de Stopdesign, Douglas Bowman se especializa en diseño simple, limpio y avanzado. Continuamente cuestiona y expande los límites de lo que es posible utilizando estándares web. Douglas fue el arquitecto del conocido rediseño de Wired News, pero promete no estancarse en esa reputación para siempre.

[ Este artículo ha sido traducido con permiso de A List Apart y su autor.]