Skip to main content

Pixel Lab

Pixel Lab is a vibrant, accessible theme for MkDocs.

Preview

Pixel Lab desktop documentation preview Pixel Lab mobile documentation preview
Desktop Mobile

Quick start

python -m pip install mkdocs-pixel-lab

Use it in mkdocs.yml:

theme:
  name: pixel-lab

The snippets below show settings to merge into your existing mkdocs.yml.

Everyday features

Responsive navigation

Primary navigation tabs and the contextual section sidebar follow MkDocs' nav: tree. Narrow browser windows use a menu drawer with the same links, whether viewed on a phone or desktop. The current page and section are marked automatically.

The toolbar search opens a compact panel backed by MkDocs' search index. Enable the standard plugin:

plugins:
  - search

Section headings (H2–H6) show a permalink icon after the title. H1 page titles keep their IDs without an icon.

Choose chain (the default filled chain icon), link (the original link icon), or hash (the # icon) with theme.permalink_icon. All three use heading-relative sizing.

The URL fragment follows the current section as you scroll, without adding browser-history entries. Enable visible heading permalinks with:

theme:
  name: pixel-lab
  permalink_icon: chain # default; or link, hash
  permalink_fill_color: "var(--accent)" # light accent by default; transparent disables it
markdown_extensions:
  - toc:
      permalink: true

The chain's colored body uses theme.permalink_fill_color (the light accent by default); its openings remain transparent. The black outline stays visible, while the shadow appears in the dark accent only on hover or keyboard focus. The original link and hash icons keep their light-accent coloring and dark-accent hover; the chain's fill setting does not affect them.

A skip-to-content link, visible focus styles, and labeled navigation regions support keyboard use. Escape closes the search panel or open navigation drawer and returns focus to its toolbar button.

Media, tables, and nested shadows

Images and videos scale to the available content width. Wide tables scroll inside a fixed bordered frame, keeping its pixel shadow in place. When cards, alerts, tables, media, or code are nested inside an elevated component, inner shadows are removed automatically so only the outer component is elevated.

Bundled fonts

Inter and IBM Plex Mono are served with the theme. No Google Fonts request or external font service is required.

Rich Markdown content

Code blocks

Syntax-highlighted code blocks include a one-click copy button with success and failure feedback. Enable Pymdown's fenced-code and highlighting extensions:

markdown_extensions:
  - pymdownx.superfences
  - pymdownx.highlight

Code and inline-code colors follow the theme palette; long blocks scroll horizontally.

GitHub Alerts

Enable GitHub-style Markdown alerts explicitly when a site uses them:

markdown_extensions:
  - mkdocs_pixel_lab.github_alerts

The extension supports NOTE, TIP, IMPORTANT, WARNING, and CAUTION:

> [!TIP]
>
> Use semantic callouts for important guidance.

Content tabs and collapsible notes

Admonitions, expandable details, and content tabs use the same pixel borders and palette as the rest of the theme. Enable the corresponding extensions:

markdown_extensions:
  - admonition
  - pymdownx.details
  - pymdownx.tabbed:
      alternate_style: true

Content tabs are separate from the primary navigation tabs below the toolbar.

Customize your site

Palette

Every theme color is configured from the single theme: block in mkdocs.yml. The default palette preserves Pixel Lab’s original appearance; override only the tokens your site needs:

theme:
  name: pixel-lab

  # Brand
  header_background: "#8315F9"
  accent_color: "#8315F9"
  accent_dark_color: "#5E0AAE"
  accent_foreground_color: "#FFFFFF"

  # Neutrals used by every component
  background_color: "#f4f1df"
  surface_color: "#fffdf2"
  surface_alt_color: "#e8e4cf"
  text_color: "#182018"
  muted_text_color: "#5f665d"
  border_color: "#101410"
  shadow_color: "#101410"

header_background accepts any CSS background value, including a linear gradient. All other options accept any valid CSS color, including rgba() and CSS variables.

Palette token reference
Tokens Used for
background_color, surface_color, surface_alt_color Page, cards, input, and table surfaces.
text_color, strong_text_color, muted_text_color Body, control, and secondary text.
border_color, shadow_color, subtle_border_color, sidebar_border_color Component outlines, offset shadows, table rules, and navigation dividers.
grid_color, overlay_color Page grid and mobile-navigation scrim.
header_background, header_border_color, header_shadow_color, accent_color, accent_dark_color, accent_foreground_color Header, links, navigation, active states, and accent-filled controls.
highlight_color, secondary_color, input_focus_background_color, inline_code_border_color, tab_hover_color Interactive controls, badges, inline code, and hover states.
code_background_color, code_text_color, code_keyword_color, code_string_color, code_function_color, code_comment_color Code block and syntax-highlight colors.
alert_note_color, alert_note_surface_color, alert_tip_color, alert_tip_surface_color, alert_important_color, alert_important_surface_color, alert_warning_color, alert_warning_surface_color, alert_caution_color, alert_caution_surface_color GitHub Alert rails, titles, and surfaces.

This separation lets a site change its border and shadow independently without having to maintain CSS overrides or edit the theme.

The analytics acceptance button uses header_background and accent_foreground_color, matching the header background and site title without separate color settings.

Favicon

Pixel Lab includes a default favicon. Override it for a site-specific mark:

theme:
  name: pixel-lab
  favicon: assets/favicon.svg

The custom path is relative to your documentation directory. SVG and PNG favicons are supported.

The site title includes a decorative pixel TM badge. Its circle and letter fill follow the title's text color; the glyph's outer and inner borders use the light and dark theme accents. Add a short footer message with theme.footer_text; the built-in Pixel Lab and Trained-by-Humans attribution remains below any related-site links:

theme:
  name: pixel-lab
  footer_text: Build something useful

Site navigation

Choose either inline links beside the site title or a dropdown beside Search, with an independent footer lane. All reuse extra.site_navigation; the dropdown shows every item, followed by the optional catalog link, without lane size limits.

Site navigation configuration
extra:
  site_navigation:
    header_mode: dropdown # dropdown | inline | none
    show_footer: true
    dropdown_label: Packages # defaults to Sites
    header_size: 4 # includes the catalog link
    footer_size: 7 # includes the catalog link
    footer_label: Packages
    items:
      - title: Core
        url: https://ml-pipes.com/
        icon: assets/core.svg
      - title: Supervision
        url: https://supervision.ml-pipes.com/
        active: true
        icon: assets/supervision.svg
        icon_hover: assets/supervision.svg#icon-hover
      - title: Vision
        url: https://github.com/trained-by-humans/ml-pipes/tree/main/packages/vision
    catalog:
      title: All Packages →
      url: https://ml-pipes.com/PACKAGES/

Omit site_navigation to render no related-site navigation. When configured, header_mode selects one toolbar presentation: dropdown (the default), inline, or none. Use it in place of the previous show_header / show_dropdown flags; the two toolbar presentations never render together. show_footer independently controls the footer lane and defaults to true.

Inline header and footer lanes require a catalog link. The inline header renders up to header_size links and the footer up to footer_size; each capacity includes the catalog link. These sizes do not limit the dropdown. On narrow screens, the inline header hides and the footer links stack vertically.

Set each item's optional icon to an SVG/PNG path relative to the documentation directory or an absolute URL. Missing icons use a themed pixel fallback; icons appear only in the dropdown. The catalog can also specify an icon. The dropdown works without a catalog and marks the configured active item. Use Tab or arrow keys to navigate, and Escape to close it. Clicking outside also closes it. On small screens, the header buttons use icons while keeping accessible labels.

Optionally set icon_hover to an animated image URL. It replaces the resting icon on pointer hover or keyboard focus, restarts on each entry, and restores the static icon on exit or when the dropdown closes. Reduced-motion users retain the static icon. Hover images are fetched once and replayed from cached data; use a same-origin asset or an external URL that allows CORS. An SVG can use a fragment such as #icon-hover to activate its own :target animation, letting the same file supply both static and animated artwork. Hover-enabled icons have a 24 × 44 px image slot, including the row's vertical spacing. Add that breathing room inside both SVG canvases so the animation stays within the viewBox without shrinking the resting artwork. Missing or failed hover images leave the resting icon unchanged. Without icon_hover, icons stay static in a 24 × 24 px slot.

Analytics and privacy

Google Analytics 4

Analytics is off by default. Configure a GA4 Measurement ID (G-…, not a Firebase API key or Google Tag Manager ID) and your privacy-notice URL to enable the built-in opt-in prompt:

site_url: https://ml-pipes.com/
theme:
  name: pixel-lab
extra:
  analytics:
    provider: google
    measurement_id: G-XXXXXXXXXX
    privacy_policy: https://ml-pipes.com/privacy/

The prompt appears automatically on the first HTTPS visit matching site_url. Allow analytics loads the Google tag; Decline does not. Choices can be changed through Analytics settings in the footer. Withdrawal disables collection, attempts to clear the site's GA cookies, and reloads the page. Set enabled: false under analytics to turn the integration off. Google is currently the only supported analytics provider.

Google setup and data-handling notes

Missing or invalid Measurement IDs leave tracking off. Local development and alternate-host previews do not collect visits. When browser storage is blocked, a choice applies only to the current page. Advertising consent remains denied; Google Signals and advertising personalization are disabled. Initial page URLs and referrers omit query strings and fragments.

To configure a GA4 property:

  1. In Google Analytics, create a GA4 property and a Web data stream for your production site.
  2. Copy its Measurement ID. Related documentation sites can share an ID; distinguish them in reports by Hostname. The theme keeps GA cookies hostname-specific, so user counts are not deduplicated across subdomains.
  3. In Enhanced measurement → Page views → Advanced settings, disable page changes based on browser history events. Heading-fragment updates are not separate page visits. Review the other automatic measurements you enable.
  4. Publish a privacy notice and configure its URL. Review applicable consent requirements; this prompt is not a certification of legal compliance. Do not send personal information through events or page titles.
  5. Deploy and verify acceptance in Realtime. Test denial in a fresh browser context; Google requests should be absent.

The Measurement ID is public, not a secret. No API key, Firebase SDK, GitHub secret, or separate subdomain property is required. Reports describe consenting visitors, not every visit or an individual's identity.

References: Google tag setup and consent implementation.

extra.analytics.privacy_policy is required: a missing, empty, or whitespace-only URL keeps analytics off. The same link appears in the consent prompt and footer, alongside Analytics settings when tracking is enabled. Retaining the URL with enabled: false keeps the policy link visible. Relative URLs such as privacy/ work from nested pages.

Publish a notice customized to your operator and data practices; Pixel Lab does not supply a universal privacy policy. Related sites may link to one shared notice that explicitly covers them.

By default, consent is stored per documentation site URL and Measurement ID, including separate project paths on the same GitHub Pages hostname. To share acceptance and rejection across a custom domain and its subdomains, configure the same consent_domain and Measurement ID on every participating site:

extra:
  analytics:
    provider: google
    measurement_id: G-XXXXXXXXXX
    consent_domain: ml-pipes.com
    privacy_policy: https://ml-pipes.com/privacy/

Both acceptance and rejection are shared through a consent-only cookie scoped to that domain, with Secure, SameSite=Lax, Path=/, and a 180-day lifetime. The prompt identifies the shared domain. Use this only for sites you control under the same privacy policy, not public suffixes or shared hosting domains such as github.io. Other open sites synchronize changes on focus and periodically. Only consent is shared; GA cookies remain hostname-specific.

Unrelated or malformed domains disable analytics, and browsers reject public-suffix cookies. No parent domain is inferred automatically. Changing the consent scope requires a new choice; previous site-only choices are not silently promoted to domain-wide permission.

Development

python -m pip install -e '.[test]'
playwright install chromium
pytest

Metadata

Release files for mkdocs-pixel-lab 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mkdocs-pixel-lab 0.1.1
File Size Uploaded
mkdocs_pixel_lab-0.1.1.tar.gz 773.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mkdocs-pixel-lab 0.1.1
File Interpreter ABI Platform
mkdocs_pixel_lab-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 908.0 kB

Release files / mkdocs_pixel_lab-0.1.1.tar.gz

Download URL mkdocs_pixel_lab-0.1.1.tar.gz
Size 773.1 kB
Tags Source
SHA-256 checksum
How to use checksums
2507f35eecad518cac0be4dc69010ca1916a2f02ad1ea5d1e1f23e312a65afd9
BLAKE2b-256 checksum
How to use checksums
79e84034f8609ecd54e8b6ea046e72c8760c45e083e6b476491f8991786373b0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release files / mkdocs_pixel_lab-0.1.1-py3-none-any.whl

Download URL mkdocs_pixel_lab-0.1.1-py3-none-any.whl
Size 134.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a736572d7a9a3cf0010bb9c045d8170cfbbeb9c77c52a43ab3f8af559e313008
BLAKE2b-256 checksum
How to use checksums
da48d1ea5702e9ee977306ec6abeb16cc7c9edcb325ca74bfe8dee450e5f7da9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.0

2 release files

0.1.3

2 release files

0.1.2

2 release files

This release

0.1.1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page