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 themin
and thelow
values, then the lower range is considered to be the preferred zone.high ≤ optimum ≤ max
– If the optimum value is between thehigh
and themax
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
- All the above mentioned attributes may be floating point numbers e.g. 12, -8, 3.625
- 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)
- 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…
- indicate the progress completion of a task (use
progress
element instead). - 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.
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.
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.
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.
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;
}
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%;
}
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. */
}
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; }
}
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;
}
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
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.
meter
element in Firefox 25Pseudo 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-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
- Official W3C Spec for meter
- MDN docs for meter
- HTMl5Doctor: Measure up with the meter tag
The HTML5 meter Element is a post from CSS-Tricks
The post The HTML5 meter Element appeared first on Blogs-design.com.