Mettre en forme un flux RSS avec CSS : ce qui marche encore dans Chrome

Une feuille CSS liée à un flux continue de fonctionner dans Chrome après la suppression de XSLT, à condition que le serveur envoie le flux en application/xml ou text/xml. Envoyé en application/rss+xml, le même flux s'affiche en texte brut et le CSS est ignoré. Nous l'avons vérifié dans Chromium 156 et sur un site WordPress de test. La mise en place tient en trois étapes.

Peut-on encore mettre en forme un flux RSS avec CSS sans XSLT ?

Oui, si le serveur envoie le flux avec le bon type de contenu. L’annonce de Chrome sur XSLT précise que l’instruction de traitement <?xml-stylesheet ... ?> reste prise en charge avec du CSS, via type="text/css". Seul XSLT disparaît, dans Chrome 158, le 17 novembre 2026.

Cela concerne les éditeurs dont le flux utilise aujourd’hui une feuille XSL. Chrome note que beaucoup de flux RSS et Atom s’en servent pour être lisibles quand on les ouvre dans le navigateur. À partir du 17 novembre, ces flux perdent leur mise en page dans Chrome. Une feuille CSS est la solution de remplacement la plus légère : elle ne transforme rien et décrit seulement l’apparence de chaque élément.

La condition sur le type de contenu tient à la façon dont Chrome traite les types de flux. Un flux envoyé en application/rss+xml ou application/atom+xml s’ouvre en texte brut dans Chrome, et dans ce cas aucune feuille de style ne s’applique, ni CSS ni XSL. Notre guide sur les flux RSS affichés en texte brut détaille ce comportement et ce que les lecteurs peuvent faire.

Pour mettre en forme un flux RSS avec CSS, il faut donc deux choses : la ligne de feuille de style dans le flux, et un serveur qui envoie ce flux en application/xml ou text/xml. Si votre flux mis en forme par XSL s’affiche aujourd’hui dans Chrome, votre serveur envoie déjà l’un de ces types : seule la ligne de feuille de style doit changer.

Avec quel type de contenu Chrome applique-t-il le CSS d’un flux ?

En application/xml ou en text/xml. Le 14 octobre 2026, nous avons ouvert dans Chromium 156 un petit flux Atom et un petit flux RSS servis par un serveur local. Chacun commençait par cette ligne, juste après la déclaration XML :

<?xml-stylesheet type="text/css" href="/feed.css"?>

La feuille de test affichait chaque élément title en rouge, en 28 pixels, et masquait les autres éléments, afin que l’on puisse vérifier le résultat dans le style calculé de l’élément, que les DevTools (outils de développement de Chrome) affichent dans l’onglet Computed (Calculé). Chaque cas a été testé deux fois : fonction XSLT de Chromium activée, puis désactivée, comme elle le sera dans Chrome 158. Les résultats étaient identiques.

Flux Type envoyé par le serveur Ce qu’a affiché Chromium
Atom application/xml CSS appliqué : titres en rouge
Atom text/xml CSS appliqué
RSS application/xml CSS appliqué
RSS text/xml CSS appliqué
Atom application/atom+xml Texte brut du flux, CSS ignoré
RSS application/rss+xml Texte brut du flux, CSS ignoré

Dans les cas en texte brut, la page montrait la source du flux telle qu’envoyée, en police à chasse fixe, ligne de feuille de style comprise. Dans les cas mis en forme, Chrome n’affichait aucun message au-dessus du contenu. Les éléments masqués, comme id et updated, n’étaient plus visibles mais restaient présents dans le document.

Sans ligne de feuille de style, le même flux RSS envoyé en application/xml s’est affiché dans la vue en arbre de Chrome, sous le message « no style information » (aucune information de style), que notre guide pour ouvrir un fichier XML dans Chrome explique. Un flux lié à une feuille XSL affiche un autre message une fois XSLT désactivé : « This document cannot be formatted as intended » (ce document ne peut pas être mis en forme comme prévu).

Comment lier une feuille CSS à un flux ?

En trois étapes.

1. Ajoutez l’instruction de traitement. La recommandation du W3C « Associating Style Sheets with XML documents » la définit. Cette instruction doit se trouver dans le prologue, c’est-à-dire juste après <?xml version="1.0"?> et avant l’élément racine, <rss> ou <feed>. Le pseudo-attribut href est obligatoire. Les autres sont facultatifs : type, title, media, charset et alternate. Un flux RSS minimal avec sa ligne de feuille de style ressemble à ceci :

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/feed.css"?>
<rss version="2.0">
  <channel>
    <title>Exemple de blog</title>
    <link>https://example.com/</link>
    <description>Derniers articles</description>
    <item>
      <title>Premier article</title>
      <link>https://example.com/premier/</link>
    </item>
  </channel>
</rss>

2. Écrivez le CSS. D’après MDN, la valeur initiale de display est inline. Un flux n’a aucun style HTML par défaut : sans vos propres règles, tous les éléments s’enchaînent sur une seule ligne. Commencez par transformer les conteneurs en blocs :

rss, channel, item, feed, entry { display: block; }
title { display: block; font-size: 1.4em; margin: 1em 0 0.3em; }
link, guid, id, updated, pubDate { display: none; }

Nous avons aussi testé cette feuille : sur un flux RSS, les titres ont pris 1,4 fois la taille de base et les liens ont été masqués. En RSS, le canal et chaque article ont chacun leur propre élément title. Pour les mettre en forme différemment, utilisez channel > title et item > title, ou feed > title et entry > title en Atom. Un simple sélecteur title s’applique aussi aux titres d’un flux Atom, dont les éléments appartiennent à l’espace de noms Atom : d’après la spécification Selectors du W3C, un sélecteur de type vise les éléments de tout espace de noms quand la feuille CSS ne déclare aucun espace de noms par défaut avec @namespace.

3. Envoyez le bon type de contenu. La liste des types MIME courants de MDN recommande application/xml pour le XML et note que text/xml est encore utilisé parfois : préférez donc application/xml. Le service de validation de flux du W3C signalera que ce type n’est pas assez précis pour que tout programme reconnaisse un flux ; quand le type ne peut pas être plus précis, il demande <rss ou <feed dans les 512 premiers octets, ce que respecte un flux qui commence par les deux lignes ci-dessus.

Sous WordPress, deux hooks suffisent. La fonction feed_content_type() renvoie application/rss+xml pour RSS et application/atom+xml pour Atom, sauf si un filtre change cette valeur, et l’action rss_tag_pre se déclenche entre la déclaration XML et l’élément racine. Ce code, enregistré dans un fichier PHP du dossier wp-content/mu-plugins/, celui des extensions « must-use », a fonctionné sur un site de test sous WordPress 7.1.3 :

<?php
// Envoie les flux RSS et Atom en application/xml, pour que Chrome applique la feuille CSS.
add_filter( 'feed_content_type', function ( $content_type, $type ) {
	return in_array( $type, array( 'rss2', 'atom' ), true ) ? 'application/xml' : $content_type;
}, 10, 2 );

// Écrit la ligne de feuille de style entre la déclaration XML et l'élément racine.
add_action( 'rss_tag_pre', function () {
	echo '<?xml-stylesheet type="text/css" href="/feed.css"?>' . "\n";
} );

Sous nginx, pour un fichier de flux statique, videz la table des types pour cette adresse et fixez un type par défaut, comme dans l’exemple de la documentation de la directive types :

location = /feed.xml {
    types        { }
    default_type application/xml;
}

Dans notre test avec nginx 1.27, ce bloc a envoyé /feed.xml en application/xml, tandis que les autres fichiers .xml gardaient le type par défaut de nginx, text/xml.

Pour savoir ce qu’envoie votre serveur, affichez le flux dans Chrome, ouvrez les DevTools, rechargez la page et sélectionnez la requête du flux dans le panneau Network (Réseau). Dans l’onglet Headers (En-têtes), content-type figure sous Response Headers (en-têtes de réponse). Dans un terminal, curl -s -o /dev/null -D - https://example.com/feed/ affiche les mêmes en-têtes de réponse.

Les flux de podcasts suivent les mêmes règles : ce sont des fichiers RSS, donc le type de contenu décide si Chrome applique le CSS ou affiche le texte brut.

Gardez tel quel le lien d’autodécouverte de vos pages HTML. Le RSS Advisory Board demande type="application/rss+xml" dans cet élément link. Cet attribut se trouve dans votre page HTML, alors que l’en-tête Content-Type du flux est fixé à part, par le serveur.

Que ne peut pas faire le CSS dans un flux RSS ?

Le CSS change l’apparence des éléments existants, pas leur nature. Trois limites en découlent.

L’élément link d’un article reste du texte. Le CSS ne le transforme pas en lien : impossible de cliquer dessus pour ouvrir l’article.

Le HTML placé dans une description reste lui aussi du texte. Dans notre test, le HTML échappé et celui placé dans une section CDATA ont tous deux affiché leurs balises telles quelles, par exemple <p> et <b>. Masquez la description, ou gardez-la en texte simple.

Le CSS ne peut ni réécrire les données ni trier les articles : une date garde le format du flux, et l’ordre reste celui du fichier.

Pour obtenir une vraie page avec des liens cliquables, il faut du HTML : vous pouvez garder une feuille XSL plutôt que du CSS. Pour les flux qui conservent leur XSL, l’annonce de Chrome suggère d’ajouter une ligne qui charge le script xslt-polyfill ; d’après Chrome, cela ne devrait pas empêcher les lecteurs de flux d’analyser le XML. Le polyfill n’applique qu’une feuille XSL que le flux désigne, et le type de contenu compte là aussi : dans notre test, XSLT désactivé, un script placé dans le flux s’est exécuté quand celui-ci était envoyé en application/xml, et jamais en application/rss+xml, car Chrome l’affichait alors en texte brut. L’autre voie consiste à produire le HTML vous-même et à le publier à une autre adresse, pour que le flux reste en XML. Nos exemples de XSLT sur le serveur montrent comment.

Pour comparer votre version CSS à la mise en page XSL qu’elle remplace, vous pouvez ouvrir le flux dans un XML viewer qui applique XSL : XMLNest, disponible sur le Chrome Web Store, applique les feuilles XSL (version 1.0) comme Chrome le faisait, et ouvre les flux RSS et Atom dans une vue de lecture.

Sources

  1. Chrome for Developers : Removing XSLT for a more secure browser (vérifiée le 14 octobre 2026)
  2. W3C : Associating Style Sheets with XML documents 1.0 (Second Edition) (vérifiée le 14 octobre 2026)
  3. W3C : Selectors Level 3, sélecteurs de type et espaces de noms (vérifiée le 14 octobre 2026)
  4. MDN : display (vérifiée le 14 octobre 2026)
  5. MDN : Types MIME courants (vérifiée le 14 octobre 2026)
  6. W3C Feed Validation Service : type de média pas assez précis (vérifiée le 14 octobre 2026)
  7. WordPress Developer Resources : feed_content_type() (vérifiée le 14 octobre 2026)
  8. WordPress Developer Resources : rss_tag_pre (vérifiée le 14 octobre 2026)
  9. WordPress Developer Resources : Must Use Plugins (vérifiée le 14 octobre 2026)
  10. Documentation nginx : module ngx_http_core_module, directive types (vérifiée le 14 octobre 2026)
  11. Chrome for Developers : Network features reference (vérifiée le 14 octobre 2026)
  12. RSS Advisory Board : RSS Autodiscovery (vérifiée le 14 octobre 2026)
  13. XSLT Polyfill, README de mfreed7/xslt_polyfill sur GitHub (vérifiée le 14 octobre 2026)
  14. Test fait par XMLNest : Testé par XMLNest dans Chromium 156.0.8078.4 le 14 octobre 2026, fonction XSLT activée puis désactivée : un flux Atom et un flux RSS liés à une feuille CSS par <?xml-stylesheet type="text/css"?> ont été mis en forme quand ils étaient servis en application/xml ou text/xml ; servis en application/atom+xml ou application/rss+xml, ils se sont affichés en texte brut, sans aucune feuille de style. La feuille publiée dans cet article s'est appliquée à un flux RSS ; le HTML d'une description, échappé ou en section CDATA, a affiché ses balises en texte ; le flux RSS sans ligne de feuille de style a affiché l'arbre XML de Chrome ; fonction XSLT désactivée, un flux lié à une feuille XSL a affiché « This document cannot be formatted as intended », et un élément script de l'espace de noms XHTML placé dedans s'est exécuté quand le flux était envoyé en application/xml, pas en application/rss+xml. Sur un site de test sous WordPress 7.1.3, lancé depuis l'image Docker officielle, le code de cet article a envoyé /feed/ et /feed/atom/ en application/xml avec la ligne de feuille de style, et Chromium a appliqué le CSS ; nginx 1.27 a envoyé /feed.xml en application/xml avec le bloc location de cet article, et les autres fichiers .xml en text/xml (vérifiée le 14 octobre 2026)