Slider CSS sin Javascript

slider CSS sin JavascriptA día de hoy, todos sabemos cómo incorporar un magnífico slider (como nivo slider) o carrusel a nuestros sitios web. De hecho, unos sabemos cómo hacerlos y otros, aunque no saben realmente cómo hacerlo, sí saben utilizar cualquiera de los múltiples plugins de jQuery que te proporcionan el tan ansiado carrusel. Es más, si utilizas wordpress tienes múltiples plugins de carruseles que ya hacen prácticamente todo el trabajo por ti. Sin embargo, estos slider tienen en común que necesitan JavaScript para funcionar.

Ahora, gracias a CSS3 podemos crear nuestros carruseles sin necesidad de utilizar JavaScript. Suuuuper-cool!! Vamos a ello!!!

En CSS3 tenemos una nueva pseudo-clase “:checked” que nos permite aplicar estilos cuando un input radio/checkbox está seleccionado. Gracias a esta pseudo-clase y a unas reglas CSS un poco más avanzadas de lo normal, lograremos nuestro ansiado objetivo: Un Slider CSS sin Javascript!!

Eso sí, es un trabajo más manual que utilizando Javascript. Si a estas alturas te estás preguntando ¿pseudo-clase? ¿:checked? Es el momento ideal para leer los siguientes artículos dónde se explica al detalle los conceptos básicos de CSS:

El proceso de creación del slider CSS paso a paso

Si quieres ver cómo se va creando paso a paso y/o no te apetece leer, aquí te dejo el vídeo de Youtube asociado a este artículo, dónde voy creando poco a poco el carrusel.

La estructura HTML5 del Slider CSS

Para poder hacer nuestro slider sin utilizar javascript, tendremos que trabajar con una estructura HTML un poco diferente a los carruseles tradicionales. Normalmente un carrusel se hacía con una estructura parecida a esta:

<!DOCTYPE html>
<html>
    <head>
        ....
    </head>
    <body>
        <ul id="slider">
            <li>Slider element 1</li>
            <li>Slider element 2</li>
            <li>Slider element 3</li>
        </ul>
    </body>
</html>

Luego, un JS se encarga de modificar los estilos para crear el efecto del carrusel. En nuestro caso no podemos hacer algo sí, porque no vamos a tener ningún javascript que altere el flujo de nuestra web.

Así pues, lo que vamos a tener como estructura es: Una serie de inputs radio que serán los que utilizaremos para controlar la transición entre los elementos de nuestro carrusel. Según qué input radio esté seleccionado, se mostrará una diapositiva u otra de nuestro slider CSS sin Javascript Para terminar, nuestro carrusel será una serie de etiquetas div, de forma que cada elemento del slider será una etiqueta div.

<!DOCTYPE html>
<html>
    <head>
        <title>Slider CSS - A Slider only with CSS</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link href="http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
        <link href="./style.css" rel="stylesheet" type="text/css" />
    </head>
    <body>
        <div id="page">
            <section>
                <input type="radio" name="slider-select-element" id="element1" checked="checked" />
                <input type="radio" name="slider-select-element" id="element2" />
                <input type="radio" name="slider-select-element" id="element3" />
                
                <div id="slider-container">
                    <div id="slider-box">
                        <div class="slider-element">
                            <article class="element-red">
                                
                            </article>
                        </div>
                        <div class="slider-element">
                            <article class="element-green">
                                
                            </article>
                        </div>
                        <div class="slider-element">
                            <article class="element-blue">
                                
                            </article>                            
                        </div>
                    </div>
                </div>
                
                <div id="slider-arrows">
                    <label for="element1"></label>
                    <label for="element2"></label>
                    <label for="element3"></label>
                </div>
            </section>            
        </div>
    </body>
</html>

La etiqueta label, clave en nuestro Slider CSS sin Javascript

En el código se puede ver cómo cada input radio tiene una etiqueta label asociada, pero no está colocada junto al input, como es habitual en los formularios, sino que los he colocado debajo del carrusel. Esto es porque los input van a estar ocultos por CSS y las etiquetas label son las que van a funcionar como las flechas de anterior/siguiente típicas de un slider. Por supuesto, en vez de como flechas de anterior/siguiente también pueden funcionar como los típicos botones circulares apareciendo todos juntos y que según pinches en uno u otro se mostrará la diapositiva del carrusel que corresponda.

El código CSS para crear nuestro slider CSS sin utilizar Javascript

/* 
    Slider CSS
    Created on : 23-abr-2014, 18:28:01
    Author     : Rolando Caldas <rolando.caldas@gmail.com>
*/

* {
    box-sizing: border-box;
}

body {
    text-align: center;
}

input[name="slider-select-element"] {
    display: none;
}

#slider-arrows {
    margin: -10% auto 0 auto;
    width: 80%;
}

#slider-box {
    height: 100%;
    width: 300%;
}

#slider-container {
    height: 20%;
    margin: 0 auto;
    overflow: hidden;
    text-align: left;
    width: 80%;
}

.element-blue,
.element-green,
.element-red {
    min-height: 400px;
    max-height: 100%;
    width: 100%;
}

.element-blue {
    background: blue;
}

.element-green {
    background: green;
}

.element-red {
    background: red;
}

.slider-element {
    float: left;
    width: 33.333%;
}

#element1:checked ~ #slider-arrows label:nth-child(2),
#element2:checked ~ #slider-arrows label:nth-child(3),
#element3:checked ~ #slider-arrows label:nth-child(1) {
    display: block;
    float: right;
}

#element1:checked ~ #slider-arrows label:nth-child(3),
#element2:checked ~ #slider-arrows label:nth-child(1),
#element3:checked ~ #slider-arrows label:nth-child(2) {
    display: block;
    float: left;
}

#element1:checked ~ #slider-arrows label:nth-child(2):before,
#element2:checked ~ #slider-arrows label:nth-child(3):before,
#element3:checked ~ #slider-arrows label:nth-child(1):before {
    color: black;
    content: "\f054";
    font-family: FontAwesome;
    font-style: normal;
    font-weight: normal;
    line-height: 1;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: antialiased;
}

#element1:checked ~ #slider-arrows label:nth-child(3):before,
#element2:checked ~ #slider-arrows label:nth-child(1):before,
#element3:checked ~ #slider-arrows label:nth-child(2):before {
    color: black;
    content: "\f053";
    font-family: FontAwesome;
    font-style: normal;
    font-weight: normal;
    line-height: 1;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: antialiased;
}

#element1:checked ~ #slider-container #slider-box {
    margin-left: 0;
}

#element2:checked ~ #slider-container #slider-box {
    margin-left: -100%;
}

#element3:checked ~ #slider-container #slider-box {
    margin-left: -200%;
}

#slider-arrows label {
    color: transparent;
    cursor: pointer;
    display: none;
    font-size: 2rem;
    height: 20px;
    width: 20px;
}

#slider-box {
    -webkit-transition: all 0.75s ease;
    -moz-transition: all 0.75s ease;
    -ms-transition: all 0.75s ease;
    -o-transition: all 0.75s ease;
    transition: all 0.75s ease;
}

Vamos a explicar un poco el funcionamiento de este CSS!

El por qué de los anchos utilizados en nuestro carrusel

#slider-box {
    height: 100%;
    width: 300%;
}

#slider-container {
    height: 20%;
    margin: 0 auto;
    overflow: hidden;
    text-align: left;
    width: 80%;
}

.slider-element {
    float: left;
    width: 33.333%;
}

En el CSS tenemos declarado que nuestro #slider-container tiene un ancho de 80% y un overflow hidden, esto lo hacemos para que:

  1. Todo nuestro slider CSS ocupe el 80% de la pantalla y nos salga centrado (el margin auto a izquierda y derecha).
  2. Con el overflow hidden, nos aseguramos de que se oculte el contenido del #slider-container que exceda el tamaño de caja indicado a este div.

En el CSS tenemos declarado que nuestro #slider-box tenga un ancho de 300%. El motivo de esta cifra es que nosotros queremos que cada elemento del slider CSS ocupe el 100% del #slider-container, como tenemos 3 elementos en nuestro carrusel (3 diapositivas), el ancho de su contenedor #slider-box tiene que ser el 100% * 3, o sea, el 300%.

También, en el CSS tenemos que cada elemento del carrusel, asociado a .slider-element, tiene un width del 33.333% y un float left. ¿por qué?:

  1. Queremos que cada elemento del carrusel ocupe el 100% del #slider-container. Como la caja que contiene los elementos del slider CSS (#slider-box) tiene un ancho del 300% (3 veces el #slider-container) cada elemento del carrusel tiene que ocupar 1/3 del #slider-box, porque así tendrá por ancho el 100% del #slider-container. Tiene que ocupar 1/3 porque son 3 elmentos los que tenemos, 1/3 de 100% es, aprox, el 33.333%. Como además, el #slider-container tiene indicado que oculte el contenido que se exceda del ancho de esta caja, sólo se mostrará un elemento del carrusel, ocultando los otros 2.
  2. Los elementos del carrusel flotan para que salgan todos en la misma línea.

Si tuviésemos 4 elementos en el carrusel, en lugar de 3, el #slider-box tendrían un ancho de 400% y el .slider-element tendría un ancho del 25%

Cómo se consigue la transición de los elementos del slider CSS

Cuando utilizamos un selector con ~ como:

#element1 ~ #slider-container {

}

Lo que estamos haciendo es seleccionar todos los #slider-container que vienen precedidos por un #element1

Gracias a esto y a la pseudo-clase :checked podemos mover nuestro #slider-container alterando su margin-left, de forma que según qué input radio esté seleccionado se mostrará un elemento u otro del carrusel:

#element1:checked ~ #slider-container #slider-box {
    margin-left: 0;
}

#element2:checked ~ #slider-container #slider-box {
    margin-left: -100%;
}

#element3:checked ~ #slider-container #slider-box {
    margin-left: -200%;
}

Así se consigue que se mueva nuestro slider CSS 😉 Esto lo combinamos con un efecto transition:

#slider-box {
    -webkit-transition: all 0.75s ease;
    -moz-transition: all 0.75s ease;
    -ms-transition: all 0.75s ease;
    -o-transition: all 0.75s ease;
    transition: all 0.75s ease;
}

Y ya tenemos el carrusel a tope!

Activando las flechas para movernos por el slider CSS

Podríamos dejarlo aquí, tendríamos unos inputs de tipo radio y según el que se marque, se muestra un elemento u otro de nuestro slider CSS. Sin embargo, queda mejor utilizar las típicas flechitas de anterior/siguiente.

Bien, utilizamos la misma idea que para mover nuestro carrusel, pero asociado a los label en vez de al contenedor del slider:

#element1:checked ~ #slider-arrows label {
    display: block;
    float: right;
}

Así lo que hacemos es activar todos los label que hay dentro de #slider-arrows cuando el #element1 esté seleccionado y, además, los flotamos a la derecha. Aunque esto no es exactamente lo que queremos!

Cuando lo que vemos es el primer elemento del carrusel (cuando #element1 está “:checked”), queremos que a la derecha salga la flecha de siguiente y que, al pinchar en ella, el #element2 pase a estar seleccionado. Esto significa que queremos que la flecha de la derecha sea el label asociado a #element2, que es el segundo label dentro de #slider-arrows, por lo que tenemos que informar vía CSS que la regla se aplica sólo al segundo label. ¿Cómo lo hacemos? con el maravilloso nth-child:

#element1:checked ~ #slider-arrows label:nth-child(2) {
    display: block;
    float: right;
}

Con esto ya hacemos que se aplique sólo al label que queremos, esto lo podemos ampliar al resto de casos y a la flecha de la izquierda (anterior) dejando nuestro CSS como es:

#element1:checked ~ #slider-arrows label:nth-child(2),
#element2:checked ~ #slider-arrows label:nth-child(3),
#element3:checked ~ #slider-arrows label:nth-child(1) {
    display: block;
    float: right;
}

#element1:checked ~ #slider-arrows label:nth-child(3),
#element2:checked ~ #slider-arrows label:nth-child(1),
#element3:checked ~ #slider-arrows label:nth-child(2) {
    display: block;
    float: left;
}

Slider CSS sin Javascript listo para funcionar

Compatibilidad del Slider CSS con los navegadores

Para que este slider CSS funcione, es necesario que se ejecute desde un navegador moderno, con soporte de HTML5. Por ejemplo, lo más escandaloso ocurre con los dispositivos android. Cuando accedes desde la versión para android de Chrome, todo va bien,  el slider funciona perfecto… pero si se abre desde el navegador por defecto de android (Internet o Navegador, esta app que tiene por icono la bola del mundo) ahí ya ná de ná… y ese será el navegador que se utilice cuando se abra un webview en una app móvil grrrrrrrrrrrrrr

Siempre se podría “apañar” utilizando modernizr para comprobar si el navegador tiene el soporte adecuado de CSS3 y, de no ser así, implementar un javascript que te genere el carrusel… sería una solución mientras necesitemos compatibilidad con navegadores obsoletos o no tan obsoletos pero con una implementación de HTM5/CSS3 un poco “deficiente”.

En navegadores de escritorio, he comprobado que va perfecto, como no, en Firefox, Chrome y Opera… en el caso del IE funciona desde la versión 9, aunque el efecto del transition lo hace desde la 10 😉

34 pensamientos en “Slider CSS sin Javascript

  1. Buenisimo!!! Te lo agradezco enormemente! Pero ¿qué habrá pasado con el audio del video desde el minuto 25 cercano al 26, que quería escuchar la explicación referente a las flechas? Ah, y en el texto de esta pagina dice “Activando las fechas…”

    1. Hola Claudia! Pues es cierto que se pierde el audio… volveré a grabar el vídeo con otro programa a ver si así queda mejor, a ver si a lo largo de la semana que entre logro tenerlo listo. Gracias por el aviso de la errata en el artículo, ya lo he corregido 😉

      saludos!

    1. Hola Oscar!

      En el vídeo se comenta cómo hacerlo. Tendrás que copiar/pegar el código de cada elemento del slider (el article y su div) y luego en el CSS cmabiar el ancho de esos elementos del 33.3% al % correspondiente y el del elemento padre, del 300% al que corresponda. Si con el artículo no te llega echa un vistazo al video a ver si te queda más claro… si tras eso tienes problemas comenta los problemas que tienes 😉

    1. Modificar el CSS de las etiquetas label que están dentro de #slider-arrows… y si quieres que sean imágenes, tendrás que jugar con la propiedad content para colocar HTML… o buscarte una imagen que te interese en webs que te ofrecen las imágenes como tipografía (te será más cómodo), por ejemplo http://www.flaticon.com/

  2. Excelente articulo! ni bien tenga un tiempo disponible voy a intentar reemplazar el slider que tengo en mi sitio por este otro. Me interesa mucho el tema de optimizar la web con este tipo de soluciones. Esto ayuda a mejorar nuestro posicionamiento en Google no es asi?

    Muchas gracias!

    1. Buenas! Sobre lo del posicionamiento… realmente no debería existir diferencia entre utilizar CSS para el slider o tirar de Javascript. Digo “no debería” porque si el slider en JS está bien hecho, cada elemento del carrusel tendrá una semántica correcta y el posicionamiento no debería variar mucho. Podría variar algo por cuestiones de número de llamadas y tiempos de descarga, pero bueno nada excesivamente relevante salvo que estemos en plena guerra de posicionamiento. Lo que sí aporta hacerlo en CSS es accesibilidad y mayor velocidad de descarga junto con menor transferencia de datos (cada vez más importante). Aunque claro… sliders en JS bien hechos respecto a semántica hay poquitos

  3. Muchas gracias por el aporte, me sirvió mucho y es tan versátil que puedo adaptarlo para cualquier contenido. Excelente! 😀

    1. Pues eliminas dos de los cuatro que hay y en el CSS deberás cambiar el 400% de #slider-box por 200%, dejarlo a 50% en .slider-element y ajustes en esa linea tal y como se explica en el post y video 😉

  4. Hola Rolando
    Buenisimo tu publicacion. Tengo una consulta, que tendria que modificar para que me cargue imagenes y no un color de fondo?

    Gracias

  5. Gracias por tu aporte, este tipo de cosas son las que hacen de internet un mundo maravilloso! y en español!

  6. Arturo Marque
    Responder

    Como cambiar los colores de fondo por imágenes JPG??? Ya vi el ejemplo que pones pero sale de igual forma los rectángulos de colores. veo que ya somos varios los que preguntamos peor no hay una respuesta concreta. Gracias

    1. Buenas Arturo. La respuesta dada es concreta… si te fijas aunque el resultado es el mismo (rectángulos de colores), se tratan de imágenes… como puedes ver en el código fuente está la etiqueta img y carga imágenes. ¿Que las imágenes son rectángulos de colores? Sí, pero la imagen usada es indiferente, se trata de imágenes y no colores de fondo en CSS

      saludos

  7. Hola Rolando!, estoy aplicando el codigo del slider, y pude seguir todos tus pasos. El problema es que cuando agrego una nueva etiqueta debajo del slider (para continuar con el maquetado), la mitad del nuevo contenido se pone ensima del slider, es decir, el nuevo contenido comienza a visualizarse a partir de la mitad del slider.

    Espero que puedas responder, gracias por el video y tus aportes, saludos!

  8. Maria de Jesús Soberanis
    Responder

    Excelente el tutorial, todo está super bien explicado no me dejas con dudas en ningún paso. Muchas felicidades y muchas gracias por el material. 😀

    Saludos y Gracias!!!!!!

  9. Gran trabajo Rolando! estoy obsesionado con la idea de crear efectos a base de puro CSS y tu ejemplo me viene de pelos. Mi única duda es si se podría conseguir que el carrusel cambie solo, sin necesidad de pinchar las flechas.
    Nuevamente felicitaciones yespero tu respuesta. Saludos!!

  10. Guau, acabo de encontrar esto y aparte de ser genial, las explicaciones por cada cosa están perfectas. Me ha ayudado a comprender algunos conceptos de CSS que no tenía claros 😉

Deja un comentario