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
- Javascript : /v201912.lightbox.js
- Javascript : https://github.com/mattbryson/TouchSwipe-Jquery-Plugin
- CSS : /v201912.lightbox.css
- SVG : ./svg/lightbox.svg
Utilisation

<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…
- Conversion SVG/CSS Encodage SVG pour CSS compatible Sass et exemple d'intégration SVG via xlink compatible CSS
- Optimisation SVG Intégration SVG via xlink/use/symbol, factorisation de symbol SVG
- Responsive SVG Utilisation des media queries internes au SVG
- Design, flux et accessibilité jQuery Responsive layout logical DOM plugin
- Lightbox Responsive et Accessible Lightbox images jQuery Responsive accessible a11y. Automatisation d'une Lightbox multipages. Lightbox image unique ou multiple. Lightbox responsive et accessible a11y wcag
- Tooltip (infobulle) a11y Tooltip (infobulle) compatible a11y et SEO, naviguable au clavier, accessible par lecteur d'écran
- Vérifier un numéro de carte bancaire Validateur de carte bancaire. Contrôle de format de numéro de carte bancaire, algorithme de Luhn carte de crédit Visa, Mastercard, Maestro, CB, Carte Bancaire, Discover Card, American Express, JCB Cards
- Owl Carousel multiple Créer et gérer plusieurs carrousel / sliders sur une seule page avec Owl Carousel 2. Create and manage multiple carousel/sliders on one page with Owl Carousel 2
- Zipcode patterns Contrôle automatisé de codes postaux
- Responsive background-image jQuery responsive background-image plugin
- Drapeaux ISO 3366 SVG Drapeaux nationaux vectoriels normés ISO alpha 2, alpha 3 et numérotation Organisation des Nations Unies (ONU). SVG drapeaux pour internationalisation de sites multilingues.
- Layout rigolo
- Serveur d'images placeholders Serveur d'images placeholder pour le développement front-end.
- Générateur de Lorem Outil de génération de Lorem Ipsum. Utilisable en ligne ou par url distante.
- Générateur de noms API de génération de couples prénom/nom aléatoires.