Grow your CSS skills. Land your dream job.

The HTML5 meter Element

Published by Guest Author

The following is a guest post by Pankaj Parashar. Pankaj has written here before, last time about the progress element. Fitting indeed then to write again about the very related meter element. They are different both functionally and semantically, so read on!

As defined by W3C,

The meter element represents a scalar measurement within a known range, or a fractional value; for example disk usage, the relevance of a query result, or the fraction of a voting population to have selected a particular candidate. This is also known as a gauge.

If you are like me, the above spec wouldn't make much sense until we dive deep into the implementation. So let's just start with a basic markup for the meter element:

<meter></meter>

Similar to its sibling - the progress element - a meter element must also have both a start tag (<meter>) and an end tag (</meter>). This becomes very useful when we devise a robust fallback technique for older browsers that do not support the meter element, later in this article.

Content model

The meter element uses the phrasing content model which means it can contain the text of the document, along with the elements that mark up that text, but there must be no (additional) meter element among its descendants.

Attributes

Apart from the global attributes, the meter element can have 6 more attributes.

value - A floating point number that represents the current value of the measured range. This must be between the min and the max value (if specified).

min - Indicates the lower bound of the measured range. This must be less than the max value (if specified). If unspecified, the minimum value is 0.

max - Indicates the upper bound of the measured range. This must be greater than the min value (if specified). If unspecified, the maximum value is 1.0.

low - It represents the upper bound of the low end of the measured range. This must be greater than the min attribute, but less than the high and max value (if specified). If unspecified, or if less than the minimum value, the low value is equal to the min value.

high - It represents the lower bound of the high end of the measured range. This must be less than the max attribute, but greater than the low and min value (if specified). If unspecified, or if greater than the max value, the high value is equal to the max value.

optimum - This attribute indicates the optimum value and must be within the range of min and max values. When used with the low and high attribute, it indicates the preferred zone for a given range. For example:

  • min ≤ optimum ≤ low - If the optimum value is between the min and the low values, then the lower range is considered to be the preferred zone.
  • high ≤ optimum ≤ max - If the optimum value is between the high and the max values, then the upper range is considered to be the preferred zone.

A meter with everything would look like:

<meter min="0" low="10" optimum="50" high="90" max="100"></meter>

Rules of thumb

  1. All the above mentioned attributes may be floating point numbers e.g. 12, -8, 3.625
  2. Based on the definition of each attribute the following inequalities become true,
    • min ≤ value ≤ max
    • min ≤ low ≤ high ≤ max (if low/high specified)
    • min ≤ optimum ≤ max (if optimum specified)
  3. There is no explicit way to specify units in the meter element, but the authors are encouraged to specify the units using the title attribute. For example, <meter max="256" value="120" title="GB">120GB out of 256GB are used</meter>

Do not use meter element to...

  1. indicate the progress completion of a task (use progress element instead).
  2. represent a scalar value of an arbitrary range — for example, to report a weight, or height of a person.

Experiment #1 - Different states of meter element

This experiment shows the various states of the meter element under different combination of input values for each attribute. Feel free to edit the attribute values of the main code to tweak the meter gauge ouput.

See the Pen HTML5 Meter Element by Pankaj Parashar (@pankajparashar) on CodePen

Experiment #2 - OSX style disk usage

In this experiment, we'll try and simulate the appearance of the disk usage panel in OS X using the meter element and then style it as cross-browser as possible.

Populating internal attributes of our meter tag with the known set of input values.

  • Total size of the disk - 120.47GB (our max attribute)
  • Current disk usage - 55.93GB (our value attribute)
  • Minimum disk size - 0 (our min attribute, not required as the default value is 0)
  • Unit - GB (our title attribute that specifies the unit)
<meter max="120" value="55.93" title="GB"></meter>

Before we apply any CSS, the meter gauge looks like this in Chrome 30 on OX X 10.9.


Default appearance of the meter element in Chrome 30 on OS X 10.9

Although the spec recommends including a textual representation of the gauge's state inside the meter tag for older browsers, we'll keep it blank for now to add the fallback content later in this article to support them.

This is pretty much all that we can do in HTML as rest of the work is done by CSS. At this stage let's not worry about the fallback techniques for supporting older browsers that don't understand the meter element.

Styling the meter element

Just like any other element, we can define dimensions by specifying width and height for meter.

meter {
  width: 500px;
  height: 25px;
}

This is where things become interesting because generally most of the A-grade browsers provide separate pseudo classes to style the meter element. Although Opera moving to Blink leaves us with less browsers to care for. At this stage, we don't really have to know about which versions of each browser support the meter element, because our fallback technique will take care of the rest. We classify them as follows:

  • Webkit/Blink
  • Firefox
  • Internet Explorer

1. Webkit/Blink (Chrome/Safari/Opera/iOS)

On inspecting the meter element via Chrome Developer Tools, we can reverse-engineer the implementation of the spec in webkit browsers.


Inspect element on Chrome DevTools

In addition, the User-Agent stylesheet of WebKit provides a wealth of information on how you can use various pseudo classes to access different states of the meter element.


User-Agent stylesheet of WebKit browsers

Pseudo class Description
-webkit-meter-inner-element Additional markup to render the meter element as read-only.
-webkit-meter-bar Container of the meter gauge that holds the value.
-webkit-meter-optimum-value The current value of the meter element and is by default green when the value attribute falls inside the low-high range.
-webkit-meter-suboptimum-value Gives a yellow color to the meter element when the value attribute falls outside the low-high range.
-webkit-meter-even-less-good-value Gives a red color to the meter element when the value and the optimum attributes fall outside the low-high range but in opposite zones. For example, value < low < high < optimum or value > high > low > optimum

First, let's start by resetting the default appearance of the meter gauge by using -webkit-appearence: none;

meter {
  width: 500px;
  height: 25px;
  -webkit-appearance: none; /* Reset appearance */
  border: 1px solid #ccc;
  border-radius: 3px;
}

For this experiment, we will only be using -webkit-meter-bar (to style the container) and -webkit-meter-optimum-value (to style the value) pseudo classes. Each color in background linear gradient represents the space consumed by the sub-categories like - Apps, Movies, Photos etc.


WebKit pseudo classes on the meter element

meter::-webkit-meter-bar {
  background: none; /* Required to get rid of the default background property */
  background-color: whiteSmoke;
  box-shadow: 0 5px 5px -5px #333 inset;
}

Output after styling the background container

meter::-webkit-meter-optimum-value {
  box-shadow: 0 5px 5px -5px #999 inset;
  background-image: linear-gradient(
    90deg, 
    #8bcf69 5%, 
    #e6d450 5%,
    #e6d450 15%,
    #f28f68 15%,
    #f28f68 55%,
    #cf82bf 55%,
    #cf82bf 95%,
    #719fd1 95%,
    #719fd1 100%
  );
  background-size: 100% 100%;
}

Output after styling the meter gauge value

CSS3 Transition/Animation

WebKit browsers support both transition and animation on the meter element. Just for the sake of testing, I experimented by changing the width of the value(on :hover) using transitions and animating the background position of the container using keyframes. Although not applicable for practical usage, both the experiments turned out pretty well on all three browsers.

meter::-webkit-meter-optimum-value {
  -webkit-transition: width .5s;
}

meter::-webkit-meter-optimum-value:hover {
  /* Reset each sub-category to 20% */
  background-image: linear-gradient(
    90deg, 
    #8bcf69 20%, 
    #e6d450 20%,
    #e6d450 40%,
    #f28f68 40%,
    #f28f68 60%,
    #cf82bf 60%,
    #cf82bf 80%,
    #719fd1 80%,
    #719fd1 100%
  );
  transition: width .5s;
  width: 100% !important; /* !important required. to override the inline styles in WebKit. */
}

CSS3 Transitions in action (:hover)

meter::-webkit-meter-bar {
  /* Let's animate this */
  animation: animate-stripes 5s linear infinite;
  background-image:
    linear-gradient(
      135deg,
      transparent,
      transparent 33%,
      rgba(0, 0, 0, 0.1) 33%,
      rgba(0, 0, 0, 0.1) 66%,
      transparent 66%
    );
  background-size: 50px 25px;
}

@keyframes animate-stripes {
  to { background-position: -50px 0; }
}

CSS3 Animated background stripes in action

Pseudo Elements

At the time of writing, only webkit browsers support pseudo elements on meter gauge. For this experiment, we could use the pseudo elements to display the meta information like HD Name, Free space right above the meter gauge.

meter {
  margin: 5em;
  position: relative;
}

meter::before {
  content: 'Macintosh HD';
  position: absolute;
  top: -100%;
}

meter::after {
  content: '64.54 GB free out of 120.47 GB';
  position: absolute;
  top: -100%;
  right: 0;
}

Pseudo elements in action

Apart from WebKit, the support for pseudo elements in other browsers is non-existent. Hence, there is no good reason to embed content inside pseudo elements, at least for now.

2. Firefox


Firebug screenshot (on inspecting the meter element in Firefox 25)

Similar to WebKit, Firefox uses -moz-appearence: meterbar to paint the meter gauge. We can get rid of the default bevel and emboss by resetting it to none.

meter {
  /* Reset the default appearence */
  -moz-appearance: none;
  width: 550px;
  height: 25px;
}

Firefox is shipped with a wholesome list of pseudo classes to style different states of the meter gauge. The snapshot below has been grabbed from the forms.css file that can be accessed from inside Firebug.


[forms.css] snapshot for meter element in Firefox 25

Pseudo class Description
-moz-meter-bar Represents the current value of the meter gauge that can be used to style the properties of the meter gauge value.
-moz-meter-optimum It gives a green color to the meter element when the value attribute falls inside the low-high range.
-moz-meter-sub-optimum It gives a yellow color to the meter element when the value attribute falls outside the low-high range.
-moz-meter-sub-sub-optimum It gives a red color to the meter element when the value and the optimum attributes fall outside the low-high range but in opposite zones. For example, value < low < high < optimum or value > high > low > optimum

For this experiment, we will only use ::-moz-meter-bar to style the background of the meter gauge value.

meter::-moz-meter-bar {
  box-shadow: 0 5px 5px -5px #999 inset;
  background-image: linear-gradient(
    90deg, 
    #8bcf69 5%, 
    #e6d450 5%,
    #e6d450 15%,
    #f28f68 15%,
    #f28f68 55%,
    #cf82bf 55%,
    #cf82bf 95%,
    #719fd1 95%,
    #719fd1 100%
  );
  background-size: 100% 100%;
}

Interestingly, in Firefox you can style the background of the container using the meter selector itself.

meter {
  /* Firefox */
  background: none; /* Required to get rid of the default background property */
  background-color: whiteSmoke;  
  box-shadow: 0 5px 5px -5px #333 inset;
}

Firefox doesn't support ::before and ::after pseudo elements on the meter gauge. The support for CSS3 transitions and animation is a bit shaky as well. Hence, there is no good reason to use them until the behavior becomes consistent across browsers.

3. Internet Explorer

To my knowledge, no stable version of Internet Explorer supports the meter element. Even the Modernizr test suite failed to detect meter in IE11 preview on Windows 8.1. This perhaps leaves us only with the fallback approaches that will be discussed in the next section.

if ('value' in document.createElement('meter')) {
  alert("Meter element is supported");
} else {
  alert("Meter element Not supported");
}

What about browsers that don't support meter?

Can I Use (and simple testing) reports the meter gauge is natively supported in: Firefox 16+, Opera 11+, Chrome, Safari 6+. Internet Explorer, however offers no support what-so-ever for any version. If you want to make meter element work in older browsers, then you've got two options:

1. Polyfill

Randy Peterman has written a polyfill that makes meter element work in older browsers (especially IE). During my cross-browser testing, I found that the polyfill works for all IE browsers down to IE6! which makes it a good candidate for usage in production.

2. HTML fallback

This is my preferred (no-JS) approach. It makes use of a common technique that was also discussed in my previous article for CSS-Tricks on the HTML5 progress element.

<meter value="55.93" min="0" max="120.47" title="GB">
  <div class="meter-gauge">
    <span style="width: 46.42%;">Disk Usage - 55.93GB out of 120GB</span>
  </div>
</meter>

The idea is to simulate the appearance of a meter gauge using div and span inside the meter tag. Modern browsers that support meter will ignore the content within the tag. Older browsers that cannot render the meter element will ignore the tag and render the markup inside it.

.meter-gauge {
    border: 1px solid #ccc;
    border-radius: 3px;
    background-color: whiteSmoke;
    box-shadow: 0 5px 5px -5px #333 inset;
    width: 550px;
    height: 25px;
    display: block;
}

.meter-gauge > span {
  height: inherit;  
  box-shadow: 0 5px 5px -5px #999 inset;
  background-color: blue;
  background-image: linear-gradient(
    90deg, 
    #8bcf69 5%, 
    #e6d450 5%,
    #e6d450 15%,
    #f28f68 15%,
    #f28f68 55%,
    #cf82bf 55%,
    #cf82bf 95%,
    #719fd1 95%,
    #719fd1 100%
  );
  background-size: 100% 100%;
  display: block;
  text-indent: -9999px;
}

It is fairly common to use both the techniques in conjunction and it is perfectly safe for usage in production sites. The demo should run fine for all the browsers including Internet Explorer (down to IE6!). The meter gauge color is blue in all the versions of Internet Explorer. Opera 11 and 12 doesn't permit changing the color of the meter gauge. Hence, it shows the default green color. The demo also uses some additional markup to display the disk usage of each sub-category like Apps, Movies, Photos etc.

See the Pen OSX-style Disk Usage by Pankaj Parashar (@pankajparashar) on CodePen

More Resources

Comments

  1. Permalink to comment#

    Thanks Pankaj and Chris (of course). Awesome post, took me a while to read it. Thank you!

  2. Dale McCarld
    Permalink to comment#

    Wow my that’s so cool. Thanks for posting this!

  3. Chrissy
    Permalink to comment#

    I needed this the other day while working on the CSSOff! I had done a search on this site and only found <progress>. You do a much better job of explaining how to style than any other site I was able to find.

  4. Permalink to comment#

    This is all nice and good but I think this tag is totally unnecessary.
    I fear we may be overengineering this one.

    • LorDex
      Permalink to comment#

      actually i kinda agree with you…

    • DarrenM
      Permalink to comment#

      I don’t know how widely useful it would be, but I have a specific application for which this tag would be perfect.

      I have a site which uses horizontal bar charts to reflect a score, and those bars look very similar to the default appearance of this tag. The scores are between 1 and 10, scores below 4.5 are considered low, scores above 7.5 are considered high and 5.5 is the optimum. It’s a perfect fit for this tag.

      At the moment I am producing the bars with SVG, which works and looks fine. However if you look at the HTML, all you see is a bunch of meaningless SVG drawing lines and polygons. With this tag, you would see a perfect semantic representation of the chart. That has implications for accessibility at the very least.

      I would use it but for the lack of browser support, but I can see it being used down the track for sure.

    • The scenario that DarrenM described is a perfect use-case for the meter element.

      @DarrenM – I don’t think you should be discouraged with the lack of browser support as the fallback technique is quite robust and doesn’t add bunch of meaningless tags to the HTML (like SVG). Hope you find it useful!

  5. Mazurka
    Permalink to comment#

    for Case 16
    <meter low=”.25″ optimum=”.85″ high=”.75″ value=”.5″></meter>

    What’s a scenario where optimum would be greater than high? And why does meter turn yellow if it’s still in between low and high? is it because it’s less than optimum?

    Thanks, really deep article.

    • For Case 16 –

      <meter low=".25" optimum=".85" high=".75" value=".5"></meter>
      

      value is between the low-high range but the optimum value is between the high-max range (default value of max is 1.0), which means that the upper range is considered to be the preferred zone.

      Now since thevalue(.5) doesn’t fall in the optimum preferred zone (.85 – 1.0), the color of the meter gauge changes to yellow. This state has been documented in the article under Attributes section.

      I can’t think of practical scenarios where this would be applicable, but the idea was to elaborate on all the possibilities defined by the spec :-)

    • Mazurka
      Permalink to comment#

      ok thx, I forgot about “max range”

  6. Fanfan
    Permalink to comment#

    Hello,

    Thanks for this interesting post!
    I don’t understand why you say “Do not use meter to represent a scalar value of an arbitrary range — for example, to report a weight, or height of a person.” as it seems perfect to me for that usage. Am I missing something?

    • Tal Ben-Ari
      Permalink to comment#

      What would your max value be for weight or height? His example, disk usage, shows a value out of a maximum space available, which is why it works.

    • Fanfan
      Permalink to comment#

      Well, I guess I would choose an arbitrary value. If I’m a t-shirt seller, this could be 2,20 meter representing the max t-shirt’s size I have. But if i’m a pollster, i’d probably choose the max in guiness book, let’s say about 3 meters.
      Same thing if I want to represent someone with a 220gb hard drive and another guy with a 300gb one. In every case, that’s right, we have to fix a max value.

    • That’s valid argument. But I think you are still using an arbitrary number to decide on a maximum value.

      Although the meter tag would correctly represent this information but that doesn’t sit well with the overall semantics and the real intention of introducing the meter tag.

    • Fanfan
      Permalink to comment#

      Ok, I see what you mean.
      Practically, as each case is different, the dev will have to decide if it seems relevant to present his data with meter (and a max fixed by him).
      Thanks!

    • DarrenM
      Permalink to comment#

      I think it would depend on the application. If you conducted a survey of the heights of people in your workplace, then you would have a max and min value when you report it. It would make perfect sense to use the meter element to reflect that because you can display where a person’s height sits within the sample.

      The high, low and optimum attributes are optional. However you might decide that anyone outside two standard deviations from the mean is either low or high and you might want to reflect that for some (preferably non-discriminatory) reason. The optimum height might be short enough to walk through the tea room door without bumping your head but tall enough to reach things on the top shelf without needing a step :)

      I think the point is that the meter element needs to have known upper and lower bounds to provide a context for the value being reported. It can’t really be used to reflect the number of red cars you saw yesterday, but it can be used to express how many of the cars you saw yesterday were red.

    • Fanfan
      Permalink to comment#

      Exactly! It makes sense to represent a value if there are min (in most cases 0) and max values set as bounds.
      It doesn’t make sense to represent a stand-alone value (equal to the max, as there is only one value) like for example the weight of a single person. I now understand what Pankaj was meaning in the initial sentence. Thanks.

  7. Permalink to comment#

    Nice article, thanks. :) Just a small correction: I guess the second -moz-meter-sub-optimum in the table should be -moz-meter-sub-sub-optimum.

  8. Arjun
    Permalink to comment#

    Can someone make a tutorial to use the new html5 slider with javascript

  9. Give me an explanation about this sentence: “It represents the upper bound of the low end of the measured range.”

  10. Mark Ayers
    Permalink to comment#

    Looks better if you don’t change the ratios of the gradient while you’re resizing.
    Like this.

    • Tal Ben-Ari
      Permalink to comment#

      I think he was trying to make the colors match up with the legend at the bottom, but I agree, yours is definitely better (but I fail to understand why the expansion is necessary to begin with).

    • The expansion on :hover thing is just a basic idea to test CSS3 transitions on the meter tag. As I said in the article, there is no real meaning behind these experiments. I just wanted to test the different possibilities.

      But @Tal Ben-Ari is right, the idea was to align the width of each gradient with the legend below. But you can go with whatever approach that suits you the best :-)

  11. Permalink to comment#

    Nice write-up. I’ll definitely keep this link for reference. I view meter as a bit arcane, perhaps useful in specialized applications (like a downloader), but it’s part of the spec so we should keep an eye on it.

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".