--- layout: default category: reference title: Mapbox Style Specification permalink: / class: fill-light options: full navigation: - title: Root subnav: - title: version - title: name - title: metadata - title: center - title: zoom - title: bearing - title: pitch - title: light - title: sources - title: sprite - title: glyphs - title: transition - title: layers - title: Light subnav: - title: anchor - title: position - title: color - title: intensity - title: Sources subnav: - title: Vector - title: Raster - title: GeoJSON - title: Image - title: Video - title: Sprite - title: Glyphs - title: Transition subnav: - title: duration - title: delay - title: Layers subnav: - title: Background - title: Fill - title: Line - title: Symbol - title: Raster - title: Circle - title: Fill-Extrusion - title: Types subnav: - title: Color - title: Enum - title: String - title: Boolean - title: Number - title: Array - title: Function - title: Filter ---

{{ page.title }}

A Mapbox style is a document that defines the visual appearance of a map: what data to draw, the order to draw it in, and how to style the data when drawing it. A style document is a JSON object with specific root level and nested properties. This specification defines and describes these properties.

The intended audience of this specification includes:

  • Advanced designers and cartographers who want to write styles by hand rather than use Mapbox Studio
  • Developers using style-related features of Mapbox GL JS or the Mapbox iOS or Android SDKs
  • Authors of software that generates or processes Mapbox styles.

Root Properties

Root level properties of a Mapbox style specify the map's layers, tile sources and other resources, and default values for the initial camera position when not specified elsewhere.

{% highlight json%} { "version": <%= ref.$version %>, "name": "Mapbox Streets", "sprite": "mapbox://sprites/mapbox/streets-v<%= ref.$version %>", "glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf", "sources": {...}, "layers": [...] } {% endhighlight %}
<% _(ref.$root).each(function(prop, name) { %> <%= item({prop: prop, id: "root-" + name, name: name}) %> <% }); %>

Light

A style's light property provides global light source for that style. <% if (ref.$root.light.example) { %>

{% highlight json %} <%= '"light": ' + JSON.stringify(ref.$root.light.example, null, 2) %> {% endhighlight %}
<% } %>

<% _(ref.light).each(function(prop, name) { %> <%= item({prop: prop, id: "light-" + name, name: name}) %> <% }); %>
<% var source_types = ['vector', 'raster', 'geojson', 'image', 'video']; %>

Sources

Sources supply data to be shown on the map. The type of source is specified by the "type" property, and must be one of <%= source_types.join(', ') %>. Adding a source won't immediately make data appear on the map because sources don't contain styling details like color or width. Layers refer to a source and give it a visual representation. This makes it possible to style the same source in different ways, like differentiating between types of roads in a highways layer.

Tiled sources (vector and raster) must specify their details in terms of the TileJSON specification. This can be done in several ways:

  • By supplying TileJSON properties such as "tiles", "minzoom", and "maxzoom" directly in the source:
    {% highlight json%} "mapbox-streets": { "type": "vector", "tiles": [ "http://a.example.com/tiles/{z}/{x}/{y}.pbf", "http://b.example.com/tiles/{z}/{x}/{y}.pbf" ], "maxzoom": 14 } {% endhighlight %}
  • By providing a "url" to a TileJSON resource:
    {% highlight json%} "mapbox-streets": { "type": "vector", "url": "http://api.example.com/tilejson.json" } {% endhighlight %}
  • By providing a url to a WMS server that supports EPSG:3857 (or EPSG:900913) as a source of tiled data. The server url should contain a "{bbox-epsg-3857}" replacement token to supply the bbox parameter. (This feature is currently supported only in Mapbox GL JS and Mapbox macOS SDK.) {% highlight json%} "wms-imagery": { "type": "raster", "tiles": [ 'http://a.example.com/wms?bbox={bbox-epsg-3857}&format=image/png&service=WMS&version=1.1.1&request=GetMap&srs=EPSG:3857&width=256&height=256&layers=example' ], "tileSize": 256 } {% endhighlight %}

vector

A vector tile source. Tiles must be in Mapbox Vector Tile format. All geometric coordinates in vector tiles must be between -1 * extent and (extent * 2) - 1 inclusive. All layers that use a vector source must specify a "source-layer" value. For vector tiles hosted by Mapbox, the "url" value should be of the form mapbox://mapid.

{% highlight json%} "mapbox-streets": { "type": "vector", "url": "mapbox://mapbox.mapbox-streets-v6" } {% endhighlight %}
<% _(ref.source_tile).each(function(prop, name) { %> <% // note that we omit 'tileSize' here, since VECTOR and raster // both use source_tile, but tileSize is prohibited for vector sources %> <% if (name === '*' || name === 'type' || name === 'tileSize') return %> <%= item({prop: prop, id: "sources-vector-" + name, name: name}) %> <% }); %>
SDK Support Mapbox GL JS iOS SDK Android SDK
basic functionality >= 0.10.0 >= 2.0.0 >= 2.0.1

raster

A raster tile source. For raster tiles hosted by Mapbox, the "url" value should be of the form mapbox://mapid.

{% highlight json%} "mapbox-satellite": { "type": "raster", "url": "mapbox://mapbox.satellite", "tileSize": 256 } {% endhighlight %}
<% _(ref.source_tile).each(function(prop, name) { %> <% if (name === '*' || name === 'type') return %> <%= item({prop: prop, id: "sources-raster-" + name, name: name}) %> <% }); %>
SDK Support Mapbox GL JS iOS SDK Android SDK
basic functionality >= 0.10.0 >= 2.0.0 >= 2.0.1

geojson

A GeoJSON source. Data must be provided via a "data" property, whose value can be a URL or inline GeoJSON.

{% highlight json%} "geojson-marker": { "type": "geojson", "data": { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-77.0323, 38.9131] }, "properties": { "title": "Mapbox DC", "marker-symbol": "monument" } } } {% endhighlight %}

This example of a GeoJSON source refers to an external GeoJSON document via its URL. The GeoJSON document must be on the same domain or accessible using CORS.

{% highlight json%} "geojson-lines": { "type": "geojson", "data": "./lines.geojson" } {% endhighlight %}
<% _(ref.source_geojson).each(function(prop, name) { %> <% if (name === '*' || name === 'type') return %> <%= item({prop: prop, id: "sources-geojson-" + name, name: name}) %> <% }); %>
SDK Requirements Mapbox GL JS iOS SDK Android SDK
basic functionality >= 0.10.0 >= 2.0.0 >= 2.0.1
clustering >= 0.14.0 Not yet supported Not yet supported

image

An image source. The "url" value contains the image location.

The "coordinates" array contains [longitude, latitude] pairs for the image corners listed in clockwise order: top left, top right, bottom right, bottom left.

{% highlight json%} "image": { "type": "image", "url": "/mapbox-gl-js/assets/radar.gif", "coordinates": [ [-80.425, 46.437], [-71.516, 46.437], [-71.516, 37.936], [-80.425, 37.936] ] } {% endhighlight %}
<% _(ref.source_image).each(function(prop, name) { %> <% if (name === '*' || name === 'type') return %> <%= item({prop: prop, id: "sources-image-" + name, name: name}) %> <% }); %>
SDK Support Mapbox GL JS iOS SDK Android SDK
basic functionality >= 0.10.0 Not yet supported Not yet supported

video

A video source. The "urls" value is an array. For each URL in the array, a video element source will be created, in order to support same media in multiple formats supported by different browsers.

The "coordinates" array contains [longitude, latitude] pairs for the video corners listed in clockwise order: top left, top right, bottom right, bottom left.

{% highlight json%} "video": { "type": "video", "urls": [ "https://www.mapbox.com/drone/video/drone.mp4", "https://www.mapbox.com/drone/video/drone.webm" ], "coordinates": [ [-122.51596391201019, 37.56238816766053], [-122.51467645168304, 37.56410183312965], [-122.51309394836426, 37.563391708549425], [-122.51423120498657, 37.56161849366671] ] } {% endhighlight %}
<% _(ref.source_video).each(function(prop, name) { %> <% if (name === '*' || name === 'type') return %> <%= item({prop: prop, id: "sources-video-" + name, name: name}) %> <% }); %>
SDK Support Mapbox GL JS iOS SDK Android SDK
basic functionality >= 0.10.0 Not yet supported Not yet supported

Sprite

A style's sprite property supplies a URL template for loading small images to use in rendering background-pattern, fill-pattern, line-pattern, and icon-image style properties. <% if (ref.$root.sprite.example) { %>

{% highlight json %} <%= '"sprite": ' + JSON.stringify(ref.$root.sprite.example, null, 2) %> {% endhighlight %}
<% } %>

A valid sprite source must supply two types of files:

  • An index file, which is a JSON document containing a description of each image contained in the sprite. The content of this file must be a JSON object whose keys form identifiers to be used as the values of the above style properties, and whose values are objects describing the dimensions (width and height properties) and pixel ratio (pixelRatio) of the image and its location within the sprite (x and y). For example, a sprite containing a single image might have the following index file contents:
    {% highlight json%} { "poi": { "width": 32, "height": 32, "x": 0, "y": 0, "pixelRatio": 1 } } {% endhighlight %}
    Then the style could refer to this sprite image by creating a symbol layer with the layout property "icon-image": "poi", or with the tokenized value "icon-image": "{icon}" and vector tile features with a icon property with the value poi.
  • Image files, which are PNG images containing the sprite data.

Mapbox SDKs will use the value of the sprite property in the style to generate the URLs for loading both files. First, for both file types, it will append @2x to the URL on high-DPI devices. Second, it will append a file extension: .json for the index file, and .png for the image file. For example, if you specified "sprite": "https://example.com/sprite", renderers would load https://example.com/sprite.json and https://example.com/sprite.png, or https://example.com/sprite@2x.json and https://example.com/sprite@2x.png.

If you are using Mapbox Studio, you will use prebuilt sprites provided by Mapbox, or you can upload custom SVG images to build your own sprite. In either case, the sprite will be built automatically and supplied by Mapbox APIs. If you want to build a sprite by hand and self-host the files, you can use spritezero-cli, a command line utility that builds Mapbox GL compatible sprite PNGs and index files from a directory of SVGs.

Glyphs

A style's glyphs property provides a URL template for loading signed-distance-field glyph sets in PBF format. <% if (ref.$root.glyphs.example) { %>

{% highlight json %} <%= '"glyphs": ' + JSON.stringify(ref.$root.glyphs.example, null, 2) %> {% endhighlight %}
<% } %>

Transition

A style's transition property provides global transition defaults for that style. <% if (ref.$root.transition.example) { %>

{% highlight json %} <%= '"transition": ' + JSON.stringify(ref.$root.transition.example, null, 2) %> {% endhighlight %}
<% } %>

<% _(ref.transition).each(function(prop, name) { %> <%= item({prop: prop, id: "transition-" + name, name: name}) %> <% }); %>
<% var layer_types = ['background', 'fill', 'line', 'symbol', 'raster', 'circle', 'fill-extrusion']; %>

Layers

A style's layers property lists all of the layers available in that style. The type of layer is specified by the "type" property, and must be one of <%= layer_types.join(', ') %>.

Except for layers of the background type, each layer needs to refer to a source. Layers take the data that they get from a source, optionally filter features, and then define how those features are styled.

<% if (ref.$root.layers.example) { %>
{% highlight json %} <%= '"layers": ' + JSON.stringify(ref.$root.layers.example, null, 2) %> {% endhighlight %}
<% } %>

<% _(ref.layer).each(function(prop, name) { %> <%= item({prop: prop, id: "layer-" + name, name: name}) %> <% }); %>

Layers have two sub-properties that determine how data from that layer is rendered: layout and paint properties.

Layout properties appear in the layer's "layout" object. They are applied early in the rendering process and define how data for that layer is passed to the GPU. For efficiency, a layer can share layout properties with another layer via the "ref" layer property, and should do so where possible. This will decrease processing time and allow the two layers will share GPU memory and other resources associated with the layer.

Paint properties are applied later in the rendering process. A layer that shares layout properties with another layer can have independent paint properties. Paint properties appear in the layer's "paint" object. Layers can also have class-specific paint properties, which are applied only when the map has a certain class name set. For example, a layer with a "paint.night" property would have those properties applied when the map has the "night" class set.

Key: supports interpolated functions supports piecewise constant functions transitionable

<% _(layer_types).each(function(t) { %>

<%= t %>

Layout Properties

<% if (_.isEmpty(ref['layout_'+t])) { %>
None
<% } else { %> <% _(ref['layout_'+t]).each(function(prop, name) { %> <%= item({prop: prop, id: "layout-" + t + "-" + name, name: name}) %> <% }); %> <% } %>

Paint Properties

<% _(ref['paint_'+t]).each(function(prop, name) { %> <%= item({prop: prop, id: "paint-" + name, name: name}) %> <% }); %>
<% }); %>

Types

A Mapbox style contains values of various types, most commonly as values for the style properties of a layer.

Color

Colors are written as JSON strings in a variety of permitted formats: HTML-style hex values, rgb, rgba, hsl, and hsla. Predefined HTML colors names, like yellow and blue, are also permitted.

{% highlight json %} { "line-color": "#ff0", "line-color": "#ffff00", "line-color": "rgb(255, 255, 0)", "line-color": "rgba(255, 255, 0, 1)", "line-color": "hsl(100, 50%, 50%)", "line-color": "hsla(100, 50%, 50%, 1)", "line-color": "yellow" } {% endhighlight %}

Especially of note is the support for hsl, which can be easier to reason about than rgb().

Enum

One of a fixed list of string values. Use quotes around values.

{% highlight json %} { "text-transform": "uppercase" } {% endhighlight %}

String

A string is basically just text. In Mapbox styles, you're going to put it in quotes. Strings can be anything, though pay attention to the case of text-field - it actually will refer to features, which you refer to by putting them in curly braces, as seen in the example below.

{% highlight json %} { "text-field": "{MY_FIELD}" } {% endhighlight %}

Boolean

Boolean means yes or no, so it accepts the values true or false.

{% highlight json %} { "fill-enabled": true } {% endhighlight %}

Number

A number value, often an integer or floating point (decimal number). Written without quotes.

{% highlight json %} { "text-size": 24 } {% endhighlight %}

Array

Arrays are comma-separated lists of one or more numbers in a specific order. For example, they're used in line dash arrays, in which the numbers specify intervals of line, break, and line again.

{% highlight json %} { "line-dasharray": [2, 4] } {% endhighlight %}

Function

The value for any layout or paint property may be specified as a function. Functions allow you to make the appearance of a map feature change with the current zoom level and/or the feature's properties.

Required (except for identity functions) array.
Functions are defined in terms of input and output values. A set of one input value and one output value is known as a "stop."
Optional string.
If specified, the function will take the specified feature property as an input. See Zoom Functions and Property Functions for more information.
Optional number. Default is <%= ref.function.base.default %>.
The exponential base of the interpolation curve. It controls the rate at which the function output increases. Higher values make the output increase more towards the high end of the range. With values close to 1 the output increases linearly.
Optional enum. One of identity, exponential, interval, categorical.
identity
functions return their input as their output.
exponential
functions generate an output by interpolating between stops just less than and just greater than the function input. This is the default for numeric domain, range functions.
interval
functions return the output value of the stop just less than the function input. This is the default for numeric domain, range functions.
categorical
functions return the output value of the stop equal to the function input. This is the default for string domain functions.
Optional enum. One of rgb, lab, hcl.
The color space in which colors interpolated. Interpolating colors in perceptual color spaces like LAB and HCL tend to produce color ramps that look more consistent and produce colors that can be differentiated more easily than those interpolated in RGB space.
rgb
Use the RGB color space to interpolate color values
lab
Use the LAB color space to interpolate color values.
hcl
Use the HCL color space to interpolate color values, interpolating the Hue, Chroma, and Luminance channels individually.
SDK Support Mapbox GL JS iOS SDK Android SDK
basic functionality >= 0.10.0 >= 2.0.0 >= 2.0.1
identity type >= 0.26.0 Not yet supported Not yet supported
colorSpace >= 0.26.0 Not yet supported Not yet supported

Zoom functions allow the appearance of a map feature to change with map’s zoom. Zoom functions can be used to create the illusion of depth and control data density. Each stop is an array with two elements, the first is a zoom and the second is a function output value.

{% highlight js %} { "circle-radius": { "stops": [ // zoom is 5 -> circle radius will be 1px [5, 1], // zoom is 10 -> circle radius will be 2px [10, 2] ] } } {% endhighlight %}

Property functions allow the appearance of a map feature to change with its properties. Property functions can be used to visually differentate types of features within the same layer or create data visualizations. Each stop is an array with two elements, the first is a property input value and the second is a function output value. Note that support for property functions is not available across all properties and platforms at this time.

{% highlight js %} { "circle-color": { "property": "temperature", "stops": [ // "temperature" is 0 -> circle color will be blue [0, 'blue'], // "temperature" is 100 -> circle color will be red [100, 'red'] ] } } {% endhighlight %}

Zoom-and-property functions allow the appearance of a map feature to change with both its properties and zoom. Each stop is an array with two elements, the first is an object with a property input value and a zoom, and the second is a function output value. Note that support for property functions is not yet complete.

{% highlight js %} { "circle-radius": { "property": "rating", "stops": [ // zoom is 0 and "rating" is 0 -> circle radius will be 0px [{zoom: 0, value: 0}, 0], // zoom is 0 and "rating" is 5 -> circle radius will be 5px [{zoom: 0, value: 5}, 5], // zoom is 20 and "rating" is 0 -> circle radius will be 0px [{zoom: 20, value: 0}, 0], // zoom is 20 and "rating" is 5 -> circle radius will be 20px [{zoom: 20, value: 5}, 20] ] } } {% endhighlight %}

Filter

A filter selects specific features from a layer. A filter is an array of one of the following forms:

Existential Filters

["has", key] feature[key] exists
["!has", key] feature[key] does not exist

Comparison Filters

["==", key, value] equality: feature[key] = value
["!=", key, value] inequality: feature[key]value
[">", key, value] greater than: feature[key] > value
[">=", key, value] greater than or equal: feature[key]value
["<", key, value] less than: feature[key] < value
["<=", key, value] less than or equal: feature[key]value

Set Membership Filters

["in", key, v0, ..., vn] set inclusion: feature[key] ∈ {v0, ..., vn}
["!in", key, v0, ..., vn] set exclusion: feature[key] ∉ {v0, ..., vn}

Combining Filters

["all", f0, ..., fn] logical AND: f0 ∧ ... ∧ fn
["any", f0, ..., fn] logical OR: f0 ∨ ... ∨ fn
["none", f0, ..., fn] logical NOR: ¬f0 ∧ ... ∧ ¬fn

A filter's key must be a string that identifies a feature property, or the special key "$type", which identifies the feature type. A value (and v0, ..., vn for set operators) must be a string, number, or boolean to compare the property value against. For the "$type" key it must be one of "Point", "LineString", or "Polygon".

Set membership filters are a compact and efficient way to test whether a field matches any of multiple values.

The comparison and set membership filters implement strictly-typed comparisons; for example, all of the following evaluate to false: 0 < "1", 2 == "2", "true" in [true, false].

The "all", "any", and "none" filter operators are used to create compound filters. The values f0, ..., fn must be filter expressions themselves.

{% highlight json%} ["==", "$type", "LineString"] {% endhighlight %}

This filter requires that the class property of each feature is equal to either "street_major", "street_minor", or "street_limited".

{% highlight json%} ["in", "class", "street_major", "street_minor", "street_limited"] {% endhighlight %}

The combining filter "all" takes the three other filters that follow it and requires all of them to be true for a feature to be included: a feature must have a class equal to "street_limited", its admin_level must be greater than or equal to 3, and its type cannot be Polygon. You could change the combining filter to "any" to allow features matching any of those criteria to be included - features that are Polygons, but have a different class value, and so on.

{% highlight json%} [ "all", ["==", "class", "street_limited"], [">=", "admin_level", 3], ["!in", "$type", "Polygon"] ] {% endhighlight %}
SDK Support Mapbox GL JS iOS SDK Android SDK
basic functionality >= 0.10.0 >= 2.0.0 >= 2.0.1
has/!has >= 0.19.0 >= 3.3.0 >= 4.1.0