Preventing flash of extra unwanted spacing before JavaScript finishes loading in a Drupal theme

This is for Drupal 8 or Drupal 9, or Drupal 10 or 11 for that matter, what i call modern Drupal

Unless i get this fixed in core which i will try to do.

Identifying a

By copying the full body HTML using Firefox inspector’s copy outer HTML and pasting it into a text file, once with JavaScript disabled and once with JavaScript enabled, and then comparing the two files with Meld, i could see that the only difference in this section of the page between no-JS and JS was

<div data-contextual-id="block:block=greenhouse_page_title:langcode=en" data-contextual-token="8LFA22KPOWe_3F7lmk2kj-5XkexewTEfMLvIcj2aUa0"></div>
 * Pre-render callback: Renders a contextual links placeholder into #markup.
 * Renders an empty (hence invisible) placeholder div with a data-attribute
 * that contains an identifier ("contextual id"), which allows the JavaScript
 * of the drupal.contextual-links library to dynamically render contextual
 * links.

Where this comment says “empty (hence invisible)” play an extremely loud buzzer sound in your head, or with an actual buzzer if you have one, and shout “WRONG!”

There was one other difference: when JavaScript filled in the empty contextual div with the HTML for the contextual link, it also added the class “contextual” to this div. This class actually does make the contextual div invisible, whether it’s empty or not.

The solution then is simple, to have Drupal core include the “contextual” class on the contextual placeholder from the start, rather than adding the class with JavaScript when the placeholder is replaced.

The code to do this is in core/modules/contextual/src/Element/ContextualLinksPlaceholder.php at line 50.


<div class="site post-header" role="region">
            <div class="site__inner container-fluid">
              <div class="site__row row">

  <div class="region region-post-header">

    <nav role="navigation" id="navigation" class="vhfa-main-menu navigation navigation--primary w-100 navbar-expand-md bg-primary block--post_header contextual-region" aria-label="Main menu">

        <div data-contextual-id="block:block=greenhouse_mainmenu:langcode=en|menu:menu=main:langcode=en" data-contextual-token="kDGahadZM7swfWlomCO5ENES0LbuorYPybSY4qCzULk" class="contextual"></div>

  <ul class="nav navbar-nav menu w-100 nav-fill">

                                      <li class="nav-item  ">
                      <a href="/partners" title="Investors, and Other Community Partners" class="nav-link" data-drupal-link-system-path="node/78">Community</a>




<div class="site post-hero" role="region" aria-label="Post-hero">
            <div class="site__inner container-fluid px-0">
              <div class="site__row row">

  <div class="region region-post-hero">

<section id="block-greenhouse-page-title" class="bg-secondary text-white text-center align-middle p-4 block--post_hero contextual-region block block-core block-page-title-block clearfix">

    <div data-contextual-id="block:block=greenhouse_page_title:langcode=en" data-contextual-token="8LFA22KPOWe_3F7lmk2kj-5XkexewTEfMLvIcj2aUa0"></div>

  <h1 class="js-quickedit-page-title page-header mb-0">Contact VHFA</h1>




In this case i’m able to work around it with this CSS:

.region-post-header {
  // Changing the display to grid prevents a flash of unwanted space (at least      
  // for viewers who can see contextual links.  This is a workaround for a core
  // issue, see raw note "Preventing flash of extra unwanted spacing before
  // JavaScript finishes loading in a Drupal theme"
  display: grid;
  width: 100%;