Kortic, Anthony Ladeuil

Lightbox Responsive et A11Y

    Principe de base d'une lightbox accessible, compatible lecteurs d'écran et responsive. Les attributs srcset peuvent être pris en charge.
    Toute proposition d'amélioration est bien sûr la bienvenue ! Ça se passe ici : contact

    Les ressources

    Utilisation

    Tout est dans le js... Exemple ici

    ou sur l'image suivante
    image Berlin-Potsdamer-Platz
    <img decoding="async"
        class="lightbox lightbox-overlay-trigger"
        title="Berlin, Potsdamer Platz"
        data-link="https://www.kortic.com/photo-berlin-potsdamer-platz.html"
        data-full="https://www.kortic.com/images/full/1000/1/15399291417640_Fjb0S6N1P.jpg"
        alt="image Berlin-Potsdamer-Platz"
        src="https://www.kortic.com/images/thumb/420/0/15399291417640_Fjb0S6N1P.jpg"
        />

    Source Javascript $.lightbox

    ;(function($) {

        /*     utilisation
            usage sur n'importe quelle balise HTML de la catégorie contenu de flux (https://developer.mozilla.org/fr/docs/Web/Guide/HTML/Catégories_de_contenu#Contenu_de_flux)

            Exemple:
            <picture class="lightbox" data-full="//domaine.com/src_image.jpg" title="Lorem ipsum" ou data-title="Lorem ipsum">

            Valeurs obligatoires :
            - classe `lightbox`
            - attribut data-full (par défaut) modifiable pour gérer plusieurs lightbox dans une même page.
              La valeur de data-full est la source de l'image en grand format affiché dans la lightbox.
              [data-full] : string uri OU objet pour images responsives. eg. {"src":"\/image@1000.jpg","srcset":["\/image@400.jpg 400vw","\/image@700.jpg 700vw","\/image@1500.jpg 1500vw"]}
            - [data-]title non vide

            Point d'attention : un objet `means[lang]` est nécessaire pour labelliser les attributs aria-
            means = {
                'fr' : {
                    'lightbox_close':             'Fermer',
                    'lightbox_first':             'Aller à la première image',
                    'lightbox_prev':             'Image précédente',
                    'lightbox_play':             'Démarrer ou arrêter le diaporama',
                    'lightbox_next':             'Image suivante',
                    'lightbox_last':             'Aller à la dernière image',
                    'lightbox_download':         'Télécharger l\'image',
                    'lightbox_enum':             'image ',
                    'lightbox_on':                 ' sur ',
                }
            };


            Valeurs optionnelles :
            - classe `lightbox-overlay-trigger` : pose la zone cliquable sur la totalité du bloc. Si absent, le trigger cliquable se positionne en haut à droite du bloc
            - data-download : définit le lien dans la lightbox vers le téléchargement direct de l'image courante
            - data-link : définit le lien dans la lightbox vers l'affichage d'une page détaillant l'image courante
            - data-scroll : contient un identifiant qui permet de faire suivre la page au changement de vue dans la lightbox

            Nécessite en option https://github.com/mattbryson/TouchSwipe-Jquery-Plugin pour la gestion du swipe sur mobile

            const FOCUSABLE_SELECTORS = 'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [tabindex="0"], [contenteditable]';

            const KEYCODES = {
                BACKSPACE: 8,
                TAB: 9,
                ENTER: 13,
                ESC: 27,
                SPACE: 32,
                LEFT: 37,
                UP: 38,
                RIGHT: 39,
                DOWN: 40
            };


        */

        'use strict';

        $.lightbox = function(){

            var blocs = $('.lightbox[data-full]').filter(function(){
                    // filter for images in owl.carousel loop or others...
                    return $(this).parents('.cloned').length == 0
                });

            if(typeof $.fn.doOnce !== 'function') {
                $.fn.doOnce = function( func ) {

                    this.length && func.apply( this );
                    return this;

                };
            }

            if(blocs.length) {

                var lbx_timer,
                    placeholder = 'data:image/gif;base64,R0lGODlhCgAKAJECAAAAAP///wAAAAAAACH5BAEAAAIALAAAAAAKAAoAAAIIlI+py+0PYysAOw==',
                    count = blocs.length;

                if(typeof $.zindex !== 'function') {
                    $.zindex = function (fromDomNode) {
                        let r = [];

                        $("*", (fromDomNode == null ? $('body') : fromDomNode )).each(function () {
                            let z = parseInt($(this).css('z-index'), 10);
                            !isNaN(z) && r.push(z)
                        });

                        let last = r.sort(function (a, b) {
                            return a-b
                        }).reverse()[0];

                        if(last == undefined) {
                            last =    0;
                        }

                        return last + 1;

                    };
                }

                if(typeof $.scrollTop !== 'function') {
                    $.scrollTop = function(time) {

                        $('html, body').animate({
                            scrollTop: (arguments[1] !== undefined ? arguments[1] : 0)
                        }, (isNaN(time) ? 500 : time));

                    };
                }

                lbx_timer = 0;

                $('#lightbox').doOnce(function(){
                    this.remove();
                });

                var classContainer    = 'lightbox-container',
                    classTrigger    = 'lightbox-trigger',
                    lbx_            = $('<section/>', {'id':'lightbox', 'tabindex': '0', 'style': 'z-index:' + $.zindex()}),
                    lbx_image        = $('<img/>', {'alt': '', 'src': placeholder, 'crossorigin': 'use-credentials', 'decoding': 'async', 'id': 'lightbox_image'}),
                    lbx_caption        = $('<div/>', {'id':'lightbox_caption', 'tabindex': '0'}),
                    lbx_controls    = $('<div/>', {'id':'lightbox_control'}),
                    lbx_first        = $('<button/>', {'id':'lightbox_first', 'aria-label': $.means('lightbox_first')}),
                    lbx_prev        = $('<button/>', {'id':'lightbox_prev', 'aria-label': $.means('lightbox_prev')}),
                    lbx_next        = $('<button/>', {'id':'lightbox_next', 'aria-label': $.means('lightbox_next')}),
                    lbx_last        = $('<button/>', {'id':'lightbox_last', 'aria-label': $.means('lightbox_last')}),
                    lbx_play        = $('<button/>', {'id':'lightbox_play', 'aria-label': $.means('lightbox_play')}),
                    lbx_loading        = $('<div/>', {'id':'lightbox_loading'}),
                    lbx_close        = $('<button/>', {'id': 'lightbox_close', 'aria-label':  $.means('lightbox_close')}),
                    lbx_next_image, lbx_prev_image,

                    lbx_fadeout = function(){
                        lbx_.fadeOut(),
                        lbx_stop();
                        $(lbx_.data('opener')).trigger('focus');
                    },

                    lbx_autostart = false,

                    lbx_stop = function() {
                        lbx_autostart = false;
                        lbx_play.removeClass('play'),
                        resetTimer();
                    },

                    initTimer = function() {
                        resetTimer();
                        lbx_timer = setTimeout(function(){
                            slide();
                        }, 5000);
                    },

                    resetTimer = function() {
                        ( (lbx_timer > 0) && clearTimeout(lbx_timer) );
                        lbx_timer = 0;
                    },

                    slide = function() {

                        $(blocs[lbx_next_image]).parents('.' + classContainer).find('.' + classTrigger).trigger('click');

                        (lbx_autostart) && initTimer();
                    };

                $('body').append(lbx_);

                lbx_.append(
                    lbx_caption,
                    lbx_close,
                    lbx_image,
                    lbx_loading,
                    lbx_controls
                );

                if(count > 1) {
                    lbx_controls.append(lbx_first, lbx_prev, lbx_play, lbx_next, lbx_last);

                    lbx_.addClass('multi-views');

                } else {

                    lbx_controls.css({'display': 'none'});
                }

                lbx_close.on('click', function() {
                    lbx_fadeout();
                });

                blocs.each(function(index){

                    var element_ = $(this),
                        parentContainer = element_.parent();

                    if(!parentContainer.hasClass(classContainer)) {
                        parentContainer.addClass(classContainer);

                        ($.inArray(parentContainer.css('position') , ['absolute', 'relative', 'fixed']) === -1) && parentContainer.addClass('position-relative');

                        parentContainer.append(
                            $('<span/>')
                                .addClass(classTrigger)
                                .attr({'tabindex': '0', 'focusable': 'true', 'data-event': 'click'})
                                .css({'z-index': $.zindex(parentContainer)})
                        );
                    }

                    element_.hasClass('lightbox-overlay-trigger') && parentContainer.addClass('lightbox-overlay');

                    parentContainer.find('.' + classTrigger).on('click', ev => {

                        ev.stopPropagation();

                        lbx_.data('opener', $(document.activeElement));

                        parentContainer.tagName().toLowerCase() === 'a' && ev.preventDefault();

                        // ajouter un lien de téléchargement de l'image dans la lightbox
                        // attribut data-download="//lien.download."

                        if(element_.data('download') !== undefined) {

                            lbx_.removeClass('.downloadable').find('.lightbox_download').first().remove();

                            if(element_.data('download') !== false) {
                                let lbx_download = $('<img/>', {
                                    'alt': '',
                                    'src': placeholder,
                                    'class': 'lightbox_download'
                                });

                                lbx_.addClass('downloadable');
                                lbx_caption.before(lbx_download);

                                lbx_download.on('click', function() {
                                    lbx_stop();
                                    document.location = element_.data('download');
                                });
                            }
                        }

                        // ajouter un lien de téléchargement de l'image dans la lightbox
                        // attribut data-link="//lien.vers.longdescription.image"

                        if(element_.data('link') !== undefined) {

                            lbx_.removeClass('.linkable').find('.lightbox_link').first().remove();

                            if(element_.data('link') !== false) {
                                let lbx_link = $('<a/>', {'href': element_.data('link'), 'class': 'lightbox_link'});

                                lbx_.addClass('linkable');
                                lbx_caption.before( lbx_link.text($.means('lightbox_link') ));

                                lbx_link.on('click', function() {
                                    lbx_stop();
                                });
                            }
                        }

                        (lbx_.is(':hidden')) && (
                            lbx_.fadeIn(),
                            lbx_play.removeClass('play')
                        );

                        lbx_next_image = index + 1;
                        (lbx_next_image > count - 1) && (lbx_next_image = 0);

                        lbx_prev_image = index - 1;
                        (lbx_prev_image < 0) && (lbx_prev_image = count - 1);

                        var index_images = $.means('lightbox_enum') + (index + 1)  + $.means('lightbox_on') + count,
                            img_caption = element_.attr('title') || element_.attr('data-title') || null;

                        lbx_caption.empty();

                        (img_caption != null && img_caption.trim().length) && lbx_caption.prepend($('<div/>').text(img_caption));


                        lbx_controls.attr('data-before', index_images);

                        lbx_image.animate({opacity: 0}, 300, function() {

                            lbx_.addClass('loading').css({zIndex: $.zindex()}),

                            lbx_loading.fadeIn(50);

                            if(typeof element_.data('full') !== 'string'){

                                let values_ = element_.data('full');

                                lbx_image.attr({
                                    'src': values_.src,
                                    'srcset': values_.srcset.join(',')
                                });
                            } else {

                                lbx_image.attr({
                                    'src': element_.data('full')
                                });
                            }

                            lbx_image.on('load', function() {

                                lbx_.attr({'aria-live': 'assertive', 'aria-modal': 'true'}).focus();
                                lbx_image.css({maxHeight: 'calc(100% - '+ ( lbx_close.outerHeight(true) + lbx_controls.outerHeight(true) ) + 'px)'});

                                lbx_loading.hide();

                                lbx_image.animate({opacity: 1}, 800, function() {
                                    lbx_.removeClass('loading');
                                }).dequeue();

                                let scrollToItem = $('[data-scroll="' + element_.data('scroll') + '"]');

                                scrollToItem.length && $.scrollTop(0, scrollToItem.offset().top.toFixed(0) - element_.outerHeight());

                                var focusable = lbx_.find(FOCUSABLE_SELECTORS);

                                if (focusable.length) {

                                    let start_ = focusable[0],
                                        end_ = focusable[focusable.length - 1],
                                        focus_ = lbx_ ? lbx_ : start_;

                                    focus_.focus();

                                    lbx_.on('keydown', function(event) {
                                        if (event.keyCode === KEYCODES.TAB) {

                                            (event.shiftKey && document.activeElement === start_) && (
                                                event.preventDefault(),
                                                    end_.focus()
                                            );

                                            (!event.shiftKey && document.activeElement === end_) && (
                                                event.preventDefault(),
                                                    start_.focus()
                                            );

                                        }

                                    });

                                }


                                if(lbx_autostart) {
                                    initTimer()
                                }
                            });

                            lbx_.on('click', e => {
                                $(e.target).attr('id') === lbx_.attr('id') && lbx_fadeout();
                            });

                        }).dequeue();

                    });

                });

                lbx_play.on('click', function() {

                    lbx_play.toggleClass('play');

                    if(lbx_autostart) {
                        lbx_autostart = false;
                        resetTimer();
                    } else {
                        lbx_autostart = true;
                        initTimer();
                    }

                });

                lbx_image.on('click', function() {
                    count > 1 ? lbx_next.trigger('click') : (document.fullscreenElement == null ? $.fullScreenOn(document.getElementById('lightbox_image')): ($.fullScreenOff(document.getElementById('lightbox_image')), lbx_.trigger('click')));
                }),

                lbx_first.on('click', function() {
                    lbx_.is(':visible') && $(blocs[0]).parents('.' + classContainer).find('.' + classTrigger).trigger('click');
                    lbx_stop();
                }),

                lbx_prev.on('click', function() {
                    lbx_.is(':visible') && $(blocs[lbx_prev_image]).parents('.' + classContainer).find('.' + classTrigger).trigger('click');
                    lbx_stop();
                }),

                lbx_next.on('click', function() {
                    lbx_.is(':visible') && $(blocs[lbx_next_image]).parents('.' + classContainer).find('.' + classTrigger).trigger('click');
                    lbx_stop();
                }),

                lbx_last.on('click', function() {
                    lbx_.is(':visible') && $(blocs[count - 1]).parents('.' + classContainer).find('.' + classTrigger).trigger('click');
                    lbx_stop();
                });



                if('ontouchstart' in window === false) {

                    lbx_.addClass('device-desktop');

                    DOM.window.on('keyup', function (ev) {

                        if(lbx_.is(':visible') && $.inArray(ev.which, [KEYCODES.ESC, KEYCODES.LEFT, KEYCODES.RIGHT]) !== -1) {
                            if(count > 1) {
                                if(ev.which === KEYCODES.RIGHT) {
                                    $(blocs[lbx_next_image]).parents('.' + classContainer).find('.' + classTrigger).trigger('click');
                                }

                                if(ev.which === KEYCODES.LEFT) {
                                    $(blocs[lbx_prev_image]).parents('.' + classContainer).find('.' + classTrigger).trigger('click');
                                }

                            }

                            ev.which === KEYCODES.ESC && lbx_fadeout();

                        }
                    });

                }

                if(typeof $.fn.swipe === 'function') {
                    if(('ontouchstart' in window === true) && count > 1) {
                        lbx_image.swipe( {
                            swipeLeft:function(event, direction, distance, duration, fingerCount) {
                                if(lbx_.is(':visible')) {
                                    $(blocs[lbx_next_image]).parents('.' + classContainer).find('.' + classTrigger).trigger('click');
                                }

                            },
                            swipeRight:function(event, direction, distance, duration, fingerCount) {
                                if(lbx_.is(':visible')) {
                                    $(blocs[lbx_prev_image]).parents('.' + classContainer).find('.' + classTrigger).trigger('click');
                                }
                            },
                            threshold: 100
                        });
                    }
                } else {
                    console.log('need https://github.com/mattbryson/TouchSwipe-Jquery-Plugin');
                }

            }

        };

        DOM.document.ready( function() {
            $.lightbox();
        });


    })(jQuery);

    Source CSS


    .lightbox-trigger {
        background-image:url('/svg/lightbox.svg#i-zoomin');
        background-position: center center !important;
        background-repeat: no-repeat  !important;
        background-color: rgba(0, 50);
        background-size: calc(100% - 30%) calc(100% - 30%) !important;
        border-radius: var(--radius);
        min-width: 2.5rem !important;
        min-height: 2.5rem !important;
        max-width: 5rem;
        max-height: 5rem;
        height: 4vw;
        width: 4vw;
        position: absolute !important;
        left: 0;
        top: 0;
    }

    html.a11y .lightbox-trigger {
        background-color: black;
    }

    .lightbox-overlay .lightbox-trigger {
        max-width: unset;
        max-height: unset;
    }

    html:not(.a11y) .device-desktop .lightbox-overlay .lightbox-trigger {
        top: 0;
        left: 0;
        bottom: 0;
        right: 0;
        width: auto !important;
        height: auto !important;
        cursor: zoom-in !important;
        opacity: 0;
    }

    html:not(.a11y) .device-desktop .lightbox-trigger {
        cursor: pointer !important;
    }

    html:not(.a11y) .device-desktop .lightbox-container.lightbox-overlay:hover .lightbox-trigger {
        background-color: rgba(0, 20);
        opacity: 1;
    }

    .lightbox-container .lightbox-trigger:focus {
        background-color: rgba(0, 90);
        opacity: 1 !important;
    }

    #lightbox {
        bottom: 0;
        color: white;
        display: none;
        left: 0;
        position: fixed;
        right: 0;
        top: 0;
    }

    html:not(.a11y) #lightbox {
        background-color: rgba(15, 97);
        outline: none;
    }

    html.a11y #lightbox {
        background-color: rgba(15, 100);
    }

    #lightbox.loading {
        background-image: url('/svg/lightbox.svg#i-loader');
        background-position: center center;
        background-size: 1.875rem 1.875rem;
    }

    #lightbox_caption {
        top: 0;
        left: 1.25rem;
        position: absolute;
        right: 3.4375rem;
    }

    #lightbox.downloadable #lightbox_caption, #lightbox.linkable #lightbox_caption {
        left: 3.4375rem;
    }

    #lightbox.downloadable.linkable #lightbox_caption {
        left: 6.875rem;
    }

    #lightbox_caption div {
        line-height: 3.125rem;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }

    #lightbox_image {
        height: auto;
        width: auto;
        max-width: calc(100% - 2.5rem);
        position: absolute;
        left: 50%;
        top: 50%;
        background-color: rgba(255, 10);
        padding: 1px;
        border-radius: var(--radius);
        -webkit-transform:translate(-50%,-50%);-moz-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);
    }

    #lightbox.multi-views #lightbox_image {
        margin-top: -0.9375rem;
    }

    #lightbox_loading {
        left: 50%;
        top: calc(50% - 2rem);
        line-height: 2rem;
        position: absolute;
        display: none;
        border-radius: var(--radius);
        -webkit-transform:translate(-50%,-50%);-moz-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);
    }

    #lightbox_control {
        position: absolute;
        display: inline-block;
        left: 50%;
        bottom: 0;
        padding-top: 1.875rem;
        min-height: 3.125rem;
        white-space: nowrap;
        -webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);
    }

    #lightbox_control:before {
        content: attr(data-before);
        position: absolute;
        top: 0;
        left: 50%;
        line-height: 1.875rem;
        opacity: .6;
        display: inline-block;
        white-space: nowrap;
        -webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);
    }

    #lightbox_close {
        background-image: url('/svg/lightbox.svg#i-close');
        background-position: center center;
        background-color: rgba(0, 0) !important;
        background-size: 1.5625rem 1.5625rem;
        cursor: pointer;
        height: 3.125rem;
        width: 3.75rem;
        position: absolute;
        right: 0;
        top: 0;
    }

    .lightbox_download, .lightbox_link, #lightbox_control button {
        background-position: center center;
        height: 3.125rem;
        width: 3.125rem;
        cursor: pointer;
    }

    .lightbox_download {
        position: absolute;
        top: 0;
        left: 0;
        background-size: 1.5rem 1.5rem;
    }

    .lightbox_link {
        position: absolute;
        top: 0;
        left: 0;
        background-size: 1.25rem 1.25rem;
        color: transparent !important;
        white-space: nowrap;
        overflow: hidden;
    }

    .lightbox_download + .lightbox_link {
        left: 3.125rem;
    }

    #lightbox_control button  {
        background-size: 2.5rem 2.5rem;
        vertical-align: bottom;
        background-color: rgba(0, 0) !important;
    }

    #lightbox_first {
        background-image: url('/svg/lightbox.svg#i-first');
    }

    #lightbox_prev {
        background-image: url('/svg/lightbox.svg#i-prev');
    }

    #lightbox_play.play {
        background-image: url('/svg/lightbox.svg#i-pause');
    }

    #lightbox_play:not(.play) {
        background-image: url('/svg/lightbox.svg#i-play');
    }

    #lightbox_next {
        background-image: url('/svg/lightbox.svg#i-next');
    }

    #lightbox_last {
        background-image: url('/svg/lightbox.svg#i-last');
    }

    .lightbox_download {
        background-image: url('/svg/lightbox.svg#i-download');
    }

    .lightbox_link {
        background-image: url('/svg/lightbox.svg#i-linkto');
    }

    Source SVG

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
        <title>Lightbox icons — Kortic</title>
        <symbol id="first" viewBox="0 0 32 32">
            <path fill='white' d='M12.38,9.85a.63.63,0,0,0-.63.63V21.33a.63.63,0,0,0,.63.63h1.16a.63.63,0,0,0,.63-.63V10.48a.63.63,0,0,0-.63-.63Z'/>
            <path fill='white' d='M20.88,10.46l-.18-.16a1,1,0,0,0-1.45.09l-4.77,4.77a1,1,0,0,0,0,1.49l4.77,4.77a1,1,0,0,0,1.45.09l.18-.18Z'/>
        </symbol>

        <symbol id="prev" viewBox="0 0 32 32">
            <path fill='white' d='M15.39,16.65a1.08,1.08,0,0,1,0-1.53c1.21-1.21,2.41-2.41,3.62-3.6A.82.82,0,0,0,19,10.31l-.18-.17a1,1,0,0,0-1.49.09l-4.89,4.89a1.08,1.08,0,0,0,0,1.53l4.89,4.89a1,1,0,0,0,1.49.09l.18-.18a.8.8,0,0,0,.05-1.2C17.79,19.06,16.6,17.84,15.39,16.65Z'/>
        </symbol>

        <symbol id="play" viewBox="0 0 32 32">
            <path fill='white' d='M14.66,10.14a.62.62,0,0,0-1,.49V21.37a.62.62,0,0,0,.35.56.63.63,0,0,0,.27.06.62.62,0,0,0,.38-.13l6.79-5.37a.62.62,0,0,0,0-1Z'/>
        </symbol>

        <symbol id="pause" viewBox="0 0 32 32">
            <circle fill='white' cx='16' cy='16' r='12'/>
            <path d='M13,9.85a.62.62,0,0,0-.62.62v10.7a.62.62,0,0,0,.62.62h1.15a.62.62,0,0,0,.62-.62V10.47a.62.62,0,0,0-.62-.62Z'/>
            <path d='M17.88,9.85a.62.62,0,0,0-.62.62v10.7a.62.62,0,0,0,.62.62H19a.62.62,0,0,0,.62-.62V10.47A.62.62,0,0,0,19,9.85Z'/>
        </symbol>

        <symbol id="next" viewBox="0 0 32 32">
            <path fill='white' d='M16.65,15.35a1.08,1.08,0,0,1,0,1.53c-1.21,1.21-2.41,2.41-3.62,3.6a.82.82,0,0,0,.05,1.21l.18.17a1,1,0,0,0,1.49-.09l4.89-4.89a1.08,1.08,0,0,0,0-1.53l-4.89-4.89a1,1,0,0,0-1.49-.09l-.18.18a.8.8,0,0,0-.05,1.2C14.25,12.94,15.44,14.16,16.65,15.35Z'/>
        </symbol>

        <symbol id="last" viewBox="0 0 32 32">
            <path fill='white' d='M19.62,22.15a.63.63,0,0,0,.63-.63V10.67a.63.63,0,0,0-.63-.63H18.46a.63.63,0,0,0-.63.63V21.52a.63.63,0,0,0,.63.63Z'/>
            <path fill='white' d='M11.12,21.54l.18.16a1,1,0,0,0,1.45-.09l4.77-4.77a1,1,0,0,0,0-1.49l-4.77-4.77a1,1,0,0,0-1.45-.09l-.18.18Z'/>
        </symbol>

        <symbol id="close" viewBox="0 0 32 32">
            <path fill='white' d='M25.333 5.333q0.573 0 0.953 0.38t0.38 0.953q0 0.563-0.385 0.948l-8.396 8.385 8.396 8.385q0.385 0.385 0.385 0.948 0 0.573-0.38 0.953t-0.953 0.38q-0.563 0-0.948-0.385l-8.385-8.396-8.385 8.396q-0.385 0.385-0.948 0.385-0.573 0-0.953-0.38t-0.38-0.953q0-0.563 0.385-0.948l8.396-8.385-8.396-8.385q-0.385-0.385-0.385-0.948 0-0.573 0.38-0.953t0.953-0.38q0.563 0 0.948 0.385l8.385 8.396 8.385-8.396q0.385-0.385 0.948-0.385z'/>
        </symbol>

        <symbol id="download" viewBox="0 0 32 32">
            <path fill='white' d='M15.15,21.65l0,0h0a1.22,1.22,0,0,0,.28.17h0a1.27,1.27,0,0,0,.42.1H16a1.11,1.11,0,0,0,.42-.1h0a1,1,0,0,0,.25-.16h0l.06-.06,4.76-4.76A1.19,1.19,0,0,0,19.9,15.2l-2.71,2.73V4.11a1.19,1.19,0,0,0-2.38,0V17.93l-2.73-2.73a1.19,1.19,0,0,0-1.68,1.68l4.76,4.77Z'/>
            <path fill='white' d='M26.73,17.23a1.2,1.2,0,0,0-1.19,1.19V22a1.2,1.2,0,0,1-1.19,1.19H7.65A1.2,1.2,0,0,1,6.46,22V18.42a1.19,1.19,0,1,0-2.38,0V22a3.58,3.58,0,0,0,3.58,3.58H24.35A3.58,3.58,0,0,0,27.92,22V18.42a1.2,1.2,0,0,0-1.19-1.19Z'/>
        </symbol>

        <symbol id="linkto" viewBox="0 0 32 32">
            <path fill='white' d='M18.986 16.471c0.164 0.018 0.327 0.026 0.49 0.026 1.216 0 2.382-0.481 3.258-1.357l7.405-7.405c0.866-0.866 1.349-2.014 1.356-3.231 0.009-1.22-0.459-2.364-1.316-3.222-0.85-0.85-1.98-1.317-3.188-1.317-0.011 0-0.021 0-0.033 0-1.217 0.008-2.364 0.49-3.23 1.356l-7.405 7.405c-1.095 1.095-1.569 2.649-1.269 4.157 0.058 0.29 0.346 0.479 0.629 0.419 0.29-0.058 0.478-0.339 0.42-0.628-0.231-1.157 0.134-2.351 0.976-3.192l7.405-7.405c0.666-0.667 1.548-1.037 2.482-1.043 0.975 0 1.805 0.35 2.458 1.003s1.010 1.527 1.004 2.458c-0.007 0.935-0.377 1.816-1.044 2.482l-7.405 7.405c-0.764 0.763-1.813 1.133-2.879 1.024-0.285-0.033-0.557 0.181-0.588 0.475-0.032 0.296 0.181 0.559 0.474 0.59zM15.14 23.273c1.148-1.148 1.608-2.769 1.229-4.334-0.069-0.287-0.351-0.466-0.646-0.394-0.287 0.069-0.463 0.358-0.394 0.645 0.291 1.201-0.063 2.444-0.946 3.328l-7.405 7.405c-0.666 0.667-1.548 1.037-2.482 1.043-0.959 0.005-1.805-0.349-2.458-1.003-0.653-0.653-1.010-1.526-1.003-2.458 0.006-0.935 0.377-1.816 1.043-2.483l7.405-7.405c0.771-0.771 1.822-1.144 2.906-1.021 0.288 0.022 0.559-0.177 0.592-0.471 0.033-0.293-0.177-0.558-0.471-0.592-1.404-0.158-2.78 0.324-3.783 1.327l-7.405 7.405c-0.866 0.866-1.348 2.014-1.356 3.231-0.009 1.22 0.459 2.364 1.316 3.222 0.85 0.85 1.98 1.317 3.188 1.317 0.011 0 0.021 0 0.033 0 1.217-0.008 2.364-0.49 3.23-1.356l7.407-7.406zM22.734 8.872c-0.209-0.209-0.547-0.209-0.756 0l-13.5 13.5c-0.209 0.208-0.209 0.547 0 0.756 0.104 0.104 0.241 0.157 0.378 0.157s0.273-0.052 0.378-0.157l13.5-13.5c0.209-0.209 0.209-0.547 0-0.756z'/>
        </symbol>

        <symbol id="zoomin" viewBox='0 0 32 32'>
            <g fill='white'>
                <path d='M26.7,25.4l-3.2-3.2a15.3,15.3,0,0,1-1.8-1.8c-.1-.1-.3-.2-.3-.3a9.22,9.22,0,0,1,.5-.8,7.46,7.46,0,0,0,.7-1.2A9.28,9.28,0,0,0,15.1,5,9.41,9.41,0,0,0,5.2,16.2a9.35,9.35,0,0,0,13.9,6c.4-.2.8-.8,1.1-.6a4.62,4.62,0,0,1,.7.7l2.4,2.4c.6.6,1.2,1.3,1.9,1.9a1,1,0,0,0,.7.4A1,1,0,0,0,26.7,25.4ZM14.3,21.7a7.57,7.57,0,0,1-7-4.9A7.48,7.48,0,0,1,9.6,8.5c5.2-4.3,13.2.5,12,7.1a7.57,7.57,0,0,1-7.3,6.1Z'/>
                <path d='M18.94,13.44H15.13V9.63a.85.85,0,1,0-1.69,0v3.81H9.63a.84.84,0,0,0-.84.84.85.85,0,0,0,.84.85h3.81v3.81a.85.85,0,0,0,1.69,0V15.13h3.81a.85.85,0,0,0,.85-.85A.84.84,0,0,0,18.94,13.44Z'/>
            </g>
        </symbol>


        <symbol id="loader" viewBox='0 0 128 128'>
            <g fill='white'>
            <path d='M63.6,0L63.6,0c2.2,0,4,1.8,4,4v32c0,2.2-1.8,4-4,4h0c-2.2,0-4-1.8-4-4V4C59.6,1.8,61.4,0,63.6,0z'/>
            <path fill-opacity='0' d='M95.7,8.4L95.7,8.4c1.9,1.1,2.6,3.6,1.5,5.5l-16,27.7c-1.1,1.9-3.6,2.6-5.5,1.5l0,0c-1.9-1.1-2.6-3.6-1.5-5.5 l16-27.7C91.3,7.9,93.7,7.3,95.7,8.4z'/>
            <path fill-opacity='.1' d='M119.2,31.7L119.2,31.7c1.1,1.9,0.4,4.4-1.5,5.5L90,53.1c-1.9,1.1-4.4,0.4-5.5-1.5l0,0 c-1.1-1.9-0.4-4.4,1.5-5.5l27.7-16C115.7,29.1,118.1,29.7,119.2,31.7z'/>
            <path fill-opacity='.1' d='M128,63.6L128,63.6c0,2.2-1.8,4-4,4H92c-2.2,0-4-1.8-4-4v0c0-2.2,1.8-4,4-4h32C126.2,59.6,128,61.4,128,63.6z' />
            <path fill-opacity='.2' d='M119.6,95.7L119.6,95.7c-1.1,1.9-3.6,2.6-5.5,1.5l-27.7-16c-1.9-1.1-2.6-3.6-1.5-5.5l0,0 c1.1-1.9,3.6-2.6,5.5-1.5l27.7,16C120.1,91.3,120.7,93.7,119.6,95.7z'/>
            <path fill-opacity='.3' d='M96.3,119.2L96.3,119.2c-1.9,1.1-4.4,0.4-5.5-1.5L74.9,90c-1.1-1.9-0.4-4.4,1.5-5.5l0,0 c1.9-1.1,4.4-0.4,5.5,1.5l16,27.7C98.9,115.7,98.3,118.1,96.3,119.2z'/>
            <path fill-opacity='.4' d='M64.4,128L64.4,128c-2.2,0-4-1.8-4-4V92c0-2.2,1.8-4,4-4h0c2.2,0,4,1.8,4,4v32C68.4,126.2,66.6,128,64.4,128z' />
            <path fill-opacity='.5' d='M32.3,119.6L32.3,119.6c-1.9-1.1-2.6-3.6-1.5-5.5l16-27.7c1.1-1.9,3.6-2.6,5.5-1.5l0,0 c1.9,1.1,2.6,3.6,1.5,5.5l-16,27.7C36.7,120.1,34.3,120.7,32.3,119.6z'/>
            <path fill-opacity='.6' d='M8.8,96.3L8.8,96.3c-1.1-1.9-0.4-4.4,1.5-5.5l27.7-16c1.9-1.1,4.4-0.4,5.5,1.5l0,0c1.1,1.9,0.4,4.4-1.5,5.5 l-27.7,16C12.3,98.9,9.9,98.3,8.8,96.3z'/>
            <path fill-opacity='.7' d='M0,64.4L0,64.4c0-2.2,1.8-4,4-4h32c2.2,0,4,1.8,4,4v0c0,2.2-1.8,4-4,4H4C1.8,68.4,0,66.6,0,64.4z'/>
            <path fill-opacity='.8' d='M8.4,32.3L8.4,32.3c1.1-1.9,3.6-2.6,5.5-1.5l27.7,16c1.9,1.1,2.6,3.6,1.5,5.5l0,0c-1.1,1.9-3.6,2.6-5.5,1.5 l-27.7-16C7.9,36.7,7.3,34.3,8.4,32.3z'/>
            <path fill-opacity='.9' d='M31.7,8.8L31.7,8.8c1.9-1.1,4.4-0.4,5.5,1.5l16,27.7c1.1,1.9,0.4,4.4-1.5,5.5l0,0c-1.9,1.1-4.4,0.4-5.5-1.5 l-16-27.7C29.1,12.3,29.7,9.9,31.7,8.8z'/>
            <animateTransform accumulate='none' additive='replace' attributeName='transform' calcMode='discrete' dur='750ms' fill='remove' repeatCount='indefinite' restart='always' type='rotate' values='0 64 64;30 64 64;60 64 64;90 64 64;120 64 64;150 64 64;180 64 64;210 64 64;240 64 64;270 64 64;300 64 64;330 64 64'></animateTransform>
            </g>
        </symbol>


        <view id="i-first"                 viewBox="10 10 32 32"/>
        <use xlink:href="#first"             x="10" y="10" width="32" height="32"/>

        <view id="i-prev"                 viewBox="60 10 32 32"/>
        <use xlink:href="#prev"             x="60" y="10" width="32" height="32"/>

        <view id="i-play"                 viewBox="110 10 32 32"/>
        <use xlink:href="#play"             x="110" y="10" width="32" height="32"/>

        <view id="i-pause"                 viewBox="160 10 32 32"/>
        <use xlink:href="#pause"             x="160" y="10" width="32" height="32"/>

        <view id="i-next"                 viewBox="210 10 32 32"/>
        <use xlink:href="#next"             x="210" y="10" width="32" height="32"/>

        <view id="i-last"                 viewBox="260 10 32 32"/>
        <use xlink:href="#last"             x="260" y="10" width="32" height="32"/>

        <view id="i-close"                 viewBox="310 10 32 32"/>
        <use xlink:href="#close"             x="310" y="10" width="32" height="32"/>

        <view id="i-download"             viewBox="360 10 32 32"/>
        <use xlink:href="#download"         x="360" y="10" width="32" height="32"/>

        <view id="i-linkto"                 viewBox="410 10 32 32"/>
        <use xlink:href="#linkto"             x="410" y="10" width="32" height="32"/>

        <view id="i-zoomin"                 viewBox="460 10 32 32"/>
        <use xlink:href="#zoomin"             x="460" y="10" width="32" height="32"/>

        <view id="i-loader"                 viewBox="10 100 32 32"/>
        <use xlink:href="#loader"             x="10" y="100" width="32" height="32"/>


    </svg>
    Si vous souhaitez participer, même modestement, au maintien du site et pour son usage, vous pouvez cliquer sur le joli bouton…
    Voir aussi…
    2019-12-09