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.

info

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.

info

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: #ff0000 and var(--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 ease for 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 -- ::before and ::after for 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.

warning

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.

lightbulb

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;
}
lightbulb

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

warning

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.