mirror of
https://github.com/tabler/tabler.git
synced 2026-10-13 21:57:00 +04:00
217 lines
7.4 KiB
Plaintext
217 lines
7.4 KiB
Plaintext
---
|
|
title: Map
|
|
summary: A map shows places and markers on an interactive world map. Tabler provides the markup and the setup code, and the map itself is rendered by MapLibre GL JS.
|
|
description: Show interactive maps with markers using MapLibre GL JS and free map tiles. No account or access token is needed.
|
|
related: [/ui/plugins/vector-map]
|
|
docs-libs: [maplibre-gl]
|
|
source: core/scss/_utilities.scss
|
|
classnames:
|
|
component:
|
|
- class: ratio
|
|
desc: Wrapper that keeps the embed at a fixed aspect ratio
|
|
size:
|
|
- class: ratio-{ratio}
|
|
desc: The aspect to hold, for example ratio-16x9 or ratio-21x9
|
|
---
|
|
import Example from '@components/Example.astro';
|
|
import Map from '@shared/components/demo/Map.astro';
|
|
import { Code } from 'astro:components';
|
|
import { site } from '@shared/lib/site.ts';
|
|
|
|
## Overview
|
|
|
|
The map is a small wrapper around [MapLibre GL JS](https://maplibre.org/maplibre-gl-js/docs/), an open-source map library. Tabler gives you the container markup and a short init script. MapLibre draws the tiles, handles zoom, and renders the markers.
|
|
|
|
The demos load their map tiles from [OpenFreeMap](https://openfreemap.org/). It needs no account and no access token, and it can be used in commercial projects. If you only need a simple map of countries or regions, use the [vector map](/ui/plugins/vector-map) instead. It makes no network calls at all.
|
|
|
|
## Installation
|
|
|
|
Install MapLibre GL JS with npm. Tabler uses version 5, the last one that ships a classic script file:
|
|
|
|
```bash
|
|
npm install maplibre-gl@5
|
|
```
|
|
|
|
Or include it from a CDN. You need two files: the stylesheet and the library.
|
|
|
|
<Code
|
|
lang="html"
|
|
code={`<link rel="stylesheet" href="${site.cdnUrl}/dist/libs/maplibre-gl/dist/maplibre-gl.css" />
|
|
<script src="${site.cdnUrl}/dist/libs/maplibre-gl/dist/maplibre-gl.js"></script>`}
|
|
/>
|
|
|
|
Tabler styles the map controls, popups and attribution to match the interface, in light and dark mode. These styles are in `tabler-vendors.css`, so load it after the MapLibre stylesheet:
|
|
|
|
<Code
|
|
lang="html"
|
|
code={`<link rel="stylesheet" href="${site.cdnUrl}/dist/css/tabler-vendors.min.css" />`}
|
|
/>
|
|
|
|
## Usage
|
|
|
|
### Markup
|
|
|
|
Put the map container inside a `ratio` element, so the map keeps its shape on every screen size. Give the inner element an `id` and the `w-100 h-100` classes.
|
|
|
|
<Example codeOnly>
|
|
<div class="ratio ratio-16x9">
|
|
<div><div id="map-simple" class="w-100 h-100"></div></div>
|
|
</div>
|
|
</Example>
|
|
|
|
Change the shape with the ratio classes, for example `ratio-21x9` for a wide map or `ratio-1x1` for a square one.
|
|
|
|
### Init the map
|
|
|
|
Create the map after the DOM is ready. Pass the id of your container, a style, a zoom level, and a center point.
|
|
|
|
```js
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
const map = new maplibregl.Map({
|
|
container: 'map-simple',
|
|
style: 'https://tiles.openfreemap.org/styles/liberty',
|
|
zoom: 13,
|
|
center: [13.4049, 52.518827],
|
|
})
|
|
})
|
|
```
|
|
|
|
<Example>
|
|
<Map mapId="simple" />
|
|
</Example>
|
|
|
|
`center` takes the longitude first and the latitude second. This is the opposite of what most map services show.
|
|
|
|
### Map styles
|
|
|
|
Set `style` to the URL of any MapLibre style. OpenFreeMap has five of them:
|
|
|
|
| Style | Result |
|
|
| --- | --- |
|
|
| `https://tiles.openfreemap.org/styles/liberty` | Default street map. |
|
|
| `https://tiles.openfreemap.org/styles/bright` | Street map with stronger colors. |
|
|
| `https://tiles.openfreemap.org/styles/positron` | Light gray map, good under charts and markers. |
|
|
| `https://tiles.openfreemap.org/styles/dark` | Dark map. |
|
|
| `https://tiles.openfreemap.org/styles/fiord` | Dark blue map. |
|
|
|
|
<Example>
|
|
<Map mapId="light" />
|
|
</Example>
|
|
|
|
Styles from other providers work the same way, as long as they follow the MapLibre style format. Check the terms of each provider, as many of them need an API key or a paid plan.
|
|
|
|
### Markers
|
|
|
|
Add a marker for each place. `setLngLat` takes the same longitude and latitude order as `center`.
|
|
|
|
```js
|
|
const cities = [
|
|
[-58.666667, -34.58333333], // Buenos Aires
|
|
[16.366667, 48.2], // Vienna
|
|
[116.383333, 39.91666667], // Beijing
|
|
]
|
|
|
|
cities.forEach(function (coords) {
|
|
new maplibregl.Marker({ color: 'var(--tblr-primary)' }).setLngLat(coords).addTo(map)
|
|
})
|
|
```
|
|
|
|
<Example>
|
|
<Map mapId="markers" />
|
|
</Example>
|
|
|
|
The `color` option is written to the `fill` attribute of the marker icon. A CSS variable works there, so `var(--tblr-primary)` keeps the markers in your theme color, including after a theme change.
|
|
|
|
### Popups
|
|
|
|
Attach a popup to a marker with `setPopup`. It opens when the marker is clicked. Click a marker on the map above to see one.
|
|
|
|
```js
|
|
new maplibregl.Marker({ color: 'var(--tblr-primary)' })
|
|
.setLngLat([16.366667, 48.2])
|
|
.setPopup(new maplibregl.Popup({ offset: 32 }).setText('Vienna'))
|
|
.addTo(map)
|
|
```
|
|
|
|
Use `setHTML` instead of `setText` for richer content. Only pass HTML you trust, as it is not escaped.
|
|
|
|
### Controls
|
|
|
|
Add the zoom and compass buttons with `NavigationControl`. They go to the top right corner by default.
|
|
|
|
```js
|
|
map.addControl(new maplibregl.NavigationControl())
|
|
```
|
|
|
|
MapLibre also has `FullscreenControl`, `GeolocateControl` and `ScaleControl`. Pass a corner as the second argument, for example `'bottom-left'`.
|
|
|
|
### Dark mode
|
|
|
|
A map style does not change with the page theme on its own. Pick the style from the `data-bs-theme` attribute, and set it again when the attribute changes:
|
|
|
|
```js
|
|
const themeStyle = function () {
|
|
const dark = document.documentElement.getAttribute('data-bs-theme') === 'dark'
|
|
return 'https://tiles.openfreemap.org/styles/' + (dark ? 'dark' : 'liberty')
|
|
}
|
|
|
|
const map = new maplibregl.Map({
|
|
container: 'map-simple',
|
|
style: themeStyle(),
|
|
zoom: 13,
|
|
center: [13.4049, 52.518827],
|
|
})
|
|
|
|
new MutationObserver(function () {
|
|
map.setStyle(themeStyle())
|
|
}).observe(document.documentElement, { attributeFilter: ['data-bs-theme'] })
|
|
```
|
|
|
|
Markers and popups stay on the map when the style changes. The maps on this page follow the theme this way.
|
|
|
|
### Attribution
|
|
|
|
MapLibre adds the credit for the map data in the corner of the map. OpenFreeMap requires it, so do not hide it.
|
|
|
|
## Examples
|
|
|
|
### Map in a card
|
|
|
|
Add a card title above the map. This is the usual layout for a small map next to other content.
|
|
|
|
<Example codeOnly>
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="card-title">Simple map</div>
|
|
<div class="ratio ratio-16x9">
|
|
<div><div id="map-card" class="w-100 h-100"></div></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</Example>
|
|
|
|
### Full-card map
|
|
|
|
Drop the card body to let the map fill the whole card. Add `rounded` to the container, so the map follows the card corners.
|
|
|
|
<Example codeOnly>
|
|
<div class="card">
|
|
<div class="ratio ratio-21x9">
|
|
<div><div id="map-full" class="w-100 h-100 rounded"></div></div>
|
|
</div>
|
|
</div>
|
|
</Example>
|
|
|
|
Live versions of these maps are on the [maps preview page](https://preview.tabler.io/maps.html).
|
|
|
|
## Using Mapbox GL JS
|
|
|
|
MapLibre GL JS started as a fork of Mapbox GL JS, so the two share most of their API. To use Mapbox instead, load its script and stylesheet, replace `maplibregl` with `mapboxgl`, set `mapboxgl.accessToken` to your public token, and use a `mapbox://` style URL.
|
|
|
|
## Accessibility
|
|
|
|
- The map is a picture for most users. Give the same information as text near it, for example the address or a list of places.
|
|
- Add an `aria-label` to the map container, so screen reader users know what the map shows.
|
|
- Do not put an action only on a marker. Repeat it in a normal link or button below the map.
|
|
- Keep a visible fallback when the script fails to load, for example the address in text.
|