Motor para crear un slider solo con CSS

Como crear un slider sin javascript

Un slider creado con CSS puro sin javascript. Diseñado para ser lo más ligero y rápido posible.

Slider creado usando CSS puro

Desarrolle este slider solo con HTML y CSS puro para zkreations, el cual no requiere JavaScript para funcionar. Su diseño es responsivo y es compatible con todos los navegadores modernos.

Este proyecto, al igual que los tooltips con CSS Puro forman parte de mi portafolio de proyectos personales, que llevo años desarrollando y que me han aportado importantes mejoras a mis habilidades como desarrollador.

Características

  • CSS puro y moderno
  • Sin dependencias
  • Ligero (minificado ~ 1kb con Brotli)
  • Rápido y de movimiento suave
  • Responsive (manteniendo la relación de aspecto)
  • Personalizable con variables CSS y Sass
  • Fácil de usar
  • Múltiples sliders en la misma página
  • De código abierto

Instalar

Sube e incluye el archivo main.min.css antes de cerrar la etiqueta </head>, si no tienes donde alojarlo, puedes incluirlo mediante una CDN desde jsdelivr:

<link href='//cdn.jsdelivr.net/npm/sheet-slider@3/dist/css/main.min.css' rel='stylesheet'/>

Modo de uso

El slider puede funcionar perfectamente con una estructura HTML muy básica, la cual solo incluye los elementos necesarios para su funcionamiento:

<div class="sheet">
  <input id="a1" type="radio" name="a" checked>
  <input id="a2" type="radio" name="a">
  <input id="a3" type="radio" name="a">
  <div class="sheet-content">
    <div class="sheet-item">
      <img class="sheet-image" src="image.jpg">
    </div>
    <div class="sheet-item">
      <img class="sheet-image" src="image.jpg">
    </div>
    <div class="sheet-item">
      <img class="sheet-image" src="image.jpg">
    </div>
  </div>
  <div class="sheet-arrows">
    <label for="a1"></label>
    <label for="a2"></label>
    <label for="a3"></label>
  </div>
</div>

Todo el contenido dentro de los elementos sheet-item serán los que se muevan. No necesariamente tienen que ser imágenes, pueden ser cualquier elemento HTML.

The slider also has two optional elements, which are the navigation buttons and the descriptive texts. If you include them, the structure would look like this:

El slider también tiene dos elementos opcionales, que son los botones de navegación y los textos descriptivos. Si los incluyes, la estructura quedaría así:

<div class="sheet">
  <input id="a1" type="radio" name="a" checked>
  <input id="a2" type="radio" name="a">
  <input id="a3" type="radio" name="a">
  <div class="sheet-content">
    <div class="sheet-item">
      <img class="sheet-image" src="image.jpg">
      <!-- description -->
      <div class="sheet-meta">
        <h4 class="sheet-title">Example title</h4>
        <p class="sheet-text">Text description</p>
      </div>
    </div>
    <div class="sheet-item">
      <img class="sheet-image" src="image.jpg">
      <!-- description -->
      <div class="sheet-meta">
        <h4 class="sheet-title">Example title</h4>
        <p class="sheet-text">Text description</p>
      </div>
    </div>
    <div class="sheet-item">
      <img class="sheet-image" src="image.jpg">
      <!-- description -->
      <div class="sheet-meta">
        <h4 class="sheet-title">Example title</h4>
        <p class="sheet-text">Text description</p>
      </div>
    </div>
  </div>
  <!-- dots -->
  <div class="sheet-dots">
    <label for="a1"></label>
    <label for="a2"></label>
    <label for="a3"></label>
  </div>
  <!-- arrows -->
  <div class="sheet-arrows">
    <label for="a1"></label>
    <label for="a2"></label>
    <label for="a3"></label>
  </div>
</div>

Nota: El atributo for de las etiquetas debe coincidir con el id de los inputs. Para varios sliders en la misma página, el atributo name de los inputs debe ser diferente, y el atributo for de las etiquetas debe coincidir con el id de los inputs del slider al que pertenecen.

Opciones

Modo de animación

Puedes elegir entre dos modos de animación: fade y vertical. Por defecto, el modo de animación es horizontal. Si quieres cambiarlo, solo tienes que agregar la clase correspondiente al contenedor principal:

<div class="sheet sheet-fade">
  ...
</div>
<div class="sheet sheet-vertical">
  ...
</div>

Personalizar

Puedes definir nuevos valores para las variables en tu archivo CSS o en el selector :root. Estas variables te permiten realizar cambios en el diseño del slider:

Variable Description
--sheet-accent Color de acento
--sheet-ratio Relación de aspecto
--sheet-space Espacio entre los elementos
--sheet-arrow-size Tamaño de las flechas
--sheet-duration Duración de la animación
--sheet-dot-size Tamaño de los botones de navegación
--sheet-timing Función de tiempo de la animación
--sheet-text-color Color del texto
--sheet-text-shadow Sombra del texto
--sheet-title-size Tamaño de la fuente del título
--sheet-text-size Tamaño de la fuente del texto
--sheet-arrow-padding Relleno de las flechas
--sheet-arrow-bg Color de fondo de las flechas
--sheet-arrow SVG utilizado para las flechas
--sheet-dot-gap Espacio entre los botones de navegación
--sheet-dot-bg Color de fondo de los botones de navegación
--sheet-dot-hover Color de los botones de navegación al pasar el mouse

Configurar en Sass

Para desarrolladores, pueden modificar los valores en el archivo inc/_variables.scss y compilarlo con Sass. Una de las opciones que recomiendo modificar según sus necesidades es:

$slider-items: 10 !default;

Aunque de todas formas el css esta muy optimizado, mientras más elementos tenga el slider, más pesado será el archivo resultante. Por defecto, el valor es 10, lo que significa que el slider puede tener hasta 10 elementos.

Modo automático

El slider no tiene un modo automático, pero puedes agregarlo fácilmente con JavaScript. Solo tienes que agregar el atributo data-sheet-time al contenedor principal, tomando en cuenta que el valor es la cantidad de milisegundos que tarda el cambio de diapositiva:

<div class="sheet" data-sheet-time="3000">
  ...
</div>
function initializeSlider(slider) {
  const time = slider.dataset.sheetTime || 3000
  const inputs = slider.querySelectorAll('input')
  let index = 0
  let intervalId

  function updateInputState() {
    inputs[index].checked = false
    index = (index + 1) % inputs.length
    inputs[index].checked = true
  }

  function startInterval() {
    index = Array.from(inputs).findIndex(input => input.checked) || 0;
    intervalId = setInterval(updateInputState, time)
  }

  const stopInterval = () => clearInterval(intervalId)

  startInterval()

  slider.addEventListener('mouseenter', stopInterval)
  slider.addEventListener('mouseleave', startInterval)
}

document.querySelectorAll('[data-sheet-time]')
  .forEach(initializeSlider)

Esto no está incluido en el proyecto, ya que perdería su propósito de ser un slider sin JavaScript. Ademas es una solución muy simple, deberás adaptarla a tus necesidades. Puedes ver un ejemplo del código en codepen.

Conclusión

La primera vez que desarrollé este slider fue en 2014, si lo comparas con el código actual, verás que ha cambiado mucho gracias a muchas cosas que he aprendido. Por eso, decidí reescribirlo desde cero, para que sea más fácil de mantener y de personalizar.

Si te ha gustado este proyecto, puedes apoyarme compartiéndolo en tus redes sociales, o dejando una estrella en GitHub. Cualquier comentario o sugerencia es bienvenida. Muchas gracias por leer.