Layers & styling
A layer draws one source’s data in one way: as circles, lines, filled areas,
labels and so on. Each entry under layers: names its type, its source,
and how it looks (paint: and layout:). Layers draw in order, the first at
the bottom, all above the basemap.
Quick start
Section titled “Quick start”Two layers can draw the same data. Here a fill shades each US state and a
line outlines it, both from one source named under sources::
type: mapid: statesconfig: center: [-98, 39] zoom: 3 mapStyle: "https://tiles.openfreemap.org/styles/liberty"sources: states: type: geojson url: "https://maplibre.org/maplibre-gl-js/docs/assets/us_states.geojson"layers: - id: state-fill type: fill source: states paint: fill-color: "#22c55e" fill-opacity: 0.4 - id: state-outline type: line source: states paint: line-color: "#166534" line-width: 1The style keys (fill-color, line-width …) are MapLibre’s, unchanged:
every one is in the MapLibre style spec.
paint: holds how a layer is coloured and sized; layout: holds what is
drawn at all (label text, line caps, visibility).
Layer types
Section titled “Layer types”type: | Draws | Data |
|---|---|---|
circle | A dot per point | Points |
symbol | Labels and icons | Points, or along lines |
line | Lines and outlines | Lines, polygons |
fill | Filled areas | Polygons |
fill-extrusion | Areas raised in 3D, such as buildings | Polygons |
heatmap | Point density as a colour surface | Points |
raster | Imagery and scanned maps | Raster tiles, COG files |
hillshade | Shaded relief | Elevation (raster-dem) |
color-relief | Elevation coloured by height (maplibre-gl 5.6 or later) | Elevation (raster-dem) |
background | One colour or pattern over the whole map | None |
A background layer covers the basemap, because your layers draw above it;
use it on a map without a basemap, or slide it under the basemap’s layers
with before:.
Points, lines and areas
Section titled “Points, lines and areas”These snippets are entries for a document’s layers: list. Each names a
source (earthquakes, routes, states) that the document defines under
sources: (Loading data).
- id: earthquakes type: circle source: earthquakes paint: circle-radius: 6 circle-color: "#ef4444" circle-stroke-width: 1 circle-stroke-color: "#ffffff"- id: routes type: line source: routes paint: line-color: "#2563eb" line-width: 4 layout: line-cap: round line-join: round- id: states type: fill source: states paint: fill-color: "#22c55e" fill-opacity: 0.5Write colours in quotes ("#22c55e"): in YAML an unquoted # starts a
comment, so the colour would be lost.
Labels
Section titled “Labels”A symbol layer with text-field writes text at each feature:
- id: city-names type: symbol source: cities layout: text-field: ["get", "name"] text-size: 13 text-offset: [0, 1.2] # below the point, in ems paint: text-color: "#1f2937" text-halo-color: "#ffffff" text-halo-width: 1.5Without text-font, a label uses the basemap’s regular font. A font has to
come from the basemap’s glyph server, so if you name one, name a font that
server has: OpenFreeMap’s styles serve "Noto Sans Regular",
"Noto Sans Bold" and "Noto Sans Italic". A font the server lacks leaves
the labels out and fills the console with failed downloads. The gallery has
Change the case of labels,
Display and style rich text labels,
and Variable label placement.
3D buildings and heatmaps
Section titled “3D buildings and heatmaps”fill-extrusion raises polygons by a height property. A layer can draw from
the basemap’s own sources by name: OpenFreeMap’s styles call theirs
openmaptiles, and its building layer has a height:
- id: buildings-3d type: fill-extrusion source: openmaptiles source-layer: building minzoom: 15 paint: fill-extrusion-color: "#aab4c3" fill-extrusion-height: ["get", "render_height"] fill-extrusion-opacity: 0.8Tilt the map (pitch: 50 in config:) to see the height. A heatmap turns
many points into a density surface:
- id: quake-density type: heatmap source: earthquakes paint: heatmap-weight: ["interpolate", ["linear"], ["get", "mag"], 0, 0, 6, 1] heatmap-radius: 20See Display buildings in 3D and Create a heatmap layer for complete maps.
Imagery and elevation
Section titled “Imagery and elevation”A raster layer shows image tiles, such as satellite imagery. hillshade
and color-relief draw elevation data, from a raster-dem source: shading
that shows the shape of the land, and colours by height. These go in a
document beside its config::
sources: imagery: type: raster tiles: - "https://tiles.maps.eox.at/wmts/1.0.0/s2cloudless-2020_3857/default/g/{z}/{y}/{x}.jpg" tileSize: 256 attribution: "Sentinel-2 cloudless by EOX IT Services GmbH (contains modified Copernicus Sentinel data 2020)" elevation: type: raster-dem url: "https://tiles.mapterhorn.com/tilejson.json" encoding: terrariumlayers: - id: imagery type: raster source: imagery paint: raster-opacity: 0.85 - id: relief type: color-relief source: elevation paint: color-relief-opacity: 0.5 color-relief-color: - interpolate - ["linear"] - ["elevation"] - 0 - "#2b83ba" - 1500 - "#abdda4" - 3000 - "#fdae61" - 4500 - "#d7191c" - id: hills type: hillshade source: elevation paint: hillshade-exaggeration: 0.6- Set
tileSize: 256for most raster tile servers. The default is 512, which stretches 256-pixel tiles and blurs them. - Set
encodingon araster-demsource. It defaults tomapbox, so terrarium tiles, such as Mapterhorn’s, needencoding: terrariumor the heights come out wrong. color-reliefneeds maplibre-gl 5.6 or later. On an older version, the map skips the layer with one console warning and draws the rest.color-relief-colorramps over["elevation"], in metres.
The same raster-dem source can also raise the map in 3D:
Map documents › Terrain, sky & projection. Gallery:
Display a satellite map,
Add a hillshade layer,
Add a color relief layer.
Data-driven styling
Section titled “Data-driven styling”To colour or size each feature by one of its properties, write a MapLibre
expression where a value would go. For classed maps (a choropleth, graduated
circles, categories with a legend), classify: writes the expression and the
legend for you: see Thematic maps & legends.
The examples here use the USGS earthquake feed, whose features carry a
magnitude (mag) and a type.
A smooth ramp: interpolate
Section titled “A smooth ramp: interpolate”type: mapid: quakes-by-magnitudeconfig: center: [-120, 37] zoom: 4 mapStyle: "https://tiles.openfreemap.org/styles/liberty"layers: - id: earthquakes type: circle source: type: geojson url: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson" paint: circle-radius: ["interpolate", ["linear"], ["get", "mag"], 1, 3, 6, 20] circle-color: ["interpolate", ["linear"], ["get", "mag"], 1, "#fef08a", 6, "#dc2626"] circle-opacity: 0.8["get", "mag"] reads the property; the pairs after it are input and output
(magnitude 1 → radius 3, magnitude 6 → radius 20), with values in between
blended.
Categories: match
Section titled “Categories: match”paint: circle-color: - match - ["get", "type"] - "earthquake" - "#ef4444" - "quarry blast" - "#3b82f6" - "#6b7280" # every other valueSteps: step
Section titled “Steps: step”paint: circle-color: - step - ["get", "mag"] - "#22c55e" # below 2.5 - 2.5 - "#eab308" # 2.5 up to 4.5 - 4.5 - "#ef4444" # 4.5 and aboveEvery expression is in the style spec’s expressions reference. The gallery’s Style lines with a data-driven property is a complete example; more are in the gallery’s Layers, icons & styling group.
Filter features
Section titled “Filter features”filter: keeps only the features that match an expression:
- id: large-earthquakes type: circle source: earthquakes filter: [">=", ["get", "mag"], 4.5] paint: circle-color: "#ef4444"Show a layer only at some zooms
Section titled “Show a layer only at some zooms”minzoom and maxzoom limit the zoom levels a layer draws at (minzoom: 12
hides it when zoomed out further). visible: false starts it hidden.
To let readers turn a layer on and off, give it a label:. The map then
shows a layer panel in the top-right corner with a checkbox for each labelled
layer; toggleable: false keeps a layer’s label without the checkbox.
Layer order
Section titled “Layer order”Layers draw in the order you list them; later ones draw on top:
layers: - id: areas # bottom type: fill - id: roads type: line - id: labels # top type: symbolAll of them draw above the basemap. To slide a layer under part of the
basemap, such as its place names, name that basemap layer in before:
(before: place_label): your layer is drawn just below it. See
Add a new layer below labels.
In the legend
Section titled “In the legend”A layer with a legend: { label, color } entry, or a classify: block, is
listed in the map’s legend. How the legend is built and placed is in
Thematic maps › The legend.
Look it up
Section titled “Look it up”- The layer reference: every key maplibre-yaml accepts on a layer, by type.
- MapLibre’s layer properties
and expressions:
every
paintandlayoutkey and what it takes. - Sources & layers: how a layer finds its source, and every key maplibre-yaml adds to a layer.
Troubleshooting
Section titled “Troubleshooting”Troubleshooting › The basemap draws but your layer doesn’t walks through an empty layer step by step. Problems specific to styling:
- A colour is ignored: it is probably unquoted. Write
"#ef4444". - Nothing draws at this zoom: check
minzoom,maxzoomandfilter:. - Labels don’t appear: the
text-fontyou named isn’t on the basemap’s glyph server. Removetext-font, or name a font it serves. - A note about
before::before:names a layer the map doesn’t have. The layer is drawn on top instead, and the note suggests the closest layer id.
Strings starting with = are reserved
Section titled “Strings starting with = are reserved”A style value that starts with =, such as text-field: "=upper({name})",
is reserved and gets a warning: in mlym validate, in the browser console,
and on the page while you develop. MapLibre receives the text exactly as
written. Write an expression instead:
layout: text-field: ["upcase", ["get", "name"]] # not "=upper({name})"For text that really starts with =, wrap it in literal, which never
warns: text-field: ["literal", "=5"]. MapLibre’s own == operator
(["==", ["get", "kind"], "park"]) is not affected. The check covers a
layer’s paint:, layout: and filter:, and a story chapter’s
setPaintProperty and setLayoutProperty values.
Next steps
Section titled “Next steps”- Thematic maps & legends: classed colours and sizes with a legend.
- Popups, hover & controls: what happens when a feature is clicked.
- Loading data: files, URLs and named sources.