Vistaprint

Visage themes

Making Visage match your brand identity

A Visage theme allows a micro-site (or visually distinct sub-section of a site) to customize some of Visage's visuals.

Protecting the brand

Where to use themes:

  • Micro-sites or other Vistaprint-owned sites that have a different brand look, e.g. the Masks site we launched in 2020, Promotique, or a holiday micro-site that uses a red-and-white color scheme

  • Specific sub-sections of a site that have a defined look-and-feel that is different from the Visage norm

  • Locales that don't use the Latin alphabet and need to change the base font, e.g. a Japanese site that wants to set the base font to Mincho

Where not to use themes:

  • To adjust the properties of a specific component to "snowflake" its look. We do not want to undermine our brand identity or create UX inconsistency! Only use themes where the Brand team has a specific campaign in mind.

Available themes

  • Masks - used by some pages on the Masks microsite

  • Holiday - used by some pages on the Vistaprint site to provide Holiday 2020 styling

  • Dark - this theme is now deprecated; instead, use the Visage Dark Mode feature.

Writing your own theme

You don't have to use one of the themes that come with Visage. For details on writing your own theme, see "Technical details", below.

You can either add your theme's stylesheet to the visage repo, or you can have it live in your project's repo.

Technical details

Visage provides themes via CSS custom properties that are either set on the :root element or on the class for a component. Visage components then use these custom properties to set their own values. To write your own theme, you write additional CSS for those custom properties, setting new override values on the :root element, such as:

css
:root
{
--visage-link-font-color: #ccbbff;
}

Ideally, your theme's CSS should come on the page after the Visage stylesheets, to make sure there aren't specificity issues. For instance, you might want to make your theme's CSS be the last stylesheet on the page. If this is not feasible, you may need to heighten the specificity of your theme's CSS, such as by setting values on :root:root instead of :root.

Scoping

Setting new values on the :root element, as shown above, will make your theme apply to the whole page. If you only want your theme to apply to specific section of a page, you can make your theme scoped instead. You might want to do this if you want to leave the global Vistaprint navigation unchanged, and have your new theme affect only the main content section of your page.

To do this, define your custom property values on your section's wrapper element, rather than on the :root element. However, note that the usual CSS rules for inheritance and specificity will still apply, so there are some additional considerations:

Base font

Note: the base font family, size, weight, line height, and color are set on the html tag, using custom properties defined on :root. Other elements on the page will then inherit from html. Changing these values on a smaller level than html won't cause all content of your section to pick up the new values, because html will still be getting its values from :root.

To change these values only on a scoped section of a page, then in addition to providing new values for the relevant custom properties, you will also need to explicitly override those CSS properties on your section's outer container. For example:

css
.my-scoped-section
{
--visage-font-base-family: Garamond;
--visage-font-base-size: 18px;
--visage-font-base-line-height: 1.6em;
--visage-font-base-weight: 400;
--visage-font-base-color: #333;
font-family: var(--visage-font-base-family);
font-size: var(--visage-font-base-size);
line-height: var(--visage-font-base-line-height);
font-weight: var(--visage-font-base-weight);
color: var(--visage-font-base-color);
}

Custom properties that use other custom properties

Visage uses some custom properties as the values for other custom properties, when we normally want the two to stay in sync, e.g.:

css
:root
{
--visage-widget-background-color: white;
--visage-widget-background-color-hover: var(--visage-widget-background-color);
}

You can redefine the value of --visage-widget-background-color for your scoped section:

css
.my-scoped-section
{
--visage-widget-background-color: purple;
}

This will change the widget's background color to purple inside your section. However, note that the hover color is defined on the :root element, so it still takes its value from --visage-widget-background-color as defined on :root. This means that the hover color will not automatically change to purple for your widget. In cases like this, you will need to define the scoped value for both properties:

css
.my-scoped-section
{
--visage-widget-background-color: purple;
--visage-widget-background-color-hover: purple;
}

Component skins and options

Visage also sometimes uses scoping internally to adjust values for a given component's skin or option. In these cases, if you want to adjust the value for the skin/option, you will need to scope your value to match:

css
--visage-widget-background-color: purple; /* default for the component */
.widget.widget-skin-valentine
{
--visage-widget-background-color: red; /* value for the "valentine" skin */
}

Adjusting component icons

Some Visage components incorporate our stock set of icons, such as Control Icons, or the open/close icons on Accordions. Visage allows you to adjust these icons, with these considerations:

Icon color

Because Visage wants to keep the stock icons centralized, the images aren't inline SVGs. Instead, Visage components create icons using a pseudo-element, and use the SVG as the background-image property on that pseudo-element.

The Visage SVG image files are brand blue by default. If we need the icon to be another color, we then use the CSS filter property to change that color as needed. For instance, the dark grey icons show up dark grey because a CSS filter reduces the blue images' saturation and brightness, turning brand blue into dark grey.

With Visage Themes, you can change the color of a particular component's icon by changing the component's custom property that specifies which filter to use. You can also change the custom properties for the filters themselves, to make all icons of a given color shift to a different color instead.

Icon type

Visage defines a number of icon choices (chevron, arrow, X, etc) as custom properties, each of which specifies the URL of that icon's SVG. You can globally change how an icon looks by giving this custom property a new value.

Components that have theme-able icons then use one of these custom properties for the a pseudo-element's background-image, giving it a value that is one of the icon choices mentioned above. To have your theme use a different icon for the component, change the custom property value for that background image.

For now — to reduce file size and complexity — not all components allow you to change which icon they use, and not all icon choices can be globally changed to a new URL. However, we can easily add this capability as needed, so reach out to us if you need us to add this support somewhere.

Note: a bug in Safari, Edge 17, and Edge 18 prevents those browsers from correctly using relative URLs as values for custom properties. Visage works around this bug by encoding the icon choices into the stylesheet using data URLs, e.g. url('data:image/svg+xml;utf8,<svg ..></svg>')

If you give one of these icon custom properties a new URL, you will either need to use absolute URLs, or will also need to use data URLs.

What properties can a theme change?

The full list of theme-able properties is quite extensive -- too long to list here! Instead, you can find out if something can be themed by examining the component with a DOM inspector, and seeing if a CSS property's value uses a custom property, e.g. border-radius: var(--visage-foo-border-radius).

In the future, we are planning on making more components theme-able. Please let us know what you'd like to see added to the list!

Found something not theme-able?

If there is a property that you want to able to adjust for your theme, but which currently doesn't support theming, please let us know, because this sort of thing is usually quite easy to add. "Snowflaking" a Visage component with custom CSS is far less scalable and maintainable than adjusting theme values, so please reach out to us!