Mostrando entradas con la etiqueta CSS2. Mostrar todas las entradas
Mostrando entradas con la etiqueta CSS2. Mostrar todas las entradas

2011/05/19

Contadores CSS

Cuántas veces hemos necesitado autonombrar elementos HTML y para ello hemos hecho un bucle en PHP que lo que hace es añadirle un número consecutivo a cada elemento?. Vale, es la solución más portable, pero CSS desde 2.1 soportaría realizar esa función de forma nativa lo caul puede ser útil cuando por ejemplo no se disponga de soporte de lenguajes de script o no se quieran usar.

Estaría soportado desde IE7 y superiores (y por supuesto por el resto de los navegadores de verdad) y la técnica se basa en utilizar las propiedades CSS counter-reset y counter-increment junto con la propiedad content dentro del pseudoelemento :before para autogenerar ids. Se puede hasta anidar contadores!

Los contadores se inicializan con
counter-reset: nombre_del_contador;

Y se incrementarían con
counter-increment: nombre_del_contador;

Se puede referenciar al valor como si fuera una "función" con la palabra reservada
counters

Vamos a ello.

En el primer ejemplo, se va a numerar atomáticamente cada sección de una página de modo que para cada sección, indicada por <h1>s tenga automáticamente la palabra "Sección <n>" con <n> el número de sección.

Primero, reseteamos el contador para que empiece por 1:
body {counter-reset: thecounter} /* el nombre del contador sería "thecounter" */

Cada <h1> cogería el prefijo "Sección " añadiéndole el contador que automáticamente se incrementaría para cada sección (que es por defecto y se puede obviar), donde "thecounter" es el nombre del contador que se va a usar para nombrar las secciones:
.counter h1:before {
    counter-increment: thecounter 1;
    content:"Sección "counter(thecounter)":";
}

Para una lista numerada anidada el contador se resetea y la numeración automática de los <ol> se desactiva porque no soporta anidamiento
ol {
    counter-reset: section;
    list-style-type: none;
}

Ahora, cada <li> recive indentación automática y sel sepearador se fija al punto "." seguido por un espacio en blanco
li:before {
    counter-increment: section;
    content: counters(section,".")"";
}
El ejemplo completo sería:
<ol>
    <li>item</li>           <!-- 1 -->
    <li>item                <!-- 2 -->
        <ol>
            <li>item</li>   <!-- 1.1 -->
            <li>item</li>   <!-- 1.2 -->
        </ol>
    </li>
    <li>item</li>           <!-- 3 -->
<ol>

2011/03/24

Usando imágenes para dar estilo a los elementos IV. Hacks de background-image

Aunque ya hemos visto una forma óptima de tratar con sprites, aún se le puede sacar algo de jugo para determinados casos. Las secciones de este artículo se van a aplantear como si existieran las propiedades CSS de las que se habla.

Emulando background-crop.
Básicamente, es lo que hemos estado haciendo en el capítulo III de esta serie de posts. Podría ponerse simplificado, pero se perdería la posibilidad de hacerlos cross-browser. Merece la pena repasar el artículo.
Hay tímidos avances en incorporar esta funcionalidad como la de firefox con -moz-image-rect y la inclusión de image slices en el borrador para imágenes de CSS3 por lo que dentro de poco debería ser una característica de base en vez de una rareza.


Emulando multiple-background (CSS2.1)
Para navegadores medianamente actuales (es decir, IE8+) se puede aplicar esta técnica. La base de todo está en cómo se componen las capas de los pseudo-elementos :before y :after en un elemento HTML. Se puede ver cómo en el diagrama de la izquierda.

Así, se podría tener un fondo para el elemento, un fondo en el :before y otro en el :after, teniendo encima de todo el contenido del elemento, todo en ese orden de "abajo" a "arriba".

Un ejemplo de ésto funcionando creando un efecto además de tipo parallax, es el que se puede ver en el siguiente CSS.

Se supone que se tiene un elemento llamado #contenedor y dentro de él se va a situar before y after una imagen, cada una con su propio fondo.
#contenedor {
   position:relative;
   z-index:1; /* pone el orden correcto */
   background:#d3ff99 url(fondo-mas-profundo.png) -10% 0 repeat-x; /* el fondo de atrás del todo */
   min-width:200px; min-height:200px; padding:120px 200px 50px; /* esto es estético */
}
/* Estilos comunes de :before y :after */
#contenedor:before,
#contenedor:after {
   position:absolute;
   z-index:-1; /* pone el orden correcto */
   top:0; left:0; right:0; bottom:0;
   padding-top:100px; /* estético */
}
/* Estilos específicos de :before y :after */
#contenedor:before {
   content:url(imagen-1.png); /* El contenido es una imagen en este caso */
   padding-left:3%; text-align:left;
   background:transparent url(fondo-intermedio.png) 300% 0 repeat-x;
}
#contenedor:after {
   content:url(imagen-2.png); /* El contenido es una imagen en este caso */
   padding-right:3%;
   text-align:right;
   background:transparent url(fondo-primer-plano.png) 70% 0 repeat-x;
}
 
Emulando background-transform.
Combinando pseudo-elementos mediante :before con transformaciones transform de CSS3, se pueden hacer cosas como por ejemplo, rotar el icono de un acordeón al ser pulsado.

Evidentemente, IE 6, 7 y 8 no están invitados a esta fiesta aunque se podría currar algo con filtros, cosa que no voy a hacer en este momento.
.accordion a:before {
   content:"";
   float:left;
   width:16px;
   height:16px;
   margin:0 5px 0 0;
   background:url(sprite.png) no-repeat 0 0;
}
.accordion.open a:before {
   -webkit-transform:rotate(90deg);
   -moz-transform:rotate(90deg);
   -ms-transform:rotate(90deg);
   -o-transform:rotate(90deg);
   transform:rotate(90deg);
}
Emulando background-transform-mirror
Este es una tontería, pero el resultado es algo que más de una vez he tenido que hacer y que he tenido que recurrir a photoshop y similares.

En vez de rotar el elemento, se hace un transform: scaleX(-1) para que las sombras queden bien.

Para simular que se ha presionado el botón y que las sombras queden bien, se hace la transformación de escalado tanto en el eje X como en el Y con transform: scale(-1,-1)

El código CSS del ejemplo sería.

.prev a:before,
.next a:before {
   content:"";
   float:left;
   width:16px; height:16px; margin:0 5px 0 0; /* tamaños */
   background:url(sprite.png) no-repeat 0 0;
}
.next a:before {
   float:right; /* Lo coloca a la derecha */
   margin:0 0 0 5px;
   -webkit-transform:scaleX(-1);
   -moz-transform:scaleX(-1);
   -ms-transform:scaleX(-1);
   -o-transform:scaleX(-1);
   transform:scaleX(-1);
}

Como os habréis imaginado el IE8 (y anteriores) no están invitados a la fiesta.

Emulando background-position
CSS 2.1 limita el uso de background-position a desplazamientos desde los lados izquierdo y superior de la imagen, pero sin embargo es posible emular el posicionamiento a partir de los border derecho e inferior aplicando el fondo a un pseudo-elemento y luego desplazando dicho pseudo-elemento.

La base es la misma que en la técnica de multiple-background y el CSS quedaría así, considerando que es el elemento #contenedor al que se le quiere colocar el fondo a partir de la derecha o parte inferior:


#contenedor {
   position:relative; /* necesario */
   z-index:1; /* necesario para ordenar las cosas correctamente */
}
#contenedor:before {
   content:"";
   position:absolute; /* necesario */
   z-index:-1;  /* necesario para ordenar las cosas correctamente */
   bottom:10px; /* Colocando respecto a la parte inferior */
   right:10px;  /* Colocando respecto a la parte derecha  */
   width:500px; height:300px;
   background:url(image.jpg);
}

Emulando background-opacity
Desarrollando un poco las técnicas que hemos estado viendo antes, se puede aplicar opacity al background de uno de los dos pseudo-elementos :before o :after de modo que se hagan transparencias con el background del propio elemento.


#contenedor {
   position:relative;
   z-index:1;
}
#contenedor:before {
   content:"";
   position:absolute;
   z-index:-1;
   top:0; bottom:0; left:0; right:0;
   background:url(image.jpg);
   opacity:0.7;
}
Una vuelta de tuerca a todo esto es la de que el :before tuviera una transparencia de por ejemplo .75 y simplemente cambiando el z-index de -1 a 1, no solo hacemos que se vea el contenido de forma translúcida, si no que además no se permitiría la selección por ratón!. He oido por ahí "selection-disabled"?. Lástima que ya exista, pero seguro que algún uso se le puede dar...
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-o-user-select: none;
user-select: none;