El hombre nunca sabe de lo que es capaz hasta que lo intenta. Charles Dickens

Generar prefijos CSS3 con PHP

Los navegadores actuales soportan las propiedades CSS3 con prefijos específicos para cada tipo de navegador, hasta que la propiedad sea aprobada y finalizada por el W3C. Eso significa mucha repetición a la hora de escribir código. Pongamos como ejemplo la siguiente declaración:

#caja{
	-moz-border-radius: 5px;
	-o-border-radius: 5px;
        -ms-border-radius: 5px;
	border-radius: 5px;
}

Más código significa mayores probabilidades de cometer errores y produce hojas de estilos que son más largas y más difícil de mantener. En lugar de escribir el prefijo específico del tipo de navegador y los valores una y otra vez, podemos utilizar PHP para generarlo por nosotros.

Podemos utilizar una función PHP para producir el código CSS3. La función tendrá que saber dos cosas: el nombre de base de la propiedad (por ejemplo, border-radius) y el valor asociado a ella ("5px"). Por lo tanto, deberíamos escribir:

<?php
header('Content-type: text/css');

function css3_write ($property, $value) {
	$css3 = "-webkit-".$property.": ".$value.";\n"
	." -moz-".$property.": ".$value.";\n"
	." -o-".$property.": ".$value.";\n"
	." -ms-".$property.": ".$value.";\n"
	." ".$property.": ".$value.";\n";
	echo $css3;
} ?>

La primera línea es para indicar el tipo de contenido del archivo php. Obviamente a la hora de invocar nuestra hoja de estilos lo haremos llamando el archivo php:

<link rel='stylesheet' type='text/css' href='css/estilos.php' />

En la función css3_write queremos producir la correspondiente declaración de CSS para todos los navegadores. La propiedad base se incluye al final, como fallback. Construiremos la declaración utilizando una serie de concatenaciones y utilizando \n (nueva línea) para hacer que la función escriba un CSS más legible.

Para producir nuestro CSS3 tan sólo tenemos que llamar a la función con la propiedad CSS3 y el valor para dicha propiedad. Por ejemplo:

#caja {
	border: 1px solid black;
	background: #fff;
    <?php css3_write("border-radius", "5px"); ?>
	width: 50%;
    <?php css3_write("box-shadow", "5px 5px 2px rgba(0, 0, 0, 0.5)"); ?>
}

Lo que generará el siguiente código:

#caja {
	border: 1px solid black;
	background: #fff;
	-webkit-border-radius: 5px;
	-moz-border-radius: 5px;
	-o-border-radius: 5px;
	-ms-border-radius: 5px;
	border-radius: 5px; width: 50%;
	width: 50%;
	-webkit-box-shadow: 5px 5px 2px rgba(0, 0, 0, 0.5);
	-moz-box-shadow: 5px 5px 2px rgba(0, 0, 0, 0.5);
	-o-box-shadow: 5px 5px 2px rgba(0, 0, 0, 0.5);
	-ms-box-shadow: 5px 5px 2px rgba(0, 0, 0, 0.5);
	box-shadow: 5px 5px 2px rgba(0, 0, 0, 0.5);
}

Este método es una alternativa al uso de compiladores como Less o Sass. Para obtener más información acerca de cómo crear CSS con PHP podéis consultar: Controlar CSS con PHP y Comprimir varios CSS en uno con PHP.

Fullscreen Layout con transiciones entre páginas

En Codrops han publicado un interesante ejemplo de cómo realizar un layout responsive con transiciones. Se presentan cuatro elementos o secciones de forma inicial en la página y haciendo click sobre cada una de las secciones, ésta se expandira. Todos los efectos se realizan con transiciones CSS y se controlan con Javascript mediante la aplicación de clases. El diseño es líquido y se han agregado algunas media queries para mejorar la visualización en pantallas de pequeño tamaño.

Fullscreen Layout con transiciones entre páginas

Desde la página de Codrops se puede tanto acceder a la demo como descargar los archivos fuente.

Fullscreen Layout with Page Transitions » »

Insertar Contadores generados con CSS

En el artículo "How To Benefit From CSS Generated Content And Counters" de Smashing Magazine nos ofrecen un interesante tutorial acerca de como agregar contenido con CSS. El tutorial abarca desde la adición de cadenas de texto o imágenes hasta la adición de contadores. En este post se realiza una traducción libre de esta parte de dicho tutorial.

Se puede insertar contenido generado desde una hoja de estilo, antes y después el contenido de un elemento, utilizando los pseudo-elementos :before y :after, respectivamente. Para representar los pseudo-elementos podemos utilizar el siguiente ejemplo:

<p>
   <before>Inicio</before>
	Contenido
   <after>Final</after>
</p>

Y el CSS sería

p:before {
   content: "Inicio";
}
p:after {
   content: "Final";
}

Ten en cuenta que si estás validando el archivo CSS contra las especificaciones CSS3, los pseudo-elementos :before y :after deberían escribirse como ::before y ::after. De lo contrario, el validador CSS dará un error.

Insertar contadores

La numeración automática de CSS es controlada por dos propiedades, counter-reset y counter-increment. Los contadores definidos por estas propiedades se utilizan con las funciones counter() y counters() de la propiedad content. La propiedad counter-reset puede contener uno o más nombres de contadores, opcionalmente seguidos por un número entero. El entero establece el valor que se incrementa por la propiedad counter-increment para cualquier coincidencia con el elemento dado. El valor predeterminado es 0. Se admiten valores negativos. La propiedad counter-increment es similar. La diferencia fundamental es que ésta incrementa un contador. El incremento de su valor por defecto es 1. También se admiten valores negativos.

Vamos a ver ahora un ejemplo:

<dl>
   <dt>elemento</dt>
   <dd>descripción</dd>
   <dt>elemento</dt>
   <dd>descripción</dd>
   <dt>elemento</dt>
   <dd>descripción</dd>
</dl>

Queremos agregar numeración progresiva (1, 2, 3, etc.) para cada definición (dt) de la lista. El CSS:

dl {
   counter-reset: item;
}
dt:before {
   counter-increment: item;
   content: counter(item);
}

Ver ejemplo en funcionamiento » »

La primera regla establece un contador para la lista de definiciones. A esto se le denomina "scope" o "alcance". El nombre (o identificador) del contador es item. Cualquier nombre que elijamos para nuestro contador debe ser idéntico al de la propiedad counter-increment.

En la segunda regla, asociamos el pseudo-elemento :before al elemento dt, ya que queremos insertar el contador precisamente antes del contenido del elemento. La función counter() acepta nuestro identificador item como argumento, y la propiedad content genera el contador.

No hay ningún espacio entre el número y el contenido del elemento. Si queremos añadir, por ejemplo, un punto y un espacio después del número, podríamos insertar la siguiente cadena en la propiedad content:

dt:before {
   content: counter(item) ". ";
}

Ver ejemplo en funcionamiento » »

Podemos agregar más estilos a los contadores aplicando otras propiedades al pseudo-elemento. Por ejemplo:

dt:before {
   padding: 1px 2px;
   margin-right: 0.2em;
   background: #ffc;
   color: #000;
   border: 1px solid #999;
   font-weight: bold;
   content: counter(item);
   counter-increment: item;
}

Ver ejemplo en funcionamiento » »

Además, los contadores pueden ser negativos. Por ejemplo, si necesitamos numeración progresiva a partir de 0, podríamos escribir lo siguiente:

dl {
   counter-reset: item -1;
}
dt:before {
   counter-increment: item;
   content: counter(item) ". ";
}

Ver ejemplo en funcionamiento » »

Al establecer la propiedad counter-reset en -1 e incrementándola en 1, el valor resultante es 0, y la numeración comenzará a partir de ese valor. Los contadores negativos pueden combinarse con contadores positivos para lograr efectos interesantes. Por ejemplo:

dl {
   counter-reset: item -1;
}
dt:before {
   counter-increment: item 3;
   content: counter(item) ". ";
}

Ver ejemplo en funcionamiento » »

Como veis, sumar y restar números positivos y negativos produce una amplia gama de combinaciones entre contadores. Con sólo unos simples cálculos, obtenemos un completo control sobre la numeración automática.

Otra característica interesante de los contadores CSS radica en su capacidad para anidar. De hecho, la numeración también se puede ordenar por subniveles progresivos, como 1.1, 1.1.1, 2.1 y así sucesivamente. Para agregar un subnivel a los elementos en la lista, deberías escribir lo siguiente:

HTML:

<ol>
    <li>elemento</li>
    <li>elemento
        <ol>
            <li>elemento</li>
            <li>elemento</li>
            <li>elemento
                <ol>
                    <li>elemento</li>
                    <li>elemento</li>
                </ol>
            </li>
        </ol>
    </li>
</ol>

CSS:

ol {
   counter-reset: item;
   list-style: none;
}
li {
   display: block;
}
li:before {
   counter-increment: item;
   content: counters(item, ".") " ";
}

Ver ejemplo en funcionamiento » »

En este ejemplo, tenemos sólo el contador item para cada nivel de anidamiento. En lugar de escribir tres contadores diferentes (como item1, item2, item3) y creando tres alcances o "scopes" diferentes para cada elemento ol anidado, contamos con la función counters() para lograr este objetivo. La segunda regla es importante y merece una explicación. Las listas ordenadas tienen marcadores por defecto (es decir, números), por lo que nos deshacemos de estos marcadores convirtiendo los elementos de lista en bloques. Recuerda que sólo elementos con display: list-items tienen marcadores.

La tercera regla es la que hace el trabajo. La primera declaración incrementa el contador establecido previamente en la lista. Luego, en la segunda declaración, la función counters() crea todas las instancias del contador para las listas internas. La estructura de esta función es el siguiente:

  • Su primer argumento es el nombre del contador dado, seguido inmediatamente por una coma.
  • Su segundo argumento es un período entre comillas dobles.

Fíjate que hemos introducido un espacio después de la función counters() para separar los números del contenido real de los elementos de lista.

Los contadores están formateados, por defecto, como números decimales. Sin embargo, los estilos de la propiedad list-style-type también están disponibles para los contadores. La notación por defecto es counter(nombre) (es decir, sin estilo) o counter(nombre, 'list-style-type') para cambiar el formato por defecto. En la práctica, los estilos recomendados son los siguientes:

  • decimal
  • decimal-leading-zero
  • lower-roman
  • upper-roman
  • lower-greek
  • lower-latin
  • upper-latin
  • lower-alpha
  • upper-alpha

Veamos un ejemplo:

HTML:

<dl>
	<dt>elemento</dt>
	<dd>descripción</dd>
	<dt>elemento</dt>
	<dd>descripción</dd>
	<dt>elemento</dt>
	<dd>descripción</dd>
</dl>

CSS:

dl {
   counter-reset: item desc;
}
dt:before {
   counter-increment: item;
   content: counter(item, upper-latin) ". ";
}
dd:before {
   counter-increment: desc;
   content: counter(desc, lower-latin) ". ";
}

Ver ejemplo en funcionamiento » »

No te olvides que estamos trabajando con sistemas numéricos. Recuerda también que la especificación no define cómo producir un sistema alfabético más allá del final de un alfabeto. Por lo que los números se recomiendan para largas listas.

También podemos añadir estilos a la función counters()

HTML:

<ol>
    <li>elemento</li>
    <li>elemento
        <ol>
            <li>elemento</li>
            <li>elemento</li>
            <li>elemento
                <ol>
                    <li>elemento</li>
                    <li>elemento</li>
                </ol>
            </li>
        </ol>
    </li>
</ol>

CSS:

ol {
    counter-reset: item;
    list-style: none;    
}

li:before {
	counter-increment: item;
	content: counters(item, ".", lower-roman) " ";
}

li:before { counter-increment: item; content: counters(item, ".", lower-roman) " "; }

Ver ejemplo en funcionamiento » »

Fíjate que la función counters() acepta también un tercer argumento (lower-roman) como el último elemento en la lista de argumentos, separado de los anteriores por una segunda coma. Sin embargo, la función counters() no nos permite especificar diferentes estilos para cada nivel de anidamiento.

CSSmatic: colección de herramientas CSS para diseñadores web

cssmatic.com es un sitio web que nos ofrece unas cuantas interesantes herramientas para crear de forma visual gradientes, texturas sucias, bordes y sombras; obteniendo de forma inmediata el código CSS3. Me ha resultado muy interesante el generador de texturas de sucias; una forma de crear fondos con algo de suciedad o ruido, pudiendo personalizar tanto el color de fondo como el de la suciedad, así como la opacidad y la densidad de la misma.

Generadores online CSS3

cssmatic.com » »

Ceaser: Herramienta para generar animaciones con easing en CSS

Ceaser es una herramienta que nos puede facilitar mucho la tarea de crear animaciones "easing" con CSS. Podemos elegir el tipo de animación además de poder crear una personalizada. Además podemos previsualizar la animación aplicada sobre un elemento. La herramienta nos devuelve el código necesario para implementar este tipo de animación en CSS. Por ejemplo:

-webkit-transition: all 100ms cubic-bezier(0.165, 0.840, 0.440, 1.000);
   -moz-transition: all 100ms cubic-bezier(0.165, 0.840, 0.440, 1.000);
    -ms-transition: all 100ms cubic-bezier(0.165, 0.840, 0.440, 1.000);
     -o-transition: all 100ms cubic-bezier(0.165, 0.840, 0.440, 1.000);
        transition: all 100ms cubic-bezier(0.165, 0.840, 0.440, 1.000); 

Para aquel que desee iniciarse en el mundo de las animaciones con CSS3 puede consultar el post publicado en este blog hace ya algún tiempo: CSS3 Animaciones.

Ceaser. CSS Easing Animation Tool » »