Customizing the new MDN redesign

Customizing the new MDN redesign

Adding custom CSS and JS to make the new design work for you

Mayank's photo
·Mar 3, 2022·

3 min read

The redesign for MDN web docs went live yesterday. But what's a redesign if not polarizing? Just look at the comments on their twitter and github.


Personally, I mostly like it, even if only for the inclusion of dark mode. From my initial experience, I've found only two things that I would change:

  • Currently, the dark mode uses hsl(250deg 13% 9%) as the background color, which creates a bit too much contrast.
  • The new browser compatibility section doesn't present enough information at first glance.

And I'm not the only one who finds both of those things problematic. There have already been github issues created: mdn/yari#5378 and mdn/yari#5366.



So while these issues will probably get fixed, we don't need to wait. With the help of browser extensions, we can take matters into our own hands. I'm going to show you what I did, but you can easily extend this approach to do all kinds of fancy stuff.

CSS: Changing the background color

I already use the Stylus extension to inject userstyles into many websites, so this one was extremely simple.

All I needed to do is slightly change the value of the --background-primary CSS variable.

:root {
  --background-primary: hsl(250deg 15% 20%);

Like every other frontend developer, I love, so I thought "why not just include a link to caniuse in the MDN page?"

So I wrote a userscript that I am injecting into MDN pages using Tampermonkey. I will include the code below, but all it does is:

  1. search the MDN page title on
  2. get the url to the top search result
  3. visit the url and parse the browser compatibility percentage
  4. on the MDN page, add an anchor element that links to the above url and displays the percentage

Here's what the result looks like:


And here's the code (feel free to modify it as you see fit):

// ==UserScript==
// @name         Add caniuse link to MDN docs
// @namespace
// @version      0.1
// @description  searches the feature name on caniuse and adds the % and link to the BC section
// @author       You
// @match*
// @icon
// @grant        GM_xmlhttpRequest
// @grant        window.onurlchange
// @connect
// ==/UserScript==

(async function () {
  'use strict';

  async function addCaniuseLink() {
    const browserCompatHeading = document.querySelector('#browser_compatibility');
    if (!browserCompatHeading) return;

    const featureName = window.location.pathname.split('/').at(-1);
    const searchUrl = `${encodeURIComponent(featureName)}`;

    const caniuseUrl = await new Promise((resolve, reject) => {
        url: searchUrl,
        method: 'GET',
        onload: ({ response, status, responseType }) => {
          if (status !== 200) reject('oopsie');

    const compatPercent = await new Promise((resolve, reject) => {
        url: caniuseUrl,
        method: 'GET',
        onload: ({ response, status, responseType }) => {
          if (status !== 200) reject('oopsie');
          const dom = (new DOMParser()).parseFromString(response, 'text/html');

    const caniuseElement = `
        style='font-size: 1.5rem; font-weight: 300; line-height: 1.5; position: absolute; inset-inline-end: 0; display: inline-flex; align-items: baseline; color: var(--text-secondary);'
        <span style='font-size: 0.8rem; margin-inline-end: 0.25rem;'>caniuse</span>
    `; = 'relative';
    browserCompatHeading.insertAdjacentHTML('beforeend', caniuseElement);

  await addCaniuseLink();
  window.addEventListener('urlchange', addCaniuseLink);


And there you have it. Hopefully goes without saying but this approach of modifying websites on your end is very fragile. Your code will probably break in the future, especially if the site gets updated regularly. But I choose to do it anyway just because it's fun. 😅