Skip to content
Documentation
Skill

/maplibre-cartography

Cartographic principles for MapLibre GL JS — label and symbol legibility on imagery vs. vector basemaps, figure-ground for point icons, styling vector roads over aerial imagery, visual hierarchy, layer ordering for data injection, and accessibility. Use when styling a map,

BOOST
From plugin
maplibre-agent-skills
15511 skills
Install
$ npx -y skills add maplibre/maplibre-agent-skills --skill maplibre-cartography --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/maplibre-cartography

Context preview

The summary Claude sees to decide when to auto-load this skill.

Cartographic principles for MapLibre GL JS — label and symbol legibility on imagery vs. vector basemaps, figure-ground for point icons, styling vector roads over aerial imagery, visual hierarchy, layer ordering for data injection, and accessibility. Use when styling a map,

SKILL.md

maplibre-cartography.SKILL.md
name: maplibre-cartography
description: Cartographic principles for MapLibre GL JS — label and symbol legibility on imagery vs. vector basemaps, figure-ground for point icons, styling vector roads over aerial imagery, visual hierarchy, layer ordering for data injection, and accessibility. Use when styling a map, choosing text or symbol colors, making markers or roads readable on satellite/aerial imagery, or ordering layers correctly.
status: verified

MapLibre Cartography

MapLibre renders exactly what you describe in your style. This skill covers how to describe it well: choosing label colors for readability on any basemap, building a coherent visual hierarchy, and ordering style layers correctly. For font/glyph setup, see [maplibre-fonts-glyphs](../maplibre-fonts-glyphs/SKILL.md); for sprites, icon sourcing, and route shields, see [maplibre-sprites-icons](../maplibre-sprites-icons/SKILL.md).

When to Use This Skill

  • Reviewing a style against cartographic best practices before it ships
  • Choosing label `text-color` and `text-halo-color`, or point symbol/icon colors, for a new or migrated style — including cases where they read fine on a flat vector basemap but disappear or camouflage once the basemap is imagery
  • Setting up or debugging `sprite`, icons, or route shields — see [maplibre-sprites-icons](../maplibre-sprites-icons/SKILL.md); for `glyphs`, see [maplibre-fonts-glyphs](../maplibre-fonts-glyphs/SKILL.md)
  • Injecting your own data layers into an existing basemap without covering labels
  • Restyling roads from a light-basemap vector palette so they sit in (not on top of) imagery
  • Auditing a style for contrast accessibility

Basemap Type Determines Label Colors

MapLibre places labels dynamically, so you cannot mask the background behind each label as you would on a static map. Instead, choose a `text-halo-color` that separates the label from every background it might land on, and a `text-color` that reads against the halo. On a single uniform basemap tone (flat light or dark vector), the halo can match that tone instead of contrasting it — the text itself does the contrasting against the basemap. Imagery has no single tone to match, so there the halo must contrast every possible background instead:

| Basemap type | Background | Recommended text color | Recommended halo | | ---------------------------------------------- | ---------------------------------------------------------- | ------------------------------- | ------------------------------------------------ | | Light vector (streets, OpenFreeMap positron) | Pale/white | Dark (`#333` or similar) | Light semi-transparent (`rgba(255,255,255,0.8)`) | | Dark vector (dark-matter, navigation night) | Dark | White or near-white (`#ffffff`) | Dark semi-transparent (`rgba(0,0,0,0.75)`) | | Satellite or aerial imagery (NAIP, Sentinel-2) | Unpredictable — bright crops, dark forests, urban rooftops | White (`#ffffff`) | **Dark semi-transparent (`rgba(0,0,0,0.75)`)** |

The most common mistake is a white halo with no transparency: unless the background is pure white, it disrupts the spatial connection between the label and the feature it labels — add transparency. The second is reusing a light-vector palette over imagery, where it fails on dark terrain, forests, and water. **On imagery, always use white text and a dark semi-transparent halo** (`"text-color": "#ffffff"`, `"text-halo-color": "rgba(0,0,0,0.75)"`, `"text-halo-width": 1.2`).

For tinted labels (parks, water, POIs), use a light tint of the semantic color (`#c8f5cc` parks, `#a8d8ff` water) rather than the dark saturated version: tints read against dark halos while keeping semantic meaning, where full-saturation colors contrast poorly at small sizes.

Halo width

Wider halos increase legibility but add visual weight. Typical values:

| Context | `text-halo-width` | | ------------------------------------- | ----------------- | | Body labels (city, town, village) | 0.8–1.5 | | Country / continent (large text) | 1.5–2.0 | | Small POI or peak labels | 0.8–1.2 | | Water / park labels with colored text | 1.0–1.5 |

`text-halo-width` is in pixels relative to the text. The halo must not bleed into adjacent labels: keep it tight at small text sizes and add transparency.

Point Symbols and Icons on Imagery

Markers face the same figure-ground problem as labels, but with different tools. A colored icon on aerial imagery competes with an unpredictable, busy, _desaturated_ photographic background.

  • **You cannot separate a symbol from a background that owns its hue.** A green icon over green parkland, a brown icon over bare soil: both camouflage. Most aerial imagery is low-saturation, so the axis the background is weakest on is **chroma**. A saturated fill (amber, terracotta) separates while still reading as a natural, earthy color. Shifting hue alone, toward a different earth tone, does not help if that hue is also in the scene.
  • **Carve the symbol out with `icon-halo-color`/`icon-halo-width`**, exactly as you would halo a label — this only affects SDF sprite images (`addImage(..., { sdf: true })` or a sprite built as SDF); a full-color raster icon has no halo paint property, so any edge treatment on it has to be baked into the artwork itself. A thin light halo reads against dark canopy and water; a darker edge holds against bright soil and rooftops. Keep it thin — a fat ring reads as a sticker — except for the one class of symbol meant to dominate the map (an emergency marker, the single most important thematic feature), where a heavier ring is the point.
  • **Flat fills read as stickers on a photo.** Give landform or 3D
Read more
Ships withmaplibre-agent-skills

Curated guidance for AI assistants building MapLibre applications — covering ecosystem and open-source best practices. Agent skills are markdown files that AI coding assistants read as context.

Get the whole plugin

Other skills on maplibre-agent-skills.