
So, what's the available methods for creating a progress bar on Roll20 sheets? Like with many things, we are somewhat restricted in what we can do in Roll20, so HTML elements like <progress> and <meter> doesn't seems to be supported by Roll20.
In this list I'll display the various methods that could be used within Roll20 to create a Progress/Health bar, and I hope people comment with their own takes, and mentions any existing sheets that have implemented this subject well. I'll link this thread to the relevant CSS Wizardry section, and update my post if new methods or improvements are figured out.
Methods for creating a progress bar on Roll20 Character sheets
1. CSS Wizardry Method - Custom Progress Bar
There is the CSS Wizardry example Custom Progress Bar that can be used, which essentially styles a generic element like <div> to look a certain way depending on the value of an <input> inside of it. You can just show show the bar at different length depending on the value, or you can add some color variation depending on if it's high or low. Original Thread
But this method seems to result in the max value & any threshold values to bee hardcoded to the css, and can't be made a variable with a _max attribute.
<div class="sheet-container"> <input type="hidden" value="2" name="attr_Character_overweight" class="sheet-hidden sheet-overweight"> <div class="sheet-overweight"></div> </div>
div.sheet-overweight { width: 90%; height: 20px; border: 1px solid black; color: black; text-align: center; } input.sheet-overweight[value="0"] ~ div.sheet-overweight { background: white; } input.sheet-overweight[value="1"] ~ div.sheet-overweight { background: linear-gradient(to left, white 60%, green 75%); } input.sheet-overweight[value="2"] ~ div.sheet-overweight { background: linear-gradient(to left, white 40%, yellow 75%); } input.sheet-overweight[value="2"] ~ div.sheet-overweight:before { content:"Bags half full"; } input.sheet-overweight[value="3"] ~ div.sheet-overweight { background: linear-gradient(to left, white 20%, orange 75%); } input.sheet-overweight[value="3"] ~ div.sheet-overweight:before { content: "Bags nearly full"; } input.sheet-overweight[value="4"] ~ div.sheet-overweight { background: linear-gradient(to left, white, red 100%); } input.sheet-overweight[value="4"] ~ div.sheet-overweight:before { content: "Bags full !"; } input.sheet-overweight[value="5"] ~ div.sheet-overweight { background: black; color: white; } input.sheet-overweight[value="5"] ~ div.sheet-overweight:before { content: "Bags too heavy !"; }
2. CSS Wizardry Method - Modify "Fill Radio Buttons to the Left"
There is the CSS Wizardry example Fill Radio Buttons to the Left, which uses either <input type["radio"]> or a <button type"action">, plus a <span> element to display a row of radio buttons that are progressively filled out. The elements could be styled and placed close together to make it look like a progress bar instead of a row of dots.
This method seems to me be more easily adjusted to accommodate a customizable _max value that selectively hides some elements to show the max length of the bar.
<div class="dots"> <input type="hidden" name="attr_strength" class="dot" value="1" /> <button type="action" name="act_strength_1" class="dot"> <span class="checked"></span> </button> <button type="action" name="act_strength_2" class="dot gt-1"> <span class="checked"></span> </button> <button type="action" name="act_strength_3" class="dot gt-1 gt-2"> <span class="checked"></span> </button> <button type="action" name="act_strength_4" class="dot gt-1 gt-2 gt-3"> <span class="checked"></span> </button> <button type="action" name="act_strength_5" class="dot gt-1 gt-2 gt-3 gt-4"> <span class="checked"></span> </button> </div> <script type="text/worker"> const strengthValues = ["1","2","3","4","5"]; strengthValues.forEach(function(value) { on(`clicked:strength_${value}`, function() { setAttrs({ "strength": value }); }); }); </script>
.sheet-dots{
display:flex;
}
/* Configure the button styling. This example makes it look like a radio. */ button.sheet-dot { padding: 0; border: solid 1px #a8a8a8; cursor: pointer; width: 14px; height: 14px; border-radius: 50%; display: flex; justify-content: center; align-items: center; } button.sheet-dot > span { width: 6px; height: 6px; border-radius: 50%; background: buttontext; } /* Hide the "checked" section of the radio if the hidden attribute value is greater than the button value */ input.sheet-dot[value="1"] ~ button.sheet-gt-1 > span.sheet-checked { display: none; } input.sheet-dot[value="2"] ~ button.sheet-gt-2 > span.sheet-checked { display: none; } input.sheet-dot[value="3"] ~ button.sheet-gt-3 > span.sheet-checked { display: none; } input.sheet-dot[value="4"] ~ button.sheet-gt-4 > span.sheet-checked { display: none; }
3. Using <input type="range">
<input type="range"> looks like a volume slider, but it might be possible to style it heavily with CSS to instead look like a progress bar.
It is confirmed to work in Roll20, and adjusting it's positing seems best achieved by have another input keyed to the same attribute.
More info:
In this example I've hidden the slider button, and color-coded the slider before and after the slider button with different colors to tell them apart. I then use the duplicate input to set the hp to a value within the range(0-10 in this example).
<div class="health-bar">
<span>HP:</span>
<input name="attr_hp" class="rangetest" type="range" min="0" max="10" value="10">
<input name="attr_hp" class="rangetest" type="number" value="10">
</div>
input[type="range"].sheet-rangetest{
width: 100px;
}
/* works only on firefox atm */
input[type="range"].sheet-rangetest::-moz-range-thumb{
background: transparent;
border-color: transparent;
color: transparent;
}
input[type="range"].sheet-rangetest::-moz-range-progress{
background: green;
height: 10px;
}
input[type="range"].sheet-rangetest::-moz-range-track{
background: red;
height: 10px;
}
Methods that doesn't work: <progress> & <meter> elements
I've tried both, and neither seems to be supported by Roll20, which is too bad as they are elements that are made for this kind of thing. The <progress> and <meter> elements would be perfect for this, and if Roll20 creates a method for dynamically adjusting the min and max value limits of <input> and these new elements, like optionally keying them to attributes with _min and _max in their name. It would enable nice progress bars on the sheet & enhance existing elements if you can now adjust the min/max for attribute fields.
<meter> does have a few fun things like low and high thresholds, that adjusts the color of the bar. If roll20 would enable adjusting the min and max values with my suggested method, it could probably be easily extended to something like _low and _high
Something like this would be great:
<label>HP:</label>
<meter
min="0" max="100"
low="33" high="66" optimum="100"
value="50" name="attr_hp">
</meter>
<input type="hidden" min="0" max="100" value="50" name="attr_hp">
<input type="hidden" value="0" name="attr_hp_min">
<input type="hidden" value="100" name="attr_hp_max">
<input type="hidden" value="33" name="attr_hp_low">
<input type="hidden" value="66" name="attr_hp_high">
Existing Sheets using Progress bars
Here we list the sheets with the best existing progress bar implementations. Looking at them might give us hints on how to make a better versions in the future.
(I don't know any examples yet)