<?xml version="1.0" encoding="UTF-8"?>
	<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>Agence web Adilade</title>
<link>https://www.adilade.fr/</link>
<description>Agence web Adilade</description>
<pubDate>Sun, 24 May 2026 09:16:28 +0200</pubDate>
<language>fr-FR</language>
<item>
<title>Carrousel accessible v2</title>
<link>https://www.adilade.fr/blog/carrousel-accessible-v2/</link>
<pubDate>Tue, 05 May 2026 02:05:00 +0200</pubDate>
<description><![CDATA[<p>Le temps était venu de moderniser ce composant JavaScript, même si son utilité reste toujours discutable !</p><p>On pourrait longuement palabrer sur l'utilité d'un carrousel, mais en attendant l'arrivée du <span lang="en">masonry layout</span> avec <code>display: grid-lanes;</code> et de sa mise en page façon Pinterest - voir d'opter pour un défilement horizontal, l'élaboration de ce type de projet demeure une expérience enrichissante du fait des compétences mises en œuvre : accessibilité, <abbr lang="en" title="Cascading Style Sheets">CSS</abbr> et JavaScript.<br>Cette nouvelle version est évidemment <span lang="en">responsive</span> et entièrement en langages natifs. De plus, ce composant fonctionne avec des images de différentes tailles, elles sont contenues à l'intérieur du bloc et centrées verticalement et horizontalement : la magie de <code>object-fit</code> couplé à <code>grid</code>.</p>
<h2>Rappel : l'accessibilité d'un carrousel</h2>
<p>Vous pouvez vous référer à l'<a href="https://www.adilade.fr/blog/carrousel-accessible-responsive-vanillajs/">article de la première version du carrousel</a> pour des explications plus exhaustives.</p>
<ul>
<li>Les contenus en mouvement doivent être contrôlables : bouton pause en début de code et raccourcis clavier pour le contrôle du carrousel</li>
<li>Zone live <abbr lang="en" title="Accessible Rich Internet Applications">ARIA</abbr> : <code>aria-live="polite"</code> et focus sur l'élément actif permet la lecture du panneau en cours</li>
<li>Attributs <abbr lang="en" title="Accessible Rich Internet Applications">ARIA</abbr> : <code>aria-controls</code>, <code>aria-selected</code> et <code>role="group"</code> sur les boutons de la navigation par points, <code>aria-roledescription</code> pour indiquer le rôle de chaque contenu, <code>aria-label</code> complète les informations</li>
<li>Arrêt du carrousel à la prise de focus</li>
</ul>
<p class="ambloc"><a href="https://codepen.io/Adilade/pen/RNoPdmL" rel="external" hreflang="en">Voir la démo sur CodePen</a></p>
<h2>La base <abbr lang="en" title="HyperText Markup Language">HTML</abbr> et ses nouveautés</h2>
<ul>
<li>Séparation du carrousel et des éléments de contrôles, le bouton d'arrêt se situant en premier dans l'arbre <abbr lang="en" title="Document Object Model">DOM</abbr></li>
<li>Ajout de <code>aria-live="off"</code> par défaut sur le conteneur</li>
<li>Ajout de <code>tabindex</code> sur chaque panneau (0 pour le panneau actif et -1 pour les autres)</li>
</ul>
<pre class="language-markup"><code>&lt;section id="slides" aria-roledescription="Slideshow" aria-label="Description of Carousel"&gt;
	
	&lt;!-- Slide Controls --&gt;
	&lt;div class="slides-panel-control"&gt;
		&lt;div class="slides-control"&gt;
			&lt;button type="button" class="slides-playpause" aria-controls="slides-items" aria-label="Stop Carousel" disabled&gt;
				&lt;svg class="playpause" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0 0 32 32" role="img"&gt;
					&lt;g class="play"&gt;
						&lt;path d="m7.43 31c2.36 0 4.29-1.93 4.29-4.29v-21.4c0-2.36-1.93-4.29-4.29-4.29-2.36 0-4.29 1.93-4.29 4.29v21.4c0 2.36 1.93 4.29 4.29 4.29zm12.9-25.7v21.4c0 2.36 1.93 4.29 4.29 4.29s4.29-1.93 4.29-4.29v-21.4c0-2.36-1.93-4.29-4.29-4.29s-4.29 1.93-4.29 4.29z"&gt;&lt;/path&gt;
					&lt;/g&gt;
					&lt;g class="pause"&gt;
						&lt;path d="m6.29 0.988c1.75-0.00742 13.3 8.37 20 12.4 2.61 1.35 2.72 3.64 0.145 5.18-6.19 3.67-18.7 12.4-20.3 12.4-1.59 0.0055-2.31-1.16-2.36-2.73 0.0104-8.27-0.0208-16.5 0.0156-24.8-0.0349-1.19 0.787-2.46 2.53-2.47z"&gt;&lt;/path&gt;
					&lt;/g&gt;
				&lt;/svg&gt;		
			&lt;/button&gt;
			&lt;button type="button" class="slides-prev" aria-controls="slides-items" aria-label="Previous Slide" disabled&gt;
				&lt;svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0 0 32 32" role="img"&gt;
					&lt;path d="m22.1 31c2.03-0.108 3.01-2.54 1.62-4.03l-10.4-10.8 10.4-11c2.34-2.26-1.13-5.73-3.39-3.39l-12 12.6c-0.903 0.904-0.937 2.36-0.0775 3.3l12 12.5c0.483 0.548 1.19 0.846 1.92 0.808z"&gt;&lt;/path&gt;
				&lt;/svg&gt;
			&lt;/button&gt;
			&lt;button type="button" class="slides-next" aria-controls="slides-items" aria-label="Next Slide" disabled&gt;
				&lt;svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0 0 32 32" role="img"&gt;
					&lt;path d="m9.9 31c-2.03-0.108-3.01-2.54-1.62-4.03l10.4-10.8-10.4-11c-2.34-2.26 1.13-5.73 3.39-3.39l12 12.6c0.903 0.904 0.937 2.36 0.0775 3.3l-12 12.5c-0.483 0.548-1.19 0.846-1.92 0.808z"&gt;&lt;/path&gt;
				&lt;/svg&gt;
			&lt;/button&gt;
		&lt;/div&gt;
	&lt;/div&gt;
	
	&lt;div id="slides-items" aria-live="off"&gt;
		
		&lt;!-- Slide 1 // Active slide: class="slideactive" and tabindex="0" --&gt;
		&lt;div id="slide-1" class="slide-item slideactive" role="group" aria-roledescription="Slide" aria-label="1 of 3" tabindex="0"&gt;
			&lt;figure&gt;
				&lt;img src="img1.webp" alt="Alternative image 1" width="1200" height="600" loading="lazy" decoding="async"&gt;
			&lt;/figure&gt;
			&lt;figcaption&gt;Slide 1 Description&lt;/figcaption&gt;
		&lt;/div&gt;
		&lt;!-- Slide 2 --&gt;
		&lt;div id="slide-2" class="slide-item" role="group" aria-roledescription="Slide" aria-label="2 of 3" tabindex="-1"&gt;
			&lt;figure&gt;
				&lt;img src="img2.webp" alt="Alternative image 2" width="556" height="247" loading="lazy" decoding="async"&gt;
			&lt;/figure&gt;
			&lt;figcaption&gt;Slide 2 Description&lt;/figcaption&gt;
		&lt;/div&gt;
		&lt;!-- Slide 3 --&gt;
		&lt;div id="slide-3" class="slide-item" role="group" aria-roledescription="Slide" aria-label="3 of 3" tabindex="-1"&gt;
			&lt;figure&gt;
				&lt;img src="img3.webp" alt="Alternative image 3" width="1200" height="1800" loading="lazy" decoding="async"&gt;
			&lt;/figure&gt;
			&lt;figcaption&gt;&lt;strong&gt;Slide 3 Description.&lt;/strong&gt;&lt;br&gt;&lt;span lang="lat"&gt;Venerem elegerit sexus mercenariae tabernaculum matrimonii in conductae post species.&lt;/span&gt;&lt;/figcaption&gt;
		&lt;/div&gt;
		
	&lt;/div&gt;
	
&lt;/section&gt;</code></pre>
<h2>Le code <abbr lang="en" title="Cascading Style Sheets">CSS</abbr> et ses nouveautés</h2>
<ul>
<li>Passage en Vanilla <abbr lang="en" title="Cascading Style Sheets">CSS</abbr> et ajout de <code>@layer</code> pour une meilleure intégration dans les projets</li>
<li>Effet de transition avec <code>transition-behavior: allow-discrete;</code> et <code>@starting-style</code> pour un support complet</li>
<li>Exit le positionnement relatif et absolu, place à <code>grid</code> <span lang="en">stack</span> et <code>flex</code></li>
<li>Utilisation de <code>display: none;</code> sur les panneaux inactifs pour éviter l'interprétation par un lecteur d'écran</li>
<li>Ajout de <code>object-fit</code> pour contraindre l'image à l'intérieur du conteneur</li>
</ul>
<pre class="language-css"><code>@layer resetdemo, carousel;

@layer resetdemo {
	*,
	*::before,
	*::after {
		box-sizing: border-box; 
		min-width: 0;
	}
	body {
		margin: 0;
		font-size: 1rem;
		font-family: system-ui, sans-serif;
		line-height: 1.5;
	}
	img, figure  {
		max-width: 100%; 
		height: auto;
		margin: 0;
	}
	svg {
		vertical-align: middle;
	}
	button {
		padding: 0;
		margin: 0;
		border-style: none;
		touch-action: manipulation;
		display: inline-block;
		border: none;
		background: none;
		cursor: pointer;
		
		&amp;:focus-visible {
			outline: max(2px, .08em) dashed currentColor;
			outline-offset: max(2px, .08em);
		}	
	}
}

@layer carousel {
	:root {
		--carousel-width: 1200px;
		--carousel-aspect-ratio: 12/6; 
		--carousel-color: DarkOrchid;
		--carousel-bg: AntiqueWhite;
	}
	#slides {
		max-width: var(--carousel-width);
		margin: 3.618em auto;
		
		.slides-panel-control {
			display: flex;
			justify-content: space-between;
		}
		/* Control Buttons */
		.slides-control, .slides-dots {		
			display: flex;
			flex-wrap: wrap;
			justify-content: center;
			margin-bottom: 1em;
			gap: 1em;
		}
		.slides-control {
			
			button {
				background-color: rgba(0, 0, 0, 0.7);
				border-radius: .3em;
				display: inline-block;
				padding: 1em;
				
				svg {
					width: 1.618em;
					height: 1.618em;
				}			
				&amp;:disabled {
					display: none;
				}
				&amp;:hover {
					background-color: var(--carousel-color);
				}
				:is(svg, g) {
					pointer-events: none;
					fill: #fff;
				}
			}
			.slides-playpause .play,
			.slides-playpause .playpause.paused .pause {
				display: none;
			}
			.slides-playpause .playpause.paused .play {
				display: block;
			}
		}
		/* Dots Buttons */
		.slides-dots {
			
			button {
				display: inline-block;
				padding: 1em;
				background-color: transparent;
			}
			svg {
				pointer-events: none;
				width: 1.618em;
				height: 1.618em;
				fill: rgba(0, 0, 0, 0.7);
			}
			:is(button:hover, button:focus, button:active) svg {
				fill: transparent;
				stroke: var(--carousel-color);
				stroke-width: .3ch;
			}
			button[aria-selected="true"] svg {
				fill: var(--carousel-color);
			}
		}
		@media (width &lt; 36rem) {
			.slides-panel-control {
				display: block;
			} 
		}
	}
	
	#slides-items {
		display: grid;
		grid: 1fr / 1fr; /* Not necessary - for greater clarity */
	
		&gt; .slide-item {
			grid-area: 1 / 1;
			overflow: hidden; /* For responsive */
			aspect-ratio: var(--carousel-aspect-ratio); /* For responsive */
			display: grid;	
			grid: 1fr / 1fr; /* Not necessary - for greater clarity */
			background: var(--carousel-bg);
	
			&gt; * {
				grid-area: 1 / 1;
			}
			
			figure {
				align-self: center;
				justify-self: center;
				max-height: calc(var(--carousel-width) / (var(--carousel-aspect-ratio)));	
				
				img {
					aspect-ratio: var(--carousel-aspect-ratio); /* For responsive */
					max-height: calc(var(--carousel-width) / (var(--carousel-aspect-ratio)));
					object-fit: contain;
				} 
			}			
			figcaption {
				align-self: end;	
				font-size: clamp(.8em, .6em + .7vw, 1.2em);
				text-align: center;
				color: #fff;
				padding: .9em;
				background-color: rgba(0, 0, 0, 0.7);
			}
		}
		.slideactive:focus-visible {
			outline: max(2px, .08em) solid currentColor;
			outline-offset: 0;	
		}	
		/* CSS Transition */
		.slideactive {
			opacity: 1;
			transition: all 2s;
			transition-behavior: allow-discrete;
			@starting-style {
				opacity: 0;
			}
		}
		.slide-item:not(.slideactive) {
			opacity: 0;
			display: none;
		}		
	}
}</code></pre>
<h2>Le code JavaScript et ses nouveautés</h2>
<ul>
<li>Ajout du focus sur l'élément en cours et gestion de <code>tabindex</code> (0 et -1) pour une meilleure restitution avec un lecteur d'écran</li>
<li>Détection de <code>prefers-reduced-motion</code> et désactivation de la rotation automatique, si nécessaire</li>
<li>Ajout du <span lang="en">swipe</span> pour mobile</li>
<li>Arrêt du carrousel à la prise de focus sur le panneau en cours lorsque la rotation automatique est activée</li>
</ul>
<pre class="language-javascript"><code>/*
* @Adilade Slideshow/Carousel
* @See www.adilade.fr/blog/carrousel-accessible-v2/
* @Version : 2.0
*
* Keyboard : 
* Previous : left arrow or ctrl + left arrow
* Next : right arrow or ctrl + right arrow
* Pause/Play : space
* 
* Free to use - No warranty
*/

var timeInterval = '7000'; // Time between slides in ms
var slidediv = document.querySelector('#slides');
var carousel = document.querySelector('#slides-items');
var items = document.querySelectorAll('.slide-item');
var panel = document.querySelector('.slides-control');

if (carousel !== undefined &amp;&amp; items !== undefined &amp;&amp; carousel !== null &amp;&amp; items !== null) {
	var itemscount = items.length;
	var btnprev = document.querySelector('.slides-prev');
	var btnnext = document.querySelector('.slides-next');
	var btnplaypause = document.querySelector('.slides-playpause');
	var btnplaypausepath = document.querySelector('.playpause');			

	// If JavaScript enabled
	btnprev.removeAttribute('disabled');
	btnnext.removeAttribute('disabled');
	btnplaypause.removeAttribute('disabled');
			
	if (itemscount &gt; 1) {
		
		// Create Dots
		var dotbox = document.createElement('div');
		dotbox.classList.add('slides-dots');
		dotbox.setAttribute('role', 'group');
		panel.after(dotbox); 		
		for (var i=0; i&lt;itemscount; i++) {
			dotbox.insertAdjacentHTML('beforeend', '&lt;button type="button" aria-controls="slide-'+(i+1)+'" aria-label="Slide number '+(i+1)+'" aria-selected="'+(document.querySelector('.slideactive').getAttribute('id').slice(-1) == (i+1) ? 'true' : 'false')+'"&gt;&lt;svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0 0 32 32" role="img"&gt;&lt;circle cx="16" cy="16" r="13" /&gt;&lt;/svg&gt;&lt;/button&gt;');
		}	
			
		var dots = document.querySelectorAll('.slides-dots button');
		var playpause = null;
	
		function slideprev() {
			var itemcurrent = document.querySelector('.slideactive');
			var dotcurrent = document.querySelector('.slides-dots button[aria-selected="true"]');
			var prevslide = itemcurrent.previousElementSibling;
			var prevdot = dotcurrent.previousElementSibling;
			if(prevslide === null) {
				prevslide = items[itemscount - 1];
				prevdot = dots[itemscount - 1]; 
			}
			// Remove current
			itemcurrent.classList.remove('slideactive');
			itemcurrent.blur();
			itemcurrent.setAttribute('tabindex', '-1');
			dotcurrent.setAttribute('aria-selected', 'false');
					
			// Add Next
			prevslide.setAttribute('tabindex', '0');
			prevslide.classList.add('slideactive');
			prevslide.focus();
			prevdot.setAttribute('aria-selected', 'true');
		}
		
		function slidenext() {
			var itemcurrent = document.querySelector('.slideactive');
			var dotcurrent = document.querySelector('.slides-dots button[aria-selected="true"]');
			var nextslide = itemcurrent.nextElementSibling;
			var nextdot = dotcurrent.nextElementSibling;
			if(nextslide === null) {
				nextslide = items[0];
				nextdot = dots[0];
			}
			// Remove current
			itemcurrent.setAttribute('tabindex', '-1');
			itemcurrent.classList.remove('slideactive');
			itemcurrent.blur();
			dotcurrent.setAttribute('aria-selected', 'false');
								
			// Add Next
			nextslide.setAttribute('tabindex', '0');
			nextslide.classList.add('slideactive');
			nextslide.focus();
			nextdot.setAttribute('aria-selected', 'true');
		}

		function slidepause() {
			clearInterval(playpause);
			playpause = null;
			btnplaypause.setAttribute('aria-label', 'Play Carousel');
			btnplaypausepath.classList.add('paused');
			carousel.setAttribute('aria-live', 'off');		
		}
		function slideplay() {
			playpause = setInterval(slidenext, timeInterval);
			btnplaypause.setAttribute('aria-label', 'Stop Carousel');
			btnplaypausepath.classList.remove('paused');							
		}						
		function slideplaypause() {
			if (playpause !== null) {
				slidepause();
				carousel.classList.add('btnpressed');
			} else {
				slideplay();
				carousel.classList.remove('btnpressed');
				//carousel.setAttribute('aria-live', 'off');
			}
		}
						
		// Dots Navigate
		[].map.call(dots, function(dot) {

			dot.addEventListener('click', function(e) {
				var itemcurrent = document.querySelector('.slideactive');
				var dotcurrent = document.querySelector('.slides-dots button[aria-selected="true"]');
				var dotclick = dot.getAttribute('aria-controls');
				var targetslide = document.querySelector('#'+ dotclick +'');
				var targetdot = document.querySelector('button[aria-controls="'+dotclick+'"]');

				// Remove current
				itemcurrent.setAttribute('tabindex', '-1');
				itemcurrent.classList.remove('slideactive');
				dotcurrent.setAttribute('aria-selected', 'false');
				itemcurrent.blur();
									
				// Add Target
				targetslide.setAttribute('tabindex', '0');
				targetslide.classList.add('slideactive');
				targetdot.setAttribute('aria-selected', 'true');
				targetslide.focus();
				
				if (playpause !== null) {
					slidepause();
				}
				carousel.setAttribute('aria-live', 'polite');
				
				e.preventDefault();
			
			});
			
		});
				
		// Navigate
		btnprev.addEventListener('click', function() {
			slideprev();
			if (playpause !== null) {
				slidepause();
			}
			carousel.setAttribute('aria-live', 'polite');
		});
		btnnext.addEventListener('click', function() {
			slidenext();			 
			if (playpause !== null) {
				slidepause();
			}
			carousel.setAttribute('aria-live', 'polite');
		});
		btnplaypause.addEventListener('click', slideplaypause);
		
		// Keyboard Navigate
		slidediv.addEventListener('keydown', keyHandler);		
		function keyHandler(e) {
			// Left Arrow
			if (e.keyCode === 37 || (e.ctrlKey &amp;&amp; e.keyCode === 37)) {		
				
				slideprev();
				if (playpause !== null) {
					slidepause();
				}
				e.preventDefault();
			}
			// Right Arrow
			if (e.keyCode === 39 || (e.ctrlKey &amp;&amp; e.keyCode === 39)) {		
				
				slidenext();
				if (playpause !== null) {
					slidepause();
				}
				e.preventDefault();
			}
			// Space
			if (e.keyCode === 32) {		
				
				slideplaypause();
				e.preventDefault();
			}
		}
		
		// Mobile/Swipe Navigate
		// Credit : https://www.kirupa.com/html5/detecting_touch_swipe_gestures.htm	
		carousel.addEventListener('touchstart', startTouch, false);
		carousel.addEventListener('touchmove', moveTouch, false);

		// Swipe Up / Down / Left / Right
		var initialX = null;
		var initialY = null;
		
		function startTouch(e) {
			initialX = e.touches[0].clientX;
			initialY = e.touches[0].clientY;
		};
		
		function moveTouch(e) {
			if (initialX === null) {
				return;
			}
		
			if (initialY === null) {
				return;
			}
		
			var currentX = e.touches[0].clientX;
			var currentY = e.touches[0].clientY;
			
			var diffX = initialX - currentX;
			var diffY = initialY - currentY;
			
			if (Math.abs(diffX) &gt; Math.abs(diffY)) {
				// sliding horizontally
				if (diffX &gt; 0) {
					// swiped left
					slidenext();
					if (playpause !== null) {
						slidepause();
					}
				} else {
					// swiped right
					slideprev();
					if (playpause !== null) {
						slidepause();
					}
				}  
			}				
			initialX = null;
			initialY = null;
			
			e.preventDefault();
		};				    	
				 
		// Animate Slides - Comment next line for disable auto-rotating
		playpause = setInterval(slidenext, timeInterval);
		
		// Stop Carousel on focusing slide only when Carousel auto-rotating
		document.querySelector('.slideactive').addEventListener('focus', function() {
			if(!carousel.classList.contains('btnpressed')) {
			  slidepause();
			}
		}); 
		
		// Prefers-reduced-motion
		var hasReducedMotion = (window.matchMedia('(prefers-reduced-motion: reduce)') === true || window.matchMedia('(prefers-reduced-motion: reduce)').matches === true);
		if (hasReducedMotion) {
			slidepause();
		} 
		
	} else { // End itemscount &lt; 1 =&gt; Remove buttons controls
		btnprev.parentNode.removeChild(btnprev);
		btnnext.parentNode.removeChild(btnnext);
		btnplaypause.parentNode.removeChild(btnplaypause);
	}
	
} // End if test</code></pre>]]></description>
<guid>https://www.adilade.fr/blog/carrousel-accessible-v2/</guid>
</item>
<item>
<title>Adilade MiniCMS : un site web statique modifiable !</title>
<link>https://www.adilade.fr/blog/minicms-site-web-statique-modifiable/</link>
<pubDate>Mon, 23 Mar 2026 00:40:00 +0100</pubDate>
<description><![CDATA[<p>Un site web statique modifiable, une idée farfelue ! Pas tant que cela ! En effet, pourquoi déployer l'artillerie lourde pour un site web de quelques pages avec des mises à jour peu fréquentes ?</p><h2>Le constat</h2>
<p>Il arrive parfois que l'installation d'un <abbr lang="en" title="Content Management System">CMS</abbr> complet comprenant une base de données, une zone d'administration, un contrat de maintenance et avec une prise en main parfois complexe, pour seulement quelques pages, ne soit pas nécessaire. La simplicité a souvent du bon. Mais, la possibilité d'effectuer facilement des modifications ciblées sur un site vitrine/statique est un atout non négligeable.</p>
<h2>Le compromis du MiniCMS</h2>
<p>Il permet de modifier simplement et aisément certains <strong>contenus textuels</strong> (prédéfini à l'avance) d'un site web statique. Il est facile à utiliser et à prendre en main sans besoin de formation.</p>
<ul>
<li>Fonctionne sans base de données</li>
<li>Volontairement minimaliste</li>
<li>Gestion de texte brut uniquement</li>
<li>Permet la modification de blocs de contenu</li>
<li>Permet l'ajout, la suppression et la réorganisation d'éléments</li>
<li>Possibilité de gérer des liens</li>
<li>Compatible mobile</li>
<li>Possibilité d'implémentation sur des sites web pré-existant (sous réserve de compatibilité technique)</li>
</ul>
<h2>Pour quels usages ?</h2>
<p>Cette solution s'adresse avant tout aux petites entreprises, artisans ou commerçants qui n'ont pas de mise à jour fréquente à effectuer : instituts de beauté, salon de coiffure, restaurant, restauration rapide, artisans du bâtiment, artisanat, hébergement touristique, etc.</p>
<h3>Quelques exemples de contenus modifiables :</h3>
<ul>
<li>Menu ou carte d'un restaurant</li>
<li>Liste de prestations</li>
<li>Horaires d'ouverture, vacances ou annonce</li>
<li>Grille tarifaire</li>
</ul>
<p class="ambloc"><a href="https://www.youtube.com/watch?v=LpW_QfqMYwk" rel="external">Regarder la vidéo sur YouTube</a></p>]]></description>
<guid>https://www.adilade.fr/blog/minicms-site-web-statique-modifiable/</guid>
</item>
<item>
<title>Adilade fête ses 20 ans !</title>
<link>https://www.adilade.fr/blog/adilade-fete-20-ans/</link>
<pubDate>Wed, 04 Feb 2026 00:04:00 +0100</pubDate>
<description><![CDATA[<p>2006 - 2026 : 20 ans de passion pour le web !</p><h2>Un web mature et plus complexe</h2>
<p>Passé d'un quasi-artisanat en 2006, la conception de site web devient une discipline d'ingénierie : plus de complexité, plus de compétences - performance, accessibilité, sécurité, etc.</p>
<ul>
<li>Les <abbr lang="en" title="Cascading Style Sheets">CSS</abbr> ont mûri, au point de se rapprocher d'un langage de programmation.</li>
<li>Tailwind ou Bootstrap, Vue.js ou Angular - de nombreux frameworks sont apparus, pour le meilleur et pour le pire (dont une certaine uniformité). Pourtant, le parti pris de la conception en langages natifs limite les dépendances et assure une plus grande universalité des projets dans le temps.</li>
<li>Les performances et les <span lang="en">Core Web Vitals</span> sont devenus la norme.</li>
<li>L'accessibilité s'intègre peu à peu dans les projets, même si son adhésion reste très lente.</li>
<li>On peut regretter la généralisation des <span lang="en">builders</span> qui produisent un code assez immonde, on se croirait revenu au temps de FrontPage ou DreamWeaver.</li>
</ul>
<h2>L'<abbr title="Intelligence Artificielle">IA</abbr> joue les trouble-fête</h2>
<p>Arrivé en trombe il y a à peine quelques années, l'<abbr title="Intelligence Artificielle">IA</abbr> s'immisce désormais dans tous les processus créatifs et techniques : code, graphisme, design, tests, etc. Mal utilisée, cela produit du code peu propre et des sites web bancals. Bien utilisée, elle augmente la productivité, la créativité tel un assistant infatigable. Le futur se jouera sur l'expérience et l'expertise.</p>
<h2>La passion et le futur</h2>
<p>La passion est essentielle, c'est le moteur qui fait vibrer le web. Et le futur s'annonce stimulant à tout point de vue : plus la complexité augmente, plus l'innovation constante et l'expertise deviennent nécessaires.</p>]]></description>
<guid>https://www.adilade.fr/blog/adilade-fete-20-ans/</guid>
</item>
<item>
<title>Voeux 2026</title>
<link>https://www.adilade.fr/blog/voeux-2026/</link>
<pubDate>Thu, 01 Jan 2026 01:30:00 +0100</pubDate>
<description><![CDATA[<p>Meilleurs Vœux 2026</p>]]></description>
<guid>https://www.adilade.fr/blog/voeux-2026/</guid>
</item>
<item>
<title>De l&#039;usage de l&#039;IA en production</title>
<link>https://www.adilade.fr/blog/usage-ia-production/</link>
<pubDate>Tue, 16 Sep 2025 06:06:00 +0200</pubDate>
<description><![CDATA[<p>L'intelligence artificielle s'est immiscée, en quelques années à peine, dans les processus créatifs et techniques : texte, image, graphisme, codage, et plus encore. Ces avancées technologiques sont parfois difficiles à intégrer en entreprises et posent des questions cruciales sur le long terme.</p><h2>Intégration dans le flux de production</h2>
<p>Passer de la découverte à l'intégration dans les méthodes de travail n'est pas chose aisée. Outre le fait que la sortie de nouveaux modèles et de nouvelles <abbr title="Intelligence Artificielle">IA</abbr> est fréquente, l'assimilation efficace au quotidien peut prendre du temps : tests, vérifications, qualité, modification des processus de création, etc. Il faut souvent faire un bilan régulier : quelle réelle plus-value ? Quelle amélioration de la productivité ou de la qualité ?</p>
<h2>Des images (encore) très marquées</h2>
<p>Première application des <abbr title="Intelligence Artificielle">IA</abbr> génératives, la création d'image s'améliore progressivement. Pour ce qui est du design, elles peuvent servir de base de travail et éviter un long processus de réflexion et d'essais. Parfait pour tester rapidement des idées ou servir de support à une vectorisation. À noter que les <abbr title="Intelligence Artificielle">IA</abbr> génératives sont très performantes dans les "associations de couleurs".</p>
<p>Pour les images de type "photo réaliste", le résultat reste encore fréquemment très marqué. Il faut régulièrement retoucher la colorimétrie, sans compter les hallucinations qui persistent parfois, en particulier sur les yeux.</p>
<p>Un exemple de "photo réaliste" générée par 3 <abbr title="Intelligence Artificielle">IA</abbr> différentes et qui utilisent le même prompt, il s'agit d'une photo destinée à réaliser des <span lang="en">mockup</span>.</p>
<p><img class="imgcenter am-img-medium amNonEditable" src="https://www.adilade.fr/media/img/3-photos-de-femmes-rousses-generees-par-intelligence-artificielle-medium.jpg?ver=1757980686" alt="" width="1200" height="600" sizes="(min-width: 1919px) 100vw, (min-width: 1200px) 1199px, 100vw" decoding="async" srcset="https://www.adilade.fr/media/img/3-photos-de-femmes-rousses-generees-par-intelligence-artificielle-thumb.jpg?ver=1757980686 440w, https://www.adilade.fr/media/img/3-photos-de-femmes-rousses-generees-par-intelligence-artificielle-medium.jpg?ver=1757980686 1200w, https://www.adilade.fr/media/img/3-photos-de-femmes-rousses-generees-par-intelligence-artificielle-large.jpg?ver=1757980686 2400w, https://www.adilade.fr/media/img/3-photos-de-femmes-rousses-generees-par-intelligence-artificielle.jpg?ver=1757980686 4800w" loading="lazy"></p>
<p>Le vrai problème vient de l'uniformisation des images, elles ont tendance à toutes "se ressembler", c'est assez flagrant sur les réseaux sociaux et maintenant sur des affiches ou des illustrations. En réalité, les images générées par <abbr title="Intelligence Artificielle">IA</abbr> présentent souvent des caractéristiques similaires : mêmes palettes de couleurs, mêmes compositions, même esthétique "lissée".</p>
<h2>Code : après l'euphorie, la désillusion</h2>
<p>L'intelligence artificielle est très efficace dans le codage : en l'utilisant comme métamoteur de recherche, on évite des longues heures de recherche dans la documentation, ou sur des forums spécialisés. L'inconvénient, c'est de ne pas réellement comprendre ce que l'on fait, avec tous les risques que cela pose en termes de qualité, de sécurité et de maintenabilité du code. Aujourd'hui, on arrive à un point ou des <a href="https://emploi.developpez.com/actu/375760/Des-codeurs-sont-embauches-pour-reparer-les-erreurs-commises-par-l-IA-qui-provoque-leurs-licenciements-specialiste-en-nettoyage-de-code-genere-par-l-IA-est-le-nouveau-titre-d-emploi-en-vogue-sur-les-CV/" rel="external">codeurs sont embauchés pour réparer les erreurs commises par l'<abbr title="Intelligence Artificielle">IA</abbr></a>.</p>
<h3>La question du <span lang="en">vibe coding</span></h3>
<p>Avec le <span lang="en">vibe coding</span>, on touche à l'expérience extrême : coder des sites web ou des applications sans rien n'y connaître (c'est-à-dire sans relire le code, le corriger, l'implémenter, le tester...). Ce genre de projet tourne quasi systématiquement à la catastrophe.</p>
<h2>Des avantages indéniables</h2>
<p>L'usage de l'<abbr title="Intelligence Artificielle">IA</abbr>, dans un process bien encadré, permet d'accélérer la productivité : résumé de contenu et rédaction de texte, génération d'images, qui peuvent servir d'ébauche, ou être utilisées comme base de travail. Codage plus rapide : <span lang="en">snippets</span> ou recherche de bug. Accès à l'apprentissage et à des domaines d'expertises plus élevés.</p>
<h2>Les inconvénients et risques à long terme</h2>
<ul>
<li><strong>Uniformisation</strong> : c'est déjà flagrant sur les images, mais aussi sur les textes ou le code. L'homogénéisation des contenus provoque une réelle menace pour l'identité de marque, et la différenciation devient plus difficile. Reproduire la complexité et la nuance, n'est pas chose aisée. Pour le code, cela pourrait aller jusqu'à un appauvrissement des écosystèmes et à des vulnérabilités plus fréquentes.</li>
<li><strong>Perte de compétence</strong> : à force d'utiliser l'<abbr title="Intelligence Artificielle">IA</abbr>, les développeurs pourraient perdre des compétences ou de l'expertise. Savoir coder avant d'utiliser l'intelligence artificielle constitue une condition préalable incontournable. Cela pourrait être pire avec les nouvelles générations, biberonnées à ChatGPT durant toutes leurs études !</li>
<li><strong>Dépendance</strong> : être accoutumé à un outil devient problématique si l'on ne conserve pas le savoir-faire humain. En cas de dysfonctionnement, tout est bloqué !</li>
</ul>
<p>À cela s'ajoute le manque de données pour l'entraînement des <abbr title="Intelligence Artificielle">IA</abbr> (elles ont déjà "digéré" tout ce que l'humain a produit) et le contenu de masse généré automatiquement commence à "polluer" le web.</p>
<h2>Conclusion</h2>
<p>Il y a fort à parier que l'<abbr title="Intelligence Artificielle">IA</abbr>, comme tous les outils précédents, finissent par s'intégrer dans les processus de production en conservant un certain équilibre : automatiser et accélérer la conception, tout en préservant l'expertise humaine pour la créativité, la stratégie et l'innovation. Utiliser l'intelligence artificielle comme un copilote, et non en remplacement de la compétence humaine.</p>]]></description>
<guid>https://www.adilade.fr/blog/usage-ia-production/</guid>
</item>
<item>
<title>Passer de Sass à Vanilla CSS</title>
<link>https://www.adilade.fr/blog/passer-de-sass-a-vanilla-css/</link>
<pubDate>Thu, 06 Mar 2025 00:06:00 +0100</pubDate>
<description><![CDATA[<p>Le préprocesseur <abbr lang="en" title="Syntactically awesome stylesheets">Sass</abbr> est un outil formidable, ne nous en cachons pas, mais les dépendances nécessaires pour la compilation et l'évolution des <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr> offre l'opportunité de revenir à l'utilisation de <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr> pur, ou Vanilla <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr>.</p><p>Les <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr> ont énormément évoluées ces dernières années et intègre en natif et avec un large support beaucoup de fonctionnalité <abbr lang="en" title="Syntactically awesome stylesheets">Sass</abbr>. Outre, la suppression à une dépendance pour la compilation, l'utilisation des standards natifs offre une meilleure maintenabilité pour le futur. Quelques éléments de base pour effectuer la transition de <abbr lang="en" title="Syntactically awesome stylesheets">Sass</abbr> vers Vanilla <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr> en douceur !</p>
<h2>Les Variables</h2>
<p>Déjà largement utilisées, les variables sont aisément implémentables, même s'il ne faut pas en abuser. Car, là où <abbr lang="en" title="Syntactically awesome stylesheets">Sass</abbr> remplace les variables par leurs valeurs respectives, ce n'est pas le cas en <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr>.</p>
<h3>Les variables en <abbr lang="en" title="Syntactically awesome stylesheets">Sass</abbr></h3>
<pre class="language-sass"><code>$color-green: #25653B;
$a11y-lineheight: 2.55rem;

main p {
	font-color: $color-green;
	line-height: $a11y-lineheight; 
}</code></pre>
<h3>Les variables en <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr></h3>
<pre class="language-css"><code>:root {
	--color-green: #25653B;
	--a11y-lineheight: 2.55rem;
}

main p {
	font-color: var(--color-green);
	line-height: var(--a11y-lineheight); 
}</code></pre>
<h2>Imbrication ou <span lang="en">Nesting</span></h2>
<p>C'est une fonctionnalité extrêmement intéressante et puissante de <abbr lang="en" title="Syntactically awesome stylesheets">Sass</abbr> qui évite des répétitions et une certaine lourdeur du code. Et, bonne nouvelle, cette fonctionnalité est déjà très largement supportée en <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr> (plus de 90%).</p>
<h3>Imbrication en <abbr lang="en" title="Syntactically awesome stylesheets">Sass</abbr></h3>
<pre class="language-sass"><code>.card {
    border: 1px solid #ddd;
	a {
		color: firebrick; 
		&amp;:hover {color: steelblue;}
	}
	p:last-child {margin-bottom: 1em;}
}</code></pre>
<h3>Imbrication en <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr></h3>
<p>Note : pour l'utilisation du sélecteur "&amp;", vous pouvez vous référer à l'article <a href="https://developer.chrome.com/docs/css-ui/css-nesting?hl=fr">Imbrication <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr></a>.</p>
<pre class="language-css"><code>.card {
    border: 1px solid #ddd;
	&amp; a {
		color: firebrick; 
		&amp;:hover {color: steelblue;}
	}
	&amp; p:last-child {margin-bottom: 1em;}
}</code></pre>
<h2>Les mixins</h2>
<p><code>@mixin</code> couplé à <code>@include</code> permet de définir un style de base réutilisable. Mais le code va être systématiquement réinjecté, ce qui alourdit la feuille de style.</p>
<h3>En <abbr lang="en" title="Syntactically awesome stylesheets">Sass</abbr></h3>
<pre class="language-sass"><code>@mixin card {
	border: 1px solid #ddd;
	a {
		color: firebrick; 
		&amp;:hover {color: steelblue;}
	}
	p:last-child {margin-bottom: 1em;}
}

.card--home {
  @include card;
  background-color: aliceblue;
}

/* Avec variable */
@mixin card($bg: azure) {
	border: 1px solid #ddd;
	background-color: $bg;
	a {
		color: firebrick; 
		&amp;:hover {color: steelblue;}
	}
	p:last-child {margin-bottom: 1em;}
}

.card--home {
	@include card(aliceblue);
}</code></pre>
<h3>En <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr></h3>
<p>En utilisant la technique <abbr lang="en" title="Block Element Modifier">BEM</abbr> et un sélecteur d'attribut, on arrive au même résultat. Avec, en bonus, un résultat plus léger, le code du bloc n'ayant pas besoin d'être systématiquement réinjecté.</p>
<pre class="language-css"><code>[class^="card"] {	
	border: 1px solid #ddd;
	&amp; a {
		color: firebrick; 
		&amp;:hover {color: steelblue;}
	}
	&amp; p:last-child {margin-bottom: 1em;}
}
.card--home {
	background-color: aliceblue;
}

/* En reprenant l'idée de la variable */
:root {
	--color-bg-card: azure; /* Couleur de base */
}
[class^="card"] {	
	border: 1px solid #ddd;
	background-color: var(--color-bg-card);
	&amp; a {
		color: firebrick; 
		&amp;:hover {color: steelblue;}
	}
	&amp; p:last-child {margin-bottom: 1em;}
}
.card--home {
	--color-bg-card: hotpink; /* Couleur de remplacement */
}</code></pre>
<h2>La règle <code>@import</code></h2>
<p>La fonction <code>@import</code> qui permet d'inclure des fichiers est supportée en <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr> depuis bien longtemps. Mais, là où <abbr lang="en" title="Syntactically awesome stylesheets">Sass</abbr> importe et compile le contenu des fichiers, ce n'est pas le cas en <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr>. Ce qui a pour conséquence d'augmenter le nombre de requêtes auprès du serveur (1 <code>@import</code> = 1 requête). Pourtant, il existe une astuce : lors de la minification, il est possible d'intégrer le contenu des fichiers importés, notamment en utilisant <code>postcss-import</code> (généralement inclut dans les outils de minification) avec un fonctionnement identique à celui de <abbr lang="en" title="Syntactically awesome stylesheets">Sass</abbr>.</p>
<h3>Exemple en <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr></h3>
<pre class="language-css"><code>/* ==Core */
@import "folder/variables.css";
@import "folder/reset.css"; 

/* ==Utilities &amp; Components */
@import "folder/helpers.css";
@import "folder/skip.css";</code></pre>
<h2>Les pseudo-classes <code>:is</code> et <code>:has</code></h2>
<p>Ces pseudo-classes permettent de cibler précisément des éléments et de simplifier l'écriture : fort utile à bien des égards. Le support complet de <code>:is</code> et <code>:has</code> n'est que très récent (<span lang="en">Baseline 2023</span>) !</p>
<h3>Exemples en <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr></h3>
<pre class="language-css"><code>/* Sans les pseudo-classes */
.card h2, 
.card cite {
	background-color: steelblue;
}
/* Avec les pseudo-classes */
.card :is(h2, cite) {
	background-color: steelblue;
}</code></pre>
<p>On cible tous les paragraphes, enfants de la classe <code>.card</code>, qui contiennent la balise <code>cite</code>.</p>
<pre class="language-css"><code>.card p:has(cite) {
	background-color: steelblue;
}</code></pre>
<h2>Conclusion</h2>
<p>Avec une approche méthodique et une planification soigneuse, le passage de <abbr lang="en" title="Syntactically awesome stylesheets">Sass</abbr> à Vanilla <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr> peut être réalisé de manière efficace. Sur des projets extrêmement complexes nécessitant des fonctions spécifiques ou des boucles, cela peut être un peu plus long, car il n'y a pas encore d'équivalent en pur <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr>, il faudra, pour cela, réintégrer le code compilé.</p>]]></description>
<guid>https://www.adilade.fr/blog/passer-de-sass-a-vanilla-css/</guid>
</item>
<item>
<title>Accessibilité : quelles différences entre le RGAA et la norme européenne EN 301 549</title>
<link>https://www.adilade.fr/blog/accessibilite-differences-rgaa-norme-europeenne-en-301-549/</link>
<pubDate>Mon, 10 Feb 2025 00:02:00 +0100</pubDate>
<description><![CDATA[<p>L'accessibilité numérique est encadrée par deux référentiels majeurs en Europe : le <abbr title="Référentiel Général d'Amélioration de l'Accessibilité">RGAA</abbr>, spécifique à la France, et la norme EN 301 549, applicable à l'échelle européenne. Ces deux cadres présentent des différences significatives : périmètre d'application, critères techniques et obligations.</p><h2>Le <abbr title="Référentiel Général d'Amélioration de l'Accessibilité">RGAA</abbr> français</h2>
<ul>
<li>Il s'applique aux sites web, applications mobiles, documents bureautiques et au mobilier urbain numérique</li>
<li>Il comporte 106 critères - précis et documentés</li>
<li>Le périmètre d'application va des organismes publics (état, collectivités territoriales, etc) aux entreprises privées dont le chiffre d'affaires en France est supérieur à 250 millions d'euros</li>
<li>Il nécessite une déclaration d'accessibilité, la mention de la conformité en page d'accueil et un schéma pluriannuel</li>
<li>Des sanctions pouvant aller jusqu'à 20 000 euros</li>
<li>Il est entré en application (en théorie !)</li>
</ul>
<h2>La norme européenne EN 301 549</h2>
<ul>
<li>Un champ d'application très large : sites web (y compris les outils d'édition des systèmes de gestion de contenu), applications mobiles, documents bureautiques, système de communication audio et vidéo, dispositifs matériels (bornes interactives, terminaux de paiement, etc), logiciels, documentation et services d'assistance, accès aux services d'urgence</li>
<li>Des critères et tests spécifiques à chaque champ d'application</li>
<li>Le périmètre d'application va des organismes publics (état, collectivités territoriales, etc) aux entreprises privées de plus de 10 salariés ou dont le chiffre d'affaires est supérieur à 2 millions d'euros</li>
<li>Il nécessite une déclaration d'accessibilité pour tous les supports numériques, la mention de la conformité et un schéma pluriannuel</li>
<li>Des sanctions pouvant aller jusqu'à 50 000 euros</li>
<li>Entre en application en juin 2025 pour les nouveaux contenus et produits et juin 2030 pour les contenus et produits déjà existants</li>
</ul>
<h2>Conclusion</h2>
<p>Le <abbr title="Référentiel Général d'Amélioration de l'Accessibilité">RGAA</abbr> et la norme EN 301 549 sont tous les deux basés sur les <abbr lang="en" title="Web Content Accessibility Guidelines">WCAG</abbr>, mais la norme européenne propose un cadre plus large en contrepartie de plus de flexibilité dans les méthodes d'évaluation. Cette dernière est une référence pour les marchés publics européens.</p>]]></description>
<guid>https://www.adilade.fr/blog/accessibilite-differences-rgaa-norme-europeenne-en-301-549/</guid>
</item>
<item>
<title>Voeux 2025</title>
<link>https://www.adilade.fr/blog/voeux-2025/</link>
<pubDate>Wed, 01 Jan 2025 01:04:00 +0100</pubDate>
<description><![CDATA[<p>Meilleurs Vœux 2025</p>]]></description>
<guid>https://www.adilade.fr/blog/voeux-2025/</guid>
</item>
<item>
<title>Pourquoi et comment construire son propre framework CSS</title>
<link>https://www.adilade.fr/blog/pourquoi-comment-construire-propre-framework-css/</link>
<pubDate>Sun, 05 May 2024 01:06:00 +0200</pubDate>
<description><![CDATA[<p>Pourquoi repartir de zéro alors qu'il existe pléthore de <span lang="en">frameworks</span> <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr> : Pure, Bootstrap, Tailwind, Materialize, Skeleton, Bulma - pour n'en citer que quelques-uns. Petit tour des avantages et inconvénients !</p><p>Après avoir longtemps travaillé avec KNACSS (obsolète depuis), la question d'une base de travail pour mes projets se posait. Construire son propre <span lang="en">framework</span> <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr> à partir de zéro peut sembler un peu fou, mais le temps investit au départ est largement compensé par la compréhension globale et sa facilité de mise en œuvre dans des projets concrets !</p>
<h2>Acquérir des compétences</h2>
<p>C'est l'un des premiers avantages : travailler sur ce type de projet permet l'acquisition de compétences spécifiques, une compréhension plus approfondie des subtilités des <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr> et une expérience d'apprentissage des plus agréable - sans doute plus intéressante que n'importe quelle formation !</p>
<h2>Adapté à vos besoins et votre méthode de travail</h2>
<p>Les <span lang="en">frameworks</span> existants sont généralistes et prévoient un support large et de nombreux cas de figure (par exemple un système de grille à 12 colonnes, pour ma part, je n'ai jamais dépassé 5) et sont donc souvent plus lourd, même en n'incluant que les composants que vous utilisez.<br>À titre d'exemple, je n'ai pas ajouté le support de <code>progress</code> que je n'ai jamais employé.</p>
<h2>On commence par définir la structure</h2>
<p>Vous pouvez vous inspirer de projets existants pour créer votre propre structure (en <abbr lang="en" title="Syntactically Awesome StyleSheets">SASS</abbr>, Less ou <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr>). Généralement, la base se constitue de variables, d'un mini <span lang="en">reset</span>, d'une base pour la typographie et l'espacement, sans oublier l'accessibilité.<br>Une seconde partie se constitue de composants et d'utilitaires comme les formulaires, les tables, un système de grille, etc.<br>Le but est de rester le plus minimaliste possible et de n'y inclure que ce que vous utilisez régulièrement.</p>
<p>Voici la structure de mon projet en <abbr lang="en" title="Syntactically Awesome StyleSheets">SASS</abbr> - c'est une méthode parmi d'autre, à adapter selon vos besoins et votre méthode de travail.</p>
<pre class="language-sass"><code>/* ==Core */
@import "variables.scss";
@import "reset.scss";  
@import "a11y.scss"; 
@import "layout.scss"; /* Typography &amp; Spacings */

/* ==Utilities &amp; Components */
@import "helpers.scss";
@import "skip.scss";
@import "tables.scss";
@import "pre.scss";
@import "video.scss"; 
@import "alerts.scss";
@import "badges.scss";
@import "details.scss"; /* Details &amp; Summary */
@import "burger.scss"; /* Menu */

/* ==Forms */
@import "forms.scss";
@import "formscheckbox.scss";
@import "formsselect.scss";
@import "formsradio.scss";
@import "formspassword.scss";
@import "buttons.scss";

/* ==Grids */
@import "grids.scss"; /* Grid 2-5 */

/* ==Utilities 2 */
@import "responsive.scss";
@import "print.scss"; 

/* ==Customer Styles  */
@import "customer.scss";</code></pre>
<h2>Quelques astuces</h2>
<ul>
<li>Limiter les couleurs au strict minimum.</li>
<li>Limiter l'usage des classes et des variables, surtout les variables <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr>.</li>
<li>Séparer au maximum les composants - en regardant le code ci-dessus, vous verrez un fichier séparé pour les champs de mots de passe (que je n'utilise pas sur tous les sites).</li>
<li>Intégrer l'accessibilité - avec une compatibilité <abbr lang="en" title="Web Content Accessibility Guidelines">WCAG</abbr> et <abbr title="Référentiel Général d'Amélioration de l'Accessibilité">RGAA</abbr> - dès le début de la conception (typographie, contraste, espacement des lignes et des paragraphes, etc).</li>
<li>Ajouter quelques classes utilitaires de base comme le centrage de textes et le centrage vertical à l'intérieur d'un bloc.</li>
<li>Ajouter des composants de base que vous utilisez régulièrement comme <span lang="en">ribbon, cards, hero section</span>, etc.</li>
</ul>
<h2>Tester et documenter (si besoin)</h2>
<p>Créer une page de test incluant tous les composants et différentes variations : bloc de texte, balises <code>h1</code> à <code>h6</code>, composants de formulaire, boutons, grilles, etc. Vous pourrez ainsi établir une stratégie pour effectuer des tests complets sur différents navigateurs et appareils (ordinateurs, mobiles et même téléviseurs).</p>
<h2>Maintenance</h2>
<p>Si votre code est bien conçu et structuré dès le départ, la maintenance reste assez faible - généralement 2 ou 3 fois par an : parfois quelques bugs visuels ou l'ajout de nouveautés <abbr lang="en" title="Cascading Styles Sheet">CSS</abbr>. Par exemple, j'ai récemment ajouté le support de <code>aspect-ratio</code> pour les vidéos.</p>
<h2>Allez plus loin</h2>
<p>Si vous souhaitez développer encore un peu plus votre <span lang="en">framework</span>, vous pouvez ajouter de nombreux éléments en fonction de vos besoins :</p>
<ul>
<li>Boutons de partages.</li>
<li>Le support étendu du focus.</li>
<li>Le support des téléviseurs <abbr title="High Definition">HD</abbr> et 4K.</li>
<li>Des <span lang="en">templates</span> prêts à l'emploi avec <code>grid-template-areas</code> : articles, galerie d'images, page d'accueil, etc.</li>
</ul>]]></description>
<guid>https://www.adilade.fr/blog/pourquoi-comment-construire-propre-framework-css/</guid>
</item>
<item>
<title>Voeux 2024</title>
<link>https://www.adilade.fr/blog/voeux-2024/</link>
<pubDate>Mon, 01 Jan 2024 00:02:00 +0100</pubDate>
<description><![CDATA[<p>Meilleurs Vœux 2024</p>]]></description>
<guid>https://www.adilade.fr/blog/voeux-2024/</guid>
</item>
</channel></rss>
