Roll20 CSS
Roll20 character sheets live inside Roll20's web application, which means your CSS runs in a specific environment with some rules and restrictions. Understanding these up front will save you from surprises when you upload your sheet.
This page covers CSS conventions and limitations specific to Roll20. If you are exporting to a different VTT, its CSS environment will have different constraints.
For Roll20's official documentation on CSS styling, see the Building Character Sheets -- CSS Styling page.
Automatic Scoping
One thing you do not need to worry about: your styles bleeding into Roll20's interface. Sheet Architect automatically wraps your CSS so it only affects your character sheet, not Roll20's menus, chat, or other UI elements.
This scoping happens during export. In the Style Editor, you write CSS as if your sheet is the only thing on the page. Sheet Architect handles the rest.
Because of automatic scoping, you do not need to add .charsheet or .sheet-root prefixes to your selectors manually. Sheet Architect adds the appropriate scoping during export.
Supported CSS Features
Roll20 supports most modern CSS features. You can use:
- Flexbox --
display: flex,flex-direction,justify-content,align-items,flex-wrap,gap, and all related properties. This is the recommended way to arrange elements side by side or in rows and columns. - CSS Grid --
display: grid,grid-template-columns,grid-template-rows,grid-area, and the full grid specification. Great for complex, two-dimensional layouts like stat blocks. - Custom properties (variables) --
--my-color: #ff0000andvar(--my-color). This is how design tokens work under the hood. - calc() -- Mathematical expressions like
width: calc(100% - 20px). Useful for precise sizing. - Transitions --
transition: background-color 0.2s easefor smooth hover effects and state changes. - Pseudo-classes --
:hover,:focus,:checked,:first-child,:last-child,:nth-child(), and others. These let you style elements based on their state or position. - Pseudo-elements --
::beforeand::afterfor decorative content. - Attribute selectors --
[type="checkbox"],[name^="attr_"], and similar patterns.
Limitations
Roll20's environment imposes several constraints you need to be aware of:
No External Fonts
You cannot load fonts from Google Fonts, Adobe Fonts, or any other external source. Roll20 provides a set of built-in fonts, and those are all you can use. The available fonts include common web-safe fonts (Arial, Georgia, Times New Roman, Courier New, etc.) and some additional options Roll20 has licensed.
If you use a font that is not available on Roll20, the browser will fall back to a default font, and your sheet will look different than it did in the Sheet Architect preview. Always specify fallback fonts in your font-family declarations.
No @import
The @import rule, which loads external stylesheets, is not supported. All your styles must be in a single CSS block.
Fixed Container Width
Roll20 character sheets display inside a popup window that is approximately 800 pixels wide. Your sheet does not have access to the full browser window. Design your layout with this fixed width in mind.
Test your sheet at different zoom levels in the Sheet Architect preview. While the container is fixed-width, players may use browser zoom, which can affect how things look.
No External Resources in url()
CSS url() values that point to external images, fonts, or other resources will be blocked by Roll20's content security policy. You cannot load background images from external servers.
No @keyframes Animations
While simple transition properties work for hover effects and state changes, complex @keyframes animations may not work reliably on Roll20.
CSS Best Practices for Roll20
Use Flexbox and Grid, Not Floats
Older sheet-building tutorials sometimes recommend float: left and float: right for layout. These are fragile and hard to maintain. Use display: flex or display: grid instead -- they are more predictable, easier to understand, and better supported.
/* Good: flexbox for a row of stats */
.stat-row {
display: flex;
gap: 8px;
align-items: center;
}
/* Avoid: floats for layout */
.stat-row .stat {
float: left; /* Don't do this */
margin-right: 8px;
}
Use Design Tokens for Consistency
Rather than typing color codes and spacing values directly, use design tokens (CSS custom properties). This keeps your theme consistent and makes it easy to change later.
/* Good: using tokens */
.section-header {
background-color: var(--primary-color);
padding: var(--spacing-sm);
}
/* Less ideal: hard-coded values scattered everywhere */
.section-header {
background-color: #1a365d;
padding: 4px;
}
Set box-sizing: border-box
By default, CSS sizing does not include padding and borders in an element's width. This leads to unexpected overflow. Adding box-sizing: border-box tells the browser to include padding and borders in the element's stated width.
* {
box-sizing: border-box;
}
Sheet Architect adds box-sizing: border-box to exported sheets by default. You can include it in your Style Editor CSS as well for accurate previews.
Keep Selectors Simple
Roll20 may add wrapper elements around your sheet. Deeply nested selectors like div > div > div > span.label are brittle and may break if Roll20's wrapper structure changes. Use class-based selectors instead:
/* Good: simple class selector */
.ability-label {
font-weight: bold;
}
/* Fragile: depends on exact nesting */
.charsheet > div > div:first-child > span {
font-weight: bold;
}
The Checkbox Hack
Roll20 sheets commonly use a CSS technique called the "checkbox hack" to create tabs, toggles, and collapsible sections without JavaScript. This works by styling elements based on whether a hidden checkbox is checked:
/* Hide the checkbox */
input.tab-toggle {
display: none;
}
/* Show content when the checkbox is checked */
input.tab-toggle:checked ~ .tab-content {
display: block;
}
Sheet Architect's tab and toggle components use this technique under the hood, so you generally do not need to write it yourself. But understanding it helps when debugging tab switching or conditional visibility.
Testing on Roll20
Always test your exported sheet on Roll20 before sharing it. The Sheet Architect preview is a close approximation, but Roll20's actual environment may render some CSS differently. Font availability, container sizing, and content security policies can all cause visual differences.
The fastest way to test is using Roll20's Sheet Sandbox, which lets you load and reload your sheet quickly during development. See Using Your Sheet -- Sheet Sandbox for setup instructions.