﻿{"id":551,"date":"2026-02-05T22:20:33","date_gmt":"2026-02-05T21:20:33","guid":{"rendered":"https:\/\/lmspro.fr\/composants-ui-modernes\/"},"modified":"2026-02-17T19:13:35","modified_gmt":"2026-02-17T18:13:35","slug":"composants-ui-modernes","status":"publish","type":"post","link":"https:\/\/lmspro.fr\/en\/composants-ui-modernes\/","title":{"rendered":"Modern UI Components"},"content":{"rendered":"<h2>Composants UI modernes<\/h2>\n<p class=\"wpa-text\">D\u00e9couvrez les techniques avanc\u00e9es pour cr\u00e9er des composants UI modernes avec des effets de glassmorphism. Ma\u00eetrisez les propri\u00e9t\u00e9s CSS modernes pour concevoir des interfaces \u00e9l\u00e9gantes et interactives qui captivent l&rsquo;attention des utilisateurs.<\/p>\n<div class=\"article-meta\">\n<p><strong>Module :<\/strong> Module 1 : Fondamentaux techniques du web<\/p>\n<p><strong>Niveau :<\/strong> D\u00e9butant<\/p>\n<p><strong>Dur\u00e9e :<\/strong> 20 minutes<\/p>\n<p><strong>Pr\u00e9requis :<\/strong> Aucun<\/p>\n<\/div>\n<h2>Objectifs p\u00e9dagogiques<\/h2>\n<ul>\n<li>Ma\u00eetriser les propri\u00e9t\u00e9s CSS pour cr\u00e9er des effets de glassmorphism<\/li>\n<li>Comprendre l&rsquo;utilisation de backdrop-filter et ses applications<\/li>\n<li>D\u00e9velopper des composants UI interactifs avec des animations fluides<\/li>\n<li>Int\u00e9grer des techniques modernes de design pour am\u00e9liorer l&rsquo;exp\u00e9rience utilisateur<\/li>\n<li>Cr\u00e9er des interfaces visuellement attractives et fonctionnelles<\/li>\n<\/ul>\n<div class=\"wpa-accordion wpa-accordion-flush\" id=\"accordion-composants-ui-modernes\">\n<div class=\"wpa-accordion-item\">\n<button class=\"wpa-accordion-header\" data-wpa-target=\"#accordion-composants-ui-modernes-item-1\" aria-expanded=\"false\"><span class=\"wpa-accordion-title\"><span class=\"wpa-accordion-number\">01<\/span> Fondamentaux du Glassmorphism<\/span><span class=\"wpa-accordion-icon\"><\/span><\/button><\/p>\n<div id=\"accordion-composants-ui-modernes-item-1\" class=\"wpa-accordion-body\">\n<div class=\"wpa-accordion-content\">\n<h4>Comprendre l&rsquo;effet de verre<\/h4>\n<p>Le glassmorphism est une tendance de design moderne qui simule l&rsquo;apparence du verre d\u00e9poli ou translucide. Cette technique utilise des arri\u00e8re-plans semi-transparents avec des effets de flou pour cr\u00e9er une sensation de profondeur et d&rsquo;\u00e9l\u00e9gance. L&rsquo;effet repose principalement sur la propri\u00e9t\u00e9 CSS backdrop-filter qui applique des filtres graphiques \u00e0 l&rsquo;arri\u00e8re-plan d&rsquo;un \u00e9l\u00e9ment.<\/p>\n<h4>Propri\u00e9t\u00e9s CSS essentielles<\/h4>\n<p>Pour cr\u00e9er un effet glassmorphism r\u00e9ussi, plusieurs propri\u00e9t\u00e9s CSS travaillent ensemble. La propri\u00e9t\u00e9 backdrop-filter avec la valeur blur() cr\u00e9e l&rsquo;effet de flou caract\u00e9ristique. La transparence s&rsquo;obtient avec background: rgba() ou hsla() pour contr\u00f4ler pr\u00e9cis\u00e9ment l&rsquo;opacit\u00e9. Les bordures subtiles avec border: 1px solid rgba(255,255,255,0.3) ajoutent de la d\u00e9finition. Enfin, box-shadow permet d&rsquo;ajouter de la profondeur avec des ombres douces.<\/p>\n<div class=\"info-box\">\n<p><strong>Point cl\u00e9<\/strong> : L&rsquo;effet glassmorphism fonctionne mieux sur des arri\u00e8re-plans color\u00e9s ou avec des images, car il r\u00e9v\u00e8le partiellement le contenu sous-jacent.<\/p>\n<\/div>\n<div class=\"tuto-objectif\" style=\"background: #f5f5f5;border-left: 4px solid #667eea;padding: 16px 20px;margin-top: 24px;border-radius: 0 8px 8px 0\">\n<h3 style=\"color: #667eea;margin: 0 0 8px 0;font-size: 16px\">\u00c0 retenir<\/h3>\n<p style=\"margin: 0;color: #333\">Le glassmorphism combine backdrop-filter, transparence et bordures subtiles pour cr\u00e9er un effet de verre moderne et \u00e9l\u00e9gant.<\/p>\n<\/div>\n<div class=\"tuto-exercise\" style=\"background: #fff3e0;border-left: 4px solid #ff9800;padding: 16px 20px;margin-top: 20px;border-radius: 0 8px 8px 0\">\n<h4 style=\"color: #ff9800;margin: 0 0 8px 0;font-size: 15px\">\ud83c\udfaf Mini-exercice : Panneau glassmorphism de base<\/h4>\n<p style=\"margin: 0;color: #333;font-size: 14px\">Cr\u00e9ez un panneau avec effet de verre sur un arri\u00e8re-plan d\u00e9grad\u00e9, en utilisant backdrop-filter et rgba pour la transparence.<\/p>\n<\/div>\n<div class=\"codepen-block\" data-block-id=\"exercise-1\">\n<p class=\"codepen-block-label\">Code de r\u00e9f\u00e9rence :<\/p>\n<div class=\"codepen-header\">\n<div class=\"codepen-tabs\">\n<button class=\"codepen-tab active\" data-tab=\"html\">HTML<\/button><br \/>\n<button class=\"codepen-tab\" data-tab=\"css\">CSS<\/button><br \/>\n<button class=\"codepen-tab\" data-tab=\"javascript\">JS<\/button>\n<\/div>\n<p><button class=\"codepen-copy-btn\">Copier<\/button>\n<\/div>\n<div class=\"codepen-code-container\">\n<pre class=\"codepen-code active\" data-lang=\"html\">&lt;div class=\"glass-container\"&gt;\n  &lt;div class=\"glass-panel\"&gt;\n    &lt;h2&gt;Glassmorphism Panel&lt;\/h2&gt;\n    &lt;p&gt;Un panneau moderne avec effet de verre&lt;\/p&gt;\n    &lt;button class=\"glass-button\"&gt;Action&lt;\/button&gt;\n  &lt;\/div&gt;\n&lt;\/div&gt;<\/pre>\n<pre class=\"codepen-code\" data-lang=\"css\">body {\n  margin: 0;\n  min-height: 100vh;\n  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  font-family: 'Arial', sans-serif;\n}\n\n.glass-container {\n  perspective: 1000px;\n}\n\n.glass-panel {\n  background: rgba(255, 255, 255, 0.15);\n  backdrop-filter: blur(20px);\n  border: 1px solid rgba(255, 255, 255, 0.3);\n  border-radius: 20px;\n  padding: 40px;\n  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);\n  text-align: center;\n  color: white;\n  transform: translateY(0);\n  transition: all 0.4s cubic-bezier(0.23, 1, 0.320, 1);\n}\n\n.glass-panel:hover {\n  transform: translateY(-10px);\n  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);\n  background: rgba(255, 255, 255, 0.25);\n}\n\n.glass-panel h2 {\n  margin: 0 0 16px 0;\n  font-size: 24px;\n  font-weight: 300;\n  letter-spacing: 1px;\n}\n\n.glass-panel p {\n  margin: 0 0 24px 0;\n  opacity: 0.9;\n  line-height: 1.6;\n}\n\n.glass-button {\n  background: rgba(255, 255, 255, 0.2);\n  backdrop-filter: blur(10px);\n  border: 1px solid rgba(255, 255, 255, 0.3);\n  border-radius: 30px;\n  color: white;\n  padding: 12px 24px;\n  font-size: 16px;\n  cursor: pointer;\n  transition: all 0.3s ease;\n}\n\n.glass-button:hover {\n  background: rgba(255, 255, 255, 0.3);\n  transform: scale(1.05);\n}<\/pre>\n<pre class=\"codepen-code\" data-lang=\"javascript\">\/\/ Ajout d'un effet de particules au survol\ndocument.querySelector('.glass-panel').addEventListener('mouseenter', function() {\n  this.style.setProperty('--mouse-x', Math.random());\n  this.style.setProperty('--mouse-y', Math.random());\n});<\/pre>\n<\/div>\n<\/div>\n<div class=\"monaco-sandbox\" data-block-id=\"exercise-1\">\n<div class=\"monaco-header\">\n<div class=\"monaco-tabs\">\n<button class=\"monaco-tab active\" data-lang=\"html\">HTML<\/button><br \/>\n<button class=\"monaco-tab\" data-lang=\"css\">CSS<\/button><br \/>\n<button class=\"monaco-tab\" data-lang=\"javascript\">JS<\/button>\n<\/div>\n<div class=\"monaco-actions\">\n<button class=\"monaco-btn monaco-btn-run\">\u25b6 Ex\u00e9cuter<\/button><br \/>\n<button class=\"monaco-btn monaco-btn-reset\">\u21ba Reset<\/button>\n<\/div>\n<\/div>\n<div class=\"monaco-container\">\n<div class=\"monaco-editor-wrapper\">\n<div class=\"monaco-editor-pane active\" data-lang=\"html\"><\/div>\n<div class=\"monaco-editor-pane\" data-lang=\"css\"><\/div>\n<div class=\"monaco-editor-pane\" data-lang=\"javascript\"><\/div>\n<\/div>\n<div class=\"monaco-preview-wrapper\">\n<div class=\"monaco-preview-header\">Result<\/div>\n<\/div>\n<\/div>\n<div class=\"monaco-status\">\n<span class=\"monaco-status-left\">\u25cf Pr\u00eat<\/span><br \/>\n<span class=\"monaco-status-right\">Monaco Editor v0.45<\/span>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"wpa-accordion-item\">\n<button class=\"wpa-accordion-header\" data-wpa-target=\"#accordion-composants-ui-modernes-item-2\" aria-expanded=\"false\"><span class=\"wpa-accordion-title\"><span class=\"wpa-accordion-number\">02<\/span> Cr\u00e9ation d&rsquo;une Carte de Cr\u00e9dit Glass<\/span><span class=\"wpa-accordion-icon\"><\/span><\/button><\/p>\n<div id=\"accordion-composants-ui-modernes-item-2\" class=\"wpa-accordion-body\">\n<div class=\"wpa-accordion-content\">\n<h4>Structure et mise en forme<\/h4>\n<p>Une carte de cr\u00e9dit glassmorphism n\u00e9cessite une structure HTML soign\u00e9e avec des \u00e9l\u00e9ments pour le num\u00e9ro de carte, le nom du porteur, la date d&rsquo;expiration et le logo de la banque. La mise en forme utilise des proportions r\u00e9alistes (ratio 16:10) et des espacements harmonieux. La carte doit avoir des coins arrondis subtils et un effet de perspective pour simuler une vraie carte physique.<\/p>\n<h4>Effets visuels avanc\u00e9s<\/h4>\n<p>Les effets visuels d&rsquo;une carte glassmorphism incluent des reflets dynamiques, des ombres r\u00e9alistes et des animations fluides. Les gradients peuvent simuler des hologrammes ou des effets iridescents. L&rsquo;utilisation de transformations 3D avec transform-style: preserve-3d permet de cr\u00e9er des effets de rotation et d&rsquo;inclinaison. Les micro-interactions comme les changements d&rsquo;\u00e9tat au survol renforcent l&rsquo;impression de r\u00e9alisme.<\/p>\n<div class=\"info-box\">\n<p><strong>Point cl\u00e9<\/strong> : Une carte de cr\u00e9dit r\u00e9ussie combine r\u00e9alisme visuel et fonctionnalit\u00e9, avec des zones cliquables et des \u00e9tats visuels clairs.<\/p>\n<\/div>\n<div class=\"tuto-objectif\" style=\"background: #f5f5f5;border-left: 4px solid #667eea;padding: 16px 20px;margin-top: 24px;border-radius: 0 8px 8px 0\">\n<h3 style=\"color: #667eea;margin: 0 0 8px 0;font-size: 16px\">\u00c0 retenir<\/h3>\n<p style=\"margin: 0;color: #333\">Une carte glassmorphism r\u00e9ussie combine proportions r\u00e9alistes, effets visuels subtils et interactions fluides pour une exp\u00e9rience utilisateur premium.<\/p>\n<\/div>\n<div class=\"tuto-exercise\" style=\"background: #fff3e0;border-left: 4px solid #ff9800;padding: 16px 20px;margin-top: 20px;border-radius: 0 8px 8px 0\">\n<h4 style=\"color: #ff9800;margin: 0 0 8px 0;font-size: 15px\">\ud83c\udfaf Mini-exercice : Carte de cr\u00e9dit interactive<\/h4>\n<p style=\"margin: 0;color: #333;font-size: 14px\">Cr\u00e9ez une carte de cr\u00e9dit avec effet glassmorphism, rotation 3D au survol et animation des d\u00e9tails de la carte.<\/p>\n<\/div>\n<div class=\"codepen-block\" data-block-id=\"exercise-2\">\n<p class=\"codepen-block-label\">Code de r\u00e9f\u00e9rence :<\/p>\n<div class=\"codepen-header\">\n<div class=\"codepen-tabs\">\n<button class=\"codepen-tab active\" data-tab=\"html\">HTML<\/button><br \/>\n<button class=\"codepen-tab\" data-tab=\"css\">CSS<\/button><br \/>\n<button class=\"codepen-tab\" data-tab=\"javascript\">JS<\/button>\n<\/div>\n<p><button class=\"codepen-copy-btn\">Copier<\/button>\n<\/div>\n<div class=\"codepen-code-container\">\n<pre class=\"codepen-code active\" data-lang=\"html\">&lt;div class=\"credit-card-scene\"&gt;\n  &lt;div class=\"credit-card\"&gt;\n    &lt;div class=\"card-front\"&gt;\n      &lt;div class=\"card-logo\"&gt;\ud83d\udcb3&lt;\/div&gt;\n      &lt;div class=\"card-chip\"&gt;&lt;\/div&gt;\n      &lt;div class=\"card-number\"&gt;4532 1234 5678 9012&lt;\/div&gt;\n      &lt;div class=\"card-details\"&gt;\n        &lt;div class=\"card-holder\"&gt;\n          &lt;span class=\"label\"&gt;Card Holder&lt;\/span&gt;\n          &lt;span class=\"value\"&gt;John Doe&lt;\/span&gt;\n        &lt;\/div&gt;\n        &lt;div class=\"card-expiry\"&gt;\n          &lt;span class=\"label\"&gt;Expires&lt;\/span&gt;\n          &lt;span class=\"value\"&gt;12\/28&lt;\/span&gt;\n        &lt;\/div&gt;\n      &lt;\/div&gt;\n      &lt;div class=\"card-brand\"&gt;PREMIUM&lt;\/div&gt;\n    &lt;\/div&gt;\n  &lt;\/div&gt;\n&lt;\/div&gt;<\/pre>\n<pre class=\"codepen-code\" data-lang=\"css\">body {\n  margin: 0;\n  min-height: 100vh;\n  background: linear-gradient(135deg, #1e3c72 0%, #2a5298 50%, #667eea 100%);\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  font-family: 'Arial', sans-serif;\n}\n\n.credit-card-scene {\n  perspective: 1000px;\n  padding: 50px;\n}\n\n.credit-card {\n  width: 400px;\n  height: 250px;\n  position: relative;\n  transform-style: preserve-3d;\n  transition: transform 0.6s cubic-bezier(0.23, 1, 0.320, 1);\n  cursor: pointer;\n}\n\n.credit-card:hover {\n  transform: rotateY(15deg) rotateX(5deg) scale(1.05);\n}\n\n.card-front {\n  width: 100%;\n  height: 100%;\n  background: linear-gradient(135deg, \n    rgba(255, 255, 255, 0.1) 0%, \n    rgba(255, 255, 255, 0.05) 100%);\n  backdrop-filter: blur(20px);\n  border: 1px solid rgba(255, 255, 255, 0.2);\n  border-radius: 20px;\n  padding: 30px;\n  box-sizing: border-box;\n  position: relative;\n  overflow: hidden;\n  box-shadow: \n    0 8px 32px rgba(0, 0, 0, 0.3),\n    inset 0 2px 0 rgba(255, 255, 255, 0.2);\n}\n\n.card-front::before {\n  content: '';\n  position: absolute;\n  top: 0;\n  left: -100%;\n  width: 100%;\n  height: 100%;\n  background: linear-gradient(90deg, \n    transparent, \n    rgba(255, 255, 255, 0.2), \n    transparent);\n  transition: left 0.5s;\n}\n\n.credit-card:hover .card-front::before {\n  left: 100%;\n}\n\n.card-logo {\n  font-size: 28px;\n  position: absolute;\n  top: 20px;\n  right: 30px;\n  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));\n}\n\n.card-chip {\n  width: 45px;\n  height: 35px;\n  background: linear-gradient(45deg, #ffd700, #ffed4e);\n  border-radius: 6px;\n  position: relative;\n  margin: 20px 0;\n  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);\n}\n\n.card-chip::before {\n  content: '';\n  position: absolute;\n  top: 5px;\n  left: 5px;\n  right: 5px;\n  bottom: 5px;\n  border: 1px solid rgba(0, 0, 0, 0.1);\n  border-radius: 3px;\n}\n\n.card-number {\n  font-size: 24px;\n  font-weight: 300;\n  color: white;\n  letter-spacing: 4px;\n  margin: 25px 0;\n  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);\n  font-family: 'Courier New', monospace;\n}\n\n.card-details {\n  display: flex;\n  justify-content: space-between;\n  margin-top: 30px;\n}\n\n.card-holder,\n.card-expiry {\n  display: flex;\n  flex-direction: column;\n}\n\n.label {\n  font-size: 10px;\n  color: rgba(255, 255, 255, 0.7);\n  text-transform: uppercase;\n  letter-spacing: 1px;\n  margin-bottom: 5px;\n}\n\n.value {\n  font-size: 16px;\n  color: white;\n  font-weight: 500;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);\n}\n\n.card-brand {\n  position: absolute;\n  bottom: 20px;\n  right: 30px;\n  font-size: 14px;\n  font-weight: bold;\n  color: white;\n  letter-spacing: 2px;\n  opacity: 0.8;\n}<\/pre>\n<pre class=\"codepen-code\" data-lang=\"javascript\">\/\/ Animation des num\u00e9ros de carte\nconst cardNumber = document.querySelector('.card-number');\nconst originalNumber = cardNumber.textContent;\n\nlet isRevealed = false;\n\ndocument.querySelector('.credit-card').addEventListener('click', function() {\n  if (!isRevealed) {\n    \/\/ Animation de r\u00e9v\u00e9lation\n    cardNumber.style.transform = 'rotateX(90deg)';\n    setTimeout(() =&gt; {\n      cardNumber.textContent = '4532 **** **** 9012';\n      cardNumber.style.transform = 'rotateX(0deg)';\n      isRevealed = true;\n    }, 200);\n  } else {\n    \/\/ Animation de masquage\n    cardNumber.style.transform = 'rotateX(90deg)';\n    setTimeout(() =&gt; {\n      cardNumber.textContent = originalNumber;\n      cardNumber.style.transform = 'rotateX(0deg)';\n      isRevealed = false;\n    }, 200);\n  }\n});\n\n\/\/ Effet de suivi de souris\ndocument.querySelector('.credit-card').addEventListener('mousemove', function(e) {\n  const rect = this.getBoundingClientRect();\n  const x = e.clientX - rect.left;\n  const y = e.clientY - rect.top;\n  \n  const centerX = rect.width \/ 2;\n  const centerY = rect.height \/ 2;\n  \n  const rotateX = (y - centerY) \/ 10;\n  const rotateY = (centerX - x) \/ 10;\n  \n  this.style.transform = `rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale(1.05)`;\n});\n\ndocument.querySelector('.credit-card').addEventListener('mouseleave', function() {\n  this.style.transform = 'rotateX(0deg) rotateY(0deg) scale(1)';\n});<\/pre>\n<\/div>\n<\/div>\n<div class=\"monaco-sandbox\" data-block-id=\"exercise-2\">\n<div class=\"monaco-header\">\n<div class=\"monaco-tabs\">\n<button class=\"monaco-tab active\" data-lang=\"html\">HTML<\/button><br \/>\n<button class=\"monaco-tab\" data-lang=\"css\">CSS<\/button><br \/>\n<button class=\"monaco-tab\" data-lang=\"javascript\">JS<\/button>\n<\/div>\n<div class=\"monaco-actions\">\n<button class=\"monaco-btn monaco-btn-run\">\u25b6 Ex\u00e9cuter<\/button><br \/>\n<button class=\"monaco-btn monaco-btn-reset\">\u21ba Reset<\/button>\n<\/div>\n<\/div>\n<div class=\"monaco-container\">\n<div class=\"monaco-editor-wrapper\">\n<div class=\"monaco-editor-pane active\" data-lang=\"html\"><\/div>\n<div class=\"monaco-editor-pane\" data-lang=\"css\"><\/div>\n<div class=\"monaco-editor-pane\" data-lang=\"javascript\"><\/div>\n<\/div>\n<div class=\"monaco-preview-wrapper\">\n<div class=\"monaco-preview-header\">Result<\/div>\n<\/div>\n<\/div>\n<div class=\"monaco-status\">\n<span class=\"monaco-status-left\">\u25cf Pr\u00eat<\/span><br \/>\n<span class=\"monaco-status-right\">Monaco Editor v0.45<\/span>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"wpa-accordion-item\">\n<button class=\"wpa-accordion-header\" data-wpa-target=\"#accordion-composants-ui-modernes-item-3\" aria-expanded=\"false\"><span class=\"wpa-accordion-title\"><span class=\"wpa-accordion-number\">03<\/span> Animations et Interactions Avanc\u00e9es<\/span><span class=\"wpa-accordion-icon\"><\/span><\/button><\/p>\n<div id=\"accordion-composants-ui-modernes-item-3\" class=\"wpa-accordion-body\">\n<div class=\"wpa-accordion-content\">\n<h4>Micro-interactions et feedback utilisateur<\/h4>\n<p>Les micro-interactions sont essentielles pour cr\u00e9er une exp\u00e9rience utilisateur engageante. Elles incluent les changements d&rsquo;\u00e9tat au survol, les animations de clic, les transitions fluides entre les \u00e9tats. Ces petites animations donnent vie \u00e0 l&rsquo;interface et fournissent un feedback imm\u00e9diat aux actions de l&rsquo;utilisateur. Les propri\u00e9t\u00e9s CSS comme transition, transform et opacity permettent de cr\u00e9er ces effets sans impacter les performances.<\/p>\n<h4>Animations CSS avanc\u00e9es avec @keyframes<\/h4>\n<p>Les animations @keyframes offrent un contr\u00f4le pr\u00e9cis sur les s\u00e9quences d&rsquo;animation complexes. Elles permettent de cr\u00e9er des effets comme des pulsations, des rotations continues, des morphings de forme. Les fonctions d&rsquo;timing comme cubic-bezier() personnalisent l&rsquo;acc\u00e9l\u00e9ration et la d\u00e9c\u00e9l\u00e9ration. L&rsquo;animation peut \u00eatre d\u00e9clench\u00e9e par des pseudo-classes (:hover, :focus) ou contr\u00f4l\u00e9e par JavaScript pour des interactions plus complexes.<\/p>\n<div class=\"info-box\">\n<p><strong>Point cl\u00e9<\/strong> : Les animations doivent avoir une intention claire et am\u00e9liorer l&rsquo;exp\u00e9rience utilisateur sans devenir distrayantes ou impacter les performances.<\/p>\n<\/div>\n<div class=\"tuto-objectif\" style=\"background: #f5f5f5;border-left: 4px solid #667eea;padding: 16px 20px;margin-top: 24px;border-radius: 0 8px 8px 0\">\n<h3 style=\"color: #667eea;margin: 0 0 8px 0;font-size: 16px\">\u00c0 retenir<\/h3>\n<p style=\"margin: 0;color: #333\">Les animations r\u00e9ussies combinent micro-interactions fluides et @keyframes sophistiqu\u00e9es pour cr\u00e9er une exp\u00e9rience utilisateur engageante et intuitive.<\/p>\n<\/div>\n<div class=\"tuto-exercise\" style=\"background: #fff3e0;border-left: 4px solid #ff9800;padding: 16px 20px;margin-top: 20px;border-radius: 0 8px 8px 0\">\n<h4 style=\"color: #ff9800;margin: 0 0 8px 0;font-size: 15px\">\ud83c\udfaf Mini-exercice : Carte avec animations complexes<\/h4>\n<p style=\"margin: 0;color: #333;font-size: 14px\">Cr\u00e9ez une carte interactive avec animations de flip 3D, effets de particules et transitions fluides entre les \u00e9tats.<\/p>\n<\/div>\n<div class=\"codepen-block\" data-block-id=\"exercise-3\">\n<p class=\"codepen-block-label\">Code de r\u00e9f\u00e9rence :<\/p>\n<div class=\"codepen-header\">\n<div class=\"codepen-tabs\">\n<button class=\"codepen-tab active\" data-tab=\"html\">HTML<\/button><br \/>\n<button class=\"codepen-tab\" data-tab=\"css\">CSS<\/button><br \/>\n<button class=\"codepen-tab\" data-tab=\"javascript\">JS<\/button>\n<\/div>\n<p><button class=\"codepen-copy-btn\">Copier<\/button>\n<\/div>\n<div class=\"codepen-code-container\">\n<pre class=\"codepen-code active\" data-lang=\"html\">&lt;div class=\"animated-card-container\"&gt;\n  &lt;div class=\"animated-card\" data-tilt&gt;\n    &lt;div class=\"card-inner\"&gt;\n      &lt;div class=\"card-face card-front\"&gt;\n        &lt;div class=\"particles\"&gt;&lt;\/div&gt;\n        &lt;div class=\"glow-effect\"&gt;&lt;\/div&gt;\n        &lt;div class=\"card-content\"&gt;\n          &lt;h3&gt;Premium Card&lt;\/h3&gt;\n          &lt;div class=\"card-number\"&gt;\u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022 1234&lt;\/div&gt;\n          &lt;div class=\"card-info\"&gt;\n            &lt;span&gt;John Smith&lt;\/span&gt;\n            &lt;span&gt;12\/28&lt;\/span&gt;\n          &lt;\/div&gt;\n          &lt;button class=\"flip-btn\"&gt;Flip Card&lt;\/button&gt;\n        &lt;\/div&gt;\n      &lt;\/div&gt;\n      &lt;div class=\"card-face card-back\"&gt;\n        &lt;div class=\"magnetic-strip\"&gt;&lt;\/div&gt;\n        &lt;div class=\"cvv-area\"&gt;\n          &lt;span&gt;CVV&lt;\/span&gt;\n          &lt;div class=\"cvv-box\"&gt;123&lt;\/div&gt;\n        &lt;\/div&gt;\n        &lt;button class=\"flip-btn back\"&gt;Flip Back&lt;\/button&gt;\n      &lt;\/div&gt;\n    &lt;\/div&gt;\n  &lt;\/div&gt;\n&lt;\/div&gt;<\/pre>\n<pre class=\"codepen-code\" data-lang=\"css\">body {\n  margin: 0;\n  min-height: 100vh;\n  background: radial-gradient(ellipse at top, #1e3c72, #2a5298);\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  font-family: 'Arial', sans-serif;\n  overflow: hidden;\n}\n\n.animated-card-container {\n  perspective: 1000px;\n  position: relative;\n}\n\n.animated-card {\n  width: 350px;\n  height: 220px;\n  position: relative;\n  cursor: pointer;\n  transition: transform 0.1s ease;\n}\n\n.card-inner {\n  width: 100%;\n  height: 100%;\n  position: relative;\n  transform-style: preserve-3d;\n  transition: transform 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275);\n}\n\n.animated-card.flipped .card-inner {\n  transform: rotateY(180deg);\n}\n\n.card-face {\n  position: absolute;\n  width: 100%;\n  height: 100%;\n  backface-visibility: hidden;\n  border-radius: 20px;\n  overflow: hidden;\n}\n\n.card-front {\n  background: linear-gradient(135deg, \n    rgba(255, 255, 255, 0.1) 0%, \n    rgba(255, 255, 255, 0.05) 100%);\n  backdrop-filter: blur(20px);\n  border: 1px solid rgba(255, 255, 255, 0.2);\n  box-shadow: \n    0 8px 32px rgba(0, 0, 0, 0.3),\n    inset 0 2px 0 rgba(255, 255, 255, 0.2);\n}\n\n.card-back {\n  background: linear-gradient(135deg, \n    rgba(50, 50, 50, 0.9) 0%, \n    rgba(30, 30, 30, 0.95) 100%);\n  backdrop-filter: blur(20px);\n  border: 1px solid rgba(255, 255, 255, 0.1);\n  transform: rotateY(180deg);\n  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);\n}\n\n.particles {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  opacity: 0;\n  transition: opacity 0.3s ease;\n}\n\n.animated-card:hover .particles {\n  opacity: 1;\n  animation: particleFloat 3s ease-in-out infinite;\n}\n\n@keyframes particleFloat {\n  0%, 100% { transform: translateY(0) rotate(0deg); }\n  33% { transform: translateY(-10px) rotate(120deg); }\n  66% { transform: translateY(5px) rotate(240deg); }\n}\n\n.glow-effect {\n  position: absolute;\n  top: -50%;\n  left: -50%;\n  width: 200%;\n  height: 200%;\n  background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%);\n  opacity: 0;\n  transition: opacity 0.3s ease;\n  animation: rotate 6s linear infinite;\n}\n\n.animated-card:hover .glow-effect {\n  opacity: 1;\n}\n\n@keyframes rotate {\n  from { transform: rotate(0deg); }\n  to { transform: rotate(360deg); }\n}\n\n.card-content {\n  padding: 30px;\n  color: white;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n  justify-content: space-between;\n  position: relative;\n  z-index: 2;\n}\n\n.card-content h3 {\n  margin: 0;\n  font-size: 18px;\n  font-weight: 300;\n  letter-spacing: 2px;\n  opacity: 0;\n  transform: translateY(20px);\n  animation: slideInUp 0.6s ease forwards 0.2s;\n}\n\n.card-number {\n  font-size: 22px;\n  font-family: 'Courier New', monospace;\n  letter-spacing: 3px;\n  margin: 20px 0;\n  opacity: 0;\n  transform: translateY(20px);\n  animation: slideInUp 0.6s ease forwards 0.4s;\n}\n\n.card-info {\n  display: flex;\n  justify-content: space-between;\n  font-size: 12px;\n  text-transform: uppercase;\n  letter-spacing: 1px;\n  opacity: 0;\n  transform: translateY(20px);\n  animation: slideInUp 0.6s ease forwards 0.6s;\n}\n\n.flip-btn {\n  background: rgba(255, 255, 255, 0.2);\n  backdrop-filter: blur(10px);\n  border: 1px solid rgba(255, 255, 255, 0.3);\n  border-radius: 25px;\n  color: white;\n  padding: 8px 16px;\n  font-size: 12px;\n  cursor: pointer;\n  transition: all 0.3s ease;\n  align-self: flex-start;\n  opacity: 0;\n  transform: translateY(20px);\n  animation: slideInUp 0.6s ease forwards 0.8s;\n}\n\n.flip-btn:hover {\n  background: rgba(255, 255, 255, 0.3);\n  transform: translateY(-2px);\n}\n\n@keyframes slideInUp {\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.magnetic-strip {\n  width: 100%;\n  height: 50px;\n  background: linear-gradient(90deg, #333, #111);\n  margin: 20px 0;\n}\n\n.cvv-area {\n  padding: 30px;\n  color: white;\n}\n\n.cvv-area span {\n  font-size: 12px;\n  opacity: 0.7;\n}\n\n.cvv-box {\n  background: rgba(255, 255, 255, 0.1);\n  border: 1px solid rgba(255, 255, 255, 0.2);\n  border-radius: 4px;\n  padding: 10px;\n  margin: 10px 0;\n  width: 60px;\n  text-align: center;\n  font-family: 'Courier New', monospace;\n}\n\n.flip-btn.back {\n  position: absolute;\n  bottom: 30px;\n  right: 30px;\n}<\/pre>\n<pre class=\"codepen-code\" data-lang=\"javascript\">\/\/ Gestion du flip de carte\ndocument.querySelectorAll('.flip-btn').forEach(btn =&gt; {\n  btn.addEventListener('click', function() {\n    const card = document.querySelector('.animated-card');\n    card.classList.toggle('flipped');\n  });\n});\n\n\/\/ Effet de suivi de souris avec tilt 3D\nconst card = document.querySelector('.animated-card');\n\ncard.addEventListener('mousemove', function(e) {\n  const rect = this.getBoundingClientRect();\n  const x = e.clientX - rect.left;\n  const y = e.clientY - rect.top;\n  \n  const centerX = rect.width \/ 2;\n  const centerY = rect.height \/ 2;\n  \n  const rotateX = (y - centerY) \/ 8;\n  const rotateY = (centerX - x) \/ 8;\n  \n  this.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale3d(1.05, 1.05, 1.05)`;\n});\n\ncard.addEventListener('mouseleave', function() {\n  this.style.transform = 'perspective(1000px) rotateX(0) rotateY(0) scale3d(1, 1, 1)';\n});\n\n\/\/ Animation des particules\nfunction createParticles() {\n  const particlesContainer = document.querySelector('.particles');\n  for(let i = 0; i &lt; 20; i++) {\n    const particle = document.createElement(&#039;div&#039;);\n    particle.style.cssText = `\n      position: absolute;\n      width: 2px;\n      height: 2px;\n      background: rgba(255,255,255,0.6);\n      border-radius: 50%;\n      left: ${Math.random() * 100}%;\n      top: ${Math.random() * 100}%;\n      animation: particleDrift ${2 + Math.random() * 3}s linear infinite;\n      animation-delay: ${Math.random() * 2}s;\n    `;\n    particlesContainer.appendChild(particle);\n  }\n}\n\n\/\/ Style pour l&#039;animation des particules\nconst style = document.createElement(&#039;style&#039;);\nstyle.textContent = `\n  @keyframes particleDrift {\n    0% { transform: translateY(0) scale(1); opacity: 0; }\n    10% { opacity: 1; }\n    90% { opacity: 1; }\n    100% { transform: translateY(-100px) scale(0); opacity: 0; }\n  }\n`;\ndocument.head.appendChild(style);\n\ncreateParticles();<\/pre>\n<\/div>\n<\/div>\n<div class=\"monaco-sandbox\" data-block-id=\"exercise-3\">\n<div class=\"monaco-header\">\n<div class=\"monaco-tabs\">\n<button class=\"monaco-tab active\" data-lang=\"html\">HTML<\/button><br \/>\n<button class=\"monaco-tab\" data-lang=\"css\">CSS<\/button><br \/>\n<button class=\"monaco-tab\" data-lang=\"javascript\">JS<\/button>\n<\/div>\n<div class=\"monaco-actions\">\n<button class=\"monaco-btn monaco-btn-run\">\u25b6 Ex\u00e9cuter<\/button><br \/>\n<button class=\"monaco-btn monaco-btn-reset\">\u21ba Reset<\/button>\n<\/div>\n<\/div>\n<div class=\"monaco-container\">\n<div class=\"monaco-editor-wrapper\">\n<div class=\"monaco-editor-pane active\" data-lang=\"html\"><\/div>\n<div class=\"monaco-editor-pane\" data-lang=\"css\"><\/div>\n<div class=\"monaco-editor-pane\" data-lang=\"javascript\"><\/div>\n<\/div>\n<div class=\"monaco-preview-wrapper\">\n<div class=\"monaco-preview-header\">Result<\/div>\n<\/div>\n<\/div>\n<div class=\"monaco-status\">\n<span class=\"monaco-status-left\">\u25cf Pr\u00eat<\/span><br \/>\n<span class=\"monaco-status-right\">Monaco Editor v0.45<\/span>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"wpa-accordion-item\">\n<button class=\"wpa-accordion-header\" data-wpa-target=\"#accordion-composants-ui-modernes-item-4\" aria-expanded=\"false\"><span class=\"wpa-accordion-title\"><span class=\"wpa-accordion-number\">04<\/span> Optimisation et Performance<\/span><span class=\"wpa-accordion-icon\"><\/span><\/button><\/p>\n<div id=\"accordion-composants-ui-modernes-item-4\" class=\"wpa-accordion-body\">\n<div class=\"wpa-accordion-content\">\n<h4>Performance des effets glassmorphism<\/h4>\n<p>Les effets glassmorphism, bien qu&rsquo;esth\u00e9tiquement attrayants, peuvent impacter les performances si mal impl\u00e9ment\u00e9s. La propri\u00e9t\u00e9 backdrop-filter est gourmande en ressources car elle n\u00e9cessite des calculs de rendu complexes. Il est essentiel de limiter le nombre d&rsquo;\u00e9l\u00e9ments utilisant cette propri\u00e9t\u00e9 simultan\u00e9ment. L&rsquo;utilisation de will-change: backdrop-filter peut optimiser le rendu en pr\u00e9parant le navigateur aux transformations.<\/p>\n<h4>Techniques d&rsquo;optimisation CSS<\/h4>\n<p>L&rsquo;optimisation passe par plusieurs strat\u00e9gies : utiliser transform et opacity pour les animations car elles d\u00e9clenchent uniquement la phase de composition, \u00e9viter les propri\u00e9t\u00e9s qui forcent le reflow comme width ou height anim\u00e9es, pr\u00e9f\u00e9rer transform: scale(). L&rsquo;utilisation de contain: layout style paint isole les \u00e9l\u00e9ments et limite les recalculs. Les animations @keyframes sont plus performantes que les transitions JavaScript r\u00e9p\u00e9t\u00e9es.<\/p>\n<div class=\"info-box\">\n<p><strong>Point cl\u00e9<\/strong> : Une interface moderne doit maintenir 60fps en limitant les op\u00e9rations co\u00fbteuses et en utilisant les optimisations navigateur.<\/p>\n<\/div>\n<div class=\"tuto-objectif\" style=\"background: #f5f5f5;border-left: 4px solid #667eea;padding: 16px 20px;margin-top: 24px;border-radius: 0 8px 8px 0\">\n<h3 style=\"color: #667eea;margin: 0 0 8px 0;font-size: 16px\">\u00c0 retenir<\/h3>\n<p style=\"margin: 0;color: #333\">L&rsquo;optimisation des composants glassmorphism n\u00e9cessite un \u00e9quilibre entre effet visuel et performance, en privil\u00e9giant les propri\u00e9t\u00e9s optimis\u00e9es par le navigateur.<\/p>\n<\/div>\n<div class=\"tuto-exercise\" style=\"background: #fff3e0;border-left: 4px solid #ff9800;padding: 16px 20px;margin-top: 20px;border-radius: 0 8px 8px 0\">\n<h4 style=\"color: #ff9800;margin: 0 0 8px 0;font-size: 15px\">\ud83c\udfaf Mini-exercice : Interface optimis\u00e9e haute performance<\/h4>\n<p style=\"margin: 0;color: #333;font-size: 14px\">Cr\u00e9ez un dashboard glassmorphism avec multiples cartes, animations fluides et techniques d&rsquo;optimisation pour maintenir 60fps.<\/p>\n<\/div>\n<div class=\"codepen-block\" data-block-id=\"exercise-4\">\n<p class=\"codepen-block-label\">Code de r\u00e9f\u00e9rence :<\/p>\n<div class=\"codepen-header\">\n<div class=\"codepen-tabs\">\n<button class=\"codepen-tab active\" data-tab=\"html\">HTML<\/button><br \/>\n<button class=\"codepen-tab\" data-tab=\"css\">CSS<\/button><br \/>\n<button class=\"codepen-tab\" data-tab=\"javascript\">JS<\/button>\n<\/div>\n<p><button class=\"codepen-copy-btn\">Copier<\/button>\n<\/div>\n<div class=\"codepen-code-container\">\n<pre class=\"codepen-code active\" data-lang=\"html\">&lt;div class=\"optimized-dashboard\"&gt;\n  &lt;div class=\"dashboard-header\"&gt;\n    &lt;h1&gt;Dashboard Optimis\u00e9&lt;\/h1&gt;\n    &lt;div class=\"performance-meter\"&gt;\n      &lt;span class=\"fps-counter\"&gt;60 FPS&lt;\/span&gt;\n    &lt;\/div&gt;\n  &lt;\/div&gt;\n  \n  &lt;div class=\"cards-grid\"&gt;\n    &lt;div class=\"dashboard-card\" data-card=\"1\"&gt;\n      &lt;div class=\"card-header\"&gt;\n        &lt;span class=\"card-icon\"&gt;\ud83d\udcca&lt;\/span&gt;\n        &lt;span class=\"card-title\"&gt;Analytics&lt;\/span&gt;\n      &lt;\/div&gt;\n      &lt;div class=\"card-content\"&gt;\n        &lt;div class=\"metric-value\"&gt;1,234&lt;\/div&gt;\n        &lt;div class=\"metric-label\"&gt;Total Views&lt;\/div&gt;\n        &lt;div class=\"progress-bar\"&gt;\n          &lt;div class=\"progress-fill\" data-progress=\"75\"&gt;&lt;\/div&gt;\n        &lt;\/div&gt;\n      &lt;\/div&gt;\n    &lt;\/div&gt;\n    \n    &lt;div class=\"dashboard-card\" data-card=\"2\"&gt;\n      &lt;div class=\"card-header\"&gt;\n        &lt;span class=\"card-icon\"&gt;\ud83d\udc65&lt;\/span&gt;\n        &lt;span class=\"card-title\"&gt;Users&lt;\/span&gt;\n      &lt;\/div&gt;\n      &lt;div class=\"card-content\"&gt;\n        &lt;div class=\"metric-value\"&gt;567&lt;\/div&gt;\n        &lt;div class=\"metric-label\"&gt;Active Users&lt;\/div&gt;\n        &lt;div class=\"progress-bar\"&gt;\n          &lt;div class=\"progress-fill\" data-progress=\"62\"&gt;&lt;\/div&gt;\n        &lt;\/div&gt;\n      &lt;\/div&gt;\n    &lt;\/div&gt;\n    \n    &lt;div class=\"dashboard-card\" data-card=\"3\"&gt;\n      &lt;div class=\"card-header\"&gt;\n        &lt;span class=\"card-icon\"&gt;\ud83d\udcb0&lt;\/span&gt;\n        &lt;span class=\"card-title\"&gt;Revenue&lt;\/span&gt;\n      &lt;\/div&gt;\n      &lt;div class=\"card-content\"&gt;\n        &lt;div class=\"metric-value\"&gt;$12,456&lt;\/div&gt;\n        &lt;div class=\"metric-label\"&gt;This Month&lt;\/div&gt;\n        &lt;div class=\"progress-bar\"&gt;\n          &lt;div class=\"progress-fill\" data-progress=\"88\"&gt;&lt;\/div&gt;\n        &lt;\/div&gt;\n      &lt;\/div&gt;\n    &lt;\/div&gt;\n    \n    &lt;div class=\"dashboard-card\" data-card=\"4\"&gt;\n      &lt;div class=\"card-header\"&gt;\n        &lt;span class=\"card-icon\"&gt;\u26a1&lt;\/span&gt;\n        &lt;span class=\"card-title\"&gt;Performance&lt;\/span&gt;\n      &lt;\/div&gt;\n      &lt;div class=\"card-content\"&gt;\n        &lt;div class=\"metric-value\"&gt;98.5%&lt;\/div&gt;\n        &lt;div class=\"metric-label\"&gt;Uptime&lt;\/div&gt;\n        &lt;div class=\"progress-bar\"&gt;\n          &lt;div class=\"progress-fill\" data-progress=\"98\"&gt;&lt;\/div&gt;\n        &lt;\/div&gt;\n      &lt;\/div&gt;\n    &lt;\/div&gt;\n  &lt;\/div&gt;\n&lt;\/div&gt;<\/pre>\n<pre class=\"codepen-code\" data-lang=\"css\">* {\n  box-sizing: border-box;\n}\n\nbody {\n  margin: 0;\n  min-height: 100vh;\n  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n  padding: 20px;\n  overflow-x: hidden;\n}\n\n.optimized-dashboard {\n  max-width: 1200px;\n  margin: 0 auto;\n  \/* Optimisation: Isolation pour limiter les repaints *\/\n  contain: layout style paint;\n}\n\n.dashboard-header {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  margin-bottom: 30px;\n  color: white;\n}\n\n.dashboard-header h1 {\n  margin: 0;\n  font-size: 32px;\n  font-weight: 300;\n  letter-spacing: 1px;\n}\n\n.performance-meter {\n  background: rgba(255, 255, 255, 0.1);\n  backdrop-filter: blur(10px);\n  border: 1px solid rgba(255, 255, 255, 0.2);\n  border-radius: 25px;\n  padding: 8px 16px;\n  font-size: 14px;\n}\n\n.fps-counter {\n  color: #4ade80;\n  font-weight: bold;\n}\n\n.cards-grid {\n  display: grid;\n  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n  gap: 24px;\n  \/* Optimisation: Sous-grille optimis\u00e9e *\/\n  contain: layout;\n}\n\n.dashboard-card {\n  background: rgba(255, 255, 255, 0.1);\n  backdrop-filter: blur(20px);\n  border: 1px solid rgba(255, 255, 255, 0.2);\n  border-radius: 20px;\n  padding: 24px;\n  color: white;\n  position: relative;\n  overflow: hidden;\n  cursor: pointer;\n  \n  \/* Optimisations critiques pour les performances *\/\n  will-change: transform;\n  transform: translateZ(0); \/* Force la couche GPU *\/\n  transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n  \n  \/* Limitation des repaints *\/\n  contain: layout style;\n}\n\n.dashboard-card::before {\n  content: '';\n  position: absolute;\n  top: 0;\n  left: -100%;\n  width: 100%;\n  height: 100%;\n  background: linear-gradient(90deg, \n    transparent, \n    rgba(255, 255, 255, 0.1), \n    transparent);\n  transition: left 0.5s ease;\n}\n\n.dashboard-card:hover {\n  transform: translateY(-8px) scale(1.02);\n  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);\n}\n\n.dashboard-card:hover::before {\n  left: 100%;\n}\n\n.card-header {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  margin-bottom: 20px;\n}\n\n.card-icon {\n  font-size: 24px;\n  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));\n}\n\n.card-title {\n  font-size: 16px;\n  font-weight: 500;\n  opacity: 0.9;\n  text-transform: uppercase;\n  letter-spacing: 1px;\n}\n\n.card-content {\n  \/* Optimisation du contenu *\/\n  contain: layout style;\n}\n\n.metric-value {\n  font-size: 36px;\n  font-weight: 700;\n  margin-bottom: 8px;\n  background: linear-gradient(135deg, #fff 0%, #f8fafc 100%);\n  -webkit-background-clip: text;\n  -webkit-text-fill-color: transparent;\n  background-clip: text;\n}\n\n.metric-label {\n  font-size: 14px;\n  opacity: 0.8;\n  margin-bottom: 16px;\n  text-transform: uppercase;\n  letter-spacing: 0.5px;\n}\n\n.progress-bar {\n  width: 100%;\n  height: 8px;\n  background: rgba(255, 255, 255, 0.1);\n  border-radius: 4px;\n  overflow: hidden;\n  position: relative;\n}\n\n.progress-fill {\n  height: 100%;\n  background: linear-gradient(90deg, #4ade80, #22d3ee);\n  border-radius: 4px;\n  width: 0;\n  transition: width 1.2s cubic-bezier(0.4, 0, 0.2, 1);\n  \n  \/* Optimisation pour l'animation de largeur *\/\n  will-change: width;\n}\n\n.progress-fill::after {\n  content: '';\n  position: absolute;\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  background: linear-gradient(90deg, \n    transparent, \n    rgba(255, 255, 255, 0.3), \n    transparent);\n  animation: shimmer 2s ease-in-out infinite;\n}\n\n@keyframes shimmer {\n  0% { transform: translateX(-100%); }\n  100% { transform: translateX(100%); }\n}\n\n\/* Animations d'entr\u00e9e optimis\u00e9es *\/\n.dashboard-card {\n  opacity: 0;\n  transform: translateY(30px);\n  animation: cardSlideIn 0.6s cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n.dashboard-card[data-card=\"1\"] { animation-delay: 0.1s; }\n.dashboard-card[data-card=\"2\"] { animation-delay: 0.2s; }\n.dashboard-card[data-card=\"3\"] { animation-delay: 0.3s; }\n.dashboard-card[data-card=\"4\"] { animation-delay: 0.4s; }\n\n@keyframes cardSlideIn {\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n\/* Media queries pour l'optimisation responsive *\/\n@media (max-width: 768px) {\n  .cards-grid {\n    grid-template-columns: 1fr;\n    gap: 16px;\n  }\n  \n  .dashboard-card {\n    padding: 20px;\n  }\n  \n  \/* D\u00e9sactivation de certains effets sur mobile pour les performances *\/\n  .dashboard-card::before {\n    display: none;\n  }\n  \n  .progress-fill::after {\n    display: none;\n  }\n}<\/pre>\n<pre class=\"codepen-code\" data-lang=\"javascript\">\/\/ Optimisation des performances avec RequestAnimationFrame\nclass PerformanceOptimizer {\n  constructor() {\n    this.isAnimating = false;\n    this.pendingAnimations = new Set();\n    this.fpsCounter = document.querySelector('.fps-counter');\n    this.lastTime = performance.now();\n    this.frameCount = 0;\n    \n    this.init();\n  }\n  \n  init() {\n    this.initProgressBars();\n    this.initFPSCounter();\n    this.initIntersectionObserver();\n  }\n  \n  \/\/ Animation optimis\u00e9e des barres de progression\n  initProgressBars() {\n    const progressBars = document.querySelectorAll('.progress-fill');\n    \n    \/\/ Utilisation d'un d\u00e9lai pour \u00e9viter les animations simultan\u00e9es\n    progressBars.forEach((bar, index) =&gt; {\n      setTimeout(() =&gt; {\n        const progress = bar.getAttribute('data-progress');\n        requestAnimationFrame(() =&gt; {\n          bar.style.width = `${progress}%`;\n        });\n      }, index * 200);\n    });\n  }\n  \n  \/\/ Compteur FPS pour monitoring des performances\n  initFPSCounter() {\n    const updateFPS = () =&gt; {\n      const currentTime = performance.now();\n      this.frameCount++;\n      \n      if (currentTime &gt;= this.lastTime + 1000) {\n        const fps = Math.round((this.frameCount * 1000) \/ (currentTime - this.lastTime));\n        this.fpsCounter.textContent = `${fps} FPS`;\n        \n        \/\/ Changement de couleur selon les performances\n        if (fps &gt;= 50) {\n          this.fpsCounter.style.color = '#4ade80'; \/\/ Vert\n        } else if (fps &gt;= 30) {\n          this.fpsCounter.style.color = '#fbbf24'; \/\/ Jaune\n        } else {\n          this.fpsCounter.style.color = '#ef4444'; \/\/ Rouge\n        }\n        \n        this.frameCount = 0;\n        this.lastTime = currentTime;\n      }\n      \n      requestAnimationFrame(updateFPS);\n    };\n    \n    requestAnimationFrame(updateFPS);\n  }\n  \n  \/\/ Intersection Observer pour les animations au scroll\n  initIntersectionObserver() {\n    const cards = document.querySelectorAll('.dashboard-card');\n    \n    const observer = new IntersectionObserver((entries) =&gt; {\n      entries.forEach(entry =&gt; {\n        if (entry.isIntersecting) {\n          \/\/ Animation uniquement quand l'\u00e9l\u00e9ment est visible\n          entry.target.style.animationPlayState = 'running';\n        }\n      });\n    }, {\n      threshold: 0.1,\n      rootMargin: '50px'\n    });\n    \n    cards.forEach(card =&gt; {\n      card.style.animationPlayState = 'paused';\n      observer.observe(card);\n    });\n  }\n}\n\n\/\/ Throttling optimis\u00e9 pour les \u00e9v\u00e9nements de souris\nfunction throttle(func, delay) {\n  let timeoutId;\n  let lastExecTime = 0;\n  return function (...args) {\n    const currentTime = Date.now();\n    \n    if (currentTime - lastExecTime &gt; delay) {\n      func.apply(this, args);\n      lastExecTime = currentTime;\n    } else {\n      clearTimeout(timeoutId);\n      timeoutId = setTimeout(() =&gt; {\n        func.apply(this, args);\n        lastExecTime = Date.now();\n      }, delay - (currentTime - lastExecTime));\n    }\n  };\n}\n\n\/\/ Gestion optimis\u00e9e des interactions\nconst cards = document.querySelectorAll('.dashboard-card');\n\ncards.forEach(card =&gt; {\n  \/\/ Utilisation de passive listeners pour am\u00e9liorer les performances\n  const handleMouseMove = throttle((e) =&gt; {\n    const rect = card.getBoundingClientRect();\n    const x = e.clientX - rect.left;\n    const y = e.clientY - rect.top;\n    \n    const centerX = rect.width \/ 2;\n    const centerY = rect.height \/ 2;\n    \n    const rotateX = (y - centerY) \/ 20;\n    const rotateY = (centerX - x) \/ 20;\n    \n    \/\/ Utilisation de transform pour \u00e9viter les reflows\n    requestAnimationFrame(() =&gt; {\n      card.style.transform = `\n        translateY(-8px) \n        scale(1.02) \n        rotateX(${rotateX}deg) \n        rotateY(${rotateY}deg)\n      `;\n    });\n  }, 16); \/\/ ~60fps\n  \n  card.addEventListener('mousemove', handleMouseMove, { passive: true });\n  \n  card.addEventListener('mouseleave', () =&gt; {\n    requestAnimationFrame(() =&gt; {\n      card.style.transform = 'translateY(0) scale(1) rotateX(0) rotateY(0)';\n    });\n  }, { passive: true });\n});\n\n\/\/ Initialisation du syst\u00e8me d'optimisation\ndocument.addEventListener('DOMContentLoaded', () =&gt; {\n  new PerformanceOptimizer();\n  \n  \/\/ Debug: Log des m\u00e9triques de performance\n  if (performance.mark) {\n    performance.mark('dashboard-loaded');\n    console.log('Dashboard optimis\u00e9 charg\u00e9:', performance.now(), 'ms');\n  }\n});<\/pre>\n<\/div>\n<\/div>\n<div class=\"monaco-sandbox\" data-block-id=\"exercise-4\">\n<div class=\"monaco-header\">\n<div class=\"monaco-tabs\">\n<button class=\"monaco-tab active\" data-lang=\"html\">HTML<\/button><br \/>\n<button class=\"monaco-tab\" data-lang=\"css\">CSS<\/button><br \/>\n<button class=\"monaco-tab\" data-lang=\"javascript\">JS<\/button>\n<\/div>\n<div class=\"monaco-actions\">\n<button class=\"monaco-btn monaco-btn-run\">\u25b6 Ex\u00e9cuter<\/button><br \/>\n<button class=\"monaco-btn monaco-btn-reset\">\u21ba Reset<\/button>\n<\/div>\n<\/div>\n<div class=\"monaco-container\">\n<div class=\"monaco-editor-wrapper\">\n<div class=\"monaco-editor-pane active\" data-lang=\"html\"><\/div>\n<div class=\"monaco-editor-pane\" data-lang=\"css\"><\/div>\n<div class=\"monaco-editor-pane\" data-lang=\"javascript\"><\/div>\n<\/div>\n<div class=\"monaco-preview-wrapper\">\n<div class=\"monaco-preview-header\">Result<\/div>\n<\/div>\n<\/div>\n<div class=\"monaco-status\">\n<span class=\"monaco-status-left\">\u25cf Pr\u00eat<\/span><br \/>\n<span class=\"monaco-status-right\">Monaco Editor v0.45<\/span>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"wpa-accordion-item\">\n<button class=\"wpa-accordion-header\" data-wpa-target=\"#accordion-composants-ui-modernes-item-5\" aria-expanded=\"false\"><span class=\"wpa-accordion-title\"><span class=\"wpa-accordion-number\">05<\/span> Int\u00e9gration et Bonnes Pratiques<\/span><span class=\"wpa-accordion-icon\"><\/span><\/button><\/p>\n<div id=\"accordion-composants-ui-modernes-item-5\" class=\"wpa-accordion-body\">\n<div class=\"wpa-accordion-content\">\n<h4>Accessibilit\u00e9 des composants glassmorphism<\/h4>\n<p>L&rsquo;accessibilit\u00e9 est cruciale pour les composants glassmorphism car leur nature translucide peut poser des d\u00e9fis de lisibilit\u00e9. Il faut s&rsquo;assurer d&rsquo;un contraste suffisant entre le texte et l&rsquo;arri\u00e8re-plan, m\u00eame avec l&rsquo;effet de transparence. Les utilisateurs avec des troubles visuels do\n<\/p><\/div>\n<\/div>\n<\/div>\n<\/div>\n<h2>R\u00e9capitulatif<\/h2>\n<div class=\"tuto-recap\" style=\"background: #f5f5f5;border-left: 4px solid #9c27b0;padding: 16px 20px;border-radius: 0 8px 8px 0\">\n<h3 style=\"color: #9c27b0;margin: 0 0 12px 0;font-size: 16px\">Points essentiels \u00e0 retenir<\/h3>\n<ul style=\"margin: 0;padding-left: 20px;color: #333\">\n<li><strong>Composants modulaires<\/strong> : Les composants UI r\u00e9utilisables acc\u00e9l\u00e8rent le d\u00e9veloppement et assurent la coh\u00e9rence visuelle.<\/li>\n<li><strong>Glassmorphism<\/strong> : backdrop-filter et transparence cr\u00e9ent des interfaces modernes et \u00e9l\u00e9gantes.<\/li>\n<li><strong>Micro-interactions<\/strong> : Le feedback visuel imm\u00e9diat am\u00e9liore l&rsquo;exp\u00e9rience utilisateur.<\/li>\n<li><strong>Pratique r\u00e9guli\u00e8re<\/strong> : La ma\u00eetrise technique s&rsquo;acquiert par l&rsquo;exp\u00e9rimentation et la r\u00e9alisation de projets concrets.<\/li>\n<\/ul>\n<\/div>\n<h2>Sources<\/h2>\n<div class=\"sources-box\" style=\"background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);border: 1px solid #cbd5e1;border-radius: 12px;padding: 16px;margin-bottom: 24px\">\n<p style=\"color: #64748b;margin: 0 0 12px 0;font-size: 13px\">Pour approfondir vos connaissances :<\/p>\n<ul style=\"margin: 0;padding-left: 0\">\n<li style=\"margin-bottom: 8px\"><a href=\"https:\/\/developer.mozilla.org\/fr\/docs\/Web\/CSS\/backdrop-filter\" target=\"_blank\" rel=\"noopener noreferrer\" style=\"align-items: center;gap: 10px;padding: 10px 14px;background: white;border-radius: 8px;text-decoration: none;color: #1e293b;border: 1px solid #e2e8f0\"><span style=\"color: #94a3b8\">\ud83d\udd17<\/span><span style=\"flex: 1;font-weight: 500;color: #0f172a\">MDN &#8211; backdrop-filter et effets de transparence<\/span><span style=\"color: #94a3b8\">\u2192<\/span><\/a><\/li>\n<li style=\"margin-bottom: 0\"><a href=\"https:\/\/css-tricks.com\/almanac\/properties\/b\/backdrop-filter\/\" target=\"_blank\" rel=\"noopener noreferrer\" style=\"align-items: center;gap: 10px;padding: 10px 14px;background: white;border-radius: 8px;text-decoration: none;color: #1e293b;border: 1px solid #e2e8f0\"><span style=\"color: #94a3b8\">\ud83d\udd17<\/span><span style=\"flex: 1;font-weight: 500;color: #0f172a\">CSS-Tricks &#8211; Guide du Glassmorphism<\/span><span style=\"color: #94a3b8\">\u2192<\/span><\/a><\/li>\n<\/ul>\n<\/div>\n<h2>Validez vos connaissances<\/h2>\n<p>Testez votre compr\u00e9hension avec ce quiz de 10 questions :<\/p>\n<div id=\"quiz-block-1\" class=\"quiz-container\" data-quiz-json=\"https:\/\/lmspro.fr\/wp-content\/plugins\/generate-article-endpoint\/quiz-data\/en\/quiz-composants-ui-modernes.json\" aria-label=\"Interactive Quiz\"><div class=\"quiz-loading\" role=\"status\" aria-live=\"polite\"><span class=\"quiz-sr-only\">Loading quiz...<\/span><\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Modern UI Components: Discover advanced techniques for creating modern UI components with glassmorphism effects. Master modern CSS properties to design elegant and interactive interfaces that capture users&#039; attention. Module: Module 1: Web Technical Fundamentals Level: Beginner Duration: 20 minutes Prerequisites: None Objectives\u2026 <a href=\"https:\/\/lmspro.fr\/en\/composants-ui-modernes\/\" class=\"more-link\">Read More<span class=\"screen-reader-text\"> \u00ab\u00a0Composants UI modernes\u00a0\u00bb<\/span> &raquo;<\/a><\/p>","protected":false},"author":1,"featured_media":552,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[38],"tags":[34,25,26,132,27,28,133,2],"class_list":["post-551","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-module-3-ux-ui-produit","tag-accessibilite","tag-animation","tag-css","tag-fondamentaux-web","tag-html","tag-javascript","tag-js","tag-ux"],"_links":{"self":[{"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/posts\/551","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/comments?post=551"}],"version-history":[{"count":1,"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/posts\/551\/revisions"}],"predecessor-version":[{"id":583,"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/posts\/551\/revisions\/583"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/media\/552"}],"wp:attachment":[{"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/media?parent=551"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/categories?post=551"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/tags?post=551"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}