NovaMonoFix
Errores PHP
X
Usuario
Password
0 FPS

Algunos efectos para botones en CSS

16 de Marzo del 2016 por Josep Antoni Bover, 0 visitas, 0 comentarios, 0 votos
Categorías : CSS, HTML, Programación.
La web está en segundo plano, animación en pausa.
Cargando animación...
Algunos efectos para botones en CSS

La intención de este documento es mostrar la forma de exprimir al máximo una simple etiqueta <button> añadiendo transiciones y transformaciones para cada uno de sus estados.

Lo que mas claro nos debe quedar a la hora de trabajar con botones son sus estados. En esencia una etiqueta <button> puede tener los siguientes estados :

Para ponernos en la situación, imaginaros que pasa al hacer click encima de un botón. Para empezar el evento :hover ya ha saltado antes de hacer el click por haber entrado dentro del área del botón. A parte al hacer el click se manda el evento :active, y además si el foco actual no es el botón en el que se hace el click, se recibe el evento :focus por que ahora lo será.

Con esta breve explicación lo que os quiero hacer ver, es que hay que pensar muy bien como distribuir las transiciones para cada evento, ya que si se activan las tres a la vez se pueden acabar pisando entre ellas. (en lo personal me pasa muchisimo utilizando transformaciones)

Para evitar que las transiciones se pisen la idea es distribuir el control en 3 capas :

Aunque los ejemplos funcionan perfectamente tanto en Firefox como en Explorer 11, recomiendo visualizar este documento con Google Chrome para obtener una mejor experiencia. Ya que en IE hay animaciones del documento que no funcionan, y en firefox el render del CSS en 3D no es de lo mejor que he visto...

Definiendo las capas

He creado varias transiciones para el hover en este documento, por lo que me ha resultado mas fácil crearme una base para los botones con los parámetros por defecto, para luego ir adaptando-los a cada transición.

El primer paso consistirá en crear un marco con el borde negro, fondo transparente, y el texto de color blanco, al que definiremos sus tres estados por defecto (:hover, :focus, :active).

Cuerpo estándar para el botón (Capa principal)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/* Clases que empiezan por 'Boton-' */
[class^='Boton-'] {
border : 2px solid #000; /* 2 pixeles de borde negro */
text-align : center; /* Texto centrado */
text-decoration : none; /* Sin decoraciones para el texto (por defecto viene con underline) */
padding : 10px; /* Un poco de padding para que se vea bien el botón */
/* La transición en el click (:active) tiene que ser rápida 150ms (transform y color), la transición para cambiar de foco en 150ms */
transition : transform 0.15s ease-in-out, color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
font-family : Karla, sans-serif; /* Fuente de google */
font-size : 1.7rem; /* Tamaño de la fuente */
color : #FFF; /* Color del texto en blanco */
margin : 10px; /* 10 pixeles de margen para separar los botones entre si. */
position : relative; /* Posición relativa para que sus hijos partan desde él */
overflow : hidden; /* Todo lo que sobresalga del botón no se verá */
cursor : pointer; /* Puntero del mouse que muestre una mano */
transform : perspective(600px) translateZ(0px) rotateZ(0deg) rotateX(0deg); /* Perspectiva, rotación y posición por defecto */
text-shadow : 1px 1px 1px #666; /* Una ligera sombra gris para el texto */
}
/* Elimino el outline del botón por una transición con la sombra */
[class^='Boton-']:focus {
outline : 0px solid transparent; /* Elimino el outline que viene por defecto en los button */
box-shadow : 0px 0px 4px 2px #800, 0px 0px 2px 1px #300; /* Creo uan sombra en gris oscuro con 2 tonalidades */
}
/* Alejo el objeto en la perspectiva cuando el usuario presiona sobre él */
[class^='Boton-']:active {
transform : perspective(600px) translateZ(-75px) rotateZ(-0.5deg) rotateX(-10deg); /* Creo el efecto de hundimiento para el botón */
color : #BBB; /* Cambio el color del texto a gris */
}
/* Color del borde rojo al pasar el mouse por encima del botón */
[class^='Boton-']:hover, [class^='Boton-']:active { border : 2px solid darkred; }

Para terminar con las capas por defecto, vamos a crear las capas animación y fondo (::before, ::after)

Cuerpos estándar para los pseudo-elementos ::before (Capa animación) y ::after (Capa fondo)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* Preparación para los pseudo elementos before y after */
[class^='Boton-']::before, [class^='Boton-']::after {
content : ''; /* Contenido (requerida para inicializar el pseudo-selector) */
position : absolute; /* Posición absoluta (relativa al button) */
top : 0px; /* Empezamos desde arriba del <button> */
left : 0px; /* Empezamos desde la izquierda del <button> */
width : 100%; /* Ancho 100% del <button> */
height : 100%; /* Alto 100% del <button> */
transition : 0.4s ease-in-out; /* Transición para el hover de 500ms para que se vea bien (capa animación) */
}
/* Para las transiciones del fondo a color rojo en el hover, se utilizara el pseudo elemento ::before (capa animación) */
[class^='Boton-']::before {
z-index : -1; /* MUY IMPORTANTE esta capa va por debajo de la capa principal */
}
/* Para mostrar el fondo negro del botón se utilizara el pseudo elemento ::after (capa fondo) */
[class^='Boton-']::after {
z-index : -2; /* MUY IMPORTANTE esta capa va por debajo de la capa animación */
background-color : rgb(60,60,60); /* Color del fondo gris oscuro */
}

Lo más importante de este fragmento de código son los z-index para colocar cada capa en su sitio, y la propiedad transition por defecto a 400ms para TODAS las propiedades.

A partir de aquí ya tenemos un botón básico con una transición en el :focus, y una transición en el :active. Mantén pulsado el mouse sobre el botón, y luego haz click fuera de él para ver las transiciones de los eventos :active y :focus.

Ahora viene la parte divertida donde vamos a crear varios efectos hover partiendo de esta base.


Efecto box-shadow

El efecto box-shadow consiste en crear una sombra por dentro del botón hasta ocupar el 100% de su área. El primero empezará desde las puntas y terminara dentro, y el segundo empezara desde dentro para terminar en las puntas.

Echad un vistazo al concepto :

Clases Boton-BoxShadow
1
2
3
4
5
6
7
8
9
10
/* Sombra interior que crece desde las puntas hacia el centro */
.Boton-BoxShadow1::before { box-shadow : 0px 0px 0px 0px transparent inset; }
.Boton-BoxShadow1:hover::before,
.Boton-BoxShadow1:active::before { box-shadow : 0px 0px 30px 25px #ea504e inset; }
/* Efecto invertido (crece desde el centro hacia las puntas)
en este caso lo más fácil es hacer el fondo rojo, mientras que el box-shadow empezara cubriendo el fondo de color gris oscuro */
.Boton-BoxShadow2::before { box-shadow : 0px 0px 30px 25px rgb(60,60,60) inset; }
.Boton-BoxShadow2:hover::before,
.Boton-BoxShadow2:active::before { box-shadow : 0px 0px 0px 0px transparent inset; }
.Boton-BoxShadow2::after { background-color : #ea504e !important; }

La cosa es muy simple asignamos el tamaño normal y el tamaño del estado hover de la sombra para generar la transición.

Para invertir el efecto en la clase Boton-BoxShadow2 he optado por la solución mas fácil, y se podría decir que hecho trampa, ya que el fondo en este caso ya no es gris, si no rojo, y la sombra empieza con el 100% del área para terminar al 0% en el evento :hover.
Esto es mas bien una manía por mi parte, pero no se si os habéis preguntado ¿por qué en el selector del .Boton-BoxShadow:hover::before también incluyo el .Boton-BoxShadow:active::before? y os voy a responder con otra pregunta, ¿que pasa si mantenemos pulsado un botón, y sin soltar el botón nos movemos fuera de él? Probad en un Box-Shadow, y luego en el Test sin el selector.

Ahora haced click una vez mas en el botón 'Test sin el selector ...', una vez soltado el botón del mouse, moved el mouse fuera del área del bóton, y presionad la tecla 'espacio' durante 3 segundos, si lo habéis hecho correctamente, no habreis visto el efecto del hover al pulsar el espacio.

La solución a estas dos situcaciones, es tratar el selector :active del mismo modo que tratamos el selector :hover.

Efecto LinealGradient

Antes de nada vamos a ver gráficamente como funciona esta transición. En el siguiente concepto podemos ver que la capa animación es mas ancha de lo normal y se desplaza de izquierda a derecha.

La idea es hacer un degradado un 400% mas ancho que el botón, que en una punta sea rojo yu en la otra transparente. Luego solo hay que desplazarlo lateralmente.

Un 400% puede parecer exagerado, de hecho mis cálculos iniciales eran para un 300% aproximadamente PERO no tuve en cuenta el ángulo de 45 grados a la hora de calcular el degradado, y al probar con algunos botones de 20x20 pixeles en mi web, me ha hecho falta hasta un 400% (con un 350% aún se veía una punta roja).
Clases Boton-LinearGradient1 y Boton-LinearGradient2
1
2
3
4
5
6
7
8
9
10
11
12
/* Desplazamiento lateral del fondo que contiene un degradado lineal. */
.Boton-LinearGradient1::before, .Boton-LinearGradient2::before { width : 400%; }
.Boton-LinearGradient1::before {
background-image : linear-gradient(45deg, #ea504e 40%, transparent 60%); /* Degradado rojo-transparente */
left : -300%;
}
.Boton-LinearGradient2::before {
background-image : linear-gradient(45deg, transparent 40%, #ea504e 60%); /* Degradado transparente-rojo */
left : 0%;
}
.Boton-LinearGradient1:hover::before, .Boton-LinearGradient1:active::before { left : 0%; }
.Boton-LinearGradient2:hover::before, .Boton-LinearGradient2:active::before { left : -300%; }

En realidad el código no tiene mucha complicación, como ya he mencionado antes asignamos un ancho del 400% con la propiedad width, creamos unos degradados con la propiedad background-image y la función linear-gradient, y los desplazamos desde su posición inicial hasta su posición final con la porpiedad left.


Efecto LinearGradient 3

Este efecto viene a ser los efectos LinearGradient1 y LinearGradient2 a la vez. Para construir este efecto, esta vez vamos a utilizar una transición tanto en la capa ::before como en la capa ::after. Echa un vistazo al concepto para este efecto :

Clases Boton-LinearGradient3
1
2
3
4
5
6
7
8
9
10
11
12
/* Desplazamiento desde el centro a los laterales con un degradado lineal utilizando el pseudo-elemento ::before (para el degradado) */
.Boton-LinearGradient3::before, .Boton-LinearGradient3::after { width : 300%; }
.Boton-LinearGradient3::before {
background-image : linear-gradient(45deg, #ea504e 40%, transparent 60%); /* Degradado de rojo a transparente */
left : -200%; /* Posición X al -200% */
}
.Boton-LinearGradient3::after {
background-image : linear-gradient(45deg, rgb(60,60,60) 40%, #ea504e 60%); /* Degradado de gris a rojo */
left : 0%; /* Posición X al 0% */
}
.Boton-LinearGradient3:hover::before, .Boton-LinearGradient3:active::before { left:0%; }
.Boton-LinearGradient3:hover::after, .Boton-LinearGradient3:active::after { left:-200%; }

La capa ::before tiene un degradado de rojo a transparente, y la capa ::after tiene un degradado de gris a rojo. De esta forma aprovechamos la capa del fondo para hacer una segunda transición.


Efecto 3D

Los efectos 3d consisten en rotar la capa ::before ajustando el origen de la transformación a un lado del botón. Veamos el concepto :

Clases Boton-3D
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.Boton-3DSuperior::before, .Boton-3DInferior::before,
.Boton-3DLateralD::before, .Boton-3DLateralI::before {
background-color : #ea504e;
transition : 0.4s cubic-bezier(.7,.24,0.26,1.52);
}
/* Inicialmente el eje X rotado 90 grados */
.Boton-3DSuperior::before { transform-origin : top center; transform : perspective(600px) rotateX(-90deg); }
.Boton-3DInferior::before { transform-origin : bottom center; transform : perspective(600px) rotateX(90deg); }
/* En el hover devolvemos la rotación del eje X a 0 grados */
.Boton-3DSuperior:hover::before, .Boton-3DInferior:hover::before,
.Boton-3DSuperior:active::before, .Boton-3DInferior:active::before { transform : perspective(600px) rotateX(0deg); }
/* Inicialmente el eje Y rotado 90 grados */
.Boton-3DLateralD::before { transform-origin : center right; transform : perspective(600px) rotateY(-90deg); }
.Boton-3DLateralI::before { transform-origin : center left; transform : perspective(600px) rotateY(90deg); }
/* En el hover devolvemos la rotación del eje Y a 0 grados */
.Boton-3DLateralD:hover::before, .Boton-3DLateralI:hover::before,
.Boton-3DLateralD:active::before, .Boton-3DLateralI:active::before { transform : perspective(600px) rotateY(0deg); }

En primer lugar hay que aplicar el transform-origin para cada lateral, y luego hay que utilizar la propiedad transform para rotar el eje X (para los laterales superior e inferior), y para rotar el eje Y (para los laterales derecho e izquierdo).

Por último en el :hover devolvemos la rotación del eje X/Y a 0.


Efecto circular

Por ultimo el efecto circular consiste en centrar la capa animación con un tamaño inicial de 0 de altura por 0 de ancho para agrandarla en el :hover.

Clase Boton-Circular
1
2
3
4
5
6
7
8
9
10
11
/* Circulo creciendo desde el centro */
.Boton-Circular::before {
border-radius : 100%; /* Borde redondeado */
width : 0px; /* Ancho a 0 */
height : 0px; /* Altura a 0 */
background-color : #ea504e; /* Color del fondo rojo */
top : 50%; /* top al 50% */
left : 50%; /* left al 50% */
transform : translateX(-50%) translateY(-50%); /* Transformación para el centrado */
}
.Boton-Circular:hover::before, .Boton-Circular:active::before { width:300px; height:300px; }
  • Circular

Lo mas importante de este fragmento de código son las lineas 7, 8, 9 que centran la capa animación sea cual sea su tamaño. Para ello asignamos la propiedades top y left al 50%, para luego utilizar la propiedad transform con un -50% a las coordenadas X e Y.

Finalmente en el evento :hover establecemos las propiedades width y height a 300 pixeles.

Lo malo de este efecto es que para que salga un círculo perfecto debemos asignar el width y el height al mismo tamaño si queremos que el efecto sea circular, y no elíptico. Esto puede ser un problema a partir de ciertos tamaños, ya que contra mas grande sea el circulo final, mas rápida será la transición hasta el punto de que llegue a ser imperceptible.

Ejemplo completo

Y esto es todo por hoy, como siempre tenéis el ejemplo completo a vuestra disposición para que podáis hacer las pruebas que queráis.