Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

CSS Styling based on Current/Max health attribute

1604890172
Richard T.
Pro
Marketplace Creator
Sheet Author
Compendium Curator
Looking for some help brainstorming a good way to do what the title says. Is there a pure CSS way to do this or should I use sheetworkers? Sheetworkers are still greek to me so I'd prefer to do it with html/css.
1604894314
GiGs
Pro
Sheet Author
API Scripter
You can likely use pure CSS. It would help to know some details on what specific styling you want to create, and the code for the inputs for the current/max attributes, and what values you want the styling to happen on.
1604904965
Richard T.
Pro
Marketplace Creator
Sheet Author
Compendium Curator
Sure, its nothing too fancy, just recolor a background color on a div.  <div class="armorcard armor-h">     <div class="flexrow">H <input type="number" name="attr_armor-current-h" value="0"></div>     <div class="flexrow">MX <input type="number" name="attr_armor-max-h" value="0"></div> </div> It looks like this currently: with this styling: .sheet-armorcard div {     background: #098C87;     padding: 0px 5px; } A number of armor cards are given a current and max amount of armor.  I'd like to be able to use background-color based on percentage of armor left.  Undamaged: #098C87 50%+: #e28800 50%-: #EB4511 Destroyed (0): #463c66
1604935652
Tetrakern
Sheet Author
Compendium Curator
You can use a hidden-type input as preceding element to style the others with the [value=X] and sibling selectors. However, unless your armor values are already percentages, you need to do some calculations first. Either with an auto-calculation and some clever rounding or a sheetworker since [value=X] only works with absolut values. You cannot specify a range. Unless you use the :in-range and  :out-of-range pseudo-selectors with a hidden number-type input in the same vein. Plus some :not() voodoo; maybe, didn't test it. You would probably still need another control element to account for zero and max, overriding the range selectors, but that should be easy.
1604936547

Edited 1604936644
GiGs
Pro
Sheet Author
API Scripter
In that case you will need to use a sheet worker, to set the value of an attribute. Edit : i wasnt aware of the in-range and out-of-range selectors. I'll have to check them out for the future, but the method below is pretty reliable. The problem is in CSS you can only check against string values - there's no way to include calculations, like check if an attribute is below half of another value. You solve this by creating a sheet worker, to create an attribute based on those calculations. If the armour is undamaged it has a value of 0, if below 50% max, it will have  value of 1; if its over 50%, a value of 2, and if max or over, a value of 3. You can then check for those values in the CSS. So, here's how to do it. First create the new attribute, and give it both  a name (which you need for it to work) and a class (which you need for the CSS part). <input type="hidden" name="attr_armour_css" class="armour-damage" value="0" > That should be placed in the html just before the armour card, like so. If its not placed there, the CSS wont work. <input type="hidden" name="attr_armour_css" class="armour-damage" value="0" > <div class="armorcard armor-h">     <div class="flexrow">H <input type="number" name="attr_armor-current-h" value="0"></div>     <div class="flexrow">MX <input type="number" name="attr_armor-max-h" value="0"></div> </div> Then a sheet worker like this: on('change:armor-current-h change:armor-max-h', () => {     getAttrs(['armor-current-h', 'armor-max-h'], values => {         const current = parseInt(values['armor-current-h']) || 0;         const max = parseInt(values['armor-max-h']) || 0;         const css = (current === 0) ? 0 : (current < Math.ceil(max/2)) ? 1 : (current < max) ? 2 : 3;         setAttrs({             armour_css: css         });     }); }); and finally the CSS: div.sheet-armorcard div {     background: #098C87;     padding: 0px 5px; } input[type="hidden"].sheet-armor-damage[value="1"] ~ div.sheet-armorcard div {     background: #E28800; } input[type="hidden"].sheet-armor-damage[value="2"] ~ div.sheet-armorcard div {     background:  #EB4511; } input[type="hidden"].sheet-armor-damage[value="3"] ~ div.sheet-armorcard div {     background: #463c66; } I've assumed here that the current stat shows the damage taken. If it shows the damage remaining,  change a line in the sheet worker to this:         const css = (current === 0) ? 3 : (current < Math.ceil(max/2)) ? 2 : (current < max) ? 1 : 0;
1604948214
Richard T.
Pro
Marketplace Creator
Sheet Author
Compendium Curator
How would I expand the sheetworker if I have multiple similarly named armor locations? The attribute names are patterned after: attr_armor-current-X attr_armor-max-X
1604949816
GiGs
Pro
Sheet Author
API Scripter
It can be done - you'll need a different hidden input for each, but the only thing that should change is its name, not its class. Lets say the one for above becomes <input type="hidden" name="attr_armour_css-h" class="armour-damage" value="0" > Then in the sheet worker, you need to create an array for each possible -X ending, and modify the sheet worker accordingly, like so: const armorendings = ['h', 'a', 'b', 'c']; armorendings.forEach(end => {     on(`change:armor-current-${end} change:armor-max-${end}`, () => {         getAttrs([`armor-current-${end}`, `armor-max-${end}`], values => {             const current = parseInt(values[`armor-current-${end}`]) || 0;             const max = parseInt(values[`armor-max-${end}`]) || 0;             const css = (current === 0) ? 0 : (current < Math.ceil(max/2)) ? 1 : (current < max) ? 2 : 3;             setAttrs({                 [`armour_css-${end}`]: css             });         });     }); }); just add all the endings to that armorendings array at the start. That one line is the only one that needs any changes. Then the CSS needs a slight tweak: div.sheet-armorcard div {     background: #098C87;     padding: 0px 5px; } input[type="hidden"].sheet-armor-damage[value="1"] ~ div.sheet-armor-h div {     background: #E28800; } input[type="hidden"].sheet-armor-damage[value="2"] ~ div.sheet-armor-h div {     background:  #EB4511; } input[type="hidden"].sheet-armor-damage[value="3"] ~ div.sheet-armor-h div {     background: #463c66; } That said, I just noticed your armor card has different colors for your current and max boxes, so the html I posted earlier and CSS might not be quite right, if you want different styling on the current and max boxes.
1604951417
Richard T.
Pro
Marketplace Creator
Sheet Author
Compendium Curator
Mech pilots salute you, GiGs
1604951569
GiGs
Pro
Sheet Author
API Scripter
Yay! :)