En CSS podemos hacer uso de contadores para enumerar elementos de la página y controlar la numeración con las propiedades counter-reset, counter-increment y counter-set.
Aunque uno domine CSS hace años muchas veces se le escapan propiedades que podrían resultar útiles en determinadas ocasiones. En este artículo vamos a ver un conjunto de ellas que resultan bastante desconocidas y que nos sirven para crear contadores en CSS con los que podemos llevar por ejemplo la cuenta del número de elementos que aparecen en la página.
Estos contadores nos pueden servir para muchas cosas, como numerar elementos de listas y hacer listados con valores arbitrarios o anidados, manejados desde las CSS, o para por ejemplo numerar los párrafos de una sección o los <h2>
de un artículo, por poner varios ejemplos.
Ámbito de los contadores CSS
Vamos a comenzar hablando del ámbito de los contadores de CSS, que nos servirá también para definirlos en nuestro código. Lo que debes saber es que los contadores de CSS se controlan dentro de un ámbito, de manera similar a lo que ocurre con las variables en los lenguajes de programación.
Dentro de un elemento HTML que deseemos podemos generar un contador que tendrá el ámbito de ese elemento. Para ello utilizaremos la propiedad counter-reset
indicando a continuación el nombre del contador, que puede ser cualquiera que nosotros queramos.
section {
counter-reset: parte;
}
Con el código anterior hemos definido que cuando comience un elemento <section>
tendremos un contador nuevo llamado 'parte', que tendrá el ámbito de esa sección.
Incremento de los contadores
En cada elemento que nosotros queramos, podemos definir un incremento del contador. Para ello usamos la propiedad counter-increment
, indicando el nombre del contador que queremos incrementar, pues en un ámbito podría haber más de 1 contador activo.
Ahora imaginemos que dentro de los section quiero llevar la cuenta del número de párrafos que tengo anidados. Entonces podría incrementar el contador de esta manera.
section p {
counter-increment: parte;
}
Cómo mostrar los contadores en la página
Los contadores estarán disponibles en CSS en el ámbito donde hayan sido definidos. Generalmente querremos volcarlos como contenido en la página en algún momento.
Para continuar con nuestro ejemplo, quisiera enumerar todos los párrafos que hay dentro del elemento <section>
, indicando algo como "PARTE 1:", "PARTE 2:", etc. Con ello tendría como resultado un bloque como el de la siguiente imagen:
Para conseguir este objetivo podemos valernos de los pseudoelementos de CSS ::before, que nos permiten insertar un contenido antes de un elemento. La idea es insertar el contenido "PARTE 1:", "PARTE 2:" justo al principio, para lo que tendremos que usar el valor del contador actual.
Para usar el valor de un contador en el CSS usamos la función counter()
a la que le pasamos el nombre del contador al que queremos acceder.
Por ejemplo en este caso estamos definiendo que el contenido del pseudoelemento before sea "Parte" seguido del valor del contador "parte".
section p::before {
content: "Parte " counter(parte) ": ";
text-transform: uppercase;
font-weight: bold;
}
Ejemplo completo del contador con CSS
Ahora vamos a ver todo el código junto de nuestro ejemplo, por si alguien se ha perdido un poco.
<style>
section {
counter-reset: parte;
}
section p {
counter-increment: parte;
}
section p::before {
content: "Parte " counter(parte) ": ";
text-transform: uppercase;
font-weight: bold;
}
</style>
<section>
<p>Lorem ipsum...</p>
<p>Eveniet, aperiam!</p>
<p>Fugiat, nesciunt!</p>
<p>Officiis accusamus...</p>
<p>Quam, in quos nisi facilis...</p>
</section>
Cómo setear el valor de un contador
Además de las dos propiedades que hemos visto anteriormente, tenemos una tercera propiedad de CSS que nos sirve para setear el valor de un contador, con cualquiera que necesitemos en un momento dado.
La propiedad se llama counter-set
y la tenemos que definir con dos valores:
- El nombre del contador que queremos setear
- El valor del contador que vamos a colocarle
Por ejemplo, imagina que quieres crear un contador con el ámbito de toda la página que comience en 1000. Podríamos usar el siguiente código CSS:
body {
counter-reset: micontador;
counter-set: micontador 1000;
}
Como has podido imaginar, si no seteamos el valor de un contador, éste comenzará en cero de manera automática.
Combinar el uso de varios contadores CSS a la vez
Esta práctica de uso de contanadores la puedes usar para muchas utilidades dentro de la página. Por ejemplo, podríamos usar dos contadores a la vez para mantener la lista de los encabezamientos, de modo que todos los encabezados h2 comiencen por su índice (1, 2, 3…) y los encabezados h3 tengan un índice y un subíndice (1.1, 1.2, 2.1…).
La idea la podemos ver en esta imagen:
El CSS que podríamos usar para conseguir este efecto es el siguiente:
body {
counter-reset: seccion;
}
h2 {
counter-increment: seccion;
counter-reset: subseccion;
}
h2::before {
content: counter(seccion) ") ";
}
h3 {
counter-increment: subseccion;
}
h3::before {
content: counter(seccion) "." counter(subseccion) ") ";
}
Contadores en niveles de anidación indeterminados
Usando una idea similar a la del ejemplo anterior podríamos marcar los índices y subíndices de listas anidadas.
Usando dos contadores como en el ejemplo anterior puedes conseguir enumerar una lista (1, 1.1, 1.2, 2, 2.1...), sin embargo ¿Qué pasaría si necesitas un tercer nivel de anidación? Lo puedes conseguir con un tercer contador, o un cuarto si fuera necesario. El problema que nos podemos encontrar es cuando no sabemos cuántos niveles vamos a tener y no queremos crear "n" contadores, complicando el código CSS y su aplicación.
La solución que vamos a explicar está expuesta en esta FAQ sobre listas anidadas y sus índices.
En este ejemplo lo vamos a resolver este problema con una regla sencilla, usando una alternativa de función counter
, pero en plural: counters()
. Esta función recibe dos parámetros:
- El nombre del contador que queremos visualizar (puede que este contador esté repetido con el mismo nombre en ámbitos anidados.
- El separador que queremos usar entre cada uno de los valores del contador.
Si tenemos "n" contadores con el mismo nombre en un ámbito, los podemos volcar todos como contenido en la página con una llamada como esta:
counters(elemento, ".") " ";
Ahora podemos ver el CSS necesario para estilizar una lista que podría tener n niveles de anidación.
ol.listaniveles {
counter-reset: elemento;
}
ol.listaniveles li {
list-style-type: none;
}
ol.listaniveles li:before {
content: counters(elemento, ".") " ";
counter-increment: elemento
}
Puedes probar este HTML de lista <ol>
anidada para visualizar cómo quedan los estilos propuestos.
<ol class="listaniveles">
<li>item 1
<ol class="listaniveles">
<li>subitem 1</li>
<li>subitem 2
<ol class="listaniveles">
<li>sub-subitem 1</li>
<li>sub-subitem 2
<ol class="listaniveles">
<li>Cuarto nivel de anidación</li>
</ol>
</li>
</ol>
</li>
<li>subitem 3</li>
</ol>
</li>
<li>item 2
<ol class="listaniveles">
<li>subitem 1
<ol class="listaniveles">
<li>sub-subitem 1</li>
</ol>
</li>
<li>subitem 2</li>
</ol>
</li>
<li>item 3</li>
<li>item 4</li>
</ol>
Espero que este artículo te haya sido de utilidad y hayas podido aprender algo nuevo de CSS que seguramente te podrá venir bien algún día.
Miguel Angel Alvarez
Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...