H4 Widget Headers – Incorrect Nesting Fix

Nothing fancy here but I’m documenting it for the benefit of beginners or people who don’t do this at all.

It seems most of the widgets in WordPress automatically give you h4 headers when you add them to the sidebar. That seems to go against the idea of nested and orderly headers that WCAG accessibility wants. Granted, I’m not an expert and reading their documentation seems more painful than it should be. I do know that the SiteImprove checker flags it on the site I’m working on so I turned to javascript for a fix.

What I need to do is take the HTML below and remove the H4 element and replace it with a div. I add a class so it’s easier for me to repeat the style that the H4 element had.

<div id="tag_cloud-2" class="widget widget_tag_cloud">
    <h4 class="widgettitle">Tags</h4>
    <div class="tagcloud">
<!--bunch of stuff removed for simplicity's sake-->
    </div>

As is typical for me, I did it on one element first and then I move to see if I can make a more generalizable function.

if (document.getElementById("tag_cloud-2")) {
   let tags = document.getElementById("tag_cloud-2");//gets the existing widget chunk
   let div = document.createElement("div");//makes the new div
   div.innerHTML = "Tags";//sets the inner HTML of the div to tags
   div.classList.add("widgettitle");//adds the class
   tags.replaceChild(div, tags.querySelector('h4'));//gets the first h4 element of the widget div and replaces it with the div we just made
 }

Now I need to repeat this for the other 3 or 4 widgets. I could just copy it over and replace it but I’m really only dealing with two variables so making a decent function makes sense. I need to select the specific ID of the widget and I need specific replacement text. That leads to a function like this.

function replaceWidgetTitles(id,text){
  if (document.getElementById(id)) {
    let widget = document.getElementById(id);
    let newTitle = document.createElement("div");
    newTitle.innerHTML = text;
    newTitle.classList.add("widgettitle");
    widget.replaceChild(newTitle, widget.querySelector('h4'));
  }
}


replaceWidgetTitles('tag_cloud-2','Tags')
replaceWidgetTitles('recent-posts-2','Recent Posts')
replaceWidgetTitles('wpp-2','Popular Posts')
replaceWidgetTitles('archives_calendar-2','Archives')

See the Pen
replace tags h4 with div
by Tom (@twwoodward)
on CodePen.