Vous voulez changer les polices et la mise en forme d’un site SharePoint Online moderne ? Les master pages ne s’appliquent plus. Voici une méthode fiable et supportée pour injecter une feuille CSS via une extension SPFx, avec étapes, code et bonnes pratiques.
Vue d’ensemble du problème
- Objectif : appliquer un fichier
customcss.css
pour ajuster polices et mise en forme d’un site SharePoint Online. - Méthode initiale : copie de
Seattle.master
, création d’uneCustom.master
dans SharePoint Designer 2013, ajout d’un lien vers la CSS, puis définition de cette master page par défaut. - Symptôme : aucune modification visible sur le site moderne ; la balise
<link rel="stylesheet">
vers la CSS n’apparaît pas dans le code source.
Pourquoi cela ne fonctionne pas sur les sites modernes
SharePoint Online « modern » (sites de communication et sites d’équipe modernes) n’utilise plus de master pages classiques ni l’option « Alternate CSS URL ». Toute personnalisation déposée dans une master page, ou toute CSS « globale » posée via les mécanismes historiques, n’est appliquée qu’aux pages classiques. Par design, Microsoft a limité l’injection de CSS/JS aux solutions SharePoint Framework (SPFx) et aux thèmes officiels (palette, quelques polices, composants Fluent). Résultat : si vous modifiez une master page, les pages modernes l’ignorent.
Solution supportée : une extension SPFx qui injecte votre CSS
La voie recommandée consiste à déployer une extension SPFx de type Application Customizer. Cette extension insère une balise <link>
vers votre customcss.css
dans l’en-tête du document pour toutes les pages modernes ciblées.
Deux stratégies de stockage de la CSS
- Bibliothèque SharePoint (Style Library ou bibliothèque dédiée) : vous hébergez
customcss.css
dans votre site. Avantage : vous pouvez modifier la CSS sans reconditionner l’app tant que l’URL reste la même. Inconvénient : pensez au cache et aux droits d’accès. - Actifs packagés dans la solution SPFx (
includeClientSideAssets
) : la CSS est servie par le CDN M365 dédié. Avantage : distribution performante et contrôlée. Inconvénient : toute modification nécessite de recompiler et republier le package.
Chemin rapide avec un exemple prêt à l’emploi
De nombreux exemples SPFx existent, notamment « react-application-injectcss ». Le principe : cloner, ajuster l’URL de la CSS, packager, déployer. Si vous préférez créer de zéro, suivez les étapes ci‑dessous.
Créer l’extension SPFx de zéro
Prérequis locaux
- NodeJS LTS compatible SPFx (ex. 16.x/18.x suivant la version SPFx utilisée).
- Yeoman, Gulp et générateur SPFx installés.
npm i -g yo gulp @microsoft/generator-sharepoint
Générer le squelette du projet
yo @microsoft/sharepoint
# Répondez :
# ? What is your solution name? inject-css
# ? Which baseline packages... SharePoint Online only (latest)
# ? Where do you want to place...? Use the current folder
# ? Do you want to allow tenant... Yes
# ? Which type of client-side component to create? Extension
# ? Which extension type? Application Customizer
# ? What's your Application Customizer name? InjectCss
# ? What's your Application Customizer description? Injects a custom stylesheet
Implémenter l’injection de la balise <link>
Dans src/extensions/injectCss/InjectCssApplicationCustomizer.ts
, ajoutez un code minimal et robuste :
import { override } from '@microsoft/decorators';
import { Log } from '@microsoft/sp-core-library';
import { BaseApplicationCustomizer } from '@microsoft/sp-application-base';
export interface IInjectCssApplicationCustomizerProperties {
cssUrl?: string;
}
const LOG_SOURCE: string = 'InjectCssApplicationCustomizer';
export default class InjectCssApplicationCustomizer
extends BaseApplicationCustomizer {
@override
public onInit(): Promise {
Log.info(LOG_SOURCE, 'Initialized InjectCssApplicationCustomizer');
```
// 1) URL depuis les propriétés (serve.json / éléments in-app)
const urlFromProps = this.properties.cssUrl && this.properties.cssUrl.trim();
// 2) Fallback : mettez ici un chemin par défaut si nécessaire
const fallbackUrl = '/sites/branding/Style Library/customcss.css';
const finalUrl = urlFromProps || fallbackUrl;
if (finalUrl) {
// Éviter les doublons
const id = 'spfx-injectcss-link';
if (!document.getElementById(id)) {
const link = document.createElement('link');
link.id = id;
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = finalUrl;
link.media = 'all';
document.head.appendChild(link);
}
} else {
Log.warn(LOG_SOURCE, 'Aucune URL de CSS fournie.');
}
return Promise.resolve();
```
}
}
Configurer l’URL de la CSS en mode debug (facultatif mais pratique)
Dans config/serve.json
(mode local debug), fournissez la propriété cssUrl
:
{
"$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
"port": 4321,
"https": true,
"serveConfigurations": {
"default": {
"pageUrl": "https://contoso.sharepoint.com/sites/comms",
"customActions": {
"00000000-0000-0000-0000-000000000001": {
"location": "ClientSideExtension.ApplicationCustomizer",
"properties": {
"cssUrl": "/sites/comms/Style Library/customcss.css?v=2025.10.01"
}
}
}
}
}
}
Vous pouvez lancer gulp serve
et ajouter les paramètres debugManifestsFile à l’URL pour tester sans packager. Pour la production, passez à l’étape suivante.
Compiler et packager
npm install
gulp bundle --ship
gulp package-solution --ship
# Le package .sppkg est généré dans sharepoint/solution
Déployer le package au catalogue d’applications
- Catalogue d’applications : utilisez le catalogue locataire (
/sites/apps/AppCatalog
) ou créez un Site Collection App Catalog pour limiter la portée. - Téléversez le
.sppkg
et validez la demande de déploiement (« Make this solution available to all sites in the organization » si souhaité). - Dans votre site cible, accédez à « Contenu du site » > « Applications pour SharePoint » et ajoutez l’application.
Option : automatiser avec PnP.PowerShell
# Connexion
Connect-PnPOnline -Url "https://contoso-admin.sharepoint.com" -Interactive
# (Facultatif) Créer un App Catalog de collection de sites
Add-PnPSiteCollectionAppCatalog -Site "[https://contoso.sharepoint.com/sites/comms](https://contoso.sharepoint.com/sites/comms)"
# Déployer l'application au niveau locataire
Add-PnPApp -Path "sharepoint/solution/inject-css.sppkg" -Publish
# Installer l'app sur un site précis
Install-PnPApp -Identity (Get-PnPApp | Where-Object {$_.Title -eq "InjectCss"}).Id `
-Scope Site -Site "[https://contoso.sharepoint.com/sites/comms](https://contoso.sharepoint.com/sites/comms)"
Héberger et versionner la feuille customcss.css
Cas A : fichier dans une bibliothèque SharePoint
Chargez customcss.css
dans une bibliothèque accessible à tous les visiteurs du site (lecture). Référencez l’URL dans l’extension (cssUrl
). Pour forcer le rafraîchissement côté client, ajoutez un paramètre de version :
<!-- URL configurée dans l'extension -->
/sites/comms/Style Library/customcss.css?v=2025.10.01
Avantage : vous pouvez mettre à jour la CSS directement depuis SharePoint (interface web, VS Code + extension SP Go, ou SharePoint Designer si Custom Script est autorisé). Aucune recompilation de la solution si l’URL ne change pas.
Cas B : fichier empaqueté comme actif client
Placez la CSS dans /assets
et activez includeClientSideAssets
dans config/package-solution.json
. L’URL déployée sera générée automatiquement. Ce modèle favorise les performances et la gouvernance, mais toute évolution de la CSS requiert un nouveau package.
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
"solution": {
"name": "inject-css",
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"version": "1.0.0.0",
"includeClientSideAssets": true,
"isDomainIsolated": false
},
"paths": {
"zippedPackage": "solution/inject-css.sppkg"
}
}
Mettre à jour la CSS sans republier l’app
- Si vous êtes en Cas A (bibliothèque) : éditez
customcss.css
depuis l’interface web, VS Code ou SharePoint Designer, puis enregistrez. Videz le cache navigateur ou testez en navigation privée. Ajoutez un suffixe de version dans l’URL (?v=YYYYMMDD
) si nécessaire. - Vérifiez dans les DevTools : onglets Network/Sources que l’horodatage et le contenu correspondent bien à la dernière révision.
- Si l’URL ou l’emplacement change, modifiez la propriété
cssUrl
dans l’extension, recompilez et redéployez le.sppkg
.
Exemple de CSS minimaliste et durable
Privilégiez des sélecteurs stables et évitez de cibler des classes internes susceptibles d’évoluer. Préférez des zones layout ou des attributs ARIA, et limitez-vous aux couleurs/typos tant que possible.
/* Charger une police d'entreprise (vérifiez la licence) */
@font-face {
font-family: "AcmeCorp Sans";
src: url("/sites/comms/Style Library/fonts/AcmeCorpSans.woff2") format("woff2");
font-display: swap;
}
/* Typo par défaut du site */
:root {
--brand-font: "AcmeCorp Sans", system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif;
}
html, body {
font-family: var(--brand-font);
}
/* Titres de page */
[data-automation-id="pageHeader"] h1 {
letter-spacing: .2px;
font-weight: 600;
}
/* Lien d'action primaire (exemple) */
a[data-interception="propagate"] {
text-underline-offset: 2px;
}
Bonnes pratiques et points d’attention
Sujet | Recommandation |
---|---|
Activation SharePoint Designer | Si vous devez éditer des fichiers via SPD, vérifiez /_layouts/15/SharePointDesignerSettings.aspx . La « Custom Script » peut être requise et se gère côté centre d’administration ou via PowerShell. |
Publishing Infrastructure | Inutile pour les sites modernes ; son activation peut même échouer depuis un site de communication. Évitez si vous n’avez pas de pages classiques. |
Mise en cache | Très agressive côté client et sur le CDN. Testez en fenêtre privée, forcez Ctrl+F5 et utilisez un paramètre de version dans l’URL de la CSS. |
Accessibilité & support | Une CSS intrusive peut casser le responsive et l’intégration dans Teams. Évitez de masquer des contrôles natifs et vérifiez les contrastes. Privilégiez les thèmes modernes quand c’est possible. |
Alternative sans code | Appliquez un thème moderne (Branding) ou créez un thème via le « Theme Designer ». Moins granulaire qu’une CSS, mais pleinement supporté. |
Gouvernance | Conservez la CSS dans un dépôt versionné, nommez-la avec un suffixe de version, documentez les règles, testez en préproduction et validez le rendu avec au moins deux navigateurs. |
Sécurité | Hébergez la CSS sur SharePoint ou un CDN approuvé. Évitez les polices externes non maîtrisées. Respectez les licences de typographies. |
Performance | Minifiez la CSS, regroupez les règles, limitez les sélecteurs coûteux (:not() multiples, sélecteurs universels) et évitez les images lourdes en background . |
Portée | Si la CSS ne doit affecter qu’un hub ou un sous-site, installez l’app SPFx à ce périmètre plutôt qu’au tenant complet. |
Vérifier que l’extension est bien chargée
- Ouvrez une page du site et inspectez le code source (F12).
- Dans l’onglet Elements, recherchez une balise
<link id="spfx-injectcss-link">
. Vérifiez l’URL. - Dans Network, filtrez sur
customcss.css
et contrôlez les en‑têtes (200 OK, taille, date). - Effacez le cache et rechargez (Ctrl+F5) si les modifications tardent à apparaître.
Procédure de rollback
- Désinstaller l’app sur le site (Contenu du site > Applications pour SharePoint > Supprimer). Les pages modernes cessent d’injecter la CSS.
- Ou neutraliser temporairement l’extension en retirant l’URL de
cssUrl
(et republiez si packagé) : sans URL, l’injection est ignorée. - Conservez un commit étiqueté de la dernière version fonctionnelle de la CSS pour un retour arrière rapide.
FAQ rapide
Peut-on encore utiliser « Alternate CSS URL » ou une master page ?
Non pour les pages modernes. Ces options restent visibles/actives uniquement pour des pages classiques.
Peut-on cibler tout le tenant ?
Oui, si vous déployez l’app au catalogue global et cochez la mise à disposition organisationnelle, ou si vous installez l’app sur chaque site à couvrir. Assurez-vous d’avoir la gouvernance nécessaire.
Les thèmes remplacent-ils la CSS ?
Les thèmes appliquent des couleurs et des styles cohérents, mais ne couvrent pas les besoins fins (typographies propriétaires, micro‑espacements, composants spécifiques). D’où l’usage d’une CSS avec SPFx.
Pourquoi mes changements ne s’affichent-ils pas immédiatement ?
À cause du cache (navigateur et CDN). Ajoutez un paramètre de version à l’URL, utilisez une fenêtre privée et vérifiez le statut de chargement dans Network.
Checklist de déploiement
- ✔️ L’App Catalog existe (locataire ou site collection).
- ✔️ L’extension Application Customizer est packagée sans erreur (
gulp package-solution --ship
). - ✔️ La CSS est accessible en lecture par tous les utilisateurs visés.
- ✔️ Un paramètre de version est prévu pour le cache busting.
- ✔️ Les tests d’accessibilité de base (contraste, focus, zoom) sont passés.
- ✔️ Une procédure de rollback est documentée.
Exemple de mise à jour de la CSS (Cas A : bibliothèque)
- Ouvrir
customcss.css
dans l’interface SharePoint et éditer. - Enregistrer et publier major/minor si la bibliothèque est versionnée.
- Augmenter le paramètre de version de l’URL (par ex.
?v=2025.10.02
) si nécessaire. - Vider le cache et contrôler le chargement dans les DevTools.
Résultat obtenu pour le demandeur
Après déploiement de l’extension SPFx, la balise <link>
vers customcss.css
est injectée correctement et la CSS est rendue sur les pages modernes. Le problème résiduel provenait majoritairement du cache. Une fois le cache vidé (ou en ajoutant un paramètre de version), les nouvelles polices et styles sont apparus immédiatement sur le site.
Modèle d’architecture recommandé
- Solution SPFx compacte (Application Customizer) avec propriétés
cssUrl
. - Bibliothèque « Branding » dédiée par site ou par hub :
/Branding/Style Library/
(droits lecture pour Tout le monde sauf externes). - Convention de versionnement :
customcss.css?v=AAAAMMJJ.hhmm
. - Pipeline (facultatif) : validation PR > build > upload via PnP.PowerShell > installation sur cibles.
Bonnes pratiques de sélecteurs (exemples)
- Préférez des attributs et des régions stables :
[data-automation-id="pageHeader"]
, zones de contenu, web parts ciblées viadata-sp-
personnalisé si vous contrôlez le composant. - Évitez de cibler des classes internes non publiques qui pourraient changer sans préavis.
- Conservez une CSS courte, thématique et modulaire (ex. fichiers
_typography.css
,_buttons.css
puiscustomcss.css
qui agrège).
Dépannage avancé
- La balise <link> n’apparaît pas : l’app est‑elle installée sur ce site ? L’extension est‑elle bien de type Application Customizer ? L’ID de l’extension existe‑t‑il dans le manifest ?
- Erreur 404 sur la CSS : vérifiez le chemin, la casse des noms, les espaces encodés, et les permissions de la bibliothèque.
- Polices non chargées : contrôlez le type MIME (
woff2
), le chemin, la directivefont-display: swap
et les droits d’accès. - Rendu cassé dans Teams : réduisez la portée des règles, testez dans l’application Teams et dans le navigateur, vérifiez les iframes et l’héritage CSS.
Conclusion
Pour personnaliser un site moderne SharePoint Online sans sortir des bonnes pratiques supportées, SPFx Application Customizer est la solution de référence. Évitez les master pages et l’« Alternate CSS URL », traitez le cache avec méthode, et isolez une CSS sobre, performante et accessible. Avec ce modèle, la maintenance se résume souvent à éditer un fichier et à gérer proprement le cache busting.