Theming

Start of documentation content

Formally has been designed to allow easy theming.

Formally has default CSS designed to inherit your page styles, and to be themed.

If you wish to customise the HTML or other behaviour of Formally instead try the React SDK Custom Controls.

Theme variables (recommended)

CSS Custom Variables (aka CSS Custom Properties) builds upon the default CSS that Formally provides, and makes for easy upgrades in the future. Visit MDN to read generally about CSS Custom Properties.

Using CSS Variables is the recommended approach to theming as it doesn't fork Formally's default CSS.

A complete list of the CSS Variables that Formally understands is at the end of the page (see "List of all CSS Variables that Formally supports" heading).

How to know which theme variables to use

In your browser developer tools inspect the element that you wish to theme and ensure that element is selected.

Tip: if you're looking to customise radio buttons or checkboxes look for the ::before or ::after pseudo elements.

In the list of styles associated with the element look for CSS classes that begin with "formally-" (eg "formally-input") and then look for CSS property values that contain var(-- (eg var(--formally-text-border-radius)).

Note: Only CSS properties containing Formally CSS Variables can be configured. Please contact support if there isn't a CSS variable for the CSS Property that you wish to configure.

With the CSS Variable name you can now override that variable to change that CSS property value.

List of all CSS Variables that Formally supports

CSS Variable (CSS Property)TypeAboutDefault value
--formally-autosuggestion-list-heightLengthAuto suggest items list height400px
--formally-color-autosuggestion-iconColorAuto suggest icon colourvar(--formally-color-brand)
--formally-color-autosuggestion-selected-list-item-borderColorAuto suggest list item border colourvar(--formally-color-border-light)
--formally-color-autosuggestion-selected-list-item-textColorAuto suggest selected list item text colourvar(--formally-color-content)
--formally-color-autosuggestion-selected-list-item-hoverColorAuto suggest selected list item hover colourvar(--formally-color-brand-light)
--formally-error-border-widthLengthThickness of error border2px
--formally-border-radiusLengthRadius of fields4px
--formally-text-border-radiusLengthRadius of text fields (FreeText)4px
--formally-select-border-radiusLengthRadius of dropdown (Select)4px
--formally-button-radiusLengthRadius of buttons6px
--formally-dateinput-border-radiusLengthRadius of date inputs4px
--formally-input-border-widthLengthBorder thickness (width) of textural inputs (FreeText etc.)1px
--formally-color-locale-picker-borderColorLocale picker border colourvar(--formally-color-white)
--formally-button-padding-horizontalLengthPadding of buttons (horizontal)24px
--formally-button-padding-verticalLengthPadding of buttons (vertical)0.75rem
--formally-button-delete-widthLengthWidth of delete button within a Repeater3em
--formally-button-delete-heightLengthHeight of delete button within a Repeater2em
--formally-xs-button-group-flex-directionButton group alignment.column
--formally-md-button-group-flex-directionButton group alignment.row
--formally-color-button-border-primaryColorPrimary Button border colour. Primary buttons are usually 'Next' or 'Submit' buttons, but not 'Previous'.var(--formally-color-brand)
--formally-color-button-text-primaryColorPrimary Button text colour. Primary buttons are usually 'Next' or 'Submit' buttons, but not 'Previous'.var(--formally-color-white)
--formally-color-button-bg-primaryColorPrimary Button background colour. Primary buttons are usually 'Next' or 'Submit' buttons, but not 'Previous'.var(--formally-color-brand)
--formally-color-button-bg-primary-darkColorPrimary Button background colour dark variation. Primary buttons are usually 'Next' or 'Submit' buttons, but not 'Previous'.var(--formally-color-brand-dark)
--formally-color-button-bg-primary-darkerColorPrimary Button background colour darker variation. Primary buttons are usually 'Next' or 'Submit' buttons, but not 'Previous'.var(--formally-color-brand-darker)
--formally-color-button-border-secondaryColorSecondary Button border colour. Secondary buttons are usually 'Previous' buttons, but not 'Next' or 'Submit' buttons.var(--formally-color-brand)
--formally-color-button-text-secondaryColorSecondary Button text colour. Secondary buttons are usually 'Previous' buttons, but not 'Next' or 'Submit' buttons.var(--formally-color-brand)
--formally-color-button-bg-secondaryColorSecondary Button background colour. Secondary buttons are usually 'Previous' buttons, but not 'Next' or 'Submit' buttons.var(--formally-color-white)
--formally-color-button-bg-secondary-darkColorSecondary Button background colour dark variation. Secondary buttons are usually 'Previous' buttons, but not 'Next' or 'Submit' buttons.var(--formally-color-brand-lighter)
--formally-color-button-bg-secondary-darkerColorSecondary Button background colour darker variation. Secondary buttons are usually 'Previous' buttons, but not 'Next' or 'Submit' buttons.var(--formally-color-brand-light)
--formally-button-group-margin-blockButton group (previous / next / submit buttons) margin3.125rem 0
--formally-button-min-tap-sizeLengthAccessible tap-size for buttons etc. Used in the a11y-target-size mixin48px
--formally-fieldset-borderFieldset bordersolid 1px var(--formally-color-border-dark)
--formally-fieldset-border-radiusLengthFieldset border radiusvar(--formally-border-radius)
--formally-fieldset-paddingFieldset padding0 var(--formally-field-padding-horizontal) var(--formally-field-padding-vertical) var(--formally-field-padding-horizontal)
--formally-fieldset-legend-paddingFieldset legend paddingvar(--formally-field-padding-vertical) var(--formally-field-padding-horizontal)
--formally-icon-sizeLengthSize of icons16px
--formally-stroke-widthNumberSVG stroke width for icons2
--formally-stroke-linecapSVG stroke-linecap for iconsbutt
--formally-stroke-linejoinSVG stroke-linejoin for iconsmiter
--formally-input-heightLengthText input (free text) field type height3rem
--formally-color-inputColorText input (free text) colourvar(--formally-color-content)
--formally-color-input-bgColorText input (free text) background colourvar(--formally-color-background)
--formally-color-input-select-bgColorInput select background colourvar(--formally-color-brand)
--formally-color-input-borderColorInput border colourvar(--formally-color-border-light)
--formally-color-input-border-focusColorInput border colour when in focus (when the field has been navigated to by the user)var(--formally-color-brand)
--formally-color-input-border-warningColorInput border colour when the field has a warning (error)var(--formally-color-warn)
--formally-input-border-size-warningLengthInput border width when the field has a warning (error)var(--formally-error-border-width)
--formally-color-input-placeholderColorInput placeholder colourvar(--formally-color-placeholder)
--formally-color-input-select-chevronColorSelect field chevron color (colour)var(--formally-color-brand)
--formally-input-liveupload-status-font-sizeLengthLive upload status font-sizevar(--formally-font-size-smaller)
--formally-input-liveupload-status--success-borderLive upload status success border colour0
--formally-color-input-liveupload-status--successColorLive upload status success text colourvar(--formally-color-brand)
--formally-color-input-liveupload-status--success-backgroundColorLive upload status success background colourvar(--formally-color-background)
--formally-input-liveupload-status--error-borderLive upload status error border coloursolid 1px var(--formally-color-warn)
--formally-color-input-liveupload-status--error-backgroundColorLive upload status error background colourvar(--formally-color-background)
--formally-color-input-liveupload-status--errorColorLive upload status error text colourvar(--formally-color-warn)
--formally-color-choice-bgColorMultichoice (checkbox/radio) background colourvar(--formally-color-white)
--formally-color-choice-bg-selectedColorMultichoice (checkbox/radio) background colour of selected itemvar(--formally-color-brand)
--formally-color-choice-borderColorMultichoice (checkbox/radio) border colourvar(--formally-color-border-light)
--formally-color-choice-border-checkedColorMultichoice (checkbox/radio) border colour of selected itemvar(--formally-color-brand)
--formally-choice-checkbox-sizeLengthCheckbox size (width/height)1.5rem
--formally-choice-checkbox-border-radiusLengthCheckbox border radius4px
--formally-color-checkbox-tickColorCheckbox ticked colourvar(--formally-color-white)
--formally-choice-radio-sizeLengthRadio size (width/height)1.5rem
--formally-color-brand-lighterColorColour variable for lighter brand colourcolor-mix(in srgb, transparent, var(--formally-color-brand) 10%)
--formally-color-brand-lightColorColour variable for light brand colourcolor-mix(in srgb, transparent, var(--formally-color-brand) 20%)
--formally-color-brand-pastelColor#e4caff
--formally-color-brandColorColour variable for brand colour#6100ff
--formally-color-brand-darkColorColour variable for dark brand colour#5000c9
--formally-color-brand-darkerColorColour variable for darker brand colour#430099
--formally-color-greyColorColour variable for grey. This variable isn't used directly. You should probably override where this is used instead of overriding this variable.#595959
--formally-color-grey-lightColorColour variable for grey. This variable isn't used directly. You should probably override where this is used instead of overriding this variable.#d0d0d0
--formally-color-blackColorColour variable for black.black
--formally-color-whiteColorColour variable for white.white
--formally-color-redColor#b5031f
--formally-color-contentColorColour variable for content.var(--formally-color-black)
--formally-color-backgroundColorColour variable for background.var(--formally-color-white)
--formally-color-modal-backgroundColorcolor-mix(in srgb, transparent, var(--formally-color-grey) 90%)
--formally-color-placeholderColorColour variable for placeholder text. Accessibility-wise placeholder text may be confused for an actual response, so placeholder text isn't recommended.var(--formally-color-grey)
--formally-color-warnColorColour variable for warning (error) messagesvar(--formally-color-red)
--formally-color-focusColorColour variable for field focus ringvar(--formally-color-brand)
--formally-color-hintColorColour variable for hint textvar(--formally-color-grey)
--formally-color-labelColorColour variable for label textvar(--formally-color-content)
--formally-color-border-lightColorLight colour variation of bordervar(--formally-color-grey)
--formally-color-border-darkColorDark colour variation of bordervar(--formally-color-black)
--formally-color-progress-indicator-bgColorProgress indicator background colour. Progress indicator is the (eg) 'Page 1 of 5' message at the top of forms.var(--formally-color-grey-light)
--formally-color-progress-indicator-bg-previousColorPage indicator previous page background colour. Progress indicator is the (eg) 'Page 1 of 5' message at the top of forms.var(--formally-color-brand)
--formally-color-progress-indicator-bg-activeColorPage indicator current page background colour. Progress indicator is the (eg) 'Page 1 of 5' message at the top of forms.var(--formally-color-brand)
--formally-color-slider-track-bgColorRange slider background colourvar(--formally-color-brand-pastel)
--formally-slider-track-heightLengthRange slider track height0.5rem
--formally-slider-track-border-radiusLengthRange slider track radius0.5rem
--formally-slider-margin-topLengthRange slider margin top1.5625rem
--formally-slider-thumb-size-pixelsLengthRange slider thumb (dragable widget) size (width/height)2.75rem
--formally-slider-thumb-margin-topLengthRange slider thumb (dragable widget) margin top-1.1875rem
--formally-color-slider-thumb-bgColorRange slider thumb background colourvar(--formally-color-white)
--formally-color-slider-thumb-borderColorRange slider thumb border colourvar(--formally-color-brand)
--formally-slider-thumb-border-widthLengthRange slider thumb border width0.75rem
--formally-slider-thumb-borderRange slider thumb border (shorthand style)var(--formally-slider-thumb-border-width) solid var(--formally-color-slider-thumb-border)
--formally-color-slider-unsetColorRange slider colour when unselected / without value#999
--formally-color-repeater-borderColorRepeater border colour.var(--formally-color-black)
--formally-repeater-title-padding-inlineLengthRepeater inline padding. Used to indent repeating items.12px
--formally-repeater-delete-button-font-sizeLengthRepeater delete button font size.var(--formally-font-size-larger)
--formally-color-repeater-delete-button-hover-backgroundColorRepeater delete button background colorvar(--formally-color-brand-light)
--formally-max-widthLengthMaximum width of the Formally container640px
--formally-space-xs-numNumberSpacing unit XS (extra small). Override with a unitless number, e.g. 10 not 10px.8
--formally-space-xs-pxLengthDerived from --formally-space-xs-num. Override that variable instead.calc(var(--formally-space-xs-num) * 1px)
--formally-space-xs-remLengthDerived from --formally-space-xs-num. Override that variable instead.calc(var(--formally-space-xs-num) / 16 * 1rem)
--formally-space-sm-numNumberSpacing unit SM (small). Override with a unitless number, e.g. 10 not 10px.12
--formally-space-sm-pxLengthDerived from --formally-space-sm-num. Override that variable instead.calc(var(--formally-space-sm-num) * 1px)
--formally-space-sm-remLengthDerived from --formally-space-sm-num. Override that variable instead.calc(var(--formally-space-sm-num) / 16 * 1rem)
--formally-space-md-numNumberSpacing unit MD (medium). Override with a unitless number, e.g. 10 not 10px.16
--formally-space-md-pxLengthDerived from --formally-space-md-num. Override that variable instead.calc(var(--formally-space-md-num) * 1px)
--formally-space-md-remLengthDerived from --formally-space-md-num. Override that variable instead.calc(var(--formally-space-md-num) / 16 * 1rem)
--formally-space-lg-numNumberSpacing unit LG (large). Override with a unitless number, e.g. 10 not 10px.20
--formally-space-lg-pxLengthDerived from --formally-space-lg-num. Override that variable instead.calc(var(--formally-space-lg-num) * 1px)
--formally-space-lg-remLengthDerived from --formally-space-lg-num. Override that variable instead.calc(var(--formally-space-lg-num) / 16 * 1rem)
--formally-space-xl-numNumberSpacing unit XL (extra large). Override with a unitless number, e.g. 10 not 10px.32
--formally-space-xl-pxLengthDerived from --formally-space-xl-num. Override that variable instead.calc(var(--formally-space-xl-num) * 1px)
--formally-space-xl-remLengthDerived from --formally-space-xl-num. Override that variable instead.calc(var(--formally-space-xl-num) / 16 * 1rem)
--formally-node-gap-numNumberVertical distance between Formally nodes (fields). Override with a unitless number, e.g. 10 not 10px.28
--formally-node-gap-pxLengthDerived from --formally-node-gap-num. Override that variable instead.calc(var(--formally-node-gap-num) * 1px)
--formally-node-gap-remLengthDerived from --formally-node-gap-num. Override that variable instead.calc(var(--formally-node-gap-num) / 16 * 1rem)
--formally-field-padding-verticalLengthForm field padding (vertical)0.75rem
--formally-field-padding-horizontalLengthForm field padding (horizontal)16px
--formally-submit-pending-font-sizeLengthFont size of message that appears when submitting and waiting for a network response1em
--formally-submit-pending-text-alignText alignment of container of message that appears when submitting and waiting for a network responseright
--formally-font-familyDefault font family.sans-serif
--formally-font-size-smallerLengthSmaller font size used for less important small print0.875em
--formally-font-size-largerLengthLarger font size used for important text1.125em
--formally-label-font-weightLabel boldnessbold
--formally-label-font-sizeLabel font sizeinherit

Would you like to style something not mentioned here? Please let us know.

Customising CSS Variables in React

React itself has a variety of methods of applying CSS.

This example uses inline style, however there are alternative examples that follow.

import { Formally } from 'formally';
import 'formally/build/styles.min.css';

export const MyForm = () => (
  <div style={{ '--formally-color-brand': 'red' }}>
    <Formally />
  </div>
);

Customising CSS Variables in React with Next.js

// _app.tsx

import 'formally/build/styles.min.css';
import './my-formally-theme.css';

const MyApp = ({ Component, pageProps }) => (
  return <Component {...pageProps} />
);

export default MyApp;
/* my-formally-theme.css */
.formally-container {
  /* configure any Formally CSS Variables here */
  --formally-color-brand: red;
}

Customising Theme Variables in React with Styled Components

import 'formally/build/styles.min.css';

const FormallyWrapper = styled.div`
  --formally-color-brand: red;
`;

export const MyForm = () => (
  <FormallyWrapper>
    <Formally />
  </FormallyWrapper>
);

Customising Theme Variables in React with CSS Modules

import 'formally/build/styles.min.css';
import styles from './my-formally-theme.module.css';

export const MyForm = () => (
  <div className={styles.myFormallyWrapper}>
    <Formally />
  </div>
);
/* my-formally-theme.module.css */
.myFormallyWrapper {
  /* configure any Formally CSS Variables here */
  --formally-color-brand: red;
}

Customising Theme Variables in HTML / CSS

<link rel="stylesheet" href="https://form-data.getformally.com/styles.min.css" />
<style>
.formally-container {
  /* configure any Formally CSS Variables here */
  --formally-color-brand: red;
}
</style>

Overriding Formally CSS classes

This approach uses Formally CSS but also your own CSS that matches CSS classes used by Formally.

This is slightly risky because if you upgrade to a later version of Formally the CSS classes may change. Formally makes no guarantees about CSS class name stability.

However if you test your CSS after you upgrade this may be an appropriate choice.

Warning: Considering entirely Custom CSS?

From a technical standpoint Formally's CSS is optional and as such developers may ignore it and instead use their own CSS.

However this isn't recommended as you will incur a significant development effort to start with, and an ongoing maintenance burden when upgrading to newer versions of Formally.

Instead please consider whether configuring Formally's CSS Variables could sufficient, and please feel free to suggest new CSS Variables (contact support!).

If you choose this approach please ensure that you use a specific version of Formally via NPM or UNPKG to avoid breaking changes. Do not use our CDN hosted version which is always the latest version and may have breaking changes against your custom CSS.

We do not support or recommend this approach.