public
Last active

  • Download Gist
meter-polyfill.css
CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
meter{
display: block;
border: 1px outset;
height: 20px;
width: 100px;
overflow: hidden;
}
meter div
{
display: block;
border-right:1px solid #000;
height: 20px;
background: #b4e391; /* old browsers */
background: -moz-linear-gradient(top, #b4e391 0%, #44AA00 35%, #b4e391 100%); /* firefox */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#b4e391), color-stop(35%,#44AA00), color-stop(100%,#b4e391)); /* webkit */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#b4e391', endColorstr='#b4e391',GradientType=0 ); /* ie */
}
.meterValueTooHigh div, .meterValueTooLow div{
background: #ffd65e; /* old browsers */
background: -moz-linear-gradient(top, #ffd65e 0%, #FBFF47 35%, #febf04 100%); /* firefox */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffd65e), color-stop(35%,#FBFF47), color-stop(100%,#febf04)); /* webkit */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffd65e', endColorstr='#febf04',GradientType=0 ); /* ie */
}
.meterIsMaxed
{
border-right: 0px none !important;
}
meter-polyfill.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
// hack for backwards compatibility
document.createElement('meter');
// create polyfill
function makeMeter(meterElement) {
// parse values and attributes
function attr(attributeName, defaultValue) {
return meterElement.getAttribute(attributeName) != null ?
meterElement.getAttribute(attributeName) :
(defaultValue ? defaultValue : null);
}
function addClass(classStr) {
var classes = meterElement.className.split(' ');
if (classes.length == 0) {
meterElement.className = classStr;
return;
}
for (classStrVal in classes) {
if (classStr == classStrVal) { return; }
}
classes.push(classStr);
meterElement.className = classes.join(' ');
}
function removeClass(classStr) {
var classes = meterElement.className.split(' ');
var i = classes.length;
while (i--) {
if (classes[i] == classStr) {
classes.splice(i, 1);
break;
}
}
meterElement.className = classes.join(' ');
}
 
function getFormParent() {
var element = meterElement;
while (element.parent && element.parent.tagName.toLowerCase() != 'form') {
element = element.parent;
}
if (element.tagName.toLowerCase() == 'form') {
return element;
}
return null;
}
 
function getFormLabels() {
var id = meterElement.id;
if (id == null || this.form == null) {
return null;
}
var elementsLabels = [];
// otherwise loop through the form's child label elements
// looking for the element that has a for="{this.id}"
var labels = this.form.getElementsByTagName('label');
for (label in labels) {
if (label['for'] == id) {
elementsLabels.push(label);
}
}
if (elementsLabels.length > 0) {
return elementsLabels;
}
return null;
}
 
this.min = parseFloat(attr('min', 0)); // default as per HTML5 spec
this.max = parseFloat(attr('max', 1)); // default as per HTML5 spec
this.high = parseFloat(attr('high'));
this.low = parseFloat(attr('low'));
this.optimum = parseFloat(attr('optimum'));
// TODO: make this look for 'innerText' if the attribute doesn't exist
this.value = attr('value') != null ? parseFloat(attr('value')) : (meterElement.textContent ? meterElement.textContent : meterElement.innerText);
 
if (meterElement.textContent) {
meterElement.textContent = '';
} else if (meterElement.innerText) {
meterElement.innerText = '';
}
this.onchange = function() { alert(1); };
 
this.title = attr('title') != null ? attr('title') : this.value;
this.form = getFormParent();
this.labels = getFormLabels();
 
/*
The following inequalities must hold, as applicable:
minimum ≤ value ≤ maximum
minimum ≤ low ≤ maximum (if low is specified)
minimum ≤ high ≤ maximum (if high is specified)
minimum ≤ optimum ≤ maximum (if optimum is specified)
low ≤ high (if both low and high are specified)
*/
 
if (this.value < this.min) {
this.value = this.min;
}
 
if (this.value > this.max) {
this.value = this.max;
}
 
if (this.low != null && this.low < this.min) {
this.low = this.min;
}
 
if (this.high != null && this.high > this.max) {
this.high = this.max;
}
 
if (meterElement.children.length == 0) {
var indicator = document.createElement("div");
} else {
indicator = meterElement.children[0];
}
 
var width = meterElement.offsetWidth;
width *= this.value / this.max;
 
indicator.style.width = Math.ceil(width) + 'px';
 
if (this.high && this.value >= this.high) {
addClass("meterValueTooHigh");
}
else if (this.low && this.value <= this.low) {
addClass("meterValueTooLow");
} else {
removeClass("meterValueTooHigh");
removeClass("meterValueTooLow");
}
 
if (this.value >= this.max) {
addClass('meterIsMaxed');
} else {
removeClass('meterIsMaxed');
}
 
meterElement.title = this.title;
 
 
if (meterElement.children.length == 0) {
meterElement.appendChild(indicator);
}
 
}
window.onload = function() {
var meters = document.getElementsByTagName('meter');
var i = meters.length;
while (i--) {
makeMeter(meters[i]);
}
}
meter.html
Liquid
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
<!DOCTYPE html>
 
<html>
<head>
<title>Meter</title>
<meta charset="utf-8" />
<style>
@import url('meter-polyfill.css');
</style>
<script type="text/javascript" src="meter-polyfill.js"></script>
</head>
<body>
<dl>
<dt>Normal</dt>
<dd><meter min="0.6" value="4.89" max="5.09"></meter></dd>
<dt>Too High</dt>
<dd><meter min="0" high="8" value="9" max="10"></meter></dd>
<dt>Too Low</dt>
<dd><meter min="0" low="3" value="2" max="10"></meter></dd>
<dt>Optimal</dt>
<dd><meter min="0" value="5" max="10"></meter></dd>
<dt>Text value in meter node</dt>
<dd><meter min="0" value="5" max="10">Cooties</meter></dd>
 
<dt>High greater than Max</dt>
<dd><meter min="0" value="5" max="10"></meter></dd>
<dt>Low greater than Min</dt>
<dd><meter min="0" high="8" value="9" max="10"></meter></dd>
 
<dt>Value greater than Max</dt>
<dd><meter min="4" value="11" max="10"></meter></dd>
<dt>Value lesser than Min</dt>
<dd><meter min="4" value="0" max="10"></meter></dd>
</dl>
 
</body>
</html>

Meter polyfill to give developers the use of the HTML5 meter element in other browsers.

also for Firefox 4, i can you this
"-moz-appearance:progressbar;" , "progresschunk"
demo:
http://hostel6.ru/tv/tmp/magic.html

The code Yaffle tried to post was the following:

<progress style="-moz-appearance:progressbar;display:inline-block;width:200px;" min="0" value="5" max="10">
<div style="-moz-appearance:progresschunk;width:50%;"></div>
</progress>

mathiasbynens, tnx

These are both forked from yours....

An updated CSS File:
https://gist.github.com/1346633

A polyfill assuming you have jQuery (to handle your addClasses and things):
https://gist.github.com/1346631

Currently broken in IE8, but close :)

I'm having several problems with this.

1) This changes my layout from 1 meter 10 to:

1
meter
10

2) I don't know how to change the value via javascript (on fallback browsers).

var rwMeter = document.getElementById("RearWidth");
rwMeter.value = rwv;

works on browsers that support but doesn't work with the polyfill.

3) This:

doesn't work properly with the polyfill (no value displayed).

"This" was a meter with a negative min, a positive max, with a value of zero. -110 min 10 max value zero should show the meter mostly full, but in poly fill it shows nothing.

For #1, I commented out the "display:block" in the meter css.

For #3, I changed the javascript:

var width = meterElement.offsetWidth;
width *= (this.value - this.min) / (this.max - this.min);

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.