Build smarter tooltips with HTML, CSS & JS

Use hotspots and tooltips to keep your designs clean and add extra information when needed.


Use hotspots and tooltips to keep your designs clean and add extra information when needed.


These two features involve the ability to allow additional content to scroll into view as the user moves their mouse pointer and the ability to present information when the user clicks on designated hotspots.

The ability to present information in this way provides benefit to design, especially where space is limited and/or where the presentation of information detracts from the website’s usability – something that can be easy to forget when focusing on making a design look appealing.

There are different ways that these tooltips can be used. Anyone who remembers the game Myst will see how this game’s concept is similar to the tooltip map created in this tutorial – where the game uses the tooltip concept to enable exploration and interaction with the game scenery instead of focusing specifically on using it as a method for accessing additional information.

This tutorial creates tooltips and hotspots used to present information about buildings in a city. A panorama image is used for the background, with clickable link elements placed over image locations that can trigger a pop-up box for access to a new page or website.


1. Establish the HTML

Create a text file called ‘page.html’ and enter our HTML from FileSilo – this will load the required CSS and JavaScript code as well as build the main page elements. The map is made from a block referenced data-map, with link elements inside for the tappable hotspots.

2. JavaScript Listeners

Create another file called ‘map.js’. Then we will wait until the page has loaded and listen for mouse or touch movements on the <main> tag. JavaScript will set the horizontal scrolling position to that of the mouse/touch pointer when events are detected.

3. Define page body

The default style rules should be defined, preparing the <html> and <body> tags to cover the fullscreen width and height. This enables child page elements to be sized in relation to the page, they don’t work for height by default.

4. Establish main styling

Create a file called ‘styles.css’ for your style rules to be placed in. The first styles to be created will set the size of the HTML, body and main elements – the latter being used as the container for our tooltip map. The <main> element has its overflow set to hidden to give the scrolling illusion.

5. Relative positioning

The element inside <main> has a [data-map] attribute that has the background image, relative positioning and a width of 200% of the <main> container width, ensuring that the content scrolls regardless of the size of <main>.

position: relative;
display: block;
width: 200%;
height: 100%;
background: url('img/background.jpg') #000 no-repeat 0 0;
background-size: 100%;

6. Marker elements

Marker elements placed inside the [data-map] use absolute positioning that is relative to the [data-map]. Markers transition their colour when highlighted and have a default + sign as their visible content. Styling is placed ‘::before’ the DOM element.

7. Marker content

Visible content that appears when a marker is selected is placed inside a child element of the marker that has a [data-content] attribute. This element is set as invisible by default, but becomes visible when the parent marker has been selected using the :target selector for the parent.

[data-marker] [data-content]{
position: absolute;
display: block;
z-index: 1;
padding: 1em;
background: #ccc;
color: #000;
margin: 1em 0 0 -0.5em;
border-radius: 0.4em;
width: 15em;
box-shadow: 5px 5px 5px 0px rgba(0,0,0,0.75);
opacity: 0;
transition: opacity 1s;
[data-marker]:target [data-content]{
display: block !important;
opacity: 1;

8. Speech bubble

For this speech bubble shape, insert a rotated square before the [data-content] element.

[data-marker] [data-content]::before{
position: absolute;
background-color: #ccc;
content: "0a0";
display: block;
height: 16px;
z-index: 0;
top: -8px;
transform: rotate( 29deg ) skew( -35deg );
-moz-transform: rotate( 29deg ) skew( -35deg );
-ms-transform: rotate( 29deg ) skew( -35deg );
-o-transform:rotate( 29deg ) skew( -35deg );
-webkit-transform: rotate( 29deg ) skew( -35deg );
width: 20px;

9. Style individual markers

Individual markers need their positions to be defined and set with percentages so that they retain their intended position on the [data-map] background image.

top: 46%;
left: 24%;
top: 60%;
left: 37%;
top: 36%;
left: 68%;