Heading HTML changes

The HTML markup of headings on wikitext pages will change in 2024 as part of MediaWiki 1.42. A wrapper will be added around each heading, and elements other than text (such as section edit links) will be moved from the heading itself to the wrapper. (T13555)

A first set of changes happened in January 2023 for DiscussionTools: a wrapper has been added for level-2 headings only, on talk pages and on pages in namespaces defined in $wgExtraSignatureNamespaces. The styling rules for those headings have slightly changed in MediaWiki 1.42.0-wmf.9 (December 2023).

What's changing edit

There should be no visual changes for editors and readers. However, maintainers of skins, extensions and gadgets that affect headings will need to update them to avoid issues for their users.

Example old and new HTML source for heading tags
    <span class="mw-headline" id="...">Heading</span>
    <span class="mw-editsection">...</span>
<div class="mw-heading mw-heading2">
    <h2 id="...">Heading</h2>
    <span class="mw-editsection">...</span>

The change does not apply to most special pages, nor to Parsoid edit-mode content, which will continue to use simple <h2>...</h2> markup.

Why this is changing edit

This change will improve accessibility for people using screen readers. It's a common workflow to navigate around a page by the headings present on it, like an automatically generated table of contents. With the old markup, interface elements like section edit links were a part of each heading, causing them to be read out along with every heading's text. The problem was exacerbated by extensions that added further interface elements to headings, such as VisualEditor's "edit source" links and DiscussionTools's "subscribe" buttons.

Opting out edit

If you haven't had a chance to update your skin to style the new markup, a skin option is temporarily available to restore the old markup: TODO. This option will be removed in the future.

When using Parsoid for page views, the new markup is used unconditionally.

Instructions for updating code edit

Skins and sitewide styles edit

Skins that use ResourceLoaderSkinModule configured with "features": { "elements": true } may not need any changes at all, since the built-in heading styles were updated.

Your styles should be compatible with three kinds of markup at the same time: the new markup, the old markup (because it may be cached in parser cache), and the simple markup with no wrappers (used by most special pages and Parsoid edit-mode content).

As a general guideline, for every selector applying to page content (e.g. .mw-body or #mw-content-text) – but not for selectors applying to skin interface (e.g. #mw-navigation) – apply the following changes:

  1. Wherever you used a selector like h1, h2, h3, h4, h5, h6, add .mw-heading.
  2. Wherever you used a selector like hN, add .mw-headingN.
  3. Wherever you used the selector .mw-headline, add h1, h2, h3, h4, h5, h6.
  4. For any styles applied to both hN and .mw-headingN, unset them when the heading is nested in the wrapper, using a selector like .mw-heading hN.

Once you drop compatibility with MediaWiki 1.41, you can remove selectors that were only needed to support the old markup (such as .mw-headline or hN .mw-editsection).

Example changes:

Old CSS Upgraded CSS
h2 {
    border: 1px solid black;
    background-color: red;
    color: white;
    font-size: 2em;
.mw-heading2, h2 {
    border: 1px solid black;
    background-color: red;
    color: white;
    font-size: 2em;
.mw-heading2 h2 {
    border: unset;
    font-size: unset;
    background-color: unset; /* optional, may be skipped */
    color: unset; /* optional, may be skipped */

    all: unset; /* alternative to above, will only work in modern browsers */

Extensions and gadgets edit

There isn't a simple pattern like for styles, but in general you'll need to update your code to work with either of the HTML structures. Sometimes it can be as easy as changing the selectors, similar to the section above.

Example changes:

Template styles edit

After the changes are deployed, you only need to worry about the new markup, because simple markup with no wrappers can't appear on content pages (the wrappers are added even to wikitext using HTML-style <h2> markup, not only when using the wikitext == markup, except if there are attributes e.g. <h2 class="some-class">), and because editing the template style page will purge the parser cache of pages using it.