Slider de imágenes no ajustable

Galería, carrusel o slider de imágenes

Slider imágenes
foto muestra mcryptImagen no disponible
Captura de pantalla de la herramienta del navegador Developer Tools de Chrome para analizar la carga de los recursos. En este caso los tiempos de carga de las imágenes de una página de este sitio web (ver texto).

Una galería, carrusel o slider de imágenes nos permite presentar un conjunto de imágenes en un contenedor. Pueden haber varias razones por las que necesitemos un slider de imágenes. Por ejemplo, por cuestiones de diseño, para hacer más atractiva la presentación de imágenes. Pero también hay un motivo relacionado con la carga de los recursos y el coste en tiempo. Es el caso cuando tenemos que mostrar muchas imágenes para acompañar al texto teniendo que incluirlas en otros tantos elementos <img>. Al cargarse la página el navegador solicita todos estos recursos de imágenes, lo que supone un coste de tiempo. Supongamos que las imágenes forman una serie consecutiva que tratan sobre un mismo tema. En el caso de que el usuario no esté interesado en verlas todas, podríamos ir descargándolas a medida que el usuario vaya solicitándolas.

Por ejemplo, en una página de este sitio quise explicar un tema acompañando unas capturas de pantalla. En la primera imagen de la izquierda puede ver como podemos analizar la carga de los recursos de esa página en las herramientas de desarrollo (developer tools) de los navegadores, en este caso de Chrome. Las imágenes de esa página son mcrypt-1.gif hasta mcrypt-6.gif, imágenes que debían exponer cómo se instalaba un componente de software. Esa página carga todas esas imágenes aunque quizás algún usuario no le interese esa exposición gráfica y pueda estar interesado en otras partes de ese tema. El total en tiempo de todas esas sería de 1411 ms. Sin embargo si sólo descargamos la primera de la serie sería de sólo 145 ms. Estos tiempos están medidos con la caché vaciada previamente y en un servidor localhost. Aunque no sea un servidor real no desvirtua el concepto de coste de carga de recursos innecesarios, pues en todo caso serían mayores.

Dado que tendría que exponer otras series de imágenes en este sitio, pensé que sería mejor hacer un slider de imágenes, creando uno como el que se muestra al lado. Algunos de ellos ya en uso los puede ver, por ejemplo, en el tema de cómo se hace un formulario de contacto, con una serie de 20 imágenes con un tamaño total de 520 KB, con pesos alrededor de los 30 KB la mayoría de ellas. La primera y única que se descarga con la página es de 30 KB y el resto se van descargando sólo cuando el usuario lo solicita.

Slider de imágenes no ajustable

Nota de actualización Julio 2017

Con las actualizaciones de este año 2017 estoy sustituyendo los sprites por iconos SVG. Las flechas de desplazamiento son ahora iconos SVG. Si un navegador no soporta SVG se mostrará un texto alternativo, en este caso los caracteres |<, <, > y >|. Ver más sobre iconos SVG.

Nota de actualización Octubre 2013

Con motivo de empezar a actualizar este sitio para los dispositivos móviles, he realizado algunos cambios en este componente. El HTML ahora es como el expuesto más abajo. El recurso pasa-fotos.css contenía el estilo mientras que pasa-fotos.js era el JavaScript que gestionaba el componente y los datos se encontraban en pasa-fotos-data.js. Estos tres archivos se vinculaban externamente, con unos tamaños de 1.19 KB, 1.57 KB y 1.81 KB. Son de pequeño tamaño y suponen un coste de peticiones de recursos al servidor, especialmente cuando se hacen desde un dispositivo móvil.

El propósito ahora es incluir el recurso pasa-fotos.css en el archivo formatos.css mientras que pasa-fotos.js se incluye en el archivo general.js, archivos ambos que agrupan estilo y funcionalidades comunes para todas las páginas. Se crea una nueva función cargarPasaFotos() que se encarga de adjudicar los eventos y preparar todos los slider de este tipo de la página. Esta función será llamada desde el window.onload del documento. Por último los datos del archivo pasa-fotos-data.js se incluye también en el script del propio documento, pues son datos específicos para cada página.

Botones slider imágenes

He modificado la anterior botonera (reproducida en la imagen anexa) porque sus reducidas dimensiones no permitían manipular los botones en un móvil. Además antes incluía un elemento <input type="number"> para acceder manualmente a una posición de una foto. Pero ese elemento <input> no se comportaba igual en todos los navegadores. Especialmente en los móviles, donde algunos incluso no permiten modificar el estilo del elemento. La idea ahora es eliminar ese <input> y ofrecer sólo texto con el número de foto y total fotos separados por una barra. Los botones de navegación son los mismos, pero más espaciados para poder accionarlos en un móvil.

He simplificado el HTML cargándose dinámicamente los botones de la barra de navegación, actualizando el número total de fotos y acomodando el ancho de los botones al ancho del contenedor. También ahora he centrado verticalmente las imágenes en su contenedor con JavaScript, aspecto que se consigue dando un estilo line-height al contenedor igual a su offsetHeight.

Otra mejora tiene que ver con los atributos width y height de la imagen. La estructura que ponemos en el HTML es la mínima necesaria para que al cargarse la página se posicione y dimensione sin cambios posteriores en la estructura del contenedor. Se incluía antes y ahora también un elemento <img> para la primera imagen de la serie. Antes no especificaba el width y height de la imagen, porque cuando navegaba a otra de distinto tamaño no modificaba esa medidas y por tanto perdía su relación de aspecto. Pero es necesario especificar las dimensiones de los elementos <img> a efectos de que el navegador no tenga que esperar por la carga de la primera imagen para seguir con el renderizado de la página.

Ahora sí especifico las dimensiones de la primera imagen en el HTML y para las siguientes lo resuelvo en la función finalizaCargaImg() que responde al evento onload al cargarse. Con JavaScript podemos obtener las propiedades naturalWidth y naturalHeight que nos darán las dimensiones originales de la imagen, para luego traspasarlas a los atributos width y height. Navegadores que no soporten eso se resuelve creando una imagen con new Image(), actualizando su atributo src y obteniendo su medidas width y height. Es un sobrecarga pero sólo pasará con navegadores como IE8. Este es el código:

if (img.naturalWidth){
        img.width = img.naturalWidth;
        img.height = img.naturalHeight;
    } else {
        //IE8 no soporta naturalWidth/Height
        var imagen = new Image();
        imagen.onload = function(event){
            img.width = imagen.width;
            img.height = imagen.height;
        };
        imagen.src = img.src;
    }

No hace falta decir que slider de imágenes hay para rato(Buscando en Google "slider imágenes" se obtienen un montón de resultados). Creo que hay que tener claro para que lo vamos a usar. En este primer tema voy a exponer este slider no ajustable en el sentido de que las imágenes conservan su tamaño original. Esto es óptimo para presentar capturas de pantalla que no tienen el mismo tamaño, siendo preferible conservar el original para evitar textos no legibles o que se deformen al reducirlas o ajustarlas al contenedor. Para incluir un slider como el de esta página hemos de poner uno (o más) contenedores HTML como el siguiente con algo de script:

<div class="pasa-fotos" style="width: 250px; ">
        <div class="pasa-fotos-titulo">Slider imágenes</div>
        <div class="pasa-fotos-img" style="height: 320px"><img
            src="ejemplos/pasa-fotos/timeline-image.png"
            width="209" height="147" alt="foto muestra mcrypt"
            /><span>Imagen no disponible</span></div>
        <div class="pasa-fotos-barra"></div>
        <div class="pasa-fotos-pie">
            ...
        </div>
    </div>
    ....
    <script>
        //Array de datos de los slider. Cada subarray es para
        //un slider de la página.
        var pasaFotosData = [
             [
                 ["URL1", "PIE1"],
                 ["URL2", "PIE2"],
                 ...
             ]
        ];
        //Cargamos todos los slider de una página
        window.onload = function(){
            ...
            cargarPasaFotos();
            ...
         };
    </script>
Código actualizado con los nuevos cambios de Octubre 2013.

En resaltado están las particularidades para cada slider:

  1. El contenedor exterior de clase pasa-fotos se dimensiona a un ancho de unos 20px mayor que la imagen más ancha de la serie. El mayor alto más también unos 20px se especifica en el contenedor pasa-fotos-img. Le damos un poco más para que la imagen quede holgada en el contenedor y no salten los scroll. Pero nada impide poner cualesquieras medidas, pues si la imagen es más pequeña saltará el scroll.
  2. Ponemos todo lo necesario para la primera imagen de la serie, src, width, height y alt.
  3. Ponemos el título, en este caso "Slider imágenes".
  4. Ponemos el texto que deberá aparece como pie de foto para la primera imagen. Si no queremos poner estos pies de fotos simplemente eliminamos este contenedor <div>.
  5. Los datos de todos los pasa-fotos de una página van en un array de JavaScript. La variable debe nombrarse como pasaFotosData. Si no es muy largo puede ponerse en el script de la página. En el window.onload iniciamos con cargarPasaFotos().

Al inicio de este tema se expone un enlace para ver un ejemplo de uso integrando todos los recursos así como para poder descargarlos en un ZIP.

Degradado de color en barras

Paint para hacer color degradado Reconozco que no soy un experto en temas de edición gráfica, pero a veces se pueden conseguir cosas con herramientas muy simples, como el programa Paint que viene en los sistemas operativos como Windows. Se trata de hacer una imagen fondo degradado de 20×23 píxeles. En la imagen adjunta puede ver una captura de pantalla en el Paint, ampliada a 800 y también capturando el cuadro de diálogo para modificar y definir colores personalizados. Elegimos un color y con el control de tonalidad de la derecha vamos seleccionando las tonalidades y dibujando las 23 rectas horizontales que componen la altura. O incluso, puede capturar el degradado del color de ese control de tonalidad y darle la vuelta a la parte inferior, pues el ancho no es significativo, aunque si lo será el alto como veremos ahora.

Una vez que tengamos ese trozo de barra lo ponemos en el estilo background-image:

.pasa-fotos-barra {
    text-align: right;
    padding-right: 1em;
    color: white;
    height: 23px;
    font-size: 1em;
    background-image: url(/res/img/fondo.png);
    background-size: contain;
    cursor: pointer;
    }
    

El valor contain para la propiedad background-size hace que ese trozo de degradado se ajuste a la barra, en este caso extendiéndose sólo horizontalmente porque el elemento tiene exactamente 23 píxeles de altura, la misma que la de la imagen.