Alsacreations.com - Apprendre - Archives (février 2026)

Les dernières ressources publiées sur Alsacreations.com

Le: 19 02 2026 à 10:00 Auteur: paleo

Il est loin le temps où Visual Studio Code courait derrière Cursor ou Claude Code. Aujourd'hui, l'éditeur open source de Microsoft est l'un des environnements de développement qui intègre le mieux l'intelligence artificielle. [...]

Retrouvez l'intégralité de ce tutoriel en ligne sur Alsacreations.com

Le: 17 02 2026 à 08:08 Auteur: Raphael

La gestion de la portée des styles est un défi historique en CSS. Des méthodologies comme BEM aux solutions techniques comme le Shadow DOM ou les CSS Modules, nous avons toujours cherché à éviter que le style d'un composant ne se propage sur ses voisins. L'arrivée de la règle @scope change la donne en offrant une solution native, flexible et puissante.

Présentation rapide de @scope

La règle @scope permet de cibler des éléments dans un fragment spécifique du DOM.

Dans cet exemple simple, seuls les <h2> à l'intérieur des éléments portant la classe .card seront colorés en hotpink. Les styles n'affecteront pas les autres <h2> de la page :

@scope (.card) {
  /* Cible les h2 uniquement dans .card */
  h2 {
    color: hotpink;
  }
}

Dans cet autre exemple sont ciblés uniquement les <h2> à l'intérieur des éléments portant la classe .card contenant un élément .title :

@scope (.card:has(.title)) {
  /* Cible les h2 uniquement dans .card qui contient .title */
  h2 {
    color: hotpink;
  }
}

Compatibilité navigateurs

Voici le tableau de compatibilité de @scope, que vous pouvez également consulter sur Caniuse.com :

support de @scope sur les navigateurs web via caniuse.com

Le sélecteur :scope et l'esperluette &

À l'intérieur d'un bloc @scope, le navigateur a besoin d'un moyen de désigner l'élément racine lui-même (celui qui porte la classe ou l'attribut de départ). Il existe deux façons de procéder :

  • :scope : Une pseudo-classe qui référence logiquement l'élément racine. C'est le cœur technique du dispositif.
  • & (Esperluette) : Comme dans le nesting classique, elle permet de coller des états à la racine (ex: &:hover).

Dans la plupart des cas, l'usage du & pour les états interactifs est recommandé pour sa simplicité.

Par exemple, si on souhaite que son composant .card ait un fond gris, mais que ses éléments internes aient leurs propres styles, on va se servir de :scope :

@scope (.card) {
  /* Cible l'élément .card lui-même */
  :scope {
    background: var(--surface);
    border: 1px solid var(--border-light);
  }
}

Pour les éléments hautement réutilisables comme les boutons, :scope associé à & (esperluette) permettent de centraliser la logique interactive (hover, focus, active) en utilisant les variables CSS.

@scope (.btn) {
  :scope {
    /* Variables par défaut */
    --button-background-color: var(--form-background, Field);
    --button-text-color: var(--on-form, ButtonText);

    background-color: var(--button-background-color);
    color: var(--button-text-color);
    transition: all var(--transition-duration);
  }

  /* Logique interactive unique pour toutes les variantes */
  &:hover, &:focus-visible {
    background-color: oklch(from var(--button-background-color) calc(l * 0.9) c h);
  }

  &:disabled {
    opacity: 0.8;
    cursor: not-allowed;
  }

  /* Variantes : On ne change que les valeurs, pas la logique */
  &.btn-primary {
    --button-background-color: var(--primary);
    --button-text-color: var(--on-primary);
  }
}

Mais pourquoi ne pas se contenter de .card .title ou .card > .title ?

C'est bien vrai ça, on pourrait croire que @scope ne sert qu'à nous compliquer la vie. Alors que… pas du tout !

  1. La proximité l'emporte sur l'ordre : en CSS standard, si deux sélecteurs ont la même spécificité, le dernier écrit gagne. Avec @scope, c'est la racine la plus proche de l'élément dans le DOM qui l'emporte. C'est idéal pour les thèmes imbriqués.
  2. La spécificité reste basse : .card .title a une spécificité de (0,2,0). À l'intérieur d'un @scope, le sélecteur .title reste à (0,1,0), facilitant les surcharges sans utiliser !important.
  3. Robustesse face au DOM : le sélecteur d'enfant direct (>) est fragile. Si on ajoute une div intermédiaire pour du layout, le style casse. @scope tolère n'importe quelle profondeur tant que la limite n'est pas franchie.

En outre, grâce à la priorité par proximité, @scope permet d'imbriquer des thèmes sans conflit, peu importe l'ordre des CSS.

@scope (.theme-dark) {
  :scope { background: #1a1a1a; color: white; }
  .title { color: var(--color-pink-300); }
}

@scope (.theme-light) {
  :scope { background: white; color: #1a1a1a; }
  .title { color: var(--color-blue-600); }
}

Permettre un périmètre sélectif ("Donut Hole")

Contrairement aux sélecteurs descendants classiques, @scope introduit deux concepts majeurs :

  1. La racine du scope (limite haute) : l'élément à partir duquel les règles s'appliquent.
  2. La limite du scope (limite basse, optionnelle) : l'élément où les règles s'arrêtent.

Dans l'exemple suivant, le navigateur cherche .card pour y colorer les h2 en rose. Cependant, dès qu'il rencontre un élément .content, il cesse d'appliquer les styles à ses descendants :

@scope (.card) to (.content) {
  /* Cible les .title dans .card mais s'arrête à .content */
  .title {
    color: hotpink;
  }
}

C'est l'atout majeur de @scope : la capacité de définir un périmètre d'exclusion via la clause to. Cela permet de protéger des zones de contenu riche (WYSIWYG, slots) ou des composants imbriqués qui ne doivent pas être affectés par les styles du parent.

Mais alors c'est mieux que BEM ?

BEM est une convention efficace mais verbeuse, et elle repose entièrement sur votre discipline de nommage et nécessite des noms de classes uniques (.card__title, .hero__title--alternate).

Avec @scope, vous pouvez garder des noms plus simples et réutilisables, tout en garantissant que les styles restent confinés à leur contexte : le HTML est épuré des préfixes répétitifs et grâce au to (.content), un titre de card situé dans un élément .content sera jamais affecté par le style de la carte, car il est "hors limite".

L'adoption de @scope marque une étape vers la fin de l'ère "tout BEM" au profit d'une approche plus sémantique et structurelle.

Dans un projet concret, BEM, @layer et @scope peuvent cependant coexister :

  • BEM est une convention de nommage pour humains (organisation visuelle).
  • @layer gère la priorité des sources (fichiers, frameworks).
  • @scope est une barrière de sécurité technique (structure du DOM).

Et Tailwind dans tout ça ?

On ne va pas se mentir : l'intégration de @scope dans un projet utilisant déjà un framework utilitaire comme Tailwind peut sembler redondante au premier abord.

Il existe cependant quelques cas d'usage où @scope peut apporter une valeur ajoutée significative, notamment pour les composants complexes et les zones de contenu dynamique qui ne sont pas facilement gérables avec les classes utilitaires seules.

Par exemple, dans Tailwind, styler du HTML brut (venant d'un CMS) nécessite souvent l'utilisation du plugin @tailwindcss/typography (classe .prose). Cependant, ce plugin est parfois trop rigide. Avec @scope, on peut créer des "bulles" de styles spécifiques pour son contenu sans polluer le reste du site et sans créer de classes complexes :

@layer components {
  @scope (.prose-custom) to (.content) {
    /* On style les balises nues uniquement dans ce contexte */
    h2 { @apply text-2xl font-bold mb-4 text-primary; }
    p { @apply leading-relaxed mb-6; }

    /* Les limites protègent les composants Tailwind imbriqués */
  }
}

En résumé

Si l'on devait résumer les avantages de @scope en quelques points clés :

  • Allègement du HTML : plus besoin de classes à rallonge comme .card-header__title. On utilise des classes simples (.title, .media, .header, .content) et faciles à retenir.
  • Proximité l'emporte sur l'ordre : les styles s'appliquent en fonction de la proximité dans le DOM, pas de l'ordre d'apparition dans le CSS. Idéal pour les thèmes imbriqués.
  • Isolation par limites : on bénéficie de la clause to pour définir une limite haute et basse et garantir que les utilitaires appliqués à un composant enfant ne seront jamais écrasés par les styles du parent.
  • Débogage facilité : dans l'inspecteur du navigateur, la règle @scope apparaît clairement, permettant de voir immédiatement quelle racine applique le style, plutôt que de chercher l'origine dans une pile de sélecteurs descendants complexes.
  • Spécificité contrôlée : contrairement aux sélecteurs descendants classiques (.card .btn) qui augmentent la spécificité, @scope maintient une spécificité faible. Cela permet à ses classes utilitaires (ex: p-4) de rester prioritaires et faciles à surcharger si besoin.

Si l'on ne devait en retenir qu'un seul, il s'agirait sans aucun doute de Conflits de nommage réduits. En effet, des noms de classes génériques comme .title peuvent être utilisées dans plusieurs scopes sans risque de conflit, car elles ne s'appliquent qu'à leur propre scope. Et tout le monde sait que nommer les choses c'est… compliqué.

Conclusion

@scope ne remplace pas les outils actuels, il complète avantageusement l'outillage natif déjà mis en place par CSS (cascade, @layer, :where(), etc.).

Totalement inadapté pour les styles globaux (reset, typographie de base, utilitaires) qui doivent se propager partout, il devient en revanche un allié précieux pour les styles de composants et les zones de contenu dynamique.

Utilisons-le dans notre @layer(components) pour isoler nos "organismes" (cartes, headers, modales). C'est la fin du "CSS qui bave" et le début d'une architecture plus proche de la structure réelle de vos pages.

Note : Le support navigateur est désormais excellent dans les versions récentes de Firefox, Chrome, Edge et Safari. Pour les projets nécessitant un support legacy, une stratégie de Progressive Enhancement via @supports (scope: html) est préconisée.

Publié par Alsacreations.com

Le: 12 02 2026 à 15:30 Auteur: Rodolphe

L'événement scrollend est une nouvelle API standardisée pour détecter la fin du défilement dans une page web.

Durant des années nous avons du jongler avec moult événements, astuces JavaScript et calculs pour attraper l'action de scroll, notamment le combiner à un debounce : cette approche consistait à déclencher un timer à chaque événement de défilement et à considérer que le scroll était terminé si aucun nouvel événement ne survenait pendant un certain délai, typiquement 100 à 200 millisecondes, selon la lourdeur de la page et la réactivité attendue.

Avant scrollend

Les inconvénients étaient des faux positifs lors de pauses qui n'en étaient pas vraiment, la consommation de ressources (processeur, carte graphique), et le délai choisi restait approximatif. De plus, on ne prenait pas en compte les animations de défilement fluide ou les gestes tactiles avec inertie.

// Approche classique/ancienne avec debounce ⚠️
let scrollTimer = null;

window.addEventListener('scroll', function() {
  // Annuler le timer précédent si le scroll continue
  if (scrollTimer !== null) {
    clearTimeout(scrollTimer);
  }

  // Définir un nouveau timer
  scrollTimer = setTimeout(function() {
    // Code exécuté "à la fin" du scroll
    console.log('Scroll terminé (probablement)');

    // Exemple : charger plus de contenu
    loadMoreContent();

    // Exemple : enregistrer la position de lecture
    trackScrollDepth();
  }, 150); // Délai arbitraire de 150ms
}, false);

Avec scrollend

Désormais scrollend (disponible dans tous les navigateurs) est aussi simple à utiliser que n'importe quel événement natif du navigateur. Il suffit d'ajouter un écouteur sur l'élément défilable concerné, que ce soit la fenêtre principale ou un conteneur spécifique.

// Avec scrollend ✅
window.addEventListener('scrollend', function() {
  // Code exécuté réellement à la fin du scroll
  console.log('Scroll terminé');

  // Exemple : charger plus de contenu
  loadMoreContent();

  // Exemple : enregistrer la position de lecture
  trackScrollDepth();
});

L'événement se déclenche de manière fiable dans tous les scénarios de défilement : que l'utilisateur utilise la molette de la souris, fasse glisser la barre de défilement, utilise les touches du clavier, effectue un geste tactile sur mobile/tablette, ou même lorsqu'un défilement programmé via scrollTo() ou scrollIntoView() se termine.

Pour le lazy-loading cet événement permet de déclencher le chargement de nouvelles données uniquement lorsque l'utilisateur a réellement terminé son défilement, y compris en infinite scroll, évitant ainsi des requêtes prématurées. On peut aussi parfaitement l'utiliser pour afficher des indicateurs de position de lecture qui se mettent à jour de façon plus pertinente, même si on peut le faire de manière encore plus élégante en CSS : Les Animations liées au scroll avec CSS.

Enfin pour les adeptes du tracking, scrollend permet de savoir jusqu'où les internautes défilent réellement dans une page, plutôt que de se baser sur des approximations.

Support navigateur et adoption

D'après Can I Use : scrollend on est plutôt à l'aise car tous les navigateurs majeurs le supportent (Chrome, Edge, Firefox, Safari). Nul besoin de polyfill.

Publié par Alsacreations.com

Le: 06 02 2026 à 10:00 Auteur: Raphael

Pendant plus d'une décennie, nous avons traité le Web comme une collection d'affiches statiques imprimées sur du papier de verre : une pour mobile, une pour tablette, une pour desktop. Mais le Web n'est pas une série de tailles d'écrans fixes. C'est un fluide continu.

Bienvenue dans l'ère de l'Intrinsic Web Design (ou Design Intrinsèque), un terme introduit Jen Simmons en 2018 où le contenu dicte la mise en page, et non l'inverse. L'objectif est de créer des composants qui s'adaptent à leur contexte, qu'ils soient dans une sidebar réduite ou dans un header très large.

Le vocabulaire de la fluidité : les mots-clés intrinsèques

Le CSS moderne nous offre un vocabulaire de précision pour définir comment les boîtes doivent se comporter face à leur contenu et leur conteneur :

  • auto : L'ancien roi. Contextuel, imprévisible parfois, il laisse le navigateur calculer la taille selon le modèle de boîte standard (display).
  • min-content : "Je veux être aussi petit que possible." Le navigateur va essayer de réduire la boîte jusqu'à ce que le mot le plus long ou l'élément le plus large force la largeur minimale. C'est le "soft wrapping" ultime.
  • max-content : "Je prends toute la place dont j'ai besoin." La boîte s'élargit pour contenir tout le texte sans aucun retour à la ligne, quitte à provoquer un scroll horizontal (à utiliser avec prudence !).
  • fit-content : Le compromis parfait. C'est mathématiquement équivalent à min(max-content, available-space). La boîte s'adapte au contenu, mais s'arrête poliment si elle touche le bord du conteneur parent.
  • stretch : L'élément s'étire pour remplir l'axe disponible. C'est souvent le comportement par défaut des flex-items ou des grid-items.

La boîte à outils mathématique : clamp(), min() et max()

Fini le temps où l'on devait déclarer font-size: 16px puis le changer à 18px au breakpoint tablette, et 20px sur desktop.

Avec les fonctions mathématiques CSS, la fluidité est native. La fonction clamp() est sans doute la plus polyvalente d'entre elles. Elle permet de définir une valeur minimale, une valeur idéale (fluide) et une valeur maximale.

h1 {
  /* Taille min: 2rem, Idéale: 5% du viewport, Max: 4rem */
  font-size: clamp(2rem, 5vw + 1rem, 4rem);
}

Contrairement à une approche type Tailwind (qui demande souvent d'empiler des préfixes text-m md:text-l lg:text-xl), clamp() gère l'interpolation mathématique tout seul. Plus de breakpoints figés, plus d'effets de saut lors du redimensionnement de la fenêtre.

🔧 L'outil Alsacréations : Pour générer ces formules sans avoir un doctorat en mathématiques, notre outil maison Elastic est toujours là pour vous servir.

L'outil Elastic" pour générer des polices fluides

Flexbox & Grid Layout : La mécanique des fluides

Vous utilisez déjà Flexbox et Grid, mais exploitez-vous vraiment leurs capacités intrinsèques ? Ces modules ont été conçus pour gérer l'espace restant et l'espace manquant sans Media Queries.

Flexbox : L'accordéon

Flexbox brille sur un axe. Ses propriétés de base sont des moteurs de fluidité :

  • flex-wrap: wrap : La base du responsive. Si ça ne rentre pas, ça passe à la ligne.
  • flex-grow: 1 : "Prends tout l'espace vide disponible".
  • flex-shrink: 1 : "Si on manque de place, réduis-toi".

Grid Layout : La structure intelligente

Grid introduit l'unité fr (fraction), qui distribue l'espace libre après le calcul des tailles fixes.

Mais la véritable puissance réside dans minmax(). Cette fonction permet de générer des colonnes occupant une largeur minimale (300px) tout en s'étirant pour remplir l'espace disponible : grid-template-columns: minmax(300px, 1fr)

Le nom d'usage "RAM" (pour "Repeat Auto Minmax") est usuellement donné au snippet magique qui génère une grille responsive automatique sans aucun breakpoint :

.grid-auto {
  display: grid;
  /* 1. repeat: Répète les colonnes...
     2. auto-fit: ...autant de fois que possible dans le conteneur...
     3. minmax: ...avec une taille min de 250px et max de 1fr.
  */
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}

Résultat : Sur desktop, vous avez 4 colonnes. Sur tablette, 2 ou 3. Sur mobile, 1 seule. Nul besoin de @media ni de breakpoints pour cela.

Bretzel Layouts : Des patterns réutilisables

Plutôt que de repartir d'une page blanche et de se battre avec les calculs de fr ou de minmax, le projet d'Alsacréations nommé Bretzel propose des styles utilitaires neutres et réutilisables qui exploitent ces concepts de design intrinsèque.

Contrairement aux frameworks lourds, Bretzel offre des solutions légères qui s'adaptent sans Media Queries pour bon nombre d'entre elles. On y retrouve notamment :

  • Autogrid, la "Grille Adaptative" : L'implémentation parfaite du repeat(auto-fill, minmax(...)) pour des listes de cartes qui se réorganisent d'elles-mêmes.
  • Switcher : Ce layout est composé d'enfants de même taille, s'affichant par défaut verticalement, ou horizontalement selon l'espace disponible.
  • Boxed, le "Centrage Automatique" : Pour gérer des conteneurs centrés qui conservent des marges de sécurité sur les côtés sans padding complexes.
  • Et plusieurs autres.

Ces patterns sont "incassables" car ils ne dépendent pas d'une largeur d'écran arbitraire mais des limites physiques imposées à leurs conteneurs.

Container Queries : le changement de paradigme

C'est ici que tout bascule : tandis que les Media Queries interrogent l'écran (le Viewport), les Container Queries interrogent un ancêtre ou le parent direct de l'élément.

Cela permet de créer des composants réellement agnostiques. Une "Card" placée dans une sidebar étroite s'affichera en mode "compact", et la même "Card" dans le contenu principal s'affichera en mode "étendu".

Mise en pratique :

/* 1. On définit le conteneur */
.card-wrapper {
  container-type: inline-size; /* Surveille la largeur */
  container-name: card; /* Optionnel, pour cibler spécifiquement */
}

/* 2. Styles de base du composant */
.card {
  display: flex;
  flex-direction: column; /* Mobile-first (ou plutôt Small-container-first) */
  gap: 1rem;
}

.card-image {
  aspect-ratio: 16/9;
  object-fit: cover;
}

/* 3. Les styles s'adaptent si le CONTENEUR > 500px */
@container card (width > 500px) {
  .card {
    flex-direction: row; /* On passe à l'horizontale */
    align-items: center;
  }

  .card-image {
    width: 30cqi; /* 30% de la largeur du CONTENEUR (Container Query Inline unit) */
    max-width: 200px;
  }

  .card-content {
    flex: 1;
    font-size: clamp(1rem, 3cqi + 1rem, 2rem); /* Typo fluide basée sur le conteneur */
  }
}

Notez l'unité cqi : Comme vw mais relative au conteneur. Indispensable pour une typographie contextuelle parfaite.

Et pour les plus audacieux, l'association avec :has() permet de transformer automatiquement un parent en conteneur si un certain enfant est présent :

/* Si l'élément .box contient un composant .card, il devient un conteneur */
.box:has(> .card) {
  container-type: inline-size;
}

Ou encore plus fort :

/* Le parent de .card, quel qu'il soit devient un conteneur */
.card {
  *:has(> &) {
    container-type: inline-size;
  }
}

🔗 Pour en savoir plus sur ce sujet, n'hésitez pas à consulter notre article détaillé "Les Container Queries en CSS"

Style Queries

Aujourd'hui, @container interroge la taille. Demain, avec les Style Queries, nous interrogerons la valeur d'une propriété ou d'une variable CSS.

Imaginez un composant qui change d'aspect non pas selon sa taille, mais selon son "thème" défini par une variable parente :

/* Conditionner le style selon une variable CSS */
@container style(--variant: highlighted) {
  .card {
    background: gold;
    border: 5px solid black;
    animation: shake 0.5s;
  }
}

Cela ouvre la porte à une logique conditionnelle directement en CSS, séparant totalement la présentation de la structure HTML.

Custom Media Queries

Si vous pensiez qu'on avait atteint le sommet, détrompez-vous. Voici ce qui arrive (et qui est déjà testable, notamment sous Firefox derrière des flags) :

À ce jour, les variables CSS ne fonctionnent pas dans les Media Queries, il est donc nécessaire de répéter systématiquement les mêmes requêtes @media (width > 48rem) à chaque fois que nécessaire.

Bientôt, vous pourrez scripter vos environnements :

/* Définition (bientôt natif) */
@custom-media --tablet (max-width: 48rem);
@custom-media --dark-mode (prefers-color-scheme: dark);

/* Utilisation */
@media (--tablet) {
  /* ... */
}

Bonus : light-dark()

Le Responsive ne concerne pas que la taille. Il concerne aussi les préférences utilisateur. La fonction light-dark() simplifie drastiquement la gestion du Dark Mode, sans avoir à envelopper tout votre CSS dans des blocs @media (prefers-color-scheme: dark).

:root {
  /* Le navigateur choisit la bonne couleur automatiquement */
  color-scheme: light dark;

  --surface: light-dark(var(--color-white), var(--color-gray-900));
  --on-surface: light-dark(var(--color-gray-900), var(--color-gray-100));
}

body {
  background-color: var(--surface);
  color: var(--on-surface);
}

Conclusion : Lâchez le contrôle

En 2026, faire du responsive ne consiste plus à boucher les trous entre deux breakpoints. C’est accepter qu’on n'est pas là pour faire de l'impression papier, mais pour construire des systèmes qui s'adaptent à de multiples contraintes.

En adoptant l’Intrinsic Web Design, on redonne au navigateur son rôle d’outil intelligent capable d'interpréter nos intentions plutôt que d'exécuter des ordres rigides. Moins de Media Queries, c’est plus de robustesse, moins de dette technique et, surtout, un Web qui respire enfin et qui résistera au prochain device pliable en forme de triangle.

Publié par Alsacreations.com

Le: 02 02 2026 à 11:47 Auteur: Rodolphe

L'API Web Share est un agrément de l'expérience utilisateur permettant de s'affranchir des dizaines de scripts tiers (parfois lourds et intrusifs) à ajouter à une page pour chaque réseau social.

C'est très facile à mettre en place et à cerner, on peut le constater en survolant la spécification W3C Web Share API qui ne pèse pas plusieurs dizaines de pages.

Historiquement, pour permettre à un utilisateur de partager un article, nous devions intégrer des boutons spécifiques pour chaque plateforme (Twitter, Facebook, LinkedIn, etc.). Cela impliquait souvent le chargement de bibliothèques JavaScript externes, réseau par réseau, ou des solutions groupées telles que addThis, allouridssant la page, posant des problèmes de performance et de respect de la vie privée.

L'API Web Share change la donne en permettant aux sites web d'utiliser le mécanisme de partage natif du système d'exploitation. C'est donc la même popup (ou popin) qui s'ouvre lorsque vous partagez une photo depuis votre galerie.

Web Share API sur mobile

À quoi sert Web Share API ?

Le bénéfice est triple :

  • Moins de JavaScript à charger, moins de requêtes HTTP.
  • L'internaute retrouve ses habitudes et ses contacts fréquents, quelle que soit l'application de destination (WhatsApp, Signal, e-mail, SMS, etc.).
  • Un seul bouton suffit pour cibler toutes les destinations possibles.

(On rappelle qu'il vaut mieux utiliser un bouton pour une action en restant sur la même page, et un lien pour une action provoquant un changement de contexte/page).

Différences entre mobile et desktop

Bien que l'API soit standardisée, le comportement visuel varie selon la plateforme :

Caractéristique Mobile (iOS / Android) Desktop (Windows / macOS)
Interface Popup de partage native Menu contextuel du système ou fenêtre dédiée
Intérêt Usage naturel Pratique mais moins évident (souvent limité à l'email ou AirDrop)
Support Quasi universel Bon sur Chromium, Safari, Edge ; pas Firefox

🔐 L'API Web Share ne fonctionne que dans un contexte sécurisé, c'est-à-dire sur HTTPS, et doit impérativement être déclenchée par une action volontaire de l'utilisateur (un clic ou un appui) sinon ce sera bloqué.

Capture d'écran de web share

Support

Si le support s'est largement généralisé, surtout sur mobile, certains environnements comme Firefox sur certains OS desktop ne l'ont pas encore appliqué alors même que la version mobile de Firefox le reconnaît.

On va donc penser amélioration progressive :

  1. On vérifie si navigator.share existe.
  2. Si oui, on affiche le bouton de partage natif.
  3. Si non, on propose une alternative (fallback) : soit une simple copie de l'URL dans le presse-papier par exemple avec l'API Clipboard, soit l'affichage de liens de partage classiques (mailto:, liens directs vers les réseaux, etc).

Ce qu'on peut partager

D'un point de vue technique, l'objet passé à la méthode navigator.share() est flexible mais chaque clé répond à des contraintes spécifiques définies par la spécification W3C.

title

Il s'agit d'une chaîne de caractères représentant le titre du document ou de l'élément partagé. On va le retrouver comme sujet de l'e-mail si l'utilisateur choisit une application de messagerie ou comme titre de l'aperçu. Ce n'est pas du HTML, uniquement du texte brut.

text

C'est le corps descriptif du partage, en général on y place un résumé ou un message personnalisé. Dans le cas d'un partage via SMS ou WhatsApp, c'est ce contenu qui remplira le champ de saisie.

url

Une chaîne de caractères représentant une URL valide (absolue ou relative). Le navigateur résout automatiquement les URL relatives par rapport à l'URL de la page courante avant de les envoyer au système.

files

C'est l'ajout le plus complexe. : un tableau d'objets File (généralement créés via un constructeur new File() ou récupérés depuis un <input type="file">). Avant de partager des fichiers, il est impératif d'utiliser la méthode navigator.canShare({ files: mesFichiers }), elle va renvoyer un booléen indiquant si le système accepte le format et le poids des fichiers. En général on accepte couramment les images, les pdf, audio et vidéo mais pas les exécutables (.exe, .js) qui seront bloqués

Exemple de code (Vanilla JS)

Voici un exemple de code utilisant les promesses.

const shareBtn = document.querySelector('#btn-partage');

// On ne montre le bouton que si l'API est supportée
if (navigator.share) {
  shareBtn.style.display = 'block'; // Ou un équivalent

  shareBtn.addEventListener('click', async () => {
    try {
      await navigator.share({
        title: 'Le titre de l\'article',
        text: 'Une courte description',
        url: window.location.href
      });
      console.log('Contenu partagé avec succès !');
    } catch (err) {
      // L'utilisateur a annulé ou le partage a échoué
      console.log(`Erreur ou annulation : ${err}`);
    }
  });
} else {
  // Optionnel : afficher une autre solution (ex: copier le lien)
  console.log("Web Share API non supportée sur ce navigateur.");
}

Dans les frames

Attention désormais dans les frames (<iframe> en réalité, ce qui est le cas de la démo ci-dessus hébergée par codepen) vous devez autoriser spécifiquement cette API pour des raisons de sécurité avec l'attribut allow="web-share".

Publié par Alsacreations.com