The Complete Visual Guide to Markdown & HTML Formatting in Data Science Notebooks and READMEs
Extracted from 500+ Kaggle competition notebooks — every pattern that actually works

The Complete Visual Guide to Markdown & HTML Formatting in Data Science Notebooks and READMEs

Every top-performing Kaggle notebook does something that most beginner notebooks don't: it looks like someone cared about it. The cover banner, the colored section headers, the styled callout boxes — these aren't just decoration. They signal that the author thought carefully about communication, not just computation.

But the formatting tricks used in those notebooks work just as well in GitHub READMEs, Jupyter Lab sessions, VS Code notebooks, and HackMD documents. Markdown is Markdown. HTML is HTML.

This guide collects every useful pattern from a scan of 500+ data science notebooks, organized by type, with working code you can copy directly.


1. The Markdown Baseline (Works Everywhere)

Before reaching for HTML, know your Markdown fundamentals. These render identically in Kaggle, GitHub, Jupyter, and VS Code:

Headings create structure AND navigation

# H1 — Title / major chapter

## H2 — Section header

### H3 — Sub-section

#### H4 — Minor heading
        

GitHub auto-generates a table of contents from headings. Kaggle and Jupyter create anchor links you can target with [link](#section-name).

Rule: Never skip a heading level. Going from # to ### without ## breaks visual hierarchy and navigation.

Text formatting

**bold text** <!-- strong emphasis -->
_italic text_ <!-- light emphasis -->
~~strikethrough~~ <!-- deprecated, removed -->
`inline code` <!-- function names, file paths -->

> blockquote <!-- important notes, quotes -->
        

GitHub Flavored Markdown (GFM) tables

| Model    | CV Score   | LB Score   |
| -------- | ---------- | ---------- |
| LightGBM | 0.9797     | 0.9810     |
| XGBoost  | 0.9789     | 0.9801     |
| Ensemble | **0.9814** | **0.9831** |
        

These render in GitHub READMEs, Kaggle, and Jupyter with proper alignment.

Fenced code blocks with syntax highlighting

```python
import lightgbm as lgb
model = lgb.LGBMClassifier(n_estimators=1000, learning_rate=0.05)
```
        

Use the language identifier (python, sql, bash, json, html) for syntax highlighting.


2. HTML in Markdown: What You Can Do

Jupyter-based platforms (Kaggle, Jupyter Lab, VS Code notebooks) render a wide subset of HTML directly in Markdown cells. This unlocks everything from colored text to full-page banner designs.

What works (everywhere except GitHub READMEs)

  • <div>, <span>, <p> with inline style="" attributes
  • CSS gradients, border-radius, box-shadow, grid, flexbox
  • <table> with custom styling
  • <details> / <summary> collapsible blocks
  • <kbd> keyboard key display
  • <a id="anchor"> for internal navigation
  • <img> with external URLs
  • <style> blocks (including @import for Google Fonts)
  • HTML entities (&nbsp;, &mdash;, &copy;, etc.)

What GitHub READMEs strip

GitHub's HTML sanitizer removes style="" attributes and <style> blocks. For GitHub, stick to Markdown tables and ![badge](shields.io URL) images.


3. Cover Banners: The Most Impactful Single Element

The notebook cover is the first thing readers see. A well-designed cover communicates competence before they read a single line of code.

Pattern 1: Dark Gradient (most common in top notebooks)

<div
  style="
    background: linear-gradient(135deg, #0f172a 0%, #1e3a5f 50%, #0f4c75 100%);
    border-left: 6px solid #14B8A6;
    border-radius: 16px;
    padding: 44px 48px;
    box-shadow: 0 10px 30px rgba(0,0,0,0.5);
    color: #f9fafb;
    font-family: 'Segoe UI', sans-serif;
"
>
  <h1 style="font-size:36px; font-weight:800; margin:0 0 12px 0;">
    🏆 Your Notebook Title
  </h1>
  <p style="color:#94a3b8; font-size:15px; margin:0 0 20px 0;">
    Competition or project description
  </p>
  <div
    style="display:flex; gap:16px; flex-wrap:wrap; font-size:13px; color:#94a3b8;"
  >
    <span>👤 <strong style="color:#f9fafb;">Author</strong></span>
    <span>📅 <strong style="color:#f9fafb;">2026</strong></span>
    <span>🏅 <strong style="color:#f9fafb;">Metric</strong></span>
  </div>
</div>
        

Pattern 2: Photo Background with Dark Overlay

<div
  style="
    background-image:
        linear-gradient(rgba(0,0,0,0.55), rgba(0,0,0,0.70)),
        url('https://images.unsplash.com/photo-XXXX?w=1200&auto=format&fit=crop');
    background-position: center;
    background-size: cover;
    padding: 60px 20px;
    border-radius: 18px;
    text-align: center;
"
>
  <h1
    style="color:white; font-size:36px; text-shadow:2px 2px 8px rgba(0,0,0,0.8);"
  >
    Notebook Title
  </h1>
  <p style="color:rgba(255,255,255,0.85); font-size:16px;">Subtitle</p>
</div>
        

Use Unsplash for free photos. The rgba(0,0,0,0.55) overlay ensures text stays readable over any image.

Pattern 3: Light Earth Tone (from high-scoring notebooks)

<div
  style="
    background: linear-gradient(135deg, #F7F3EA 0%, #EEF4ED 100%);
    border: 1px solid #D9D0BF;
    border-radius: 18px;
    padding: 30px;
"
>
  <div
    style="font-size:11px; letter-spacing:0.14em; text-transform:uppercase;
                color:#7A6045; font-weight:700; margin-bottom:8px;"
  >
    Subtitle Label
  </div>
  <div style="font-size:2rem; font-weight:800; color:#233127;">
    Main Heading
  </div>
</div>
        

This light variant works well when your notebook uses light-mode matplotlib plots.


4. Section Headers: Dividing Long Notebooks

Long notebooks need clear visual section breaks. Here are the three most common patterns extracted from competition notebooks:

Left-border section header (clean and readable)

<div
  style="
    padding: 12px 22px;
    background: linear-gradient(90deg, #0f2d24 0%, #0d4a3e 100%);
    border-radius: 10px;
    border-left: 5px solid #84cc16;
    color: #f9fafb;
    margin: 28px 0 14px 0;
"
>
  <div style="font-size:20px; font-weight:600;">
    2. Exploratory Data Analysis
  </div>
</div>
        

Inline heading-div fusion (for Kaggle/Jupyter only)

# <div style="text-align:center; border-radius:15px; padding:15px;

     background:linear-gradient(90deg,#0f2027,#2c5364); color:white;">

<b>Section Title</b></div>
        

This embeds a CSS-styled div inside a Markdown heading tag. The heading still acts as a navigable anchor, but displays with full CSS styling.

ALL-CAPS minimal divider

<p
  style="font-size:11px; letter-spacing:3px; text-transform:uppercase;
          color:#64748b; font-weight:700; border-bottom:1px solid #e2e8f0;
          padding-bottom:6px; margin:28px 0 14px 0;"
>
  ⬛ Section 4 · Model Training
</p>
        

5. Callout Boxes: Highlighting Key Information

Callout boxes catch the reader's eye for important notes, warnings, or insights.

Bootstrap-style alerts (the quick way)

Most notebook platforms support <div class="alert alert-info"> Bootstrap-style alerts natively:

<div class="alert alert-success">
  <strong>✅ Key Result:</strong> Ensemble achieved CV 0.9814 — top 3% of
  leaderboard.
</div>

<div class="alert alert-warning">
  <strong>⚠️ Warning:</strong> Target encoding must be fit inside CV folds to
  prevent leakage.
</div>

<div class="alert alert-danger">
  <strong>🚨 Critical:</strong> This dataset has severe class imbalance (3.3%
  positive class).
</div>
        

Custom styled callouts (for dark notebooks)

<div
  style="
    background: #1e293b;
    border: 1px solid #334155;
    border-left: 4px solid #60a5fa;
    padding: 14px 18px;
    border-radius: 0 8px 8px 0;
    font-family: 'Segoe UI', sans-serif;
"
>
  <strong style="color:#93c5fd;">📌 Note</strong><br />
  <span style="color:#cbd5e1; font-size:14px;">Your important note here.</span>
</div>
        

Metric cards grid

<div
  style="display:grid; grid-template-columns:repeat(4,1fr); gap:12px; font-family:'Segoe UI',sans-serif;"
>
  <div
    style="background:linear-gradient(135deg,#1e3a5f,#2563eb); border-radius:10px;
                padding:16px; text-align:center; color:white;"
  >
    <div style="font-size:26px; font-weight:800;">75,000</div>
    <div
      style="font-size:12px; opacity:0.8; text-transform:uppercase; letter-spacing:1px; margin-top:4px;"
    >
      Training Rows
    </div>
  </div>
  <!-- Repeat for other metrics -->
</div>
        

6. Progress Bars and Visual Indicators

Progress bars are a clean alternative to tables when you want to show relative scores at a glance:

<div style="font-family:'Segoe UI',sans-serif; margin:12px 0;">
  <div style="margin:6px 0;">
    <div
      style="display:flex; justify-content:space-between; font-size:13px; margin-bottom:3px;"
    >
      <span>LightGBM</span><span>97.97%</span>
    </div>
    <div style="background:#e2e8f0; border-radius:6px; height:12px;">
      <div
        style="background:#2563eb; width:97.97%; height:12px; border-radius:6px;"
      ></div>
    </div>
  </div>
  <div style="margin:6px 0;">
    <div
      style="display:flex; justify-content:space-between; font-size:13px; margin-bottom:3px;"
    >
      <span>Ensemble</span><span style="font-weight:700;">98.14% 🏆</span>
    </div>
    <div style="background:#e2e8f0; border-radius:6px; height:12px;">
      <div
        style="background:linear-gradient(90deg,#16a34a,#4ade80); width:98.14%; height:12px; border-radius:6px;"
      ></div>
    </div>
  </div>
</div>
        

7. Badges (Shields.io) — GitHub-Friendly Metadata

Badges are SVG images generated by Shields.io and embedded as regular Markdown images. They work in GitHub READMEs, Kaggle notebooks, and everywhere else.

![Python](https://img.shields.io/badge/Python-3.10+-3776AB?logo=python&logoColor=white)
![License](https://img.shields.io/badge/License-MIT-green)
![CV Score](https://img.shields.io/badge/CV_Score-0.9797-brightgreen)
![Kaggle](https://img.shields.io/badge/Kaggle-20BEFF?logo=kaggle&logoColor=white)
        

Render as: inline colorful badges visible in any platform.

Common badge patterns:

  • ?style=flat (default) or ?style=flat-square for square corners
  • Add logo: ?logo=python&logoColor=white
  • Custom colors: use hex (-1e3a5f) or named colors (-brightgreen, -blue, -red)


8. Keyboard Tags, Entities, and Other HTML Gems

<kbd> keyboard shortcut display

Press <kbd>Shift</kbd> + <kbd>Enter</kbd> to run a cell.
        

Renders as styled keyboard keys that look like actual key caps.

HTML entities for special characters

IntentCodeOutputForce space / indent&nbsp;(non-breaking space)Show < literally&lt;<Em dash in prose&mdash;—Copyright&copy;©Right arrow&rarr;→

<details> collapsible sections

<details>
  <summary
    style="cursor:pointer; padding:10px 14px; background:#f1f5f9;
                border-radius:6px; font-weight:600;"
  >
    ▶ Click to expand: Parameter details
  </summary>
  <div
    style="padding:14px; background:#f8fafc; border:1px solid #e2e8f0; border-radius:0 0 6px 6px;"
  >
    Your expanded content here.
  </div>
</details>
        

Works in Kaggle, GitHub, Jupyter, VS Code, and HackMD.


9. Multi-Column Layouts

CSS Grid makes side-by-side content easy in any notebook platform that supports inline CSS:

<div style="display:grid; grid-template-columns:1fr 1fr; gap:16px;">
  <div
    style="background:#f8fafc; border:1px solid #e2e8f0; border-radius:10px; padding:16px;"
  >
    <h4 style="margin:0 0 8px 0; color:#1e3a5f;">Left Column</h4>
    <p style="margin:0; font-size:14px; color:#64748b;">Content here</p>
  </div>
  <div
    style="background:#f8fafc; border:1px solid #e2e8f0; border-radius:10px; padding:16px;"
  >
    <h4 style="margin:0 0 8px 0; color:#1e3a5f;">Right Column</h4>
    <p style="margin:0; font-size:14px; color:#64748b;">Content here</p>
  </div>
</div>
        

Note: CSS grid is stripped by GitHub's sanitizer. Use a Markdown table or plain paragraphs for GitHub READMEs.


10. Platform Compatibility Reference

Not all HTML works everywhere. Here's a quick reference:

FeatureKaggleJupyterGitHub READMEVS CodeHackMDInline CSS style=""✅✅❌ stripped✅✅<style> block✅✅❌ stripped✅✅CSS grid / flexbox✅✅❌✅✅<details> collapsible✅✅✅✅✅LaTeX math✅✅❌⚠️ ext✅Shields.io badges✅✅✅✅✅External images✅✅✅✅✅Google Fonts @import✅ (internet)✅❌⚠️✅

Key rule: Write for Kaggle/Jupyter's full HTML support, then simplify for GitHub by removing inline styles and <style> blocks.


11. Complete Notebook Template

Here's a minimal but well-formatted notebook starter you can drop into any data science project:

Cell 1 — Cover (Markdown):

<a id="top"></a>
<div
  style="background:linear-gradient(135deg,#0f172a,#1e3a5f,#0f4c75);
            border-left:6px solid #14B8A6; border-radius:16px; padding:44px 48px;
            box-shadow:0 10px 30px rgba(0,0,0,0.5); color:#f9fafb;
            font-family:'Segoe UI',sans-serif;"
>
  <h1 style="font-size:34px; font-weight:800; margin:0 0 10px 0;">
    🏆 Your Notebook Title
  </h1>
  <p style="color:#94a3b8; font-size:15px; margin:0 0 20px 0;">
    Project description · Metric · Date
  </p>
  <div
    style="display:flex; gap:16px; flex-wrap:wrap; font-size:13px; color:#94a3b8;"
  >
    <span>👤 <strong style="color:#f9fafb;">Your Name</strong></span>
    <span>📅 <strong style="color:#f9fafb;">2026</strong></span>
  </div>
</div>
        

Cell 2 — Section Header (Markdown):

<div
  style="padding:12px 20px; background:linear-gradient(90deg,#1e3a5f,#2563eb);
            border-radius:10px; color:white; margin:20px 0 10px 0;"
>
  <h2 style="margin:0; font-size:18px; font-weight:700;">1. Introduction</h2>
</div>
        

Cell 3 — Footer (Markdown):

<center>
  <div
    style="display:inline-block; padding:10px 24px; border-radius:8px;
            background:linear-gradient(90deg,#1e3a5f,#2563eb); color:white;
            font-family:'Segoe UI',sans-serif; font-size:15px;"
  >
    <strong>👍 If this helped you, please upvote!</strong>
  </div>
</center>
        

12. Advanced Patterns: Narrative Templates & Dynamic Elements

These patterns come from a deeper scan of top-performing competition notebooks. They solve a specific problem: how do you make a long analytical notebook readable — not just technically correct?

12.1 Dashed-Border Key Findings Box

After every major plot, add a dashed annotation box. The dashed border reads as a comment on the chart above — not an alert, not a callout box, but an honest "here's what I noticed":

<div
  style="padding:18px 24px; background:#fafaf9; border:1.5px dashed #a3a3a3;
            border-radius:10px; margin:14px 0; font-family:'Segoe UI',sans-serif;"
>
  <p
    style="margin:0 0 8px 0; font-size:11px; letter-spacing:2px;
              text-transform:uppercase; color:#737373; font-weight:600;"
  >
    ✏ Key findings
  </p>
  <ul
    style="margin:0; font-size:14px; color:#525252; font-style:italic;
               line-height:1.7; padding-left:18px;"
  >
    <li><b>Feature A</b> shows the largest class separation.</li>
    <li>Train and test distributions are well-aligned.</li>
  </ul>
</div>
        

12.2 Sub-Section Divider Strip

A left-border heading strip for three-tier hierarchy — section pill → sub-section strip → findings box:

<div
  style="padding:8px 18px; border-left:4px solid #14b8a6;
            background:#f0fdf4; border-radius:0 8px 8px 0; margin:18px 0 10px 0;"
>
  <h3
    style="margin:0; color:#0f2d24; font-size:16px; font-weight:700;
               font-family:'Segoe UI',sans-serif;"
  >
    3.1 — Numerical feature distributions
  </h3>
</div>
        

Available in three variants: teal (default analysis), blue (informational), amber (important/warning).

12.3 Faded-Prefix Numbered Section Header

Dark gradient pill where the number is at reduced opacity — creates magazine-style editorial section breaks:

<div
  style="padding:12px 22px; background:linear-gradient(90deg,#0f2d24,#0d4a3e);
            border-radius:10px; border-left:5px solid #84cc16; color:#f9fafb;
            margin:28px 0 14px 0; font-family:'Segoe UI',sans-serif;"
>
  <div style="font-size:20px; font-weight:600;">
    <span style="opacity:0.45; font-weight:500; margin-right:12px;">01</span>
    Data Quality &amp; Structure
  </div>
</div>
        

12.4 Score Metric Mini-Cards

Horizontal flexbox strip for displaying model results — each card has a color-coded top border matching the metric type:

<div
  style="display:flex; gap:12px; flex-wrap:wrap; margin:16px 0;
            font-family:'Segoe UI',sans-serif;"
>
  <div
    style="flex:1; min-width:130px; background:#1e293b; border-radius:10px;
                padding:14px 18px; border-top:3px solid #2563eb; text-align:center;"
  >
    <div
      style="font-size:11px; color:#94a3b8; text-transform:uppercase;
                    letter-spacing:1.5px; margin-bottom:6px;"
    >
      CV Score
    </div>
    <div style="font-size:26px; font-weight:800; color:#60a5fa;">0.9797</div>
    <div style="font-size:11px; color:#64748b; margin-top:4px;">
      5-Fold Stratified KFold
    </div>
  </div>
  <!-- Add more cards: LB Score (teal), Models (purple), Top % (amber) -->
</div>
        

12.5 HTML Model Comparison Table

Styled leaderboard with gradient dark header and alternating row shading. Supports emoji medals and per-column color coding — none of which Markdown tables can do:

<table
  style="border-collapse:collapse; width:100%; font-size:14px; margin:16px 0;
              font-family:'Segoe UI',sans-serif;"
>
  <thead>
    <tr
      style="background:linear-gradient(90deg,#1e3a5f,#2563eb); color:#f1f5f9;"
    >
      <th style="padding:11px 16px; text-align:left;">Model</th>
      <th style="padding:11px 16px; text-align:center;">CV Score</th>
      <th style="padding:11px 16px; text-align:center;">LB Score</th>
    </tr>
  </thead>
  <tbody>
    <tr style="background:#f8fafc;">
      <td style="padding:10px 16px; border-bottom:1px solid #e2e8f0;">
        🥇 Ensemble
      </td>
      <td
        style="padding:10px 16px; text-align:center; color:#16a34a; font-weight:700;"
      >
        0.9797
      </td>
      <td
        style="padding:10px 16px; text-align:center; color:#16a34a; font-weight:700;"
      >
        0.9774
      </td>
    </tr>
  </tbody>
</table>
        

12.6 Dynamic Dataset Summary Strip (Python → HTML)

A Python function that emits an HTML banner inline, between data preview cells. The banner shows row count, column count, and memory usage — all computed dynamically from the actual DataFrame:

from IPython.display import HTML, display

def dataset_summary(df, label="Dataset"):
    display(HTML(f"""
    <div style="border-left:5px solid #2563eb; padding:10px 18px;
                background:#eff6ff; border-radius:0 8px 8px 0; margin:12px 0;
                font-family:'Segoe UI',sans-serif;">
        <b style="color:#1e3a5f;">{label}</b>
        <span style="margin-left:14px; color:#2563eb; font-weight:600;">{df.shape[0]:,} rows</span>
        <span style="margin-left:10px; color:#64748b;">×</span>
        <span style="margin-left:10px; color:#2563eb; font-weight:600;">{df.shape[1]} columns</span>
        <span style="margin-left:16px; color:#94a3b8; font-size:12px;">
            memory: {df.memory_usage(deep=True).sum() / 1024**2:.1f} MB
        </span>
    </div>"""))
    return df

# Use as a wrapper — returns the dataframe so .head() chaining still works
dataset_summary(train_df, "Training Set").head()
        

12.7 Hypothesis → Inference Blockquote Chain

A pure Markdown pattern for feature engineering rationale. The 👉 emoji acts as a visual pointer; the > blockquote highlights the core claim:

### 🔗 Interaction Features

Based on EDA: extreme values in a single feature rarely predict the target alone.

👉 **Hypothesis:**

> If variable_A is high **and** variable_B is low → the target outcome is likely Class 1.

We therefore created a ratio feature: `variable_A / (variable_B + 1e-6)`
        

This creates a clear audit trail: every engineered feature has a documented reason for existing.

12.8 ELI5 + Section Insight Template

The most consistent structural pattern in highly-voted notebooks: every major analysis block starts with a plain-English ELI5 preamble and ends with a 💡 Insight footer.

## 📦 Section 3 — Numerical Feature Distributions

**ELI5:** For each numerical feature, we want to know:

- What values are typical? (mean, median)
- Are train and test distributions similar?

[... code + plots ...]

---

### 💡 Section 3 Insight

**Uniform kurtosis signature:** All excess kurtosis values cluster near −1.2.
This tells us features were sampled independently and uniformly.

**Implication for modeling:**

- No imputation needed
- Feature interactions will matter more than raw feature values
        

The ELI5 pattern serves two audiences simultaneously: beginners who need context, and experts who skip straight to the Insight footer.


Summary

The patterns in this guide were extracted directly from 500+ Kaggle competition notebooks and validated across multiple platforms. The key takeaways:

  1. Markdown first — everything in section 1 works everywhere
  2. Inline CSS works in Kaggle, Jupyter, VS Code, and HackMD but is stripped by GitHub
  3. CSS grid/flexbox unlocks multi-column layouts in notebooks
  4. A cover banner takes 10 minutes and makes your notebook look 10× more professional
  5. Section headers help readers navigate long notebooks — use left-border divs or # <div> fusion
  6. Shields.io badges are the only way to add styled metadata that works in GitHub READMEs
  7. <details> is the one HTML element that GitHub does render — use it for collapsible content
  8. ELI5 + Insight structure makes your notebook useful to both beginners and experts — and forces you to articulate what you actually found

The complete catalog notebook with rendered examples of every pattern above is available at: Kaggle — Markdown & HTML Reference Catalog.

And also you can visit Medium or Github.


All patterns tested on data science competition notebooks. Code examples are production-ready and copy-paste safe.

To view or add a comment, sign in

More articles by Huseyin Cenik

Others also viewed

Explore content categories