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 Wizardry

1401391658

Edited 1494542224
Lithl
Pro
Sheet Author
API Scripter
EDIT: THE TRICKS IN THIS THREAD ARE NOW AVAILABLE&nbsp; ON THE WIKI . I'd like to share some cool things I've done with CSS for the Character Sheets (mine and others), and I'm sure other people have accomplished cool things as well. Hopefully, a repository of tricks will be able to make everyone's sheets better! Note: In my sample code that follows, I'm not using character sheet-specific stuff, like naming inputs "attr_*" or prefixing classes with "sheet-". These samples are meant to be illustrative of techniques, not snippets to blindly copy. Each sample comes with a link to a JSFiddle copy, so you can fiddle around with the code and better learn how it works. Styling Checkboxes and Radio Buttons Checkboxes and radio buttons don't like getting changed much. Instead, it can be easier to hide the actual checkbox/radio and put a more cooperative element underneath. For example : &lt;input type="checkbox" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="radio" name="r" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="radio" name="r" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="radio" name="r" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="radio" name="r" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="radio" name="r" /&gt;&lt;span&gt;&lt;/span&gt; /* Hide actual radio/checkbox */ input[type="radio"], input[type="checkbox"] { opacity: 0; width: 16px; height: 16px; position: relative; top: 5px; left: 6px; margin: -10px; cursor: pointer; z-index: 1; } /* Fake radio/checkbox */ input[type="radio"] + span::before, input[type="checkbox"] + span::before { margin-right: 4px; border: solid 1px #a8a8a8; line-height: 14px; text-align: center; display: inline-block; vertical-align: middle; -moz-box-shadow: 0 0 2px #ccc; -webkit-box-shadow: 0 0 2px #ccc; box-shadow: 0 0 2px #ccc; background: #f6f6f6; background: -moz-radial-gradient(#f6f6f6, #dfdfdf); background: -webkit-radial-gradient(#f6f6f6, #dfdfdf); background: -ms-radial-gradient(#f6f6f6, #dfdfdf); background: -o-radial-gradient(#f6f6f6, #dfdfdf); background: radial-gradient(#f6f6f6, #dfdfdf); } /* Fake radio */ input[type="radio"] + span::before { content: ""; width: 12px; height: 12px; font-size: 24px; -moz-border-radius: 50%; -webkit-border-radius: 50%; border-radius: 50%; } input[type="radio"]:checked + span::before { content: "•"; } /* Fake checkbox */ input[type="checkbox"] + span::before { content: ""; width: 14px; height: 14px; font-size: 12px; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; } input[type="checkbox"]:checked + span::before { content: "✓"; } The key here is the opacity: 0; set on the actual input, and then the width , height , and content set on the span::before immediately following the input. The checkbox/radio will be on top of the span: invisible, but still clickable. When the checkbox/radio is selected, then, the style on the span::before is changed. Do note that because of the way this is set up, if you do not have a span element immediately following your checkbox/radio button, the checkbox/radio button will not be visible. Alternative Checkboxes You're not restricted to a box with a check on it if you want a binary state (on or off). When styling your checkbox (or radio button!) you can use just about anything. For example : /* Fake checkbox */ input[type="checkbox"] + span::before { margin-right: 4px; line-height: 14px; text-align: center; display: inline-block; vertical-align: middle; content: "▼"; width: 14px; height: 14px; font-size: 12px; } input[type="checkbox"]:checked + span::before { content: "►"; } Now, instead of an empty box, or a box with a checkmark, you've got a right-pointing arrow or a down-pointing arrow. You can also use an image instead of a string, such as content: url(' <a href="http://i.imgur.com/90HuQPr.png" rel="nofollow">http://i.imgur.com/90HuQPr.png</a> ') Hide Areas In a similar fashion, you can hide areas on the character sheet based on the checkbox. Instead of the adjacent sibling selector ( + ), you should use the sibling selector ( ~ ). For example : &lt;div&gt; &lt;input type="checkbox" class="arrow" /&gt; &lt;h4&gt;Stuff and Things&lt;/h4&gt; &lt;div class="body"&gt; &lt;input type="text" placeholder="Name" /&gt;&lt;br /&gt; &lt;input type="text" placeholder="Description" /&gt; &lt;input type="number" min="0" max="20" value="0" /&gt;&lt;br /&gt; &lt;textarea placeholder="Fulltext"&gt;&lt;/textarea&gt; &lt;/div&gt; &lt;/div&gt; &lt;div&gt; &lt;input type="checkbox" class="arrow" /&gt; &lt;h4&gt;More Stuff&lt;/h4&gt; &lt;div class="body"&gt; &lt;input type="text" placeholder="Name" /&gt;&lt;br /&gt; &lt;input type="text" placeholder="Description" /&gt; &lt;input type="number" min="0" max="20" value="0" /&gt;&lt;br /&gt; &lt;textarea placeholder="Fulltext"&gt;&lt;/textarea&gt; &lt;/div&gt; &lt;/div&gt; &lt;div&gt; &lt;input type="checkbox" class="arrow" /&gt; &lt;h4&gt;Other Things&lt;/h4&gt; &lt;div class="body"&gt; &lt;input type="text" placeholder="Name" /&gt;&lt;br /&gt; &lt;input type="text" placeholder="Description" /&gt; &lt;input type="number" min="0" max="20" value="0" /&gt;&lt;br /&gt; &lt;textarea placeholder="Fulltext"&gt;&lt;/textarea&gt; &lt;/div&gt; &lt;/div&gt; input.arrow { float: left; } input.arrow:checked ~ div.body { display: none; } Whenever one of the checkboxes in this example is checked, the following div becomes hidden. Fill Radio Buttons to the Left This is one I'm particularly proud of; a number of games use a set of bubbles, filled in from left to right, to represent various traits. Radio buttons can only have one selected value, however, and if we used a set of checkboxes, it would be annoying to make the user click each and every one of them to set the character's attribute. Also, a set of checkboxes would make macros extremely ugly: @{Strength_1} * 1 + @{Strength_2} * 1 + ... However, with the radio button styling, we can solve this problem and use a radio button anyway, and only have one value. For example : &lt;input type="radio" name="r" checked="checked" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="radio" name="r" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="radio" name="r" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="radio" name="r" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="radio" name="r" /&gt;&lt;span&gt;&lt;/span&gt; /* Hide actual radio */ input[type="radio"] { opacity: 0; width: 16px; height: 16px; position: relative; top: 5px; left: 6px; margin: -10px; cursor: pointer; z-index: 1; } /* Fake radio */ input[type="radio"] + span::before { margin-right: 4px; border: solid 1px #a8a8a8; line-height: 14px; text-align: center; display: inline-block; vertical-align: middle; -moz-box-shadow: 0 0 2px #ccc; -webkit-box-shadow: 0 0 2px #ccc; box-shadow: 0 0 2px #ccc; background: #f6f6f6; background: -moz-radial-gradient(#f6f6f6, #dfdfdf); background: -webkit-radial-gradient(#f6f6f6, #dfdfdf); background: -ms-radial-gradient(#f6f6f6, #dfdfdf); background: -o-radial-gradient(#f6f6f6, #dfdfdf); background: radial-gradient(#f6f6f6, #dfdfdf); content: "•"; width: 12px; height: 12px; font-size: 24px; -moz-border-radius: 50%; -webkit-border-radius: 50%; border-radius: 50%; } /* Remove dot from all radios _after_ selected one */ input[type="radio"]:checked ~ input[type="radio"] + span::before { content: ""; } Here, all radio buttons are styled by default to appear as though they're checked. The radio buttons after the one that's actually checked then have the dot removed. The result is that the checked radio button and all of the ones to the left are "filled in," while the ones to the left are empty. You can invert this behavior (right of the checked radio are filled, checked and left of checked are empty) by swapping the two content lines. To reverse this behavior (checked radio and right of checked radio are filled, left of checked radio are empty), swap the two content lines and change the last selector to this: input[type="radio"]:checked ~ input[type="radio"] + span::before, input[type="radio"]:checked + span::before Note: If no radio button is selected, all of them will appear filled in (or all will appear empty if you've reversed/inverted the CSS). Therefore, it is wise to include checked="checked" on one of the radio buttons. That said, you may desire a "zero" value for the trait in question. I recommend having an extra radio button with value="0" checked="checked" and without the span element immediately following it. This will give you an initial value of 0, your radio button group will appear as intended, and the "zero" value will not show up to the user. Note: All radio buttons which are siblings will be affected by the selection of one of the radios. It is therefore recommended that you wrap the button group in some element, such as span or div. Circular Layouts Some character sheets have rather interesting layouts. Mage: the Ascension , for example, has a pair of traits called Quintessence and Paradox that are both mapped onto a wheel of checkboxes. While I'm not the author of the Mage sheet, I did help get a proper "wheel" look for the Q/P. For example : &lt;div&gt; &lt;div&gt; &lt;input type="checkbox" class="wheel wheel9 middle left-1" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="checkbox" class="wheel wheel27 mid-three-eighth left-2" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="checkbox" class="wheel wheel45 mid-quarter left-3" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="checkbox" class="wheel wheel63 mid-eighth left-4" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="checkbox" class="wheel wheel81 top left-5" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="checkbox" class="wheel wheel99 top left-6" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="checkbox" class="wheel wheel117 mid-eighth left-7" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="checkbox" class="wheel wheel135 mid-quarter left-8" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="checkbox" class="wheel wheel153 mid-three-eighth left-9" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="checkbox" class="wheel wheel171 middle left-10" /&gt;&lt;span&gt;&lt;/span&gt; &lt;/div&gt; &lt;div&gt; &lt;input type="checkbox" class="wheel wheel171 middle-2 left-1" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="checkbox" class="wheel wheel153 mid-five-eighth left-2" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="checkbox" class="wheel wheel135 mid-three-quarter left-3" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="checkbox" class="wheel wheel117 mid-seven-eighth left-4" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="checkbox" class="wheel wheel99 bottom left-5" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="checkbox" class="wheel wheel81 bottom left-6" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="checkbox" class="wheel wheel63 mid-seven-eighth left-7" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="checkbox" class="wheel wheel45 mid-three-quarter left-8" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="checkbox" class="wheel wheel27 mid-five-eighth left-9" /&gt;&lt;span&gt;&lt;/span&gt; &lt;input type="checkbox" class="wheel wheel9 middle-2 left-10" /&gt;&lt;span&gt;&lt;/span&gt; &lt;/div&gt; &lt;div class="marker"&gt;•&lt;/div&gt; &lt;/div&gt; /* Hide actual checkbox */ input[type="checkbox"] { position: absolute; opacity: 0; width: 15px; height: 15px; cursor: pointer; z-index: 1; margin-top: 6px; } /* Fake checkbox */ input[type="checkbox"] + span::before { border: solid 1px #a8a8a8; line-height: 14px; text-align: middle; display: inline-block; vertical-align: middle; -moz-box-shadow: 0 0 2px #ccc; -webkit-box-shadow: 0 0 2px #ccc; box-shadow: 0 0 2px #ccc; background: #f6f6f6; background: -moz-radial-gradient(#f6f6f6, #dfdfdf); background: -webkit-radial-gradient(#f6f6f6, #dfdfdf); background: -ms-radial-gradient(#f6f6f6, #dfdfdf); background: -o-radial-gradient(#f6f6f6, #dfdfdf); background: radial-gradient(#f6f6f6, #dfdfdf); position: relative; content: ""; width: 14px; height: 14px; font-size: 12px; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; } /* Styles unique to fake checkbox (checked) */ input[type="checkbox"]:checked + span::before { content: "✓"; color: #a00; -moz-box-shadow: 0 0 2px transparent; -webkit-box-shadow: 0 0 2px transparent; box-shadow: 0 0 2px transparent; } /* Position checkboxes vertically in circle */ input.top { margin-top: 5px; } input.top + span::before { top: 0px; } input.mid-eighth { margin-top: 12px; } input.mid-eighth + span::before { top: 7px; } input.mid-quarter { margin-top: 27px; } input.mid-quarter + span::before { top: 22px; } input.mid-three-eighth { margin-top: 45px; } input.mid-three-eighth + span::before { top: 40px; } input.middle { margin-top: 67px; } input.middle + span::before { top: 62px; } input.middle-2 { margin-top: 73px; } input.middle-2 + span::before { top: 68px; } input.mid-five-eighth { margin-top: 95px; } input.mid-five-eighth + span::before { top: 90px; } input.mid-three-quarter { margin-top: 113px; } input.mid-three-quarter + span::before { top: 108px; } input.mid-seven-eighth { margin-top: 127px; } input.mid-seven-eighth + span::before { top: 122px; } input.bottom { margin-top: 135px; } input.bottom+ span, input.bottom+ span::before { top: 130px; } /* Position checkboxes horizontally in circle */ input.left-1 { margin-left: 14px; } input.left-1 + span::before { left: 14px; } input.left-2 { margin-left: 1px; } input.left-2 + span::before { left: 1px; } input.left-3 { margin-left: -4px; } input.left-3 + span::before { left: -4px; } input.left-4 { margin-left: -5px; } input.left-4 + span::before { left: -5px; } input.left-5 { margin-left: -2px; } input.left-5 + span::before { left: -2px; } input.left-6 { margin-left: 1px; } input.left-6 + span::before { left: 1px; } input.left-7 { margin-left: 3px; } input.left-7 + span::before { left: 3px; } input.left-8 { margin-left: 2px; } input.left-8 + span::before { left: 2px; } input.left-9 { margin-left: -4px; } input.left-9 + span::before { left: -4px; } input.left-10 { margin-left: -16px; } input.left-10 + span::before { left: -16px; } /* Rotate checkboxes */ input.wheel9, input.wheel9 + span::before { transform:rotate(9deg); -ms-transform:rotate(9deg); -webkit-transform:rotate(9deg); } input.wheel27, input.wheel27 + span::before { transform:rotate(27deg); -ms-transform:rotate(27deg); -webkit-transform:rotate(27deg); } input.wheel45, input.wheel45 + span::before { transform:rotate(45deg); -ms-transform:rotate(45deg); -webkit-transform:rotate(45deg); } input.wheel63, input.wheel63 + span::before { transform:rotate(63deg); -ms-transform:rotate(63deg); -webkit-transform:rotate(63deg); } input.wheel81, input.wheel81 + span::before { transform:rotate(81deg); -ms-transform:rotate(81deg); -webkit-transform:rotate(81deg); } input.wheel99, input.wheel99 + span::before { transform:rotate(99deg); -ms-transform:rotate(99deg); -webkit-transform:rotate(99deg); } input.wheel117, input.wheel117 + span::before { transform:rotate(117deg); -ms-transform:rotate(117deg); -webkit-transform:rotate(117deg); } input.wheel135, input.wheel135 + span::before { transform:rotate(135deg); -ms-transform:rotate(135deg); -webkit-transform:rotate(135deg); } input.wheel153, input.wheel153 + span::before { transform:rotate(153deg); -ms-transform:rotate(153deg); -webkit-transform:rotate(153deg); } input.wheel171, input.wheel171 + span::before { transform:rotate(171deg); -ms-transform:rotate(171deg); -webkit-transform:rotate(171deg); } div.marker { margin: 36px 0px 0px 5px; font-size: 20px; } Getting the exact positioning and rotation was difficult for this one, but it looks darn cool! Share your techniques! What tricky stuff have you done with the HTML & CSS to make your character sheets beautiful?
1401392037
Gid
Roll20 Team
Awesome post, Brian!
1401399274

Edited 1401399341
Outstanding Post. I am trying to make a Character sheet for iron kingdoms (IKRPG) and I am having trouble making a damage grid. I think some of your ideas will be useful. I also hope more people add ideas.....like how I can do a damage grid ;)
1401403058
Lithl
Pro
Sheet Author
API Scripter
Well, the damage grid for a 'jack is relatively simple -- it's literally a grid. (Although, as I understand it, different 'jacks could have different numbers of boxes, and have different systems failing at different damage amounts? I've only played IKRPG once, and I didn't have 'jack.) The damage capacity for a character is a little more complicated. Considering the way damage can be inserted at any point and flows into following tracks and such, I would recommend using checkboxes rather than radio buttons. You can make checkboxes look like circles by styling them as I've shown, and using border-radius: 50%; -- each corner of the span will be rounded, and the radius of the curve will be 50% of the side. If the span is square, the result will look like a circle. You can then position the checkboxes as you need them to create the desired effect (similar to the Quintessence wheel). Your only real option for the curved text is splitting each and every letter into its own element and rotating them: a pain in the butt without some form of automation like JavaScript, so it's probably better to simply use a background image. While you can draw curves with CSS (such as the ones linking each circle in the damage capacity together), it would probably be better to simply put those curves on the background image, since you'll likely want images for the curved text anyway. The upshot of this is that you could probably simply take a picture of the damage capacity, set it as a background image, and position/resize the checkboxes on top of it so that they line up with the bubbles in the image. This makes the job much simpler. =)
1401442079
Casey
Sheet Author
You can draw text on curves with SVG too, not sure if the markup is filtered out by Roll20 though: demo
HOLY GUACAMOLE...my mind is BLOWN! I am far from an HTML or CSS master so these trick are very neat to me. Is there a good place to pick all this stuff online? THANKS again I will try all your stuff and post the results (if they are good).
1401462276
Sam M.
Pro
Sheet Author
Thanks for this, I'm putting the triangle checkboxes in my sheet for section hiding now.
1401490218

Edited 1488865954
Lithl
Pro
Sheet Author
API Scripter
Tabs There have been a couple threads about this recently, so I thought I'd throw out an example for creating tabs. For example : &lt;input type="radio" name="attr_tab" class="sheet-tab sheet-tab1" value="1" checked="checked"&gt;&lt;span title="First Tab"&gt;&lt;/span&gt; &lt;input type="radio" name="attr_tab" class="sheet-tab sheet-tab2" value="2"&gt;&lt;span title="Second Tab"&gt;&lt;/span&gt; &lt;input type="radio" name="attr_tab" class="sheet-tab sheet-tab3" value="3"&gt;&lt;span title="Third Tab"&gt;&lt;/span&gt; &lt;input type="radio" name="attr_tab" class="sheet-tab sheet-tab4" value="4"&gt;&lt;span title="Fourth Tab"&gt;&lt;/span&gt; &lt;div class="sheet-tab-content sheet-tab1"&gt; &nbsp; &nbsp; &lt;h1&gt;Tab 1&lt;/h1&gt; &nbsp; &nbsp; Lorem ipsum dolor sit amet &lt;/div&gt; &lt;div class="sheet-tab-content sheet-tab2"&gt; &nbsp; &nbsp; &lt;h1&gt;Tab the Second&lt;/h1&gt; &nbsp; &nbsp; consectetur adipisicing elit &lt;/div&gt; &lt;div class="sheet-tab-content sheet-tab3"&gt; &nbsp; &nbsp; &lt;h1&gt;3rd Tab&lt;/h1&gt; &nbsp; &nbsp; sed do eiusmod tempor incididunt ut labore et dolore magna aliqua &lt;/div&gt; &lt;div class="sheet-tab-content sheet-tab4"&gt; &nbsp; &nbsp; &lt;h1&gt;Fourth Tab&lt;/h1&gt; &nbsp; &nbsp; Ut enim ad minim veniam &lt;/div&gt; div.sheet-tab-content { display: none; } input.sheet-tab1:checked ~ div.sheet-tab1, input.sheet-tab2:checked ~ div.sheet-tab2, input.sheet-tab3:checked ~ div.sheet-tab3, input.sheet-tab4:checked ~ div.sheet-tab4 { display: block; } input.sheet-tab { &nbsp; &nbsp; width: 150px; &nbsp; &nbsp; height: 20px; &nbsp; &nbsp; position: relative; &nbsp; &nbsp; top: 5px; &nbsp; &nbsp; left: 6px; &nbsp; &nbsp; margin: -1.5px; &nbsp; &nbsp; cursor: pointer; &nbsp; &nbsp; z-index: 1; &nbsp; &nbsp; opacity: 0; } input.sheet-tab + span::before { &nbsp; &nbsp; content: attr(title); &nbsp; &nbsp; border: solid 1px #a8a8a8; &nbsp; &nbsp; border-bottom-color: black; &nbsp; &nbsp; text-align: center; &nbsp; &nbsp; display: inline-block; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; background: #fff; &nbsp; &nbsp; background: -moz-linear-gradient(to top, #c8c8c8, #fff, #c8c8c8); &nbsp; &nbsp; background: -webkit-linear-gradient(to top, #c8c8c8, #fff, #c8c8c8); &nbsp; &nbsp; background: -ms-linear-gradient(to top, #c8c8c8, #fff, #c8c8c8); &nbsp; &nbsp; background: -o-linear-gradient(to top, #c8c8c8, #fff, #c8c8c8); &nbsp; &nbsp; background: linear-gradient(to top, #c8c8c8, #fff, #c8c8c8); &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; width: 150px; &nbsp; &nbsp; height: 20px; &nbsp; &nbsp; font-size: 18px; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; position: absolute; &nbsp; &nbsp; top: 12px; &nbsp; &nbsp; left: 13px; } input.sheet-tab:checked + span::before { &nbsp; &nbsp; background: #dcdcdc; &nbsp; &nbsp; background: -moz-linear-gradient(to top, #fcfcfc, #dcdcdc, #fcfcfc); &nbsp; &nbsp; background: -webkit-linear-gradient(to top, #fcfcfc, #dcdcdc, #fcfcfc); &nbsp; &nbsp; background: -ms-linear-gradient(to top, #fcfcfc, #dcdcdc, #fcfcfc); &nbsp; &nbsp; background: -o-linear-gradient(to top, #fcfcfc, #dcdcdc, #fcfcfc); &nbsp; &nbsp; background: linear-gradient(to top, #fcfcfc, #dcdcdc, #fcfcfc); &nbsp; &nbsp; border-bottom-color: #fff; } input.sheet-tab:not(:first-child) + span::before { border-left: none; } input.sheet-tab2 + span::before { &nbsp; &nbsp; background: #fee; &nbsp; &nbsp; background: -moz-linear-gradient(to top, #f8c8c8, #fee, #f8c8c8); &nbsp; &nbsp; background: -webkit-linear-gradient(to top, #f8c8c8, #fee, #f8c8c8); &nbsp; &nbsp; background: -ms-linear-gradient(to top, #f8c8c8, #fee, #f8c8c8); &nbsp; &nbsp; background: -o-linear-gradient(to top, #f8c8c8, #fee, #f8c8c8); &nbsp; &nbsp; background: linear-gradient(to top, #f8c8c8, #fee, #f8c8c8); &nbsp; &nbsp; left: 163px; } input.sheet-tab2:checked + span::before { &nbsp; &nbsp; background: #dcdcdc; &nbsp; &nbsp; background: -moz-linear-gradient(to top, #fcecec, #f8c8c8, #fcecec); &nbsp; &nbsp; background: -webkit-linear-gradient(to top, #fcecec, #f8c8c8, #fcecec); &nbsp; &nbsp; background: -ms-linear-gradient(to top, #fcecec, #f8c8c8, #fcecec); &nbsp; &nbsp; background: -o-linear-gradient(to top, #fcecec, #f8c8c8, #fcecec); &nbsp; &nbsp; background: linear-gradient(to top, #fcecec, #f8c8c8, #fcecec); &nbsp; &nbsp; border-bottom-color: #fcecec; } input.sheet-tab3 + span::before { left: 313px; } input.sheet-tab4 + span::before { left: 463px; } div.sheet-tab-content { &nbsp; &nbsp; border: 1px solid #a8a8a8; &nbsp; &nbsp; border-top-color: #000; &nbsp; &nbsp; margin: 2px 0 0 5px; &nbsp; &nbsp; padding: 5px; } div.sheet-tab2 { background-color: #fcecec; } The key to take away from this is that we have a set of radio buttons which are siblings to the divs that contain each tab's content. Then, we hide all of the tabs' content and use the sibling selector along with the :checked property to show the tab content associated with that particular radio button. The rest of this example shows off means to make your tabs look pretty, such as using content: attr(title) to set the text of the tab, gibing them colors and borders, and even making certain tabs different from the others in some fashion. Note: Riley has talked about having alternate sheet configurations available in the near future, so I'm not sure how necessary this trick will be in the coming weeks. It's still cool, though. EDIT (3/6/2017): Updated the above code and JSFiddle link with code from page 2 of this thread, to support a failure in Firefox.
@Brian. It's still useful to know to show or hide other areas. I use it to show and hide optional rules elements.
1401541429

Edited 1401541502
Josiah B.
Sheet Author
Hexes It's not the only way to do it, but it's the easiest I have found so far. Example &lt;div class="hex hex-3" style='background-color: #444; width:100px; height:57px;'&gt; &lt;div class="inner"&gt; &lt;h4&gt;Stat&lt;/h4&gt; &lt;input type='number' style='width:50%'&gt; &lt;/div&gt; &lt;div class="corner-1"&gt;&lt;/div&gt; &lt;div class="corner-2"&gt;&lt;/div&gt; &lt;/div&gt; .hex { width: 100px; height: 57px; background-color: #ccc; background-repeat: no-repeat; background-position: 50% 50%; background-size: auto 173px; position: relative; float:left; margin:25px 5px; text-align:center; zoom:1; } .hex.hex-gap { margin-left: 86px; } .hex a { display:block; width: 100%; height:100%; text-indent:-9999em; position:absolute; top:0; left:0; } .hex .corner-1, .hex .corner-2 { position: absolute; top:0; left:0; width:100%; height:100%; background: inherit; z-index:-2; overflow:hidden; backface-visibility: hidden; } .hex .corner-1 { z-index:-1; -webkit-transform: rotate(60deg); } .hex .corner-2 { -webkit-transform: rotate(-60deg); } .hex .corner-1:before, .hex .corner-2:before { width: 173px; height: 173px; content: ''; position: absolute; background: inherit; top:0; left: 0; z-index: 1; background: inherit; background-repeat:no-repeat; backface-visibility: hidden; } .hex .corner-1:before { transform: rotate(-60deg) translate(-87px, 0px); transform-origin: 0 0; } .hex .corner-2:before { transform: rotate(60deg) translate(-48px, -11px); bottom:0; } /* Custom styles*/ .hex .inner { color:#eee; } .hex h4 { font-family: 'Josefin Sans', sans-serif; margin:0; } .hex hr { border:0; border-top:1px solid #eee; width:60%; margin:15px auto; } .hex p { font-size:16px; font-family: 'Kotta One', serif; width:80%; margin:0 auto; } .hex.hex-1 { background: #74cddb; } .hex.hex-2 { background: #f5c53c; } .hex.hex-3 { background: #80b971; } You can override the color and height and width on the element. Keep the width to .57 of the height and the shep should be good.
There are a handful of custom fonts that Roll20 uses for it's various symbols. If you use the css property "font-family" you can change your font to one of these custom fonts, for some easy icons. Especially if you want it to match the Roll20 image (For example, on the GURPS sheet I wanted to add a button that sends your Basic Speed to the tracker). Of course, Roll20 may change their fonts in the future which will cause your character sheet to change, perhaps to an unexpected image. font-family: "Pictos" font-family: "Pictos Custom" font-family: "Pictos Three" font-family: "dicefontd6" font-family: "dicefontd8" font-family: "dicefontd10" font-family: "dicefontd20" There also appears to be a "dicefontd4" and "dicefontd12", but I couldn't get pictures of those.
1401895724

Edited 1401896850
Casey
Sheet Author
Styling Drop Downs &lt;select&gt; elements are notoriously non-styleable, which can really crimp your sheet's style. I picked up a technique from Brian in the Mentors forum to create pseudo select-like elements using radio buttons and CSS. This original fiddle I gleaned this technique from. My improvements can be seen live on the Firefly RPG character sheet page . Just hover over one of the dice values to see the effect. Here is a minimal example: <a href="http://jsfiddle.net/xMZsg/" rel="nofollow">http://jsfiddle.net/xMZsg/</a> You will need to duplicate your CSS for every dropdown you put in your sheet. To ease the pain, I've created a LESS mixin to help generate your dropdown styles.
1401896257

Edited 1401896382
Lithl
Pro
Sheet Author
API Scripter
Casey said: I picked up a technique from someone in the Mentors forum to create pseudo select-like elements using radio buttons and CSS. This original fiddle I gleaned this technique from, if you made this, speak up! That was me. I was going to post it in this thread, but I couldn't find the link to my fiddle! Yours is certainly a much nicer example, anyway. =) (FWIW, selects aren't completely un-styleable; check the Caste dropdown on my Exalted 2E sheet)
1402364298

Edited 1402631258
Lithl
Pro
Sheet Author
API Scripter
This one isn't CSS Wizardry, more math wizardry, but I spent enough time trying to get it to work that I felt I should share. We do not have access to the min(x) or max(x) functions in autocalc fields. However, we can get the same result, thanks to the abs(x) function! &lt;input type="number" name="attr_A" value="0" /&gt; &lt;input type="number" name="attr_B" value="0" /&gt; &lt;input type="number" name="attr_MAX" value="((@{A} + @{B}) + abs(@{A} - @{B})) / 2" disabled="true" /&gt; &lt;input type="number" name="attr_MIN" value="((@{A} + @{B}) - abs(@{A} - @{B})) / 2" disabled="true" /&gt;
1402553020

Edited 1494454010
Lithl
Pro
Sheet Author
API Scripter
Styling Your Repeating Sections It's possible to style your repeating sections in various ways, such as alternating the background color, or adding a border to only the last element. The key is the repcontainer, repitem, and repcontrol classes, and the data-groupname attribute. When your repeating section is actually rendered, here's the general format of the HTML: &lt;fieldset class="repeating_MyRepeatingSection" style="display: none;"&gt; &lt;!-- MyRepeatingSection HTML --&gt; &lt;/fieldset&gt; &lt;div class="repcontainer" data-groupname="repeating_MyRepeatingSection"&gt; &lt;div class="repitem"&gt; &lt;div class="itemcontrol"&gt; &lt;button class="btn btn-danger pictos repcontrol_del"&gt;#&lt;/button&gt; &lt;a class="btn repcontrol_move"&gt;≡&lt;/a&gt; &lt;/div&gt; &lt;!-- MyRepeatingSection HTML --&gt; &lt;/div&gt; &lt;!-- repeat the div.repitem for each repeating item the user has added --&gt; &lt;/div&gt; &lt;div class="repcontrol" data-groupname="repeating_MyRepeatingSction"&gt; &lt;button class="btn repcontrol_edit"&gt;Modify&lt;/button&gt; &lt;button class="btn repcontrol_add"&gt;+Add&lt;/button&gt; &lt;/div&gt; Also: when you click the Modify button, the Add button is set to display: none and the Modify text is swapped to "Done"; when you click Done, the Add button is set to display: inline-block and the Done text is swapped to "Modify". While modifying repitems, the div.repcontainer gains the class "editmode". Armed with this knowledge, you can do numerous things to alter how your repeating items are displayed. For example, on my Exalted sheet, I have a repeating section which doesn't jump to the next row until you've filled the first one, and it takes two repitems to fill a row; this gives me a two-column repeating section without requiring the user to have an even number of elements. Here's the CSS responsible: div[data-groupname="repeating_charms"] .repitem { display: inline-block; } /* Adjust right column. the :nth-child selector could also be used to alternate background colors, or similar */ div[data-groupname="repeating_charms"] .repitem:nth-child(even) { margin-left: 8px; } Note that you do not add "sheet-" to the beginning of the repitem class! The same applies to repcontainer and repcontrol; unlike all of the classes you put into your own HTML, these classes will not be prepended with "sheet-" at render time. Remember to use data-groupname to match up the specific repeating section you want (unless, of course, you want to apply a style to all of your repeating sections at once). Here's another example; I've got a repeating section that's pretending to be tabular data. I have several span elements of specific widths which serve as the table header. They have thin borders between each other, the first has a thick left border, the last has a thick right border, and they all have a thick top border. My actual repitem has a thick left and right border, and thin borders between the precisely-sized "cells". Then, the final repitem has a thick bottom border. /* header "cells" */ span.sheet-span-header { display: inline-block; padding: 4px; margin: 0px; font-weight: bold; font-size: 110%; } /* lines between rows */ div[data-groupname="repeating_attack"] div:not(:first-child) div.sheet-attack { border-top: 1px solid #ccc; } /* lines between cells */ div.sheet-weapons div.sheet-attack input, div.sheet-weapons div.sheet-attack select { border: 1px solid black; border-left: none; margin: 0px; border-radius: 0px; } div.sheet-combat-equipment div.sheet-weapons { display: inline-block; vertical-align: top; } div.sheet-weapons div.sheet-attack select { height: 28px; vertical-align: top; } div.sheet-weapons div.sheet-rolls { padding: 5px; } div.sheet-weapons span { border-top: 3px solid black; border-right: 1px solid black; } /* left border on header and each row */ div.sheet-weapons span:first-of-type, div.sheet-weapons div.sheet-rolls, div.sheet-weapons div.sheet-attack input:first-of-type { border-left: 3px solid black; } /* right border on header and each row */ div.sheet-weapons span:last-of-type, div.sheet-weapons div.sheet-rolls, div.sheet-weapons div.sheet-attack input:last-of-type{ border-right: 3px solid black; } /* bottom border for the table */ div.repcontainer[data-groupname="repeating_attacks"] div.repitem:last-child div.sheet-rolls { border-bottom: 3px solid black; } So, What Can You Not Do? You cannot: Change the "display" property on the original fieldset Change the text of the add, modify/done, move, or delete buttons Although you could set the opacity to 0 and display something else in their place, much like the radio/checkbox button styling in the first post, as well ass add ::before or ::after pseudo-elements to them. Change the "display" property of the add button after the user has pressed "Modify" once.
1402674108
Casey
Sheet Author
Devindra P, how did you generate those font previews? I've tried extracting the woff data from the base64 encoded data-uris, but i'm not having any luck getting well formed font files. It would be useful to know which characters map to which icon in the font.
1402697188
Lithl
Pro
Sheet Author
API Scripter
He may have simply output A-Za-z0-9 with each font, considering that, for example the trash-can icon used for the delete button on repeating sections is "#" in the Pictons font.
1402931298

Edited 1402931462
Devindra P.
Sheet Author
I used the Chrome inspector to look at the page's resources. The previews were generated by the chrome inspector, I just took a screenshot.
1402984456

Edited 1402985353
Hey Brian, Can you post a new section with an input checkbox where the checkbox acts as a tab and changes the character sheet as specified? e.g. --html-- &lt;div class="sheet-heading"&gt; &lt;img src="<a href="http://i.imgur.com/A746uyc.png?1" rel="nofollow">http://i.imgur.com/A746uyc.png?1</a>" style="float: center; width:25%"&gt;&lt;/img&gt;&lt;br&gt;3.5e Character Sheet &lt;input class="sheet-selectsheet" name="attr_check" value="yes" type="checkbox" title="sheet changer"&gt; &lt;/div&gt; &lt;div class="sheet-charactersheet sheet1"&gt; &lt;div class="sheet-name"&gt; Sheet1 &lt;/div&gt; &lt;/div&gt; &lt;div class="sheet-charactersheet sheet2"&gt; &lt;div class="sheet-name"&gt; Sheet2 &lt;/div&gt; &lt;/div&gt; --css-- div.sheet-charactersheet { display: none; } input.sheet-selectsheet:not(:checked) ~ div.sheet-sheet1{ display: block; } /*not working at all*/ input.sheet-selectsheet:checked ~ div.sheet-sheet2{ display: block; } /*not working at all*/ .charsheet { background-color: white/*#B2B2FF*/; background-image: none; } .charsheet div.sheet-heading{ border: 1px solid white; background-color: #6D6D93; text-align:center; color: white; font-size: 1.5em; } .charsheet div.sheet-name{ border 1px solid white; background-color: gray; color: white; font-size: 1.25em; text-align: center; } Also I tested your "hide areas" html and css, and it was copied exactly, and it does not seem to work in roll20, but it does in jsfiddle.
1402989331
Lithl
Pro
Sheet Author
API Scripter
Your checkbox-tab isn't working because the "tab" elements that you're showing or hiding **MUST** be siblings of the checkbox, or descended from siblings of the checkbox. You have the checkbox wrapped in the sheet-heading div, so it won't work. If you copied it exactly from the code in my first post in this thread, then it won't work in Roll20, because Roll20 prepends "sheet-" to the class names. Add "sheet-" to the classes in the CSS (eg, "input.sheet-arrow" instead of "input.arrow") and it should work fine.
1402991265

Edited 1402991404
Thanks, again! And: I should have realized that, but I didn't. Teaching yourself HTML on the fly is tricky. I just started HTML recently, so thanks.
1403240694

Edited 1494458272
Lithl
Pro
Sheet Author
API Scripter
Functions with an asterisk before them on their headline are approximations; you can increase their accuracy by adding iterations to the calculation. Replicating JavaScript Math Library Constants The following are constants in JavaScript, so there's no reason why you can't simply use them as constants on a character sheet if you happen to need them. Math.E Euler's constant &lt;input type="hidden" disabled="true" name="attr_cE" value="2.718281828459045" /&gt; Math.LN2 Natural logarithm of 2 &lt;input type="hidden" disabled="true" name="attr_cLN2" value="0.6931471805599453" /&gt; Math.LN10 Natural logarithm of 10 &lt;input type="hidden" disabled="true" name="attr_cLN10" value="2.302585092994046" /&gt; Math.LOG2E Base-2 logarithm of E &lt;input type="hidden" disabled="true" name="attr_cLOG2E" value="1.4426950408889634" /&gt; Math.LOG10E Base-10 logarithm of E &lt;input type="hidden" disabled="true" name="attr_cLOG10E" value="0.4342944819032518" /&gt; Math.PI Ratio of a circle's circumference to its diameter &lt;input type="hidden" disabled="true" name="attr_cPI" value="3.141592653589793" /&gt; Math.SQRT1_2 Square root of 0.5 &lt;input type="hidden" disabled="true" name="attr_cSQRT1_2" value="0.7071067811865476" /&gt; Math.SQRT2 Square root of 2 &lt;input type="hidden" disabled="true" name="attr_cSQRT2" value="1.4142135623730951" /&gt; Trivially Represented The following are functions you can use on your character sheet easily, because they're either simple or directly available to you. abs(x) If x &lt; 0, the result is -1 * x, while if x &gt;= 0, the result is x &lt;input type="hidden" disabled="true" name="attr_abs" value="abs(@{x})" /&gt; ceil(x) Rounds towards positive infinity &lt;input type="hidden" disabled="true" name="attr_ceil" value="ceil(@{x})" /&gt; floor(x) Rounds towards negative infinity &lt;input type="hidden" disabled="true" name="attr_floor" value="floor(@{x})" /&gt; max(x, y, z, ...) If x &gt; y, the result is x, while if x &lt; y, the result is y &lt;input type="hidden" disabled="true" name="attr_max_xy" value="(((@{x} + @{y}) + abs(@{x} - @{y})) / 2)" /&gt; &lt;input type="hidden" disabled="true" name="attr_max_xyz" value="(((@{max_xy} + @{z}) + abs(@{max_xy} - @{z})) / 2)" /&gt; &lt;input type="hidden" disabled="true" name="attr_max_xyzw" value="(((@{max_xyz} + @{w}) + abs(@{max_xyz} - @{w})) / 2)" /&gt; min(x, y, z, ...) If x &gt; y, the result is y, while if x &lt; y, the result is x &lt;input type="hidden" disabled="true" name="attr_min_xy" value="(((@{x} + @{y}) - abs(@{x} - @{y})) / 2)" /&gt; &lt;input type="hidden" disabled="true" name="attr_min_xyz" value="(((@{min_xy} + @{z}) - abs(@{min_xy} - @{z})) / 2)" /&gt; &lt;input type="hidden" disabled="true" name="attr_min_xyzw" value="(((@{min_xyz} + @{w}) - abs(@{min_xyz} - @{w})) / 2)" /&gt; pow(x, y) x^y, this is x multiplied by itself y times; fractional values for y are permissible &lt;input type="number" disabled="true" name="attr_pow" value="(@{x}**@{y})" /&gt; round(x) Round to the nearest integer (0.5 rounds up) &lt;input type="hidden" disabled="true" name="attr_round" value="round(@{x})" /&gt; sign(x) If x &lt; 0, the result is -1, while if x &gt; 0, the result is 1 and if x = 0, the result is 0; unfortunately, because we need to calculate it and 0 / 0 in JavaScript is NaN, we won't get the last case; we can do all values where x &lt;&gt; 0, though. &lt;input type="hidden" disabled="true" name="attr_sign" value="(@{x} / abs(@{x}))" /&gt; trunc(x) Round towards 0 &lt;input type="hidden" disabled="true" name="attr_trunc" value="(@{sign} * floor(abs(@{x})))" /&gt; exp(x) E^x &lt;input type="hidden" disabled="true" name="attr_exp" value="(@{cE}**@{x})" /&gt; cbrt(x) Cube root: cbrt(x)^3 = x &lt;input type="hidden" disabled="true" name="attr_cbrt" value="(@{x}**(1/3))" /&gt; sqrt(x) Square root: sqrt(x)^2 = x &lt;input type="hidden" disabled="true" name="attr_sqrt" value="(@{x}**0.5)" /&gt; hypot(x, y, z, ...) Hypotenuse: sqrt(x^2 + y^2 + z^2 + ...) &lt;!-- include as many values as you need --&gt; &lt;input type="hidden" disabled="true" name="attr_s" value="(@{x}**2 + @{y}**2 + @{z}**2)" /&gt; &lt;input type="hidden" disabled="true" name="attr_hypot" value="(@{s}**0.5)" /&gt; Trigonometric Functions Some trigonometric functions can be defined in terms of one another. @{log_2x} is the natural logarithm of 2 * x, which will be defined in the next section. *acos(x) Inverse function of cos; acos(cos(x)) = x, and if abs(x) &lt;= 1, cos(acos(x)) = x &lt;input type="hidden" disabled="true" name="attr_acos" value="(@{cPI} / 2 - @{asin})" /&gt; *acosh(x) Hyperbolic arccosine &lt;input type="hidden" disabled="true" name="attr_acosh" value="(@{log_2x} - (1 / (4 * @{x}**2) + 3 / (32 * @{x}**4) + 15 / (288 * @{x}**6) + 105 / (384 * @{x}**8)))" /&gt; *asin(x) Inverse function of sin; asin(sin(x)) = x, and if abs(x) &lt;= 1, sin(asin(x)) = x &lt;input type="hidden" disabled="true" name="attr_asin" value="(@{x} + @{x}**3 / 6 + (3 * @{x}**5) / 40 + (15 * @{x}**7) / 336)" /&gt; *asinh(x) Hyperbolic arcsine &lt;input type="hidden" disabled="true" name="attr_asinh" value="(@{x} - @{x}**3 / 6 + 3 * @{x}**5 / 40 - 15 * @{x}**7 / 336)" /&gt; *atan(x) Inverse function of tan; atan(tan(x)) = x = tan(atan(x)) &lt;input type="hidden" disabled="true" name="attr_atan" value="(@{x} - @{x}**3 / 3 + @{x}**5 / 5 - @{x}**7 / 7)" /&gt; *atanh(x) Hyperbolic arctangent &lt;input type="hidden" disabled="true" name="attr_atan" value="(@{x} + @{x}**3 / 3 + @{x}**5 / 5 + @{x}**7 / 7)" /&gt; *atan2(y, x) The same as atan(y / x), although the actual Math library function avoids divide-by-zero errors &lt;input type="hidden" disabled="true" name="attr_atan2" value="((@{y} / @{x}) - (@{y} / @{x})**3 / 3 + (@{y} / @{x})**5 / 5 - (@{y} / @{x})**7 / 7)" /&gt; *cos(x) The ratio of the adjacent side of a triangle from the given angle (on a right triangle) to the hypotenuse &lt;input type="hidden" disabled="true" name="attr_cos" value="(1 - @{x}**2 / 2 + @{x}**4 / 24 - @{x}**6 / 720 + @{x}**8 / 40320)" /&gt; *cosh(x) Hyperbolic cosine &lt;input type="hidden" disabled="true" name="attr_cosh" value="(1 + @{x}**2 / 2 + @{x}**4 / 24 + @{x}**6 / 720 + @{x}**8 / 40320)" /&gt; *sin(x) The ratio of the opposite side of a triangle from the given angle (on a right triangle) to the hypotenuse &lt;input type="hidden" disabled="true" name="attr_sin" value="(@{x} - @{x}**3 / 6 + @{x}**5 / 120 - @{x}**7 / 5040)" /&gt; *sinh(x) Hyperbolic sine &lt;input type="hidden" disabled="true" name="attr_sinh" value="(@{x} + @{x}**3 / 6 + @{x}**5 / 120 + @{x}**7 / 5040)" /&gt; *tan(x) The ratio of the opposite side of a triangle from the given angle (on a right triangle) to the adjacent side &lt;input type="hidden" disabled="true" name="attr_tan" value="(@{sin} / @{cos})" /&gt; *tanh(x) Hyperbolic tangent &lt;input type="hidden" disabled="true" name="attr_tanh" value="(@{sinh} / @{cosh})" /&gt; Other Transcendental Functions Transcendental functions cannot be expressed with a finite number of algebraic operations. The trigonometric functions above are transcendental; the following functions are the remainder of the transcendental functions in the Math library. *log(x) Natural logarithm (log base E) of x &lt;input type="hidden" disabled="true" name="attr_log" value="(@{x} - @{x}**2 / 2 + @{x}**3 / 3 - @{x}**4 / 4 + @{x}**5 / 5 - @{x}**6 / 6 + @{x}**7 / 7)" /&gt; &lt;!-- for acosh, above --&gt; &lt;input type="hidden" disabled="true" name="attr_log_2x" value="(@{cLN2} + @{log})" /&gt; *log1p(x) log(1 + x) &lt;input type="hidden" disabled="true" name="attr_log1p" value="((1 + @{x}) - (1 + @{x})**2 / 2 + (1 + @{x})**3 / 3 - (1 + @{x})**4 / 4 + (1 + @{x})**5 / 5 - (1 + @{x})**6 / 6 + (1 + @{x})**7 / 7)" /&gt; *log10(x) Log base 10 of x &lt;input type="hidden" disabled="true" name="attr_log10" value="(@{log} / @{cLN10})" /&gt; *log2(x) Log base 2 of x &lt;input type="hidden" disabled="true" name="attr_log2" value="(@{log} / @{cLN2})" /&gt; *clz32(x) The number of leading zero bits in a 32-bit number (eg, 64 = 00000000000000000000000001000000, so clz32(63) = 25) &lt;input type="hidden" disabled="true" name="attr_clz32" value="(32 - ceil(@{log1p} / @{cLN2}))" /&gt; Impossible to Implement Or at least, I don't know how fround(x) Round to the nearest 32-bit representable floating point number. In browsers that don't implement this function, it can be emulated with: var f32 = new Float32Array(1); return f32[0] = x, f32[0]; imul(x, y) Perform 32-bit multiplication. This is functionally equivalent to trunc(x * y) , except when large numbers get involved. In browsers that don't implement this function, it can be emulated with: var ah = (a &gt;&gt;&gt; 16) & 0xffff; var al = a & 0xffff; var bh = (b &gt;&gt;&gt; 16) & 0xffff; var bl = b & 0xffff; return ((al * bl) + (((ah * bl + al * bh) &lt;&lt; 16) &gt;&gt;&gt; 0)|0); random() Generate a random number in the range [0,1). Not possible; just roll dice instead! =)
For the random between [0,1) you can do this &lt;button type="roll" value="[[1d100 / 100]]"&gt;
1403378168
Lithl
Pro
Sheet Author
API Scripter
Which is rolling dice. =P
Got me.
1404231364

Edited 1404235883
WOW - Brian this is totally Amazing! I don't fully understand this, but you appear to be making sibling elements display or not display based on the status of a checkbox... sort-of an If-Then statement for CSS. Would you please give me an example (if it's possible) of doing something similar based on the values of other types of inputs?? For example, I'm working on a "character class" section, like this: This is a repeating section, since we can have multiple character classes, and all four rows are inside the repeating &lt;fieldset&gt;. I have a &lt;select&gt; input with all of the character classes in it. What I WANT to happen is to have the row with the "spells per level" only be shown if the class in question is a spell-casting class, AND have the row with "spells known" only be shown if the class casts spells without preparation (such as sorcerers and bards.) Can I set these &lt;div&gt;s to "display=false" based on the value of a &lt;select&gt;?
1404240438
Lithl
Pro
Sheet Author
API Scripter
Sarjenka A said: Would you please give me an example (if it's possible) of doing something similar based on the values of other types of inputs? Sadly, this is not really possible. Only checkbox and radio button inputs can be used in this way. If you look at the Firefly character sheet, you can style some radio buttons so that they pretend to be a select dropdown, and then use the :checked property for the radio buttons, however. There are other pseudo-classes you might be able to make use of, such as :in-range and :out-of-range. They don't work in IE, but they could let you set styles based on number inputs being above or below the min and max attributes. Of course, if the number input has a min and/or max, the user would have to type in a number manually to get something out-of-range, since the up/down arrows won't let you go out of the specified range. The :focus pseudo-class lets you style things when you have an element selected (such as while you're typing in a text input). :valid and :invalid can be used for native validation of fields... but you only have a limited scope of what counts as "valid", such as &lt;input type="email"&gt; being valid for pretty much anything in the basic form of <a href="mailto:a@b.c" rel="nofollow">a@b.c</a>
Awww, that sucks. I was really hoping they'd give us more access to JavaScript for this. OK, well Thank You...
1404923029

Edited 1404923256
Alicia
Sheet Author
I can't find the original mention of this, but when the Character Sheets were in dev it was possible to use google fonts in the CSS. Anyone recall what the code for that is? I have the font I want to use, but no idea of the syntax to make it work @import url( <a href="http://fonts.googleapis.com/css?family=Audiowide" rel="nofollow">http://fonts.googleapis.com/css?family=Audiowide</a> ); Edit .. Well, I feel a little silly.. I clicked on the link for the import and got what I needed.
1404924661
Casey
Sheet Author
There are no special considerations for CSS font embedding, except that currently the fonts won't work in firefox due to this bug .
1404924990
Alicia
Sheet Author
Casey said: There are no special considerations for CSS font embedding, except that currently the fonts won't work in firefox due to this bug . The sheet will still work, just the special font won't process?
1405000732
Casey
Sheet Author
Correct, sheet works, but it will fallback to another available font.
1405018415
Alicia
Sheet Author
Casey said: Correct, sheet works, but it will fallback to another available font. I can live with that...
1405041706

Edited 1405042025
Tom
Pro
Sheet Author
A couple of ridiculous questions: 1) How do I adjust the size of my pull down menu buttons; or figure out what the dimensions are so I can make sure my text entries line up (by adjusting the line height)? 2) I want to have an input box and a pull down menu line up. How do I do that? 3) Is there a good way to set a uniform line-height for breaks? That appears to be what is throwing off my skill names and pull downs. Thanks!
1405043542
Lithl
Pro
Sheet Author
API Scripter
Unless you want to try and change the arrow on the right side of the select, styling it should be simple. Are you having trouble with it? The default stylesheet adds a fairly large margin to the bottom of all selects. select { margin-bottom: 0; } ought to fix your problem. I'm not sure what you mean?
1405105209
Tom
Pro
Sheet Author
Brian, I'm attaching an image so you'll get a clearer picture (pun intended) of what I'm trying to do here. As you can see, things line up pretty nicely until the first line break, at which point everything falls apart. Also, the input field and the drop down menu button do NOT want to line up together. I figure it's all just a matter of setting css parameters or hunting down existing code. Unfortunately, my CSS is poor at best. So any help would be great!
1405115771
Lithl
Pro
Sheet Author
API Scripter
What are you using to generate that?
1405123780
Tom
Pro
Sheet Author
The roll20 character sheet editor. If you'd like I can PM you the code.
1405124410
Lithl
Pro
Sheet Author
API Scripter
Yes, I meant "What [code] are you using to generate that?"
1405595381
Tom
Pro
Sheet Author
Another question for you Brian. say I wanted to include a roll button that was a different color. This one has a slightly different function than the other roll button, so I don't want to change all of them, just have it available as an alternative. What sort of CSS code do I need to create that? Tom
1405613556
Lithl
Pro
Sheet Author
API Scripter
The best solution would be to create a class that you could use to differentiate them. For example: &lt;button type="roll" name="roll_attack" class="sheet-attack-button" value="/roll @{attack-dice}"&gt;&lt;/button&gt; &lt;button type="roll" name="roll_damage" class="sheet-damage-button" value="/roll @{damage-dice}"&gt;&lt;/button&gt; button[type=roll].sheet-attack-button { background-color: blue; } button[type=roll].sheet-damage-button { background-color: red; }
1405988695

Edited 1405988807
I am having problems getting areas to hide using Brian's code. I had it working after some initial problems that seemed to solve themselves out of the blue. Then I realized I need to change the name of my div so I could use it elsewhere. The only thing I changed was the div class and associated css so I really can't understand why it quit working. Any help would be greatly appreciated. Here is my code: input.sheet-arrow:checked ~ div.sheet-expansion-area { display: none; } &lt;div&gt; &lt;fieldset&gt; &lt;input type="text" name="attr_feature" value="" style="width:90%; text-align:left" /&gt; &lt;input type="checkbox" name="attr_feature_display" /&gt;&lt;span&gt;&lt;/span&gt; &lt;div style="padding-top: 5px"&gt; &lt;textarea name="attr_feature_desc" style="width: 96%; height: 60px; margin-bottom: 5px";&gt;&lt;/textarea&gt; &lt;/div&gt; &lt;/fieldset&gt; &lt;/div&gt; Edit: Bah, I don't even know how to do code blocks on this forum.
1405992233
Lithl
Pro
Sheet Author
API Scripter
Rich, you don't have any classes in the HTML you posted, so the CSS won't match anything. Also, to format text as code, click the paragraph button at the top-left of the Post Reply area, and select Code from the dropdown.
1405993055

Edited 1406032440
Hmm, that is strange because I went back and it was there but it still doesn't work. I'm also pretty positive it was there when I copied the code to paste into my post the first time. Maybe I just need more sleep. Unfortunately I have to go to work. But here is the html again. Thanks for taking a look! &lt;div class="sheet-skill-table"&gt; &lt;fieldset class="repeating_skills"&gt; &lt;input type="text" name="attr_feature" value="" style="width:90%; text-align:left" /&gt; &lt;input type="checkbox" name="attr_feature_display" class="sheet-arrow" /&gt;&lt;span&gt;&lt;/span&gt; &lt;div class="sheet-expansion-area" style="padding-top: 5px"&gt; &lt;textarea name="attr_feature_desc" style="width: 96%; height: 60px; margin-bottom: 5px";&gt;&lt;/textarea&gt; &lt;/div&gt; &lt;/fieldset&gt; &lt;/div&gt; Edit: After validating my code and fixing several errors like the semicolon at the end of my textarea tag, still no luck :(
1406060113
Lithl
Pro
Sheet Author
API Scripter
Rich, are you testing that piece of code you posted on its own, or on the sheet at large? When testing just what you've posted (with or without the bad semicolon), it works fine.
Finally got it sorted. Thanks for trying to help Brian and thanks for all of your examples in this thread. Turns out I had an extra curly bracket in my css that the validator didn't even point out &gt;:(
I've been trying to integrate the Hide Area script into one of my character sheets to no avail. I made sure that I renamed the CSS script to sheet-arrow and it still hasn't worked. I just tried copying it into a blank character sheet with no luck. HTML: &lt;div&gt; &lt;input type="checkbox" class="arrow" /&gt; &lt;h4&gt;Stuff and Things&lt;/h4&gt; &lt;div class="body"&gt; &lt;input type="text" placeholder="Name" /&gt;&lt;br /&gt; &lt;input type="text" placeholder="Description" /&gt; &lt;input type="number" min="0" max="20" value="0" /&gt;&lt;br /&gt; &lt;textarea placeholder="Fulltext"&gt;&lt;/textarea&gt; &lt;/div&gt; &lt;/div&gt; &lt;div&gt; &lt;input type="checkbox" class="arrow" /&gt; &lt;h4&gt;More Stuff&lt;/h4&gt; &lt;div class="body"&gt; &lt;input type="text" placeholder="Name" /&gt;&lt;br /&gt; &lt;input type="text" placeholder="Description" /&gt; &lt;input type="number" min="0" max="20" value="0" /&gt;&lt;br /&gt; &lt;textarea placeholder="Fulltext"&gt;&lt;/textarea&gt; &lt;/div&gt; &lt;/div&gt; &lt;div&gt; &lt;input type="checkbox" class="arrow" /&gt; &lt;h4&gt;Other Things&lt;/h4&gt; &lt;div class="body"&gt; &lt;input type="text" placeholder="Name" /&gt;&lt;br /&gt; &lt;input type="text" placeholder="Description" /&gt; &lt;input type="number" min="0" max="20" value="0" /&gt;&lt;br /&gt; &lt;textarea placeholder="Fulltext"&gt;&lt;/textarea&gt; &lt;/div&gt; &lt;/div&gt; CSS: /*Hiding Sections*/ input.sheet-arrow { float: left; } input.sheet-arrow:checked ~ div.body { display: none; } All three sections display properly in the preview as well as in-game. However the checkboxes do not hide the areas.
1406311714
Lithl
Pro
Sheet Author
API Scripter
Roll20 prefixes all class names with "sheet-". Try using "input.sheet-arrow:checked ~ div.sheet-body" as your second selector.
1406651871

Edited 1406652210
Tom
Pro
Sheet Author
On the subject of hiding sections, how would I change the CSS if I wanted the content to SHOW when the checkbox was checked? Additional Bug?: When testing the code, once I've checked the section to hide the sheet won't let me uncheck it.
1406657442
Lithl
Pro
Sheet Author
API Scripter
Tom said: On the subject of hiding sections, how would I change the CSS if I wanted the content to SHOW when the checkbox was checked? Swap the display: none and display: block parts. You can also use :not(:checked) to style based on something being unchecked, rather than styling based on being checked. Tom said: Additional Bug?: When testing the code, once I've checked the section to hide the sheet won't let me uncheck it. I couldn't say without looking at your code.
1406664651
Tom
Pro
Sheet Author
Brian said: Tom said: Additional Bug?: When testing the code, once I've checked the section to hide the sheet won't let me uncheck it. I couldn't say without looking at your code. Pretty much just plugged in what Andrew posted above. &lt;div&gt; &lt;input type="checkbox" /&gt; &lt;h4&gt;Stuff and Things&lt;/h4&gt; &lt;div&gt; &lt;input type="text" placeholder="Name" /&gt; &lt;br /&gt; &lt;input type="text" placeholder="Description" /&gt; &lt;input type="number" min="0" max="20" value="0" /&gt; &lt;br /&gt; &lt;textarea placeholder="Fulltext"&gt; &lt;/textarea&gt; &lt;/div&gt; &lt;/div&gt; And CSS: /*Hiding Sections*/ input.arrow { float: left; } input.sheet-arrow:checked ~ div.sheet-body { display: none; }