Uno de los elementos más comunes de un sitio web, es el slider o carrusel de fotos, muy útil no sólo para mostrar galerías sino para mostrar contenido publicitario dentro de nuestro página. Por esa razón, vamos a realizar un slider muy sencillo únicamente con CSS y PHP ¡Manos a la obra!
Tabla de Contenido
Preparando el camino para nuestro slider
Dentro de la carpeta del proyecto, necesitamos crear una subcarpeta para guardar las imágenes.
En esa subcarpeta, colocamos las imágenes que necesitamos para nuestro slider, preferentemente deben tener las mismas dimensiones. Para facilitar aún más el trabajo hemos cambiado los nombres de las imágenes por un número consecutivo.
También necesitamos una base HTML en nuestro archivo PHP (Esto se puede omitir si ya lo tenemos)
<!doctype html>
<html lang="es">
<head>
<meta lang="es" />
<meta charset="utf-8" />
<title>Slider con CSS y PHP</title>
</head>
<body>
</body>
</html>
Trabajando con PHP primero
Comencemos nuestro trabajo, creando dentro del <body> un <div> al que le pondremos como nombre de clase slider.
<div class="slider"></div>
Necesitamos abrir un bloque de código PHP dentro del <div> En esa primera parte, creamos un array para los números de cada imagen, otro para los texto del atributo alt y una variable que obtenga siempre la cantidad de elementos a utilizar con la función count.
<?php
$ids = array(1,2,3,4,5);
$alt = array(
"Slide 1",
"Slide 2",
"Slide 3",
"Slide 4",
"Slide 5"
);
$max = count($ids);
Con un ciclo (for, while, etc) creamos tantos botones tipo radio como la variable max nos indique, estos botones usarán como id el número de cada imagen contenido dentro del array, por lo que usaremos la variable que hagamos dentro del ciclo para irlo recorriendo. Además deben compartir un nombre único y estar ocultos.
for($s=0;$s<$max;$s++){ ?>
<input type="radio" id="<?= $ids[$s]; ?>" name="image-slide" hidden />
<?php } ?>
Inmediatamente, creamos un nuevo <div> al que llamaremos slideshow ya que esté será el que mostrarás las imágenes.
<div class="slideshow"></div>
Dentro de ese <div> haremos un ciclo con PHP que nos permita recorrer los array que creamos al principio.
<?php for($s=0;$s<$max;$s++){ ?>
Creamos un nuevo <div> con nombre de clase item-slide.
<div class="item-slide"></div>
Dentro de ese <div> colocaremos una etiqueta <img /> que llame a través de su atributo src a las imágenes tomándolas una a una del array. También asignaremos el atributo alt usando el otro array.
<img src="img/<?= $ids[$s]; ?>.jpg" alt="<?= $alt[$s]; ?>" />
Ahora cerramos el ciclo.
<?php } ?>
Así va nuestro código hasta el momento:
Debajo de la última línea de código, vamos a crear otro <div> más. Le llamaremos pagination, ya que será el encargado de la paginación de las imágenes.
<div class="pagination"></div>
Ahí dentro, repetimos el mismo ciclo de hace rato (Se puede copiar y pegar)
<?php for($s=0;$s<$max;$s++){ ?>
Crearemos un <label> con nombre de clase pag-item ya que cada uno de estos serán los que harán avanzar el slider. También hacemos con su atributo for que apunten a los botones de radio que creamos al principio a través del número correspondiente a cada imagen.
<label class="pag-item" for="<?= $ids[$s]; ?>"></label>
Dentro de ese <label> cargamos la imagen de nuevo, tal como lo hicimos antes.
<img src="img/<?= $ids[$s]; ?>.jpg" alt="<?= $alt[$s]; ?>" />
Y cerramos el ciclo.
<?php } ?>
Ese último bloque de código debe quedar como se muestra:
Es hora de hacer que nuestro slider funcione con CSS
Primero enlacemos nuestro archivo a un CSS que debemos crear.
<link href="slider.css" rel="stylesheet" type="text/css" />
Dentro de nuestro archivo CSS, primero cargamos el charset UTF-8
@charset "utf-8";
Después, haremos un pequeño reset (Este es opcional y se puede omitir si ya se cuenta con uno)
body, html, div, img{
margin: 0;
padding: 0;
}
Comencemos con el contenedor para el slider. Será una caja flexible (flexbox) con un ancho al 100%, todo el contenido centrado, una posición relativa y por supuesto ocultaremos todo lo que se desborde.
.slider{
width: 100%;
display: flex;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
}
Haremos también que las imágenes dentro del contenedor, nunca rebasen el ancho máximo de este.
.slider img{ max-width: 100%; }
Nuestro slideshow será también un flexbox con una transformación 3D inicialmente en o y tendrá un efecto de transition de 2500 ms. También haremos que invoque a una animación llamada autoplay (hay que crearla más adelante) está durará 25 segundos y se reproducirá de forma infinita.
.slideshow{
display: flex;
transform: translate3d(0, 0, 0);
transition: all 2500ms;
animation-name: autoplay;
animation-duration: 25s;
animation-direction: alternate;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
}
Cada elemento del slide será un flexbox con posición relativa, también ajustaremos algunas características del flexbox para asegurarnos que este uno después del otro.
.item-slide{
position: relative;
display: flex;
width: 100%;
flex-direction: column;
flex-shrink: 0;
flex-grow: 0;
}
La paginación será otro flexbox, pero con posición absoluta. Lo separamos 20 píxeles de la parte inferior de su contenedor y centramos todo su contenido.
.pagination{
position: absolute;
bottom: 20px;
left: 0;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
width: 100%;
}
Cada botón del cuadro de paginación será un cuadrado de 16×16 píxeles con las esquinas redondas. Lo pintamos de blanco, le ponemos una separación de 10 píxeles de izquierda a derecha y le ponemos una transición de 800ms (Puede variar a gusto)
.pag-item{
display: flex;
flex-direction: column;
align-items: center;
border: 2px solid #CCC;
width: 16px;
height: 16px;
border-radius: 5px;
overflow: hidden;
cursor: pointer;
background: rgba(255, 255, 255, 0.5);
margin: 0 10px;
text-align: center;
transition: all 800ms;
}
Después, haremos que al pasar el ratón encima de cada uno de esos botones, crezca al doble de su tamaño.
.pag-item:hover{ transform: scale(2); }
A la imagen dentro del elemento de la paginación, la convertimos en un inline-block, le quitamos la opacidad, la obligamos a ajustarse a la escala de su contenedor al eliminar su ancho y ponerle una altura de 100%. También haremos que tenga una breve transición de 300 milisegundos al pasar el ratón.
.pag-item img{
display: inline-block;
max-width: none;
height: 100%;
transform: scale(1);
opacity: 0;
transition: all 300ms;
}
Por supuesto, al pasar el ratón sobre esa imagen, le regresamos la opacidad.
.pag-item:hover img{
opacity: 1;
}
Colocando la animación y transiciones finales
Por supuesto, necesitamos que se realice la animación. En este punto, debemos recordar cuantas imágenes tenemos en nuestro slider y dividir 100 entre ese número. En nuestro caso tenemos 5, así que 100 / 5 = 20. Esto significa que cada 20% necesitamos hacer una traslación del eje horizontal.
Con @keyframes, es momento de crear nuestra animación llamada autoplay. Con la función calc, haremos el movimiento del eje horizontal de 20 en 20. Observe el código.
@keyframes autoplay{
20%{ transform: translate3d(calc(-100% * 0), 0, 0); }
40%{ transform: translate3d(calc(-100% * 1), 0, 0); }
60%{ transform: translate3d(calc(-100% * 2), 0, 0); }
80%{ transform: translate3d(calc(-100% * 3), 0, 0); }
100%{ transform: translate3d(calc(-100% * 4), 0, 0); }
}
La razón por la que se mueve así, es que en el eje horizontal, la primera imagen ocupa la posición 0, la siguiente imagen ocupa la posición 1 y así sucesivamente.
Para hacer la paginación funcional, necesitamos que cada elemento de la paginación realice la misma acción que la animación, pero en su correspondiente posición. Esto lo logramos haciendo que cada input (iremos uno por uno, pero se puede lograr una optimización con algún preprocesador) a través de su id realice esa acción y que además pare la animación en curso para que no se vea raro el cambio de dirección.
input[id="1"]:checked ~ .slideshow{
animation: none;
transform: translate3d(cal(-100% * 0),0,0);
}
input[id="2"]:checked ~ .slideshow{
animation: none;
transform: translate3d(cal(-100% * 1),0,0);
}
input[id="3"]:checked ~ .slideshow{
animation: none;
transform: translate3d(cal(-100% * 2),0,0);
}
input[id="4"]:checked ~ .slideshow{
animation: none;
transform: translate3d(cal(-100% * 3),0,0);
}
input[id="5"]:checked ~ .slideshow{
animation: none;
transform: translate3d(cal(-100% * 4),0,0);
}
Como detalle adicional, podemos resaltar el elemento de la paginación utilizado, simplemente lo pintaremos de blanco cuando se le click.
input[id="1"]:checked ~ .pagination .pag-item[for="1"]{
background: #FFF;
}
input[id="2"]:checked ~ .pagination .pag-item[for="2"]{
background: #FFF;
}
input[id="3"]:checked ~ .pagination .pag-item[for="3"]{
background: #FFF;
}
input[id="4"]:checked ~ .pagination .pag-item[for="4"]{
background: #FFF;
}
input[id="5"]:checked ~ .pagination .pag-item[for="5"]{
background: #FFF;
}
Por supuesto, esta última parte se puede optimizar todavía más.
Probemos el resultado final
Si todo salió bien, este debe ser el resultado que obtenemos.
DESCARGA EL CÓDIGO FUENTE ORIGINAL PARA PROBAR
¡Y eso es todo por ahora! ¿Te ha resultado? Déjanos saber en los comentarios aquí abajo, en nuestra cuenta de twitter @cablenaranja7 o en nuestra página de facebook.
Docente, IT Manager, Blogger & Developer. Escribo por diversión, educo por pasión. | Grandstanding is not my thing.
Felicidades excelente explicaición, contenido en tu sitio, y para mi es de suma ayuda.
100% php
¡Gracias! Me alegra que te sea de utilidad.
Gracias por la información es de utilidad.
Muchas gracias! excelente explicación y ejemplos. Genial!
Excelente muchas gracias
Gracias, muy inspirador:
Estoy intentando usarlo para una web de arte en la que quiero mostrar 13 imágenes, pero sólo me muestra hasta cinco, a partir de la seis vuelve a contar como la primera; me estoy volviendo loco y no doy cual puede ser el problema. El array lo he ampliado a 13 (1,2,3,4,5,6,7,8,9,10,11,12,13). Las imágenes jpg. están también numeradas hasta trece…en fin. ¿Cual puede ser el problema? Todo va bien excepto que no consigo presentar más de 5 imágenes.
Saludos Jesús, gracias por tus palabras.
Respecto a lo que comentas, seria bueno ver cómo haces el código que muestra las imágenes.
Sí, ya lo encontré. No había colocado bien el índice de numeración en la función calc() de los @keyframes. Ahora pretendo colocar 41 imágenes pero se me hace muy engorroso colocar 41 porcentajes de distribución y la cantidad de inputs se acrecienta; ¿qué es el preprocesador?
Así es como se ve ahora, está en proceso aunque el aspecto minimalista es intencionado, quiero que predomine la muestra de imágenes: https://elargo.art
Se ve bastante bien.
Un preprocesador es una herramienta para escribir código CSS de una manera en teoría más sencilla (aunque si lo utilizas mal, puede ser todo lo contrario)
Si se te complica mucho, puedes ocupar Javascript, concretamente jquery. Aquí tienes una lista de galerías que lo utilizan: https://www.creativosonline.org/plugins-jquery-para-galerias-de-fotos.html