Skip to content
VoteFirst Docs
Dashboard

Embed

Appearance

The widgets already wear the colours your public board wears, so in most cases there is nothing to do here at all.

What happens by default

Change your colours in the dashboard under Theme and colors and every page embedding the board follows on its next load. There is no second palette to keep in step with the first.

Six colours and a corner radius come from your theme, and everything else is mixed from them by the same formulas your public page uses. The font is the one value that does not travel: a theme names a family your public page loads from a font service, and a page that never loaded it would fall back to something generic, so the widgets inherit the font of the page they are in instead.

Dark and light

Widgets follow the color-scheme of the page around them, not the reader's operating system. A page that declares both schemes is inviting the system setting to decide; a page that declares dark alone is a dark page; and a page that has never said anything is light. Force one with the theme option.

VoteFirst.roadmap('#roadmap', { theme: 'dark' });

Overriding a colour

Every value below is a custom property on .vf, and the appearance option sets the same properties from JavaScript. A number is read as pixels, so radius: 0 and radius: '0px' mean the same thing.

One widget, your own accent
VoteFirst.roadmap('#roadmap', {
  appearance: { accent: '#6C4EBB', radius: 4 }
});
appearance keyCustom propertyDefault
accent--vf-accentYour board's accent
accentText--vf-accent-textBlack or white, whichever reads on the accent
bg--vf-bgYour board's background
cardBg--vf-card-bgYour board's card background
border--vf-borderYour board's border
borderControl--vf-border-controlMixed from your border and your text, for the edge of a control
text--vf-textYour board's text
textSecondary--vf-text-secondaryYour board's secondary text
danger--vf-dangerThe colour a form error is written in
radius--vf-radiusYour board's corner radius
space--vf-space8px, which most gaps are a multiple of
font--vf-fontInherited from your page
fontSize--vf-font-size13px on the root, which the smaller sizes inside do not follow
changelogWidth--vf-changelog-width820px, the width a release note stays readable at

The same properties can be set in your own stylesheet, which is the better place for them if every widget on the site should look the same.

In your stylesheet
.vf {
  --vf-accent: #6C4EBB;
  --vf-radius: 4px;
}

Load your own rules after votefirst.css. They are on the same selector, so the later of the two wins, and a stylesheet loaded first is a stylesheet with no effect.

Both palettes at once

Your board has a light palette and a dark one, and the widgets carry both rather than resolving one. That is why a widget set to auto follows the reader's system setting the moment they change it, with no listener and no repaint.

They arrive as --vf-l- and --vf-d- properties, and the stylesheet picks the prefix that applies. Anything you set through appearance, or in your own CSS, is written without a prefix and therefore applies to both. Set a property under a @media (prefers-color-scheme: dark) rule of your own if you want it in one of them only.

The resolved answer is on the widget root as data-vf-theme, so your own rules can read it: .vf[data-vf-theme="dark"] .vf-card { ... }.

Writing your own CSS

Pass appearance: false, or leave the stylesheet out of your page entirely, and the widgets arrive with structure and no styling.

Almost every element carries a vf- class. The ones worth writing rules against are vf-card, vf-card-title, vf-card-description, vf-dev-response, vf-card-tags, vf-tag, vf-card-progress, vf-card-meta, vf-vote-btn, vf-vote-count, vf-meta-item, vf-column, vf-column-title, vf-release, vf-release-card, vf-modal, vf-form and vf-button. The view a card opens adds vf-detail, vf-detail-heading, vf-detail-description, vf-detail-stats, vf-comments, vf-comment, vf-comment-author and vf-comment-content.

A declined feature carries vf-dev-response-denial beside vf-dev-response, so the owner's answer and the reason something was turned down can read differently without any state of your own.

A vote control this visitor has already used carries aria-pressed="true", so a rule can style a cast vote without any state of your own.