How to display Markdown content in a popup dialog in a Python script using ipywidgets in a Jupyter Notebook

I’ve created a dashboard using Python v3.6.8, Pandas v0.25.3, and ipywidgets v7.16.3. I wrote a user guide for my dashboard using Markdown. I then created a button widget labeled “Help”. When a user presses the button a popup modal appears, with the contents of my user guide. However, there are several problems I am trying to fix:

  1. The popup modal is transparent, such that you can see all of the underlying text in my Jupyter notebook, thereby making the user guide, for the most part, unreadable. In my code the alpha value for the background color is 1, but the popup remains transparent regardless of what I set that value to.

  2. There is a scroll bar in the modal popup, but it is inaccessible and unresponsive by my mouse. Not everything is inaccessible, though. The modal popup contains a Close button which I can press and does close the popup, and my user guide does contain hyperlinks that I can successfully click on, too.

  3. When I place the mouse anywhere within the boundaries of my popup and use the mouse wheel to scroll up and down, it scrolls the underlying Jupyter Notebook up and down, not the contents of my user guide. Through trial and error, I found that if I put my mouse on the far left side of the popup, then the focus is the popup, and scrolling then works as expected, but it is a very narrow slice of the popup real estate.

  4. Bullets in markdown, show up as asterisks in my modal popup, not bullets.

  5. Images do not appear in the user guide. All of my images are in jpg format, and are in a folder called “images”. The file help_guide.md resides in the same directory as my Jupyter notebook, and images is a subfolder in that directory. In my markdown editor, the images are rendered correctly, as are the bullets in item 4.

This is what the popup modal looks like with the above-stated anomalies:

Here is my complete, self-contained code:

import pandas as pd
import markdown

from ipywidgets import widgets, Dropdown
from ipywidgets import interactive, Layout
from IPython.core.display import display, HTML, Javascript

# Create a button widget
button = widgets.Button(description="Help", layout={"width": "100px", "margin": "0 0 0 20px "})

# Define a function to display the help page in a pop-up frame
def display_help(button):
    with open("help_guide.md", "r") as f:
        help_markdown = f.read()

        # Convert Markdown to HTML with table of contents
        help_html = markdown.markdown(help_markdown, extensions=['extra', 'toc'])

        # Create HTML content for the modal
        modal_content = f"""
        <div id="helpModal" style="position: fixed; z-index: 1; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(255, 255, 255, 0); display: none;">
            <div style="position: relative; margin: 10% auto; padding: 20px; width: 70%; background-color: #fff; border-radius: 10px; box-shadow: 0 4px 8px 0 rgba(0,0,0,0);">
                <h2>Help</h2>
                <div style="text-align: left; overflow-y: scroll; max-height: 400px;">
                    {help_html}
                </div>
                <button onclick="closeModal()" style="background-color: #4CAF50; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer;">Close</button>
            </div>
        </div>
        <script>
            function openModal() {{
                document.getElementById('helpModal').style.display = 'block';
            }}
            function closeModal() {{
                document.getElementById('helpModal').style.display = 'none';
            }}
            openModal();
        </script>
        """

        # Display the HTML content
        display(HTML(modal_content))

# Bind the button click event to the display_help() function
button.on_click(display_help)

# Display the button widget
display(button)

And finally, here is a small sample of my help_guide.md file:

# Operational Metrics Dashboard
The Operational Metrics Dashboard is your all-in-one tool for analyzing key performance metrics.

# Table of Contents
[About](#about)  
[Staying Connected](#staying-connected)  
[Widgets](#widgets)  
* [Basis for All Visuals](#basis-for-all-visuals)
* [Trailing 12-Months](#trailing-12-months)
* [Date Range](#date-range)
* [Model](#model)
* [Client](#client)
* [Metrics](#metrics)
* [Kolmogorov-Smirnov Diagnostics](#kolmogorov-smirnov-ks-diagnostics)
* [Checkbox Group](#checkbox-group)
<br><br>

# About
This dashboard corresponds to version 2.0, reflecting the current production model.

# Staying Connected
Stay connected to the dashboard via the VPN.  Should you become disconnected simply reconnect to the VPN.

# Widgets
## Basis for All Visuals
Tailor the context of the visuals from two different perspectives:
* **List Date:**  Observe not only what has been listed and recovered as a direct result of those listings.  
* **Close Date:**  Whenever we discuss revenue generated, it is from the perspective of the Close Date.  

## Trailing 12-Months
Selecting this checkbox:
* Adjusts the [Date Range](#date-range) and greys them out.
* Displays an interactive line chart with Client-specific trendlines.

## Date Range
Set a custom timeframe for visuals using the Date Pickers, Start Date and End Date.

![Alt text](images/datepicker.jpg)

## Model
Select 2.0 or 1.0. The [Date Range](#date-range) defaults accordingly. 

## Client
The visuals can be holistic or specific to individual Clients based on account listings or closings within the timeframe specified in the [Date Range](#date-range).

The checkboxes in the rectangular frame are only active under the following conditions:
* 'All Clients' is selected.
* The 'Actual' radio button is chosen in [Metrics](#metrics).

## Metrics
Forecasted metrics are only active under the following conditions:
* 'All Clients' is selected in the [Client dropdown](#client).\n\
* 2.0 is selected in the [Model dropdown](#model).\n\
* 'List Date' radio button is selected in the [Basis for All Visuals](#basis-for-all-visuals).

## Kolmogorov-Smirnov (KS) Diagnostics
KS statistics measure the discriminatory power of a model.

## Checkbox Group
When you select "All Clients" from the [Client dropdown](#client), the 13 analytic checkboxes within the rectagular frame become active.

I just want my popup modal to:

  • be opaque
  • allow me to scroll using the scroll bars or the mouse wheel anywhere within the boundaries of the popup
  • And have the bullets and images appear correctly.

So, those are my questions to all you Python/Jupyter Notebook experts: what do I need to do to accomplish these things? Even if you do not know the answers to all of my questions, ANY answers/suggestions will be greatly appreciated!