HTML5 Development Center

Developed for you in part by
 
thermometer

Create Your Own HTML5 Environmental Thermometer

By | | CSS3 | HTML | HTML5 | Programming

There is no doubt: HTML5 and CSS3, and their related APIs, are hot stuff. In this article I will show how you can use these technologies to create a complete and functional environmental thermometer.

The Ingredients

An HTML5 environmental thermometer is a simple and adaptive thermometer that allows you to gauge the temperature of a chosen location. This demo uses semantic HTML5 markup, CSS3 and JavaScript for styling and positioning the thermometer in order to make it look like a real environmental thermometer.

Since it uses an SVG background image, it can be adapted to different sizes without being stretched. However, in the folder that contains the source code there’s also a PNG background image to support older browsers which don’t support SVG.

So, in full, here are the various technologies we’ll be using:

  • HTML5 for the markup
  • CSS3 to style the thermometer
  • JavaScript and jQuery to adjust the thermometer position and to set and position its labels
  • SVG for the background to be adaptive
  • Polyfill to support the browsers that don’t support the tag (jonstipe/meter polyfill is used)
  • Geolocation API to get the user’s position
  • Google Maps API to convert the geolocation into an address
  • Yahoo! Weather API to retrieve the WOEID code and the temperature

How it Works

Using this thermometer is very simple. To retrieve the temperature, you have to write the name of a city — or even better, an address — in the related field (for example, “Naples” as shown below), and click the button reading “Get temperature!”.

As soon as the temperature is retrieved, you’ll see the meter bar rising (or falling, depending on the case) until the correct measure is reached and the relevant information, on the upper right-hand side, is autofilled with the data. In the case where you need the temperature of your current location, you can simply take advantage of the Geolocation API used in the code. So, all you need to do is to click on “Get my position” and the field will be automatically filled with your current position (to be honest, it is an approximation).

Let’s Analyze the Code

In this section I won’t explain the entire code, but just the most interesting parts of it; some of the CSS rules or JavaScript lines are just complementary to the core.

HTML5

The markup underpinning the thermometer is quite simple:

<div id="thermometer-wrapper">
  <meter id="thermometer" min="-30" max="50" value="0"></meter>
  <div id="labels"></div>
</div>
<div id="info"> The temperature in <label id="city">-</label> is <output id="temperature" form="request">-</output>
  <label id="error"></label>
</div>
<form id="request" name="request" action="#">
  <label>Type the city:</label>
  <input type="text" id="location" name="location" size="30" placeholder="Frattamaggiore, Italy" required="required"/> or <a id="my-position" href="#">Get my position</a>
  <br />
  <input type="submit" name="submit" value="Get temperature!" />
</form> 

The external div delimits the area in use and it is used to attach the background image. The second line shows a meter tag which is the actual element used for the thermometer. The meter tag gives the demo a pinch of semantic meaning, which is never a bad thing. The third line contains the labels attached to the thermometer, but they will be created on-the-fly using JavaScript.

The remaining code is used to show the info in a written form and to request the user location. The important tags and attributes here are the output tag, inside the inner div, to show the current temperature which is attached to the form; as well as the required and placeholder attributes of the location field.

CSS3 and SVG

CSS3 is not used only to style the code simply, but to transform the markup into a real environmental thermometer. The background image is an SVG which means that it will render well and determine if the dimensions of the demo will change. Here, I used the CSS3 rule background-size.

#thermometer-wrapper {
  background-image: url('background.svg');
  background-repeat: no-repeat;
  position: relative;
  height: 300px;
  width: 75px;
  float: left;
  margin: 0em 1em 1em 0em;
  -ms-background-size: cover;
  -webkit-background-size: cover;
  -moz-background-size: cover;
  -o-background-size: cover;
  background-size: cover;
}

To give the whole thing a nicer look and feel, the metertag is rotated 90 degrees to be displayed vertically. This, however, brings a problem with both sizing and centering the element inside the div. The sizing problem arises from the fact that, being displayed vertically, to prolong the bar, we have to change the height attribute. Unfortunately, in order to work as expected, this change has to be done after the bar is rotated and so this is done via JavaScript. For the same reason, centering the bar is a problem that has to be solved programmatically using JavaScript — in particular, jQuery. The transform rule is the only CSS3 rule used on the element, as shown below:

#thermometer {
  position: absolute;
  transform: rotate(-90deg);
  -ms-transform: rotate(-90deg);
  -webkit-transform: rotate(-90deg);
  -o-transform: rotate(-90deg);
  -moz-transform: rotate(-90deg);
}

JavaScript and jQuery

JavaScript plays an important role in this demo. Infact, since CSS is not sufficient to center the thermometer, JavaScript has to be used. Moreover, the latter has been used to set the number of labels dynamically and to evenly space things. Even if the dimensions of the wrapper of the thermometer are changed, the labels will be adapted proportionally. The relevant part of code is:

// Calculates the space between each label
margin = (thermometer.width() + (parseFloat(labels.css('font-size')) / 2)) / ((max - min) / step);
margin -= parseFloat(labels.css('font-size'));

JavaScript helps to make the thermometer more adaptive. Infact, by simply changing one or two variables inside the JavaScript file, it is possible to have a different number of grade labels that still are evenly spaced. The same thing happens if you alter the font-size. Here’s how you center the bar:

// Calculates the position of the thermometer
thermometer.width(0.9 * wrapper.height());
thermometer.css('bottom', ((wrapper.height() - thermometer.height()) / 2) + 'px');
thermometer.css('left', (thermometer.width() - wrapper.width()) / -2);

The APIs

In this demo I used several APIs. The Geolocation API is used to retrieve the user’s position; this data is immediately sent to the Google Maps API to retrieve an address from the coordinates. Finally, the Yahoo! Weather API is used to retrieve the WOEID (Where on Earth Identifier) and get the current temperature of the location requested.

That’s a basic look at the markup and script used to create this environmental thermometer. Take a look at the online demo, and download the source code, check it out for yourself and feel free to have a play around with it. (The HTML5 environmental thermometer is completely open source and released dual licensed under the MIT and the GPL-3.0 licenses.)

Learn Responsive Web Design

Join Learnable $29 Includes all SitePoint books

Aurelio De Rosa

I'm an Italian web and app developer with more than 5 years' experience programming for the web using HTML5, CSS3, JavaScript and PHP. I mainly use the LAMP stack and frameworks like jQuery, jQuery Mobile, Cordova (PhoneGap) and Zend Framework but my interests also include web security, web accessibility, SEO, WordPress and everything I can put my hands on. In the little spare time left, I contribute to the open source community writing libraries for PHP as well as jQuery plugins. Currently I'm self-employed working with the cited technologies. I'm also a regular blogger for several networks (SitePoint, Tuts+, FlippinAwesome) where I write articles about the topics I usually work with and more.

More Posts - Website - Twitter - LinkedIn - Google Plus

{ 12 comments }

Vinay September 15, 2012 at 6:33 am

nce one…..hey i m learning html5 and css3 so please give me any source to learn this properly….pls

Aurelio De Rosa September 16, 2012 at 2:43 pm

I’m glad you like it. You can download the source code freely at the link given in the post but you can find the most updated source at: https://bitbucket.org/AurelioDeRosa/html5-environmental-thermometer

Diane Ensey September 13, 2012 at 5:11 pm

It is probably something obvious, but why does the meter display green when the CSS background-color is #B1241B (red)?

Aurelio De Rosa September 13, 2012 at 5:30 pm

The question is good, don’t worry. The browsers that support the tag meter will render the bar using the default look and feel set by the browsers themselves. Moreover, they will ignore what is inside the meter tag because it is used for backward compatibility. Unfortunately at the moment, using CSS, there’s no way to change the color of the displayed bar and so it is shown green. Said that, inside the meter tag there’s a div element to support old browsers. Since the div background can be easily changed using CSS, I decided to use a red background color to simulate the mercury of a typical thermometer.

Diane Ensey September 13, 2012 at 5:35 pm

Thank you! I was completely puzzled by this.

John Palmer September 13, 2012 at 4:29 pm

Very nice experiment. I like it, expecially the fact that you used polyfill to support old browsers. I think I’ll put this on my website.

Chris Crowe September 13, 2012 at 1:19 pm

Sorry demo did not work on iPad in moreea, Tahiti

Basically got red line from -30 to 0 even though temp was shown as 26c

I will try when I am back in new zealand tomorrow

Chris

Aurelio De Rosa September 13, 2012 at 4:24 pm

I just tried with your location and it works as you can see here: http://img854.imageshack.us/img854/6258/moreea.jpg

Do you got any error?

AkVarr September 10, 2012 at 5:43 am

That’s really good stuff! Great job! :)

Aurelio De Rosa September 10, 2012 at 3:43 am

Thank you to both of you for the compliments.

Paul September 8, 2012 at 12:11 pm

Hi Aurelio! Your work looks impressive. I find that it’s a very interesting and awesome experiment. I liked this tutorial very much and surely I’ll try to do the same following your step-by-step guideline.
At the moment are you working on something similar? I’d like to discover the power of these combined technologies with some practical examples and I’m searching for suggestions and inspiration.
Anyway, many compliments! :)

Miroku September 8, 2012 at 8:17 am

Good article and great job, congratulations

Comments on this entry are closed.