EstiloCSSTutoriales y tips en español

RSS

Cómo usar counter-increment y counter-reset en CSS 2

Por Iván Bustos en . Actualizado: 14/7/2011. Visitado 493 veces. Compartir en LinkedIn

PobreExcelente 

Basado en 5 votaciones.

Iván BustosIván Bustos, un desarrollador web en Colombia con más de 10 años de experiencia en el desarrollo de experiencias en línea, enamorado de los estándares web y del poder de JavaScript. Fundador de Estilocss.com y creador de IBForm.

Aprenda más en:
http://www.ivanbustos.com

La idea de este ejercicio experimental es simplemente practicar un poco con la función de contadores integrada desde CSS Nivel 2 para poder emular el comportamiento de una lista <ol>.

Hay situaciones en las que el uso de listas ordenadas realmente no es el adecuado. Las listas deberían ser usadas para plasmar información que se puede dividir lógicamente en partes. En el caso de listas ordenadas, la información también puede estar ordenada de una manera secuencial. Es decir, una idea depende de la anterior.

En el ejemplo de hoy lo que quiero hacer es jugar un poco con las primeras estrofas de Rin Rin Renacuajo. La idea es numerar cada una de las estrofas sin hacer uso de elementos HTML adicionales además de los <p> usados para escribir el poema. Considera el siguiente código que hace uso de listas ordenadas.

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es">
  3.    <head>
  4.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5.     <title>Rin Rin renacuajo</title>
  6.    </head>
  7.    <body>
  8.     <h3>Rin Rin Renacuajo</h3>
  9.     <h5>Por Rafael Pombo</h5>
  10.     <ol>
  11.        <li>El hijo de rana, Rinrín renacuajo<br />Salió esta mañana muy tieso y muy majo<br />Con pantalón corto, corbata a la moda<br />Sombrero encintado y chupa de boda.</li>
  12.        <li>-¡Muchacho, no salgas!- le grita mamá<br />pero él hace un gesto y orondo se va.</li>
  13.        <li>Halló en el camino, a un ratón vecino<br />Y le dijo: -¡amigo!- venga usted conmigo,<br />Visitemos juntos a doña ratona<br />Y habrá francachela y habrá comilona.<br /></li>
  14.        <li>A poco llegaron, y avanza ratón,<br />Estírase el cuello, coge el aldabón,<br />Da dos o tres golpes, preguntan: ¿quién es?<br />-Yo doña ratona, beso a usted los pies</li>
  15.     </ol>
  16.    </body>
  17. </html>

Lo que proporcionaría el siguiente resultado:

Imagen de Rin Rin Renacuajo usando listas

Como verás, hemos logrado el objetivo. Cada una de las estrofas del poema está numerada. El problema con esta técnica es que desde el punto de vista semántico, las listas ordenadas no están diseñadas para presentar poemas. La manera más correcta de hacerlo sin lugar a dudas es mediante el elemento <p>. Considera el siguiente ejemplo.

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es">
  3.    <head>
  4.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5.     <title>Rin Rin renacuajo</title>
  6.    </head>
  7.    <body>
  8.     <h3>Rin Rin Renacuajo</h3>
  9.     <h5>Por Rafael Pombo</h5>
  10.     <h4>Estrofa 1</h4>
  11.     <p>El hijo de rana, Rinrín renacuajo<br />Salió esta mañana muy tieso y muy majo<br />Con pantalón corto, corbata a la moda<br />Sombrero encintado y chupa de boda.</p>
  12.     <h4>Estrofa 2</h4>
  13.     <p>-¡Muchacho, no salgas!- le grita mamá<br />pero él hace un gesto y orondo se va.</p>
  14.     <h4>Estrofa 3</h4>
  15.     <p>Halló en el camino, a un ratón vecino<br />Y le dijo: -¡amigo!- venga usted conmigo,<br />Visitemos juntos a doña ratona<br />Y habrá francachela y habrá comilona.<br /></p>
  16.     <h4>Estrofa 4</h4>
  17.     <p>A poco llegaron, y avanza ratón,<br />Estírase el cuello, coge el aldabón,<br />Da dos o tres golpes, preguntan: ¿quién es?<br />-Yo doña ratona, beso a usted los pies</p>
  18.    </body>
  19. </html>

Que proporcionaría lo siguiente:

Imagen de Rin Rin Renacuajo usando párrafos

La anterior es indudablemente la manera más correcta de hacerlo. No cabe duda. El único problema que le veo a esta técnica (o más bien inconveniente) es que el proceso de numeración realmente no es automático. Imagínate si estuviéamos hablando de un poema de 30 estrofas por ejemplo. A cada una de estas estrofas tendríamos que anteponerle su elemento <h4> numerando el número de estrofa.

Aqui es donde toma lugar el ejercicio de hoy. La idea es hacer eso mismo sin la necesidad de usar los subtítulos <h4> y al igual que las listas ordenadas, lograr una numeración automática. Esto lo haremos a través de el sistema básico de contadores introducido desde CSS Nivel 2.

Para empezar, lo que haremos es coger el código anterior y quitarle todos los títulos <h4>.

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es">
  3.    <head>
  4.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5.     <title>Rin Rin renacuajo</title>
  6.     <link rel="stylesheet" href="basic.css" type="text/css" media="screen" />
  7.    </head>
  8.    <body>
  9.     <h3>Rin Rin Renacuajo</h3>
  10.     <h5>Por Rafael Pombo</h5>
  11.     <p>El hijo de rana, Rinrín renacuajo<br />Salió esta mañana muy tieso y muy majo<br />Con pantalón corto, corbata a la moda<br />Sombrero encintado y chupa de boda.</p>
  12.     <p>-¡Muchacho, no salgas!- le grita mamá<br />pero él hace un gesto y orondo se va.</p>
  13.     <p>Halló en el camino, a un ratón vecino<br />Y le dijo: -¡amigo!- venga usted conmigo,<br />Visitemos juntos a doña ratona<br />Y habrá francachela y habrá comilona.<br /></p>
  14.     <p>A poco llegaron, y avanza ratón,<br />Estírase el cuello, coge el aldabón,<br />Da dos o tres golpes, preguntan: ¿quién es?<br />-Yo doña ratona, beso a usted los pies</p>
  15.    </body>
  16. </html>

Nota por favor que en la línea 6 del código anterior, incluí una referencia a un archivo CSS externo el cual llamé basic.css.

Antes que nada, abre el archivo basic.css recién creado y en él escribe el siguiente código. La idea es que el poema use la fuente cursiva.

  1. p
  2. {
  3.    font-style: italic;
  4. }

Hasta este punto, deberíamos tener algo como lo siguiente:

Imagen de Rin Rin Renacuajo con letra cursiva

¡Buen trabajo! En este momento lo único que nos falta hacer realmente es el contador. El sistema funciona de una manera muy similar a la del uso de variables en cualquier lenguaje de programación estricto. La idea básica es declarar la variable y luego ir asignándole nuevos valores a medida de que nuevos versos sean ingresados.

Para declarar una variable contador en CSS, usaremos la propiedad counter-reset. La idea es definir esta regla en algún elemento que no se vaya a contar. El elemento <body> por ejemplo no se repetirá jamás lo que lo convierte en el candidato ideal para inicializar nuestra variable. En cambio, si definiéramos la variable en uno de los versos que son los que supuestamente se repiten, nuestro contador se reinicializaría automáticamente en cada iteración.

Por cierto, puedes leer un poco más sobre las propiedades contadoras del CSS2 en la especificación original del CSS2.

Abre el archivo basic.css y justo antes del selector p que definimos anteriormente, añade la siguiente regla:

  1. body
  2. {
  3.    counter-reset: numeroDePs;
  4. }
  5. p
  6. {
  7.    font-style: italic;
  8. }

En la línea 3 del código anterior, hemos definido la variable numeroDePs. Hasta ahora no hemos logrado nada. Tan sólo hemos definido la variable con la que pretendemos hacer la iteración. Con el fin de aumentar en 1 el valor de nuestra variable por cada párrafo o verso que tenga el poema, le asignaremos la propiedad counter-increment a nuestro selector p.

Justo después de la línea 7 del código anterior, ingresa la siguiente línea:

  1. counter-increment: numeroDePs;

Excelente. Ahora por cada párrafo en nuestro verso (o en cualquier parte de la página para ser exacto porque el selector que usamos en nuestro css no es específico) nuestra variable numeroDePs aumentará en 1.

No pasa nada. A pesar de que la variable ya se está incrementando por cada párrafo nuevo no vemos ningún cambio en pantalla. Esto sucede por que aún no hemos mostrado en ningún momento el valor de nuestra variable.

La idea que tengo es que antes de cada párrafo podamos leer el número del verso. Para hacer esto usaremos el pseudo-elemento :before para mostrar el valor de nuestro contador antes de mostrar cada uno de los párrafos.

Al final de todas las reglas en nuestro archivo CSS, agrega la siguiente regla:

  1. p:before
  2. {
  3.    content: "Verso " counter(numeroDePs) ":";
  4. }

Hasta este punto, nuestro CSS debe lucir de la siguiente forma:

  1. body
  2. {
  3.    counter-reset: numeroDePs;
  4. }
  5. p
  6. {
  7.    font-style: italic;
  8.    counter-increment: numeroDePs;
  9. }
  10. p:before
  11. {
  12.    content: "Verso " counter(numeroDePs) ":";
  13. }

Lo que nos muestra el siguiente resultado:

Imagen de Rin Rin Renacuajo usando contadores css

¡Lo hemos logrado! Por lo menos la parte difícil ya está hecha. Efectivamente logramos enumerar cada uno de los versos correctamente. Lo único que nos hace falta es el toque final. La idea es separar cada enumeración del verso al que pertenece agregando un nuevo retorno de línea.

Modifica la línea 12 del código anterior de la siguiente forma:

  1. content: "Verso " counter(numeroDePs) ":\A";

Te darás cuenta que justo después de los dos puntos he agregado \A. Este escape sirve para agregar un nuevo retorno de línea directamente al HTML y es simplemente una representación del caracter de retorno de línea en Unicode cuyo valor es U+000A. (Más información acá).

Te darás cuenta que no hemos hecho nada. Nuestro poema sigue luciendo igual. La razón por la cual esto sucede es debido a que nuestro escape \A realmente no inserta un <br /> nuevo en nuestro HTML si no simplemente un retorno de línea cualquiera tal cual lo hubiéramos hecho nosotros mismos con la tecla retorno de nuestro teclado. Como el HTML naturalmente ignora espacios adicionales, esa línea de retorno no se muestra como lo esperábamos.

Sin embargo, si logramos tratar el espacio en blanco de cada párrafo tal y como un elemento <pre> lo trataría habremos logrado lo que queremos. En CSS, hay una manera muy fácil de lograrlo.

A continuación te comparto nuestro archivo CSS final:

  1. body
  2. {
  3.    counter-reset: numeroDePs;
  4. }
  5. p
  6. {
  7.    font-style: italic;
  8.    counter-increment: numeroDePs;
  9.    white-space: pre;
  10. }
  11. p:before
  12. {
  13.    content: "Verso " counter(numeroDePs) ":\A";
  14. }

Notarás que en la línea 9 del código anterior hemos asignado una nueva propiedad a nuestro selector p. En simples términos, le estamos diciendo al motor CSS que trate cada retorno de línea en cada uno de los párrafos tal y como lo haría si se tratara de un elemento <pre>.

Al hacer esto, obtenemos nuestro resultado final:

Imagen de Rin Rin Renacuajo terminado

¡Felicidades! hemos terminado el experimento. Esta técnica te puede ser útil. Así como puedes enumerar párrafos, también puedes enumerar títulos, imágenes, etc. Ten en cuenta que los contadores no sirven en IE7 o menor.

Cualquier comentario siempre será apreciado. Muchas gracias por leer.

El 29 de junio de 2011, claudio araya dijo:

Para ser de Dificultad Principiante. No entendi nada creo que debo aprender otra base antes de adentrarme en esta área. Si tienes algo me escribes a mi correo personal por favor??

Haga clic en cualquier etiqueta para ver más tutoriales

EstiloCSS.com | Creative Commons License | Otro sitio más de Iván Bustoshttp://www.ivanbustos.com/Miami, FL 33166United States.