sample image

Visage

the Vistaprint UI Library & Design System

Visage (pronounced "vizz-edge") represents the public face of the Vistaprint brand.

What's New:

Showing deprecated items

Many older components, features, and APIs have been deprecated in 3.0. In a future release, we will be removing these deprecated features, to help keep file size small and to improve performance.

You can identify which elements on your (non-production!) page are deprecated by adding the show-deprecated.css stylesheet to your local environment. This stylesheet will make deprecated elements flash, and they will take on a rusted-out color with a border of rust-colored dots. Do not use this stylesheet in production!

Changes since v3.0

See the changelist at Gitlab.

Upgrading to v3

There is a detailed document on Confluence with all the v3 changes.

Breaking Changes in v3

  • There's a new set of packages for v3, e.g. react-visage instead of react-vp-uilibrary
  • The "evergreen" version on the CDN is no longer getting updates; it will be forever on the latest v2.N release. To update to v3, you'll have to move off of the evergreen URLs.
  • There is a new Page Setup API with new static file paths and new typography support.
  • The Grid is now proportional by default, and your page's outermost grid(s) needs a new Bounded Content container around it.
  • If you're not using the React components, the static file paths have changed, and you'll need to update them. (They are all now just /css/* or /js/*).
  • If you're not using the React component for Alert Box, the component's dependencies have changed.

New components and new APIs

  • Standard Tiles no longer need a Card Set around them. (Card Set is now deprecated.)
  • Selection Set is a new component to replace Option Set. It has a simpler API, and it's 59% smaller! (Option Set is now deprecated.)
  • Forms now have a new "standard form" component and an Input Group component that provide a standard layout.
    • The searchbar input now uses the new Control Icon instead of a textbutton, so it has an updated API. (The old API is deprecated, but will still work for now.)
  • Grid now supports col-md- classes that set column widths on Medium screens only.
  • Toggle Switch is a new component to replace Flipswitch. (Flipswitch does not meet accessibility standards, so you should replace any Flipswitches with Toggle Switches immediately.)
  • Control Icon is a new component to replace the more complicated Graphic Button. (Graphic Button is now deprecated.)
  • Dropdowns have a new look and a simpler API to go with it. (The old API still works, but is now deprecated.)
  • Breadcrumbs have a new API with better accessibility support. (The old API still works, but is now deprecated.)

Looking for the React documentation?

The code examples for each component have a link to the React documentation for that component, or you can skip to the React main page.

Showing all components:

Accessibility Utilities

.visually-hidden

Putting the class ".visually-hidden" on an element hides it on screens, but leaves it visible to screen readers and assistive technologies. This paragraph is visible to all browsers and devices, unlike the next one, which is hidden on screens:

This paragraph is visually hidden, so it will not show on a screen, but will be read by screen readers and other assistive technologies.

Developer Guidelines

  • visually-hidden can be used when image alt text or an aria-label doesn't work for providing a cue to an element's function. For instance, a paginator might have "previous" and "next" buttons with icons provided via the background-image property, meaning it can't use alt text. In this case, you could put a span inside that button with visually-hidden on it and the word "Previous" or "Next" as its contents.

.accessibility-keyboard-clickable

The class ".accessibility-keyboard-clickable" makes it so that if the element is in focus, and the user hits either the Enter or Space keys, the keypress will act as a click upon the element.

The native tags for interactive elements (such as radio buttons, checkboxes, and <button> tags) are inherently clickable with the keyboard. This feature is for elements that semantically serve as buttons or interactive elements, but for whatever reason cannot use the semantically-appropriate tag.

A span tag WITHOUT accessibility-keyboard-clickable A span tag WITH accessibility-keyboard-clickable

Accessibility Guidelines

  • Whenever possible, you should use a semantically appropriate tag for an interactive element, such as <button> or <input>. These elements are natively clickable with the keyboard, and don't need this feature. This feature is only for those rare instances when, for whatever reason, you can't use the semantically correct tag.
  • The element with this class will also need the attribute tabindex="0" to put it into the tab order. Without this, the user can't put the element into focus using the keyboard or a screen reader.
  • The element also needs an appropriate ARIA role to indicate its function; typically this will be role="button" for a clickable element that acts (but doesn't necessary look like!) a button.

Accordion

An accordion is comprised of collapsible list items that open and close when their summary is clicked, hiding or revealing content.

I'm the collapsible content.
By default I'm closed, but you can click the header to open me.
Extra content to show how a collapsible looks when it's tall
Extra content to show how a collapsible looks when it's tall
Extra content to show how a collapsible looks when it's tall
Extra content to show how a collapsible looks when it's tall
Extra content to show how a collapsible looks when it's tall

I'm the collapsible content.
By default I'm closed, but you can click the header to open me.
Extra content to show how a collapsible looks when it's tall
Extra content to show how a collapsible looks when it's tall
Extra content to show how a collapsible looks when it's tall
Extra content to show how a collapsible looks when it's tall
Extra content to show how a collapsible looks when it's tall

I'm a collapsible that is open by default, using aria-expanded="true" and class="collapsible-content-open"

Accordion with "multiple" option (allows multiple open nodes)

I'm the collapsible content for section 1.

I'm the collapsible content for section 2.

I'm the collapsible content for section 3.

Accordion using the "steps" skin

I'm the collapsible content for picking corner style. This collapsible's value has the "error" skin on it, indicating that the current selection is no longer valid.

I'm the collapsible content for picking a finish.

Collapsible whose summary text changes

I'm the collapsible content.

Accordion using the "peek" skin

The "peek" skin shows a small amount of the content while the accordion is closed. It is intended for SEO copy and similar blocks of text where we want to entice the user into opening the accordion. This skin should only be used for accordions with a single collapsible.

I'm the collapsible content for the "peek" skin, where you can see part of the content peeking out when the collapsible is closed. Clicking on the summary then lets you see the rest of the content.

This feature is intended for things like SEO copy on product pages.

If you want the summary text to be horizontally centered, you can use the text-center class from our typography:

I'm the collapsible content for the "peek" skin, where you can see part of the content peeking out when the collapsible is closed. Clicking on the summary then lets you see the rest of the content.

This feature is intended for things like SEO copy on product pages.

Collapsible with a "rich" summary

Using the "rich" option on the summary element allows you to customize the summary typography by putting typographic styles onto sub-elements inside the summary. Those sub-elements will be arranged in a single horizontal line, aligned to the left.

Adding the "align right" option to the last sub-element will make that sub-element align to the right edge.

I'm the collapsible content.

Accordion with the "bounded" option (which draws left and right borders)

I'm the collapsible content for section 1.

I'm the collapsible content for section 2.

I'm the collapsible content for section 3.
"minimal" skin for Collapsibles

I'm the collapsible content.
By default I'm closed, but you can click the summary to open me.

old (deprecated) API:

I'm the collapsible set content for section 1.
I'm the collapsible set content for section 2.
I'm the collapsible set content for section 3.

Tree (nested accordions)

I'm the collapsible set content for section 1.
I'm the collapsible set content for section 2.
I'm the collapsible set content for section 3.
I'm the collapsible set content for section 1.
I'm the collapsible set content for section 2.
I'm the collapsible set content for section 3.
I'm the collapsible set content for section 1.
I'm the collapsible set content for section 2.
I'm the collapsible set content for section 3.

Designer Guidelines

  • It is important that each summary be written to clearly indicate what is in its contents. Make sure the text is unambiguous to the user.
  • Content within a closed accordion is not visible to search engines, since search engines can't see any information that requires user interaction to view. For "see more info" collapsibles this might be okay, but for lengthy accordions, make sure at least one accordion is open by default.
  • The "steps" skin is for Accordions that let the user progress through a series of related steps.
  • When using a nested accordion (a Tree), try not to go beyond a parent/child. Too many nests are hard for users to understand, especially when the accordion has multiple nested nodes opened.

Developer Guidelines

  • A collapsible that should default to open needs both an aria-expanded="true" onto the collapsible-summary-button element and the class collapsible-content-open on the associated collapsible-content element. If using the old API, the aria-expanded="true" should go onto the collapsible-header instead.
  • By default, an accordion will only allow one collapsible to be open at a given time. You can change it to allow multiple nodes open at once by adding CSS class "accordion-multiple" to the element that has class "accordion" on it.
  • Any element in the collapsible header with the class "collapsible-ignore-click" will not toggle the collapsible open/closed.

Accessibility Guidelines

  • Every collapsible-summary-button (or, for the old API, every collapsible-header) must have:
    • an aria-expanded attribute set to true or false, depending on whether the accordion is open or closed.
    • an aria-controls attribute whose value is the id of the collapsible-content section it controls.
    • both role="button" and tabindex="0" attributes, so that the collapsible-header will be recognized by assistive devices as something that the user can click on.

SEO Considerations

  • Googlebot is able to crawl and get data within accordions as long as that data is part of the page's source HTML. If the content is added dynamically through JavaScript, the developer must validate with the Organic Search team that Googlebot can crawl the content.
  • Important content should not go into an accordion, since Googlebot considers content within an accordion as secondary (or less important), as it requires one more click from the user.

Accordion as Step Indicator

Since the Step Indicator does not provide a good user experience on Extra-Small screens, pages should use adaptive design and provide an Accordion (with the "steps" skin) instead of a Step Indicator on those screens.

In this case, the "collapsibles" for previous steps might not have content in them; they might actually be links or buttons that take the user back to a previous page in the flow. Similarly, "collapsibles" for future steps might be disabled, because the user has not yet reached that step in the flow.

To support this, Accordions can have fake collapsibles that are actually links/buttons, or collapsibles that are disabled and cannot be opened.

  1. Step 1 T-Shirt Type Women

  2. I'm the collapsible content for picking a style.
  3. Step 3 Placement

Accessibility Guidelines

  • As with Step Indicator, an Accordion serving this function should use <ol> and <li> tags, as it represents a list of steps.
  • The collapsible representing the current step must have aria-current="step" on it.

Alerts and Errors

Form input errors

Form input errors indicate where a user's input for a specific input field was invalid or incorrect.

Last name required.

Please select a shipping method.

Designer Guidelines

  • Form input errors should occur directly below their input, inside an Input Group as part of a Form.
  • Use form input errors for errors with individual text fields and dropdowns. If there is an error with a set of radio buttons, use an Alert Box at the top of the radio buttons, rather than put form input errors next to each of the radio buttons.

Developer Guidelines

  • When an error message occurs, preserve as much user input as possible, so that the user can modify their (incorrect) information, rather than have to re-enter it from scratch.

Accessibility Guidelines

  • When a form input field has a visible error message, the input should have aria-invalid="true" to indicate that its current value is invalid. It should also have both an aria-describedby attribute and an aria-errormessage attribute, both of whose values are the id of the error message.
  • If you are dynamically adding an error message after initial page load, then the content area where the error will appear will need to already have role="status" aria-live="polite" on it. These attributes inform assistive technologies that they need to notify the user when any content inside that area changes, and thus the browser will announce the error message when it appears.

Alert box

Alert boxes are for alert messages that apply to an entire page, or to a section of a page. For instance, if a user has incorrectly filled out some form fields, each form field might get its own individual error message (see above), but the whole form would also get an alert box at the top, right below its heading, calling attention to the entire form.

default alert

with "error" or "warning" skin

with "positive" skin

with "legal warning" skin

default alert using Background Color component

If the Alert Box is on a light grey background, you can use the Background Color component to change the background color to white.

Page alerts

Page alerts are for page-level alerts, and are displayed at the top of the page, right below the site navigation.

with "warning" skin

with "error" skin

Usage

  • Examples of when to show an Alert Box:
    • The user submits a form that contains one or more errors
    • A system-related error occurs
    • A process the user initiated has errors
    • The page's content is inaccessible
    • A price changes due to taxes or shipping charges
    • The user's design is outside of the safety line
    • The image that the user uploaded has too low resolution
  • The "legal warning" skin for the Alert Box is intended for legally-required warning messages, such as those covered by California's Prop 65. These Alert Boxes should not have a close button.

Designer Guidelines

  • The "legal warning" skin for the Alert Box has specific legal requirements governing its icon, font size, and font color. These Alert Boxes should not have a close button.
  • The Page Alert should come at the top of the page, right below the site navigation, and should be outside of the layout grid so that it will span the full width of the window.

Developer Guidelines

  • When an alert occurs, preserve as much user input as possible, so that the user can modify their (incorrect) information, rather than have to re-enter it from scratch.

Accessibility Guidelines

  • Users with vision issues may not be able to see the icon and/or color of the alert. For clarity, the nature of the alert must be clear via text alone. It may be useful to use the class visually-hidden to hide some of the text from screens. For instance, a positive alert indicating that an operation has succeeded might have <span class="visually-hidden">Success:</span> at the start of the message.
  • You must provide localized text inside the close button saying "Close alert". This text will be hidden on screens, but will guide users on assistive technologies.
  • If you are dynamically adding an alert after initial page load, then the content area where the alert will appear will need to already have role="status" aria-live="polite" on it. These attributes inform assistive technologies that they need to notify the user when any content inside that area changes, and thus the browser will announce the alert when it appears.

Background color

The background color containers are simple wrappers which just set the background color of a section.

This is a section with "background-light-grey".

This is a section with "background-light-blue".

This is a section with both "background-dark-blue" and "text-color-white".

This is a section with "background-white", shown inside a section with a different-colored background.

This is a section with "background-loading-shimmer".

This is a Card Container with "background-light-grey", overriding the Card Container's innate white background.

This is a section with "background-mist".

This is a section with "background-translucent-blue". (Note that it is no longer actually translucent after the 2020 Refresh, where we only use opaque light-blue backgrounds instead.)

This is a section with "background-black", plus "knockout" on the text.

using the "short" option

The "short" option makes the background color only 80% of the height of the container, with gaps at the top and bottom.

This is some content inside a section with "background-light-blue" and the short option. The dashed lines show the true height of this content.

Designer Guidelines

  • The "loading-shimmer" background is for sections of pages that are currently loading, such as skeleton screens. Typically a section with this background will not have any content inside of it.

Accessibility Guidelines

  • All text must have at least a 4.5:1 contrast ratio with its background.

SEO Considerations

  • A background color must be really different from the text on the top of it. Displaying text with the same or similar color as the background (e.g. light grey text on a white background) may generate a penalty from Google, as this will be considered hidden content.

Badge

A badge is an inline piece of text that draws attention to a particular characteristic, such as a product being recommended or having a different price. (Contrast Badges with Callouts, which are overlaid on top of another element such as a product image or tile.)

This sentence has a Sample badge in the middle of it. Here's a badge on a line by itself:

Recommended

50% off — using the "discount" skin

New! — using the "announcement" skin (plus the Typography class "all-caps")

Through Dec 25 — using the "holiday" skin

Design Guidelines

  • Vistaprint's badges look mostly like normal text, but many sites might want a pill-shaped badge with a colored background. Visage's themes allow a site to give a Badge such an appearance.

Copy Guidelines

  • Text should be short — no more than 14 characters. If there is not enough room to display the whole component, its text will ellipse.
  • A badge that says "New" should only be used for products launched within the last 6 months.
  • A badge that says "Top Rated" should only be used for products with a rating of 3.5 stars or more.
  • A badge that says "Up to NN% Off" should only be used for product "Red" sales.

Banner

Visage doesn't have a single banner component, but here are some of the types of banners that it offers:

Details Banners

example image

Example Details Banner

A Details Banner puts an image alongside some details about the content shown in that image. It can contain any content you want in the details, including buttons. Details Banners can show the image on the right, and can have colored backgrounds behind the text.

Learn more

Standard Hero as mid-page banner

Standard Hero can be used outside of the page's hero zone to create a narrow banner in the middle of a page. To do so, add the "narrow" option to the Standard Hero, which will adjust the hero's layout and typography to better fit a narrow width. Then place the Standard Hero inside a layout grid element.

Overline

Banner title

This banner uses the "narrow" options, plus the "text-center" and "text-align-bottom" options.

sample image

Banner title

This banner is showing the "transparent-background" option.

sample image

Bounded Content

A Bounded Content box is used around a page's central content. It puts a maximum width on that content, keeping the content from touching the edges of the browser window.

Most pages will want to place any content between header and footer inside of a Bounded Content box. Any content that should span the full browser window, such as hero zones, should go outside the Bounded Content.

Development Guidelines

  • A Bounded Content container keeps the layout grid from spanning the full browser window. Any content that should span the full window, such as a hero, should not go inside Bounded Content.

Breadcrumbs

Breadcrumbs are typically located at the top of the page, and contain navigational links. They indicate the user's location within the site hierarchy.

Putting class .breadcrumbs and a role onto the ul element instead:

Developer Guidelines

  • Breadcrumbs are important for SEO. The underlying HTML should use the SEO-friendly structured data format below, to tell search engine bots that these links belong to structured breadcrumbs. (Contact the Organic Search team with any questions.)

Accessibility Guidelines

  • The <nav> tag signifies that the breadcrumbs are a navigation landmark.
  • The aria-label attribute helps guide users on assistive technologies as to what this particular navigation is. Its value will be displayed to assistive technologies, so the value must be localized.
  • An older, now-deprecated API for the breadcrumbs put the breadcrumbs class onto the <ul> tag, along with role="navigation", leaving out the <nav> tag. This API was incorrect; since it redefined the <ul> as a navigation element, it would then cease to act as a proper container for the <li> list items.

SEO Considerations

  • Breadcrumbs should be integrated on all public indexed pages, in order to help Google have a better understanding of the website hierarchy.
  • If a page belongs to two parent pages, you should just display one of those parents on the breadcrumbs to make it easier for bots.
  • Breadcrumbs need Structured Data; see Developer Considerations above.

Button

Textbutton

"Textbutton" is our name for our standard site button.

These skins are deprecated, and predate our current site look. No new instances of these should be added to the site. If your page is using any of them, please update them to use a skin that isn't deprecated.

Here's how they appear using our current site visuals:

width options

The "wide" option puts extra padding on the left and right sides of the button:

With the "full-width" option, the textbutton expands to fill the width of its container. Here's an example inside a col-6 element, where the col-6's edges are shown with a dashed line:

Textbuttons that aren't <button> tags

  • A textbutton should use an <a> tag instead of a <button> tag if it acts as a link, where clicking on it just takes the user to a new page without any submission of form information.
  • It should use a <label> tag only when acting as a label for a (presumably hidden) input element.
  • It should only use a <span> tag when an unusual technical limitation prevents the use of a better tag.
<a> tag <span> tag

Buttons that are not <button> tags can't use the disabled property, so they should set aria-disabled="true" instead.

primary with aria-disabled secondary with aria-disabled

Do

  • Use a primary button to show an important CTA for users.
  • Use primary and secondary buttons side by side when there are multiple CTAs. The more important CTA should be primary, to create information hierarchy.
  • Align buttons accordingly with the content grouping for visual consistency. For example, left-aligned typography includes a left-aligned button.
  • Align buttons based on where they appear on a page, dialog, form, or panel.
  • Keep button text clear and short, with directive language to signal what will happen next. Try to lead with a verb.

Don't

  • Use too many buttons on a page.
  • Alter the button shape, height or width. Button size variations are available for different use cases.
  • Use lengthy text inside a button.
  • Use buttons for navigation. Use links instead.

Designer Guidelines

  • A "Primary" button is the call to action (CTA) for the primary action or outcome on a webpage. Only one "Primary" CTA should be shown at once, unless the decision choices are of equal weight and/or value.
  • A "Secondary" button is for secondary actions. Numerous "Secondary" buttons can be shown at once.
  • The "Super" option should only be used when the text is long enough to warrant wrapping onto two lines.
  • The "Disabled" option is used when an option or action is unavailable.
  • Use clear, concise, descriptive copy of the action being performed on the button.
  • Place buttons in flow near relevant content, with negative space to call the maximum amount of attention to the action.
  • Ensure buttons have appropriate contrast when placed on busy backgrounds.

Developer Guidelines

  • Text buttons will grow wide enough to accommodate their text. If there is not enough room for the button to grow, a button will truncate the text with ellipses. Button text will not normally line-wrap onto two lines.
  • "Super" buttons can wrap onto two lines a button lacks enough space to display the text on one line. However, they will not naturally wrap onto two lines if there is enough space to display the text on one line. If two lines is desired, you will likely need to force a line break into the button text.
  • "Super" buttons that are <a> or <span> tags should not put any additional tags inside the button other than a <br> tag or an icon. Super buttons with these tags use flex layout, and any internal tags will be treated as flexbox children, which can affect the button's layout.

Accessibility Guidelines

  • Use the <a> for buttons that are hyperlinks to a new page, the <button> tag for textbuttons that interact with the page, and <span> tags only when the previous two tags can't be used for some reason.
  • Buttons that are <span> tags also need the class accessibility-keyboard-clickable and the attribute tabindex="0" to make them usable with a keyboard and/or screen reader. They also need the attribute role="button" to mark them functionally as buttons.
  • If the button is disabled, and the HTML tag does not support the disabled attribute (e.g. it is a span tag), add the attribute aria-disabled="true" to aid in accessibility.

Textbutton with icon

standard icon choices

Textbuttons with "icon left" option

Textbuttons with custom icons

Textbuttons with custom icons that have a hover state

Textbuttons with icons that aren't <button> tags

<a> tag <span> tag

Designer Guidelines

  • For text buttons with custom icons, the icons should be inline (as <img> tags). Images should be square, and at least 36px by 36px. The icon will stretch to fill the available space inside the button, so if you want the icon to appear smaller, you will want to include whitespace in the image itself, around the visible part of the icon.

Developer Guidelines

  • While the textbutton-with-icon feature will work on a <button> tag, it can't be used on an <input> tag.

Other buttons

These buttons are not Textbuttons, but are instead skins for the <button> tag.

"Link" and "unstyled" buttons

These skins are for elements that semantically function like buttons, even if they don't look like it.

If you need a <button> tag for proper semantics, but it needs to look like a link, you can use a .
You can also add the to a button (although this skin is not intended for inline links, and should only be used in specific locations such as Standard Heroes and Standard Tiles!)

"Link" buttons can also and can have a Control Icon inside them, or just like a real link.

This paragraph has an in the middle of it.

This paragraph shows what a looks like, or one with .

Developer Guidelines

  • If a "link" doesn't actually take the user to a new location, but instead performs an action on the current page, then semantically it's a <button> and not a link. The "link" class can be used on a <button> to give it the appearance of a link.
  • The "unstyled" skin provides no affordance on touch devices and little affordance on desktops, so it should only be used to wrap a component that provides its own affordance. For instance, it might go around a Standard Tile, since that component has a visible underline and a hover state.

Clear Selection buttons

Considerations

  • Used in places like Gallery where the user has made selections. The button shows a current selection, with an "X" icon indicating that the user can click the button to cancel that selection.

Launcher buttons

These buttons are used to launch "panel" modal dialogs.

Quantity:

Designer Guidelines

  • Used to launch "panel" model dialogs.

Accessibility Guidelines

  • The button's text is the selected value, and so does not act as an accurate label for the button. Instead, the button needs an aria-labelledby attribute whose value is the id of the element that labels the button.
  • Screen reader users cannot see the arrow icon on the button, so will only hear the value of the button. To make the button's purpose clear to users on assistive technologies, you will likely need to add visually-hidden text inside the button, such as "(Click to change selection)".

Buttonbar

A buttonbar is a set of choices that are visually grouped together. A buttonbar can be either multi-select (using checkboxes) or mutually exclusive (using radio buttons).

Buttonbar of radio buttons

Buttonbar of checkboxes

Buttonbar of secondary textbuttons

using the "full-width" option

Designer Guidelines

  • Buttonbars of radio buttons can be used as a toggle control when the choices are not "on" or "off". (If you need to toggle between "on" and "off" states, consider a Toggle Switch instead.)
  • Buttonbars should not be used for navigation.

Developer Guidelines

  • You cannot use a <fieldset> tag for the buttonbar, because Chrome doesn't support enough styling of that tag.

Accessibility Guidelines

  • The buttonbar needs an aria-label whose value is a localized description of what the buttonbar is or does, e.g. "Change view".
  • If the buttonbar controls another section of the page, it should have an aria-controls attribute whose value is the id of the section it controls.

Callout

A callout is a merchandising element that is overlaid on top of another element such as a product image or tile. It calls attention to that element. (Contrast with Badges, which are inline pieces of text.)

default skin

"holiday" skin

"discount" skin

"neutral" skin

"hollow-dark" skin

"hollow-light" skin

"sale-discount" skin

"new" skin

"promo-grape" skin

"promo-fire-orange" skin

"gold-foil" skin

Design Guidelines

  • Only use a skin for the purpose indicated by the skin name, so the "holiday" skin is only for holiday messaging, not just because you want to use red.

Copy Guidelines

  • Text should be short — no more than 14 characters. If there is not enough room to display the whole component, its text will ellipse.
  • A callout that says "New" should only be used for products launched within the last 6 months.
  • A callout that says "Top Rated" should only be used for products with a rating of 3.5 stars or more.
  • A callout that says "Up to NN% Off" should only be used for product "Red" sales.

Card

Cards provide a strong visual cue of content relationships. They are simple containers into which you can put any content. They are often used to wrap clickable product tiles.

Card Container

Sample Card Container. Note that a card has some padding by default. Note also that its default background color is white.
Sample Card Container with longer content. Note that a card container will expand to cover its contents, but by default it won't match the heights of any other cards on the same grid row.

Card Container with "bordered" option

Sample Card Container with "bordered" option that draws a border around the edge.

Card Container with "full bleed" option

The "full bleed" option removes the internal padding around the card's contents, so that the contents will touch the border of the card.

Example image This Card Container above has the "full bleed" option. With this option, the Container has no internal padding, so the image runs right up to the edges of the Card Container.

Card Container with "even height" option

By default, a card container will only be as tall as its contents. If you want all the card containers on the same grid row to have the same visible height, add the "even height" option to the cards. This will also put some vertical spacing below each card, so that there is a gap between rows of cards.

Sample Card Container with "even height"
Sample Card Container with "even height" that has much, much longer text, so that it's taller than the other elements on the same row as this one.
Sample Card Container with "even height"
Sample Card Container with "even height". Notice how there is spacing between this tile and the tile above it.

Card Container with Card Dividers

Adding a set of dividers inside a Card will create vertical dividing lines.
Note: the dividers don't add any internal spacing. Use the spacing system if you need to add spacing between the dividing lines and the content.

Card Dividers section 1
Card Dividers section 2
Card Dividers section 2
Card Dividers section 2
Card Dividers section 2
Card Dividers section 3
Card Dividers inside a Card with the "full-bleed" option, so that the dividing lines touch the top and bottom edges of the card.
Card Dividers section 2
Card Dividers section 2
Card Dividers section 2
Card Dividers section 2
Card Dividers section 3

Card Containers that are radio buttons

Card Container, where each card is a link

Card Set

A Card Set is a row in the layout grid that gives all of its column elements the appearance of a card. All cards in the same visual row will have the same height.

Sample card.
Sample card that is taller.
It will make any other cards on the same visual row stretch to match its height.
Sample card.
Sample card. Cards in the same set automatically get vertical spacing between them, as shown above.
Sample card with a nested grid row.
Nested grid column
Sample card with a nested grid container.
Nested col-6 element
Nested col-6 element

Card Set, where the cards are links

Card Set, where the cards are radio buttons

Card Set, using "full bleed" option

Sample card.
Sample card that is taller.
It will make any other cards on the same visual row stretch to match its height.
Sample card.

Card Set inside a proportional grid

Sample card.
Sample card that is taller.
It will make any other cards on the same visual row stretch to match its height.
Sample card with col-xs-6
Sample card with col-xs-6
Sample card with col-2
Sample card with col-2
Sample card with col-3
Sample card with col-3 that is taller.
It will make any other cards on the same visual row stretch to match its height.
Sample card with col-6

Card Set with Card Dividers

Adding a set of dividers inside a Card will create vertical dividing lines.
Note: the dividers don't add any internal spacing. Use the spacing system if you need to add spacing between the dividing lines and the content.

Card Dividers section 1
Card Dividers section 2
Card Dividers section 2
Card Dividers section 2
Card Dividers section 2
Card Dividers section 3
Card Dividers with full-bleed to make the dividing lines touch the top and bottom edges of the card.
Card Dividers section 2
Card Dividers section 2
Card Dividers section 2
Card Dividers section 2
Card Dividers section 3

Designer Guidelines

  • Cards can be used when visual separation is needed with the page structure.
  • Cards can be used to group items related to a product, such as an image product, name, and actions related to that product.
  • Cards can also be used to collect related groups of interactive items, such as paper thickness and paper stock selections.
  • Cards should not be used to frame an entire page section, but rather to frame groups within a given page section.
  • Cards are just that — containers. They are flexible enough to handle a wide array of layouts.
  • For maximum contrast, consider using cards on a tinted background.
  • Card Sets can be used for product tiles that are clickable.

Developer Guidelines

  • We recommend not combining a Card Container with another UI Library component, as you may get unexpected layout and/or behavior. Ideally, treat it simply as a container into which you put other components. In particular, don't combine a Card Container with a grid element.

Accessibility Guidelines

  • If the cards are acting as radio buttons:
    • The row element (e.g. the card-set element) around the cards element must have a role="radiogroup" attribute.
    • The row element (e.g. the card-set element) element must have an aria-labelledby attribute whose value is the id of the element that acts as a title for the set of cards (typically, a heading right above that set.) If the set of cards does not have a visible title, then instead it needs an aria-label attribute whose value is a descriptive title of the set; this text must be localized, as some browsers will read it to the user.

Checkbox

Checkboxes are almost never intended to be used on their own. Instead, they should be used within a Selection Set, so that they have a standard label and standard layout.

Developer Guidelines

  • Checkboxes are typically used inside a Selection Set component, and not on their own.
  • Any JavaScript handlers should listen for events on the input tag, and not any label or related visual element.

Accessibility Guidelines

  • If not used inside a Selection Set, and if there is more than one checkbox, they should either be inside:
    • a fieldset, or
    • an element with the attribute role="group". This wrapper element must have an aria-labelledby attribute whose value is the id of the element that acts as a title for the group — or, if the group does not have a visible title, an aria-label attribute whose value is a descriptive title of the group. The value of aria-label must be localized, as some browsers will read it to the user.
  • If a checkbox is a required field before the user can submit the page, add the attribute aria-required="true" to the input.
"favorite" checkbox

"favorite" checkbox

This legacy API creates accessibility issues. Do not use it, and update any instances of it as soon as possible.
@Html.Control(new StylizedCheckbox() { Id = "checkbox-favorite" }, new { @class = "stylized-checkbox-skin-favorite" })

Developer Guidelines

  • Any JavaScript handlers should listen for events on the input tag, and not any label or related visual element.

Accessibility Guidelines

  • The span inside the label will be read to the user by assistive technologies, so it must be localized. Use text that reflects the function of the checkbox.

Color

We use a minimal color palette on our site to help communicate simple information hierarchy, while reinforcing our brand presence in an aesthetically-pleasing way.

Primary Palette

Brand Blue: #0075c2
$selected-color (for input elements that are selected)
Dark Blue: #004471
White: #ffffff
Charcoal: #00111a
$global-font-color (for fonts)
$link-color (for links)
$icon-color (for icons)

Secondary Palette

Light Blue: #f0f9ff
Light Grey: #f6f7f8
Medium Grey: #d6dce0
$border-color (for borders)
Dark Grey: #6b7276

Tertiary Palette

Accent Green: #00875a
Pink: #e10096
$discount-color (for discounts)
Red: #d12c0b
$error-color (for error messaging)
$holiday-color (for holiday)
$charcoal
#00111a
$graphite
#494b4d
$dolphin
#727272
$carbon
#919699
$silver or $border-color
#c8cbcc
$platinum
#e6e6e6
$mist
#f8f8f8
$accent-blue or $link-color
#0099e0
$green
#05a34a
$midnight
#38454f
$discount-color
#eb0a87
$error-color
#e00808
$warning-color
#ff8200

Gradients

Silver Gradient
#fff to #f9f9f9
Black Gradient
#202b34 to $charcoal

Background Color

You can set the background color of a page zone using the Background Color component.

Light grey
Light blue
Dark blue
White
Loading shimmer

Text Color

You can set the text color using our typography classes.

Default text is charcoal.

.text-color-dark-grey

.text-color-holiday

.text-color-pink

.text-color-brand-blue

.text-color-white

.knockout

.error

.alert

Semantic classes like "error" and "alert" should only be used for error and alert messages, not for arbitrarily changing text to a certain color.

Do

  • Use the branded blues as the grounding foundation. They are for links, underlines, backgrounds, buttons, and to highlight special areas.
  • Use the neutral greys mainly for backgrounds and typography.
  • Use the pop color pink for sale pricing and promotions.
  • Use the pop color red for holiday communications and for error states.
  • Use color combos with enough contrast to keep to accessibility standards.
  • Use color to ground visual elements and draw the user's eye for attention.
  • Use ample white space with color for contrast and visual separation.

Don't

  • Add new colors or shades to the design system elements without proper notification.
  • Use color combos for important content that includes low contrast. Legibility is limited.
  • Rely on color alone to communicate information.

Designer Guidelines

  • Discount pricing uses $discount-color across the site.

Developer Guidelines

  • The above examples use $ in the color variable names, which is the syntax for SCSS. If your project is still using LESS, you should use a @ symbol for the variables instead.
  • Always use the variables in your stylesheets. This ensures that when Vistaprint does a visual refresh, your page will stay in sync with the new look.
  • Use the semantic color names where applicable. That is, use $border-color for borders instead of $medium-grey, because in future visual refreshes, our borders might no longer be medium grey.

Accessibility Guidelines

  • WCAG AA contrast requirements require a 4.5:1 constrast ratio for legibility. Our charcoal and dark grey on white meet this.

Color Swatches

Color swatches are used to show and/or select color options for products.

default size:

"super" size:

two-tone swatches:

Using a Selection Set with radio buttons:

Older, deprecated API that puts class color-swatches onto the Selection Set itself:

Using a Selection Set with checkboxes:

Older, deprecated API that puts class color-swatches onto the Selection Set itself:

Developer Guidelines

  • By default, color swatches have a transparent background circle. You will need set each swatch's background-color CSS property, either with an inline style attribute, or via an external stylesheet.
  • If you want to create two-tone swatch, set the background-color attribute to the shade on the bottom/right, and the color attribute to the color on the top/left.
  • For color swatches that are acting as radio buttons or checkboxes, setting the disabled property on the associated input tag will give the swatch the disabled look. For color swatches that are not radio buttons or checkboxes, you can add the color-swatch-disabled class to the swatch itself.

Accessibility Guidelines

  • To support users with visual accessibility issues, each swatch must have both a title attribute (for color-blind users) and an aria-label attribute (for assistive technologies), whose values are a localized description of the color choice, e.g. title="light blue" aria-label="light blue"
  • If used as a Selection Set, see also the Accessibility Guidelines for that component.

Control Icon

The Control Icon is a utility component that lets you create an arbitrary icon from our stock icon set. The typical use case is inside a button or link, so that a click on the icon performs a related action.

Using "brand-blue" skin:

Using "white" skin:

Control Icon as a button

If you want a Control Icon to be a button all by itself, place it inside an "unstyled" button.

control-icon-hover-container

A Control Icon changes its color when it is directly hovered over. However, if you want the icon to also change color when an ancestor is hovered over, place the class control-icon-hover-container on that ancestor.

A link with an icon inside it

A link with an icon inside it

Do

  • Use to enable user action when space is limited.

Don't

  • Alter or manipulate the existing icons.
  • Change or add colors to the existing icons.

Accessibility Guidelines

  • Control icons need to use the correct HTML tag and/or ARIA attributes, depending on their function:
    • If the control icon is just for display and is not independently clickable (e.g. it just shows an "info" icon, or a ">" icon at the end of a hyperlink), it should just use a span tag.
    • If the control icon is clickable by itself, and acts functionally as a button (i.e. it can be clicked to perform an action on the page), it should be a span tag inside a button tag.
    • If the control icon is clickable by itself, and acts as a hyperlink (i.e. clicking on it takes the user to a new page), it should be a span tag inside an a tag.
  • Then, it also needs to either have its role made obvious for assistive technologies, or it needs to be hidden from them:
    • If the icon is purely decorative (e.g. the ">" at the end of a text link or button), it should have the attribute aria-hidden="true" to hide it from assistive technologies.
    • If the icon is clickable by itself, but has nearby text that explains what it does, it should have an aria-labelledby attribute whose value is the id of the element that describes it.
    • If the icon is clickable and sits on its own, but does not have nearby text that explains what it does (e.g. an "x" button that closes a panel), the button should have an inner span with class visually-hidden. Inside this span, add localized text explaining what the button does (e.g. "Close", "Next").

Count

Counts are numeric messages that indicate amount.

4 24

"alert" skin

4 24

"cart" skin

4 24

"empty" skin

0
"alert" skin with "shadow" option

4

Designer Guidelines

  • Counts should be no more than two digits.
  • Counts are used to indicate the number of items in your cart, saved items in a gallery, times liked, tweeted, rated, reviewed, etc.
  • Use the "alert" skin to call particular attention and encourage action.

Accessibility Guidelines

  • Users on assistive devices may not have full context for what the count number represents. You may need to add a span with the class visually-hidden that provides additional context; this element will be hidden from screens, but read out by assistive devices. For instance, if a Count of 4 represents 4 items in the cart, add <span class="visually-hidden"> Items</span> inside the Count, after the number.

Datepicker

Datepicker is deprecated. It requires C#, .NET, and the legacy UI Library package. It is only available in the old platform.

The datepicker allows users to pick a single date to fill-in a text field. A calendar displays months and days of the week in a localized format. Datepicker is used in Studio for highlighting dates in a calendar.

Use

When a calendar icon or text field is selected, an overlay appears that displays the current and next month, from which the user may select a date for input.

Designer Guidelines

We don't support a direct entry of dates into a text field, to guarantee the date is in a valid format.

Details Banner

A Details Banner shows an image, and alongside it some details about the content shown in the image.

example image

An example heading

You can put whatever content you want inside the text zone, and then use Visage's type and spacing options to adjust that content. Here we're showing an h3 heading, a paragraph of text, and a button, all using default spacing and type.

example image
Putting the "text-left" option on the Details Banner will put the text zone to the left of the image instead.
example image
You can add a background color to the text zone. This example uses a light blue background.
example image
This example uses a light grey background.
example image
This banner is using the "staggered" option that makes the image and the background staggered, along with a dark blue background.
example image
This example uses the "holiday" background, a staggered background, and the "text-left" option.

Designer Guidelines

  • Images should have a 16:3 aspect ratio on most screens, but 4:3 on Extra-Small screens.

Divider

Dividers are used to divide content into visible sections.

"strong" skin

Usage

  • Regular dividers draw a horizontal rule across the content area.
pipe

This is a paragraph of text with a | divider in the middle of it, using class .pipe around a | character.

Usage

  • The "pipe" divider provides a short vertical line, with some spacing around it. It is used to separate inline elements.

Dropdown

Dropdown is a pull-down list of items that appear when the dropdown is selected; this list remains open until a user selects an item or dismisses the list.

options:

skins:

deprecated old API

Deprecated: wrapping the dropdown in a container with class stylized-select-container

Implementation Notes

Our dropdown uses (and extends) the native <select> element, rather than try to reproduce its functionality with HTML. This does impose some limits on the styling we can perform on the options inside the dropdown. There are many reasons for using a native dropdown:

  • Since 2019, about half of our sessions are on tablets and phones. Using a native <select> means that phone users get their device's own select experience, which is mobile-optimized. (For instance, iPhone users get the fullscreen "scroll wheel" display.) The browser manufacturers have invested a lot of UX research into determining that this is a good user experience for touch-screen users.
    • Replicating this experience across browsers is complex and difficult to maintain. Apple, Google, and Microsoft have invested considerable development and QA time into their versions, which we get to use for free. Building it ourselves would be technically challenging, would require considerable cross-browser and cross-device testing, and we would have a continuous maintenance cost on this going forward.
    • Consider a small screen where the dropdown, when opened, drops down off the bottom edge of the screen. If the user touches the screen to scroll downward to see more choices, that touch will be registered as a click on the dropdown, thus making a selection and closing the dropdown! This is not an easy usability problem to surmount, which is exactly why phone browsers have built their own unique dropdown experiences such as the iOS scroll wheel.
  • Recreating the browser's own built-in functionality always makes for poor performance, both in terms of bandwidth (the browser must download the custom code) and rendering speed (a JavaScript-based dropdown will never react as quickly as the browser's built-in version.) In addition, the custom version won't react to user input as quickly as a native dropdown, making it feel sluggish.
  • The native control automatically has accessibility support across devices, including assistive technologies. Replicating the accessibility features would require even more JavaScript (e.g. supporting keyboard access), creating an even greater negative impact on performance.
  • Any given implementation will create an unfamiliar user experience for some users. For instance, the iPhone Safari dropdown doesn't look or act like the Android Chrome dropdown, so if we made our dropdown look like one of these, users of the other one would have a strange-looking dropdown. The dropdowns on Chrome for Mac don't even look like the ones on Chrome for Windows! The "correct" visual experience on one browser/OS combination will look strange on any other combination, so by using the browser's built-in dropdown, the user always gets a comfortable and familiar user experience.

Designer Guidelines

For usability, the dropdown uses generous padding and a large font. This means that the control does have a certain minimum width (this number depends on the widest option within the dropdown). For this reason, you should be sure to place it in a part of the page that gives it sufficient room to render, including the possibility that translated text might be longer than English text. If it is placed in an area that is too narrow, it may not display properly.

We have limited styling choices for the content of the dropdown's menu items, because we use the browser's native dropdown menu (see "Implementation Notes") to provide an optimal experience on mobile devices and assistive technologies. The browsers don't give you as much styling control as you might want; for instance, we can set the font color, size, and weight, but only for the entire dropdown, not for just one part of it. We cannot use strikethrough text or set any layout inside those dropdown choices.

Developer Guidelines

  • If your dropdown is created after the DOMready event, you will need initialize it by triggering an initializeControl event on it.
  • We recommend that you not place a dropdown inside an element that is a table cell or has CSS display: table-cell on it, as this can cause the dropdown to be rendered more narrowly than its true minimum width.

Accessibility Guidelines

  • Dropdowns, like any form input field, need an accessible label, preferably a <label> tag, with a for attribute whose value is the id of the dropdown. (If a <label> tag is not possible, the <select> tag either needs a aria-labelledby attribute, or an aria-label attribute with a localized value.)
  • When a dropdown has an error, the error message should not be a label tag pointing to the dropdown. Instead, the <select> tag should have aria-describedby and aria-errormessage attributes whose value is the id of the error message. In addition, while the dropdown's value is invalid, the <select> should have aria-invalid="true" on it.
  • If an dropdown is a required field before the user can submit the page, add the attribute aria-required="true" to the <select> tag.

Fieldset

The fieldset is a container that groups a set of related form fields.

Visage fieldset:

Social Security Number

for comparison, a default HTML fieldset:

Social Security Number

Developer Guidelines

  • Fieldsets are for sets of form elements. If there is a single form element, don't use a fieldset.

Accessibility Guidelines

  • All <fieldset> tags must have a <legend> tag that labels them, for accessibility. If the information in the legend is superfluous to sighted users, the legend can be hidden on screens by putting the CSS class visually-hidden on the legend.
  • The <legend> cannot be (or contain) a heading (H1-H6) tag. If the page structure requires a heading to label the form fields, don't use a <fieldset> tag. Instead, group them using a wrapper tag that has the role="radiogroup" attribute (for radio buttons) or role="group" attribute (for everything else), plus an aria-labelledby attribute whose value is the id of the heading.

Flipswitch

Flipswitch is deprecated, because it does not meet accessibility standards. Please update any Flipswitches to use the Toggle Switch instead.

The flipswitch is a toggle used to turn a feature or app on or off. The flipswitch stretches its width to fit its contents.

Show Prices:

Off

Show Prices:

Off
This older API uses two label tags, which creates accessibility issues.

Designer Guidelines

  • Flipswitches are only for features with "on" and "off" states. If you need to toggle between two states that aren't semantically "on" and "off", consider a buttonbar or other treatment instead.
  • Limit the number of characters within the flipswitch, so the width doesn't become exaggeratedly long.
  • Try to keep the text for the "on" and "off" states at about the same length.

Accessibility Guidelines

  • Flipswitch does not meet accessibility requirements and should be replaced with Toggle Switch immediately. Its "on" and "off" labels are hidden from screen readers, which leaves the function of the switch unclear or ambiguous.
  • If the text inside the label tag does not sufficiently describe the function of the switch, you will need to give the input tag an aria-labelledby attribute whose id is the element that describes the function of the switch (as shown above).

Site Examples

Used in the UK site's header to set VAT tax.

Floating Container

The floating container pins its contents to the left- or right-hand side of a grid element, with the rest of the content flowing around it.

A col-12 with additional text that should start to the right of the container, and wrap around the container so that it ends up below the container. (Except on Extra-Small screens, where all the text should sit below the container.) Here's some additional text to make this paragraph a little longer.

A col-12 with additional text that should start to the left of the container, and wrap around the container so that it ends up below the container. (Except on Extra-Small screens, where all the text should sit below the container.) Here's some additional text to make this paragraph a little longer.

A col-12 with additional text that should start to the right of the container, and wrap around the container so that it ends up below the container. Here's some additional text to make this paragraph a little longer. Here's some additional text to make this paragraph a little longer.

A col-12 with additional text that should start to the left of the container, and wrap around the container so that it ends up below the container. Here's some additional text to make this paragraph a little longer. Here's some additional text to make this paragraph a little longer.

Considerations

Floating can position assets and cause other assets such as text to wrap around them. A clear property can be used to eliminate wrapping.

Developer Guidelines

The floating container should be used only inside another col-N element, as a direct child of that col-N element. (If you place it elsewhere, such as making it a child of a grid container or a row element, you may get layout errors.)

If the content of the floating container is secondary to the main text (as is usually the case), consider using a semantically-accurate <aside> tag instead of a generic <div> for the floating container.

Design Specs

Invision for Floating Container

Form

standard (vertical) form

Our "standard form" wraps a series of Input Group elements and their labels, providing a standardized layout for forms.

Helper text

Error message.

Please select a shipping method.

"tight" skin

The "tight" skin puts less vertical space between each input group.

Helper text

horizontal form

A horizontal form uses rows in the layout grid to arrange the labels and form inputs side-by-side.

Horizontal forms assume a vertical arrangement on Extra-Small screens.

Helper text

Error message.

Labels for required fields

Adding the class label-required to a <label> tag will mark it as a required field, automatically adding an asterisk after the text.
(Your page will still need to provide a legend as to what the asterisk means!)

Designer Guidelines

  • Do not visually indicate that a form field is required; use the default visual state for required fields. If a field is not required, add "(Optional)" inside the label, as shown above.

Accessibility Guidelines

  • Any input field needs an accessible label, preferably a <label> tag, with a for attribute whose value is the id of the input. (If a <label> tag is not possible, the input either needs a aria-labelledby attribute, or an aria-label attribute with a localized value.)
  • If an input is a required field, you must add the attribute aria-required="true" to the input, to signal to assistive technologies that the field is required.
  • If there is more than one form element in a logical group, they should be grouped together in the code, either with:
    • a fieldset, or
    • an element with the attribute role="group". This wrapper element must have an aria-labelledby attribute whose value is the id of the element that acts as a title for the group — or, if the group does not have a visible title, an aria-label attribute whose value is a descriptive title of the group. The value of aria-label must be localized, as some browsers will read it to the user.
  • If the input should support autocomplete (e.g. a mailing or shipping address, or credit card entry), then it should have an appropriate value for the autocomplete property.
  • When an input field has helper text and/or an error message, it should have an aria-describedby attribute whose value is a space-separated list of the ids of the message(s).
  • When an input field has an error, the error message should not be a label tag pointing to the input. Instead, the input should have aria-describedby and aria-errormessage attributes whose value is the id of the error message. In addition, while the input's value is invalid, the input should have aria-invalid="true" on it.
  • For inputs with buttons beside them or inset inside them, if the button is simply an icon and has no visible text, it will need to provide assistive devices with information on what the button does:
    • If the button has nearby text that explains what it does, the button should have an aria-labelledby attribute whose value is the id of the element that describes it.
    • Otherwise, the button should have an inner span with class visually-hidden whose contents are localized text explaining what the button does (e.g. "Search").

Full-width container

Full-width containers are deprecated as of Visage v3.0.
Use Bounded Content with the layout grid to limit the width of page content.

Full-Width Containers are for laying out parts of the page (such as hero zones) that should try to span the full available width, rather than using the layout grid.

full-width-container

"full-width-container-capped" option

full-width-container-capped
(the container is normally full-width, but also has a maximum width)
Fraction zones are deprecated as of 2018-May-7. Do not create any new instances of them. Use the "proportional grid" option of the layout grid instead.

fraction zones

1
1/2
1/2
1/3
2/3
1/4
1/2
1/4

Design Guidelines

  • Full-Width Containers can either span the full browser window, or can be "capped", meaning their maximum width will be as wide as the site navbar.
  • Full-Width Containers are typically used with the hero; we strongly recommend not using this container mid-page.

Gradient tile

Example image

Gradient tile with Fluid Image

Example image

Gradient tile with Responsive Image

Graphic button

Graphic button is deprecated as of Visage v3, and will be removed in the future.

If you just need a simple icon, instead please use a Control Icon.

If your page currently contains a Graphic Button with a visible border around it (using a textbutton skin), the new site look no longer uses this visual style, so your page will need some redesign work to figure out what should go there instead — whether that's a button without a visible border, a textbutton with both text and an icon, etc. Please reach out to us for assistance, or to your designer if your team has one.

Graphic buttons are graphics that show an icon, such as "X" close icons or arrows. They may perform an action when pressed. They may have a buttonlike look, or have a transparent background.

with a transparent background

with a textbutton-like appearance

These skins are only meant to be used on a <button> tag, on elements that are clickable and interactive.

Using the "primary" skin:

Using the "secondary" skin:

using an actual textbutton (aka round icon textbutton)

An older API used actual textbuttons to create the Graphic Button look.

Note: this feature cannot be used on an <input> tag.

with a textbutton skin, "super" size:

Accessibility Guidelines

  • Graphic buttons need to use the correct HTML tag and/or ARIA attributes, depending on the button's function:
    • If the graphic button acts functionally as a button (i.e. it can be clicked to perform an action on the page), it should use a button tag. If that is not possible for some reason, you need to add the attributes role="button", tabindex="0", and class="accessibility-keyboard-clickable" to provide accessibility.
    • If the graphic button acts as a hyperlink (i.e. clicking on it takes the user to a new page), it should use a span tag inside an a tag. It should not have the attributes role="button" or tabindex="0", so that it does not provide inaccurate accessibility.
    • If the graphic button is just for display and is not independently clickable (e.g. it just shows an "info" icon, or a ">" icon at the end of a hyperlink), it should use a span tag. It should not have the attributes role="button" or tabindex="0", so that it does not provide inaccurate accessibility.
  • For accessibility, any graphic button needs to either have its role obvious for screen readers, or needs to be hidden:
    • If the button is clickable and has nearby text that explains what it does, it should have an aria-labelledby attribute whose value is the id of the element that describes it.
    • If the button is clickable and sits on its own (such as an "x" button that closes a panel), the button should have an inner span with class visually-hidden whose contents are localized text explaining what the button does (e.g. "Close").
    • If the button is purely decorative (e.g. the ">" at the end of a hyperlink), it should have the attribute aria-hidden="true" to hide it from screen readers.

Site Examples

Graphic buttons are used in Studio controls, info icons, and video play buttons.

Grid

The grid is an invisible framework responsible for the order and rhythm of a page. By imposing constraints on layout, the grid makes it easy to achieve consistent and proportionate designs across devices.

  • A grid row can have up to 12 columns. The most common layouts divide this space up evenly, e.g. three 4-column, or two 6-columns. On Extra-Small and Small screens (e.g. phones and tablets), only divide a row into 3-column, 6-column, 9-column, or 12-column sections.
  • The grid uses fluid widths for the columns, so as the overall grid widens, so will each of its columns.
  • Gutter and margin differ according to screen size, where larger screens have more whitespace.

Vistagrid basics

The grid starts with an element with class grid-container. Inside it, place a row element with class row. Within the row, place one or more col-N elements, where N is a number between 1 and 12.

You can safely place more than 12 columns' worth inside a single row; the grid elements will show the first 12 columns' worth, and then will line-wrap the rest.

col-1
col-1
col-1
col-1
col-1
col-1
col-1
col-1
col-1
col-1
col-1
col-1
col-2
col-2
col-2
col-2
col-2
col-2
col-3
col-3
col-3
col-3
col-4
col-4
col-4
col-6
col-6
col-3
col-7
col-2
col-12

Nesting

You can nest one grid element inside another one. The nested (inner) grid will be divided into 12 new columns, proportional to the width of the nested (inner) grid.

You'll need to place another row element inside the outer element, around the inner column elements.

col-4
col-5
col-4
col-7
col-7
col-3
col-9 col-xs-9
col-3 col-xs-6
col-3 col-xs-6
col-3 col-xs-6
col-3 col-xs-6

You can also place an entire new grid container inside a column element:

col-12 with a grid container inside it:

col-12 inside that nested grid container
col-6 inside that nested grid container
col-6 inside that nested grid container

Offsets

Offsets let you indent a grid element, or widen the gap between elements. Offsets shift a block over to the right by a certain number of columns.
They are ignored on Extra-Small screens.

col-6 col-offset-3
col-3
col-3 col-offset-6 col-sm-offset-1
col-5 col-offset-2 col-sm-offset-0
col-5

Changing the layout for different screen sizes

The grid's layout is adjustable for our different screen sizes:

  • Large - 1440 pixels or more (e.g. wide monitors)
  • Medium - 1024-1439 pixels (e.g. small monitors, tablets in landscape)
  • Small - 768-1023 pixels (e.g. tablets in portrait, some large phones in landscape)
  • Extra-Small - less than 768 pixels (e.g. most phones)

When you put a col-N class on a grid block, by default all screen sizes (except Extra-Small) will make that grid block fill that number of columns. You can override that number for specific screen sizes:

  • On Large screens, append an additional class of col-lg-N. This class will tell the grid blocks how many columns to occupy on Large screens, overriding the default col-N value.
  • On Medium screens, similarly, you can change the layout by appending an additional class of col-md-N.
  • On Small screens, append col-sm-N.

On Extra-Small screens, by default, all the column elements will be full-width and will fill the whole display. This is true regardless of their col-N element. You can override this behavior by appending a class of col-xs-N.

col-1
col-sm-2 col-sm-offset-2
col-2
col-sm-2
col-5
col-sm-2
col-4
col-sm-2
col-1
col-sm-6
col-2
col-sm-6
col-5
col-sm-6
col-4
col-sm-6
col-1
col-xs-3
col-2
col-xs-3
col-5
col-xs-6
col-4
col-xs-6
col-6
col-md-3
col-6
col-md-3
col-1
col-xs-6
col-2
col-xs-6
col-5
col-xs-6
col-4
col-xs-6
col-1
col-lg-6
col-2
col-lg-6
col-5
col-lg-6
col-4
col-lg-6

Column re-ordering (pushes and pulls)

If columns in a row need to be re-ordered on a certain screen size, they can be "pushed" rightward or "pulled" leftward. Pushes and pulls are ignored on Extra-Small screens.

In each of the examples below, the green "col-9" element occurs first in the HTML. Pushes and pulls are used to move the elements around.

col-9
col-3
col-9
col-push-3
col-3
col-pull-9
col-9
col-sm-push-3
col-3
col-sm-pull-9
col-9 col-push-3
col-sm-push-0
col-3 col-pull-9
col-sm-pull-0
col-9 col-push-3
col-lg-push-0
col-3 col-pull-9
col-lg-pull-0

Hidden/Visible

You can hide an element entirely on a certain screen size by using a hidden-XX class. By contrast, you can make an element visible only on a certain screen size with a visible-XX class.

You can apply more than one visible-XX class to a given element, but don't put both a visible-XX and a hidden-XX onto the same element.

These classes can be used on non-grid elements as well!

visible-lg (visible only on Large)
visible-md (visible only on Medium)
hidden-md (hidden on Medium)
visible-sm (visible only on Small)
visible-xs (visible only on Extra-Small)
visible-xs visible-sm (visible only on Extra-Small and Small)
visible-md visible-lg (visible only on Medium and Large)
col-5 (visible on all screens)
col-xs-6 (visible only on Extra-Small)
col-5 (visible on all screens)

Grids as List items

Sometimes a row should semantically be a list, since the columns are list items (e.g. rows of product tiles). Other times, a grid container should be a list, since the rows are list items (e.g. Cart). To support this, grid elements can be ul and li tags.

  • This grid container is a UL tag, and the rows are LI tags.
  • This grid container is a UL tag, and the rows are LI tags.

  • This row is a UL tag, and the columns are LI tags.
  • This row is a UL tag, and the columns are LI tags.

The "col-flex-column" option

Adding the class col-flex-column to a col- element will cause all of its direct children to be arranged as a column, spread out evenly between the top and bottom of the row (rather than all being aligned to the top). This is useful for keeping some elements aligned to the top and bottom of a taller neighboring element.

A
A
A
A
A
A
first child of B
(B has col-flex-column on it)
second child of B
(B has col-flex-column on it)
C
C
C

The "col-vertically-center" option

Adding the class col-vertically-center to a col- element will cause its contents to be vertically centered within the row.

A
A
A
A
A
A
B
B
C
C

Sticky columns

Making a column element "sticky" means it will stay on screen so long as some other element in the same row is also visible. You can see it in action below by scrolling slowly downward. (However, things get a little tricky here on the UI Library Viewer because its navbar overlaps the content.)

To make the stickiness function properly, the row will not vertically stretch all its columns to be the same height, as it normally does. This can affect the display of the columns in that row. For instance, if you are using a Card Container with the "even height" option, (or a Card Set), the cards in that row may not be all the same height.

Adding the class "col-unsticky-xs" will make a sticky column act normally (that is, not sticky) on Extra-Small screens.

col-3 that is sticky
col-3
col-3
col-3 that has really tall content
col-3 that is sticky, but unsticky on Extra-Small screens
col-3
col-3
col-3 that has really tall content

Design Guidelines

  • Columns stack by default.
  • Column widths can be changed for each screen size.

Do

  • Use only 3-column, 6-column, 9-column, and 12-column divisions for Extra-Small and Small screens.
  • Use a nested grid to achieve greater design flexibility.
  • Specify the layout for each breakpoint at handoff.

Don't

  • Adjust the size of columns, margins, and gutters.
  • Scale or stretch UI to fit the grid. Use components as intended for layout.

Developer Guidelines

Do

  • If you are placing one col-N element inside another, put a row element around the inner element, or a layout error may occur.
  • Place more than 12 columns' worth inside a single row, if you have a layout such as a long list of tiles. The grid elements will show the first 12 columns' worth, and then will line-wrap the rest of the content down onto the next row.

Don't

  • Put margin, padding, widths, or other layout-oriented styling onto layout grid elements, or a layout errors may occur when grid's code is changed in the future. If you need to add this styling to your content, put that styling on a wrapper element placed just inside the grid element.
  • Combine grid elements with other components, by putting a grid CSS class and another component's CSS class on the same HTML element. (For instance, don't put col-3 and standard-section on the same element.) Those other components may add spacing that will conflict with the grid component's spacing, and might alter the grid's display. Notable exception: you can put Background Color onto a grid element.

Developer Considerations

  • If you need to suppress the Bounded Content feature on this Viewer page (so you can see how the grid will look when it touches the edges of the window), you can toggle Bounded Content on and off with . When Bounded Content is suppressed, this page will show the background with stripes.

Accessibility Guidelines

  • If the grid elements are semantically part of a list, use ul and li tags as appropriate instead of div tags. For instance, if a row contains a sequence of product tiles, the row should be an ul tag, and the column elements should be li tags — because semantically, those tiles are a list.

Hotspot Zone

Hotspot zones allow clickable hotspots to be placed over a background image. The user can click a hotspot to view more information about what is displayed in that part of the image.

sample image
Hotspot dialog content 1 Hotspot dialog content 2 Hotspot dialog content 3

using the "white" or "holiday" skin

sample image
Hotspot dialog content 4 Hotspot dialog content 5

Developer Guidelines

  • Each hotspot must have a data-hotspot-top and data-hotspot-left attribute, whose value is a number indicating how far across the hotspot should be from the background's top left corner (considered as a percentage). For instance, a hotspot that should be 40% of the way down from the top should have data-hotspot-top="40" as an attribute.

Icon Tile Set

An Icon Tile Set consists of a number of Icon Tiles, which give prominence to important standalone links or elements. An Icon Tile Set can be used to create a "brand banner".

default Icon Tile Set:

Icon Tile that is not a link

Icon Tile description

Icon Tile with an internal link

Icon Tile description with a link inside it

using the "horizontal" option:

Icon Tile that is not a link

Icon Tile description

Icon Tile with an internal link

Icon Tile description with a link inside it

using the "align left" option on a horizontal tile:

Usage

  • An Icon Tile requires both an icon and a heading. A description beneath the heading is optional.
  • If there is a link for an Icon Tile, it should either be a link for the whole tile (the whole tile is clickable), or the link should be at the very end of the description.
  • An Icon Tile Set should have no more than four Icon Tiles.

Designer Guidelines

  • An Icon Tile Set is often used under the hero image to create a "brand banner".
  • Use these sparingly and effectively; when used excessively, they'll lose their prominence.

Image

Responsive Image

Do not use the separate responsive-image stylesheet in the current platform. It is part of a now-outdated API for the old platform only, and it will screw up the appearance of images.

Responsive Image is for when the image's aspect ratio is known. A Responsive Image will expand to fill its container.

Example image

Developer Guidelines

  • The wrapper element must have an inline style that sets the padding-bottom, with a value equal to the image's aspect ratio, expressed as a percentage.
  • The img tags can, and often should, use the srcset attribute to provide both hi-res and lo-res versions of the image. You can read more info on srcset at MDN.

Accessibility Guidelines

  • All images must have an alt attribute. Typically, the alt attribute should have a small description of the image itself. However, sometimes that attribute might be a blank value (alt=""):
    • Use an empty alt attribute if there is nearby HTML text that presents the same content as the image description. For instance, a product tile offers both a product image and the product name. The image does not also need the product name in its alt attribute, since this would mean that screen readers would say the same thing twice in a row: "Business Cards... Business Cards." In this case, the product image should use an empty alt attribute.
    • Use an empty alt attribute if the image is purely decorative, such as a page divider, or a > glyph at the end of a link.
    • For more information on how to properly use the alt attribute, the WC3 provides a handy flowchart, "An alt Decision Tree".
  • If an image should have empty alt attribute for accessibility reasons, but we cannot use an empty string for some reason (e.g. we need the image to have a descriptive string to help boost SEO for image searches), then as long as the image and its accompanying text are both inside the same link, you can put role="presentation" aria-hidden="true" onto the image. This signals to assistive technologies that the image is decorative and should be hidden from assistive technologies.

SEO Considerations

  • Each image should have a friendly file name, since the file name is used by Google for indexing. "blue-square-business-cards.jpg" is better than "UI_99760.jpg".
  • Images should be compressed to minimize file size.

Fluid Image

Fluid Image is for when the page does not know the image's aspect ratio. A Fluid Image will expand to fill its container, but will also force a reflow once it loads, so it is less preferable than a Responsive Image.

Example image

Developer Guidelines

  • The img tags can, and often should, use the srcset attribute to provide both hi-res and lo-res versions of the image. You can read more info on srcset at MDN.

Accessibility Guidelines

  • See the considerations for Responsive Image (above).

Input Group

An Input Group groups together a Text Input with any helper text or error message. It is only meant to be used inside a Standard Form.

Helper text

Error text

Developer Guidelines

  • Input Group is only meant to be used inside of a Standard Form. It will display incorrectly if used elsewhere.
  • Each input must have a label associated with it. The helper text and error message are optional.

Accessibility Guidelines

Left-hand navigation

Left-hand navigation is a vertical list of links used to navigate a site section. Left-hand navigation is a pattern made up of multiple link-list components.

Usage

  • Can have two-level (parent and child) hierarchy
  • When used with hierarchy, a linkable heading can be used
  • A section for additional content may be used at the bottom of navigation list and can link to other site sections

Designer Guidelines

  • Keep they taxonomy shallow
  • Keep the list height reasonable; consult with UX
  • Keep title text length short as not to wrap

Accessibility Guidelines

  • For accessibility, the lists of links should be inside a nav tag. If for some reason you cannot use the nav tag, you must instead place role="navigation" on the wrapper element.

Lazyload Zone

Lazyload Zone is only available in the old platform.

A lazyload zone will delay the loading of its contents until after the main content of the page finishes loading.

This paragraph contains content that is not lazyloaded, so it will be shown as soon as the page loads.

This is content inside the lazyload zone that is not commented out, so it will not be lazyloaded.

Developer Guidelines

  • The content to be lazyloaded must be inside the zone and must be inside an HTML comment. The lazyload zone will extract the content from inside the comment, and un-comment it.
  • Any content inside a comment will be un-commented, so don't put any HTML comments inside the zone that you don't want turned into page content.
  • Content will be lazyloaded after the "DOM ready" event.
  • Once a zone has been lazyloaded, the zone will trigger a "lazyloaded" event.
  • The lazyload zone can be any tag, not just a div, so choose a semantically-appropriate tag. The zone has display: contents set on it, for those browsers that support that value.
  • The container that has the lazyload zone in it should have the attribute aria-live="polite" on it, to cue screen readers and other assistive technologies.

Media query variable

Media query variables are a feature used in LESS/SCSS to make some CSS only apply to certain screen sizes.

(The layout grid also features some pre-defined hidden-XX and visible-XX CSS classes that replicate some of this functionality. Those classes can be used to make elements appear or not appear on certain screen sizes.)

This text should only be red on Large screen sizes.

This text should only be red on Small screen sizes.

This text should only be red on Extra-Small screen sizes.

This text should only be red on Small screens or smaller.

This text should only be red on Small screens or larger.

Considerations

  • Use the media query variables instead of hardcoding in breakpoints. This keeps our experience standardized across the site.

Meta-info

For meta-level information that is not shown to customers. For instance, this might be used for metadata sections shown during debugging, or for information shown only in Sitecore's Experience Editor but not in the actual customer-facing page.

This is regular content.

This is a meta-info section.

This is regular content.

Modal Dialog

A Modal Dialog is a secondary window that appears in a layer above the application, to display content that demands user action.

Stylized Dialog

Our modern modal dialog is also known as "Stylized Dialog", since it adds Vistaprint styling to the native <dialog> element.

Title

I am a stylized dialog.

Here's some dialog content that extends all the way across and wraps down onto a second line.

(or open it programmatically)

Some other dialog use cases:

Title

I am a stylized dialog.

Here's some dialog content that extends all the way across and wraps down onto a second line.

Title

I am a stylized dialog.

Here's some dialog content that extends all the way across and wraps down onto a second line.

I am a stylized dialog whose textbuttons have the "full-width" option.

I am a stylized dialog that's really tall.

here's a really tall image or something

And now here's some more content.

Title

I am a stylized dialog that's really tall.

here's a really tall image or something

And now here's some more content.

I am a stylized dialog that's really tall.

here's a really tall image or something

And now here's some more content.

Title

I am a stylized dialog with a max width of 1000. Here's some dialog content that extends all the way across and wraps down. Here's some dialog content that extends all the way across and wraps down. Here's some dialog content that extends all the way across and wraps down.

Title

I am a stylized dialog with a max width of 50vw. Here's some dialog content that extends all the way across and wraps down. Here's some dialog content that extends all the way across and wraps down. Here's some dialog content that extends all the way across and wraps down.

Title

I am a stylized dialog that has no id. Don't do this. Give your dialogs ids, please!

"takeover" option

Setting the "takeover" option will cause the dialog to fill the full screen.

I am a stylized dialog. Here's some dialog content that extends all the way across and wraps down onto a second line.
I am a takeover dialog that has a translucent background, so the underlying content is slightly visible.

"no close button" option

The "no close button" will suppress the "X" close button in the dialog.

Title

This dialog has no close "X" button. The dialog must itself provide at least one button that will close it, such as these ones:

"full bleed" skin

The "full bleed" skin removes the padding around the dialog content, so that the dialog's content touches the dialog's edges.

I am a stylized dialog with the "full bleed" skin. My content goes right up to the edge of the dialog.

Title

I am a stylized dialog with the "full bleed" skin. My content goes right up to the edge of the dialog.

"enable browser history" option

The "data-dialog-enable-browser-history" attribute allows modal dialogs to be closed with the browser's back button.

I am a stylized dialog. I will use the browser's history on all screen sizes

I am a stylized dialog. I will use the browser's history on extra-small screens only

"panel" option

The "panel" option turns the dialog into a panel that slides out from the right-hand edge of the screen. The panel will be as tall as the screen.

"Panel" dialogs can also add a "pinned" option that will make the dialog footer pinned to the bottom of the dialog (for those browsers that can support this feature).

Title

I am a stylized dialog with the "panel" option.

Title

I am a stylized dialog that is using the "no close button" option to hide the close button, and then adds in a "back" button using the associated feature.

Title

This dialog's footer will always be pinned to the bottom of the dialog, regardless of the dialog's height.

Title

This dialog's footer zone will always be pinned to the bottom of the dialog, regardless of the dialog's height.

here's a really tall image or something

And here's a closing paragraph.

Instead of a dialog footer, an older API used two optional sub-elements:

  • a "top" zone that will touch the panel's edges, allowing for a full-bleed image
  • and a "bottom" zone that can contain any content, including buttons. By default, this zone will remain pinned to the bottom of the panel if the panel's contents are taller than the screen. Adding the "pinned" option to the dialog will instead make the bottom zone always pinned to the bottom, regardless of how tall the dialog contents are.
Example image

Title

This dialog features a "top zone" before the title; the top zone will touch the dialog's edges. It is intended for images.

It also has a "bottom zone" that can contain any content, not just buttons. This bottom zone will stay pinned to the bottom if the dialog's contents are taller than the screen.

Some other info

Example image

Title

This dialog's bottom zone will always be pinned to the bottom of the dialog, regardless of the dialog's height.

Some other info

"panel menu" option

The "panel menu" is for left-hand flyout menus, such as the site navigation on mobile devices.

Title

Title

Title

Designer Guidelines

  • Avoid dialogs that are so tall that they require scrolling. They make for a poor user experience on small screens such as phones. If the content of the dialog is tall, consider a form of progressive disclosure, such as tabs, or an accordion, or a nested scrollable container. Also consider re-formulating the content so it doesn't need to be so large, or that it can be split across a wizard flow.
  • Avoid any UX that involves having two modal dialogs open at once, such as a modal dialog that opens another modal dialog. This is a UX anti-pattern, and our modal dialog component was not designed to support it.
  • Because a modal dialog disables the application beneath it and may interrupt the user's workflow, use it for very important information -- information that when provided could lessen the user's effort, or if it maintains the context of a task, such as editing.
  • Do not place any SEO-relevant information in a modal dialog, since search engines can't see any information that requires user interaction to view. (Please consult the Organic Search team with any questions.)
  • Place the primary action button to the right of secondary actions, using primary and secondary button styling (see textbutton guidelines).
  • When adding more than one action button, follow this order: destructive (delete, sign out), dismissive (cancel), affirmative (confirm, sign in).
  • Best practices state that you should not use a modal dialog in the checkout flow.
  • Modal dialog content should be focused, and should not involve complex decision-making effort.

Developer Guidelines

  • The JavaScript file for the dialog should go at the end of the body tag, and not in the head tag. This will ensure that it smoothly loads its polyfill as needed.
  • The dialog will be hidden by default. It will be shown when there is a click on an element with a data-dialog-show attribute whose value is the ID of the dialog. You can also show it by calling the method showStylizedDialog() with the dialog's DOM node as the argument. Once the dialog has been shown, it will trigger a showStylizedDialog event. Do not use the native showModal() or show() methods, as these will cause display and functionality errors.
  • The dialog will close when there is a click on any internal element that has class stylized-dialog-close on it. You can also close it by calling the method closeStylizedDialog() with the dialog's DOM node as the argument. Do not use the native close() method. Once the dialog has been closed, it will trigger a close event.
  • The dialog defaults to a max width of 600px (on Medium screens) or 95% of screen width (on smaller screens), but will attempt to stretch to fit its contents. You can specify a different max-width by putting a data-dialog-max-width attribute on the dialog, e.g. data-dialog-max-width="1000"
  • To have the dialog create an iframe inside it, place three attributes on the dialog: data-dialog-iframe-url (the URL of the iframe), data-dialog-iframe-id (the id of the iframe), and data-dialog-iframe-title (the title of the iframe).
    • The iframe will be appended to the end of the dialog's content, so you will likely want to have any of the dialog's buttons be inside the iframe.
    • While the iframe is loading, the user will see a preloader graphic, replaced by the full dialog once the iframe is ready.
  • The dialog's JavaScript code will move the location of the dialog node within the DOM tree, in order to position it properly on the screen and to provide accessibility support. Therefore, you shouldn't rely upon the dialog being able to inherit any CSS from any given ancestor, and you shouldn't use an ancestor selector in your CSS that expects the dialog to have a certain ancestor. Any CSS selectors for the dialog content should only refer to elements within the dialog itself.
  • All dialogs should have an id attribute on them.
  • The vanilla JS (non-React) version of the dialog does not allow you to change its options or configuration after the dialog has been instantiated.

Accessibility Guidelines

  • If the dialog has an internal title, then the dialog tag should have an attribute aria-labelledby whose value is the id of the title. If it does not have a heading, then the dialog tag needs an aria-label attribute whose value acts as a title for the dialog; the text for this value must be localized, since some browsers will read it to the user.
  • If the dialog has a piece of content that can act as a description of the dialog's contents, then the dialog tag should have an attribute aria-describedby whose value is the id of that descriptor element.
  • If you are using the "no close button" option, the dialog will attempt to put focus on the first interactive element (button, input field, etc) inside the dialog. If no such element exists at the time the dialog opens, you will need to move focus yourself onto the first interactive element, once one becomes available.

SEO Considerations

  • Panel dialogs must be rendered on the server, and part of the page's source HTML, to be readable by Googlebot.
  • Panel dialogs should contain less important content. Since they require an additional click to be seen by users and bots, the content appearing inside them may have less importance for ranking (especially on desktop).

jQuery Modal Dialog (deprecated)

The old jQuery Modal Dialog component is now deprecated. It is based on the SkinnyJS modal dialog component.

"basic" skin

Open the dialog

Here's some dialog content that extends all the way across and wraps down onto a second line.

Open the dialog (using <a> tags for the buttons, instead of <button> tags)

Here's some dialog content

Open the iframe dialog

"titled" skin

Open the dialog

Here's some dialog content

Open the iframe dialog

"full-bleed" skin

Open the dialog

Here's some dialog content that extends all the way across and wraps down onto a second line.

"primary" skin

Open the dialog

Here's some dialog content

"neutral" skin

Open the dialog

Here's some dialog content

"media" skin

Open the dialog

Here's some dialog content

"lightbox" skin

Open the dialog

Here's some dialog content

Option Set

Option Set is deprecated as of Visage 3.0. Its functionality has been largely supplanted by the much simpler Selection Set.

Option sets allow users to make selections from a set of choices, arranging visual labels for those choices. Option sets can be either multi-select (using radio buttons) or single-select (using checkboxes).

This legacy API creates accessibility issues. Do not use it, and update any instances of it as soon as possible.
First option
Second option
Third option
which is
extra tall
Disabled option

using checkboxes instead of radios

using "text small" option
using "detailed" option

(The "detailed" option lets you provide additional details, which will sit to the far right of each option.)

using "detailed" option with an inner control

(You can add inner controls besides the left-hand radio button.)

"buttons" skin
Shown inside a 6-column grid element:
"buttons" skin, using "centered" option
"buttons" skin, using "wide" option

(The "wide" option gives the buttons a minimum width, typically wider than the button's content.)

Shown inside a 6-column grid element:
Using a <fieldset> tag for the Option Set (a deprecated API):
Option A
Option B is Really Really Long
Option C
Option D
"buttons" skin, using "half" option

(The "half" option makes the buttons be half as wide as their container, so that they line up neatly into two vertical stacks.)

Shown inside a Card Container, using the "justified" and "flush-bottom" options for proper alignment:

"strong" skin
"buttons-detailed" skin
"buttons-with-images" skin
"simple" skin
"sectioned" skin

Shown with simple content:

Shown with horizontal Secondary Tiles inside the labels:

Usage

  • Use checkboxes when there are more than one option to be made. Use radio buttons when the list of options are mutually exclusive — the user may only select one option. It is best practice to default to a selection when using radio buttons on a list of single select options.
  • The "detailed" option is used with the default skin, allowing for additional details to be set off to the right (e.g. quantity and pricing) in a grid-shaped layout.
  • The "buttons" skin is best used for configurations where one option may negate another option. They should not be used for filtering. It should be used inside 6 column and 12 column wide grids. 6-column option sets are typical, and used on most GPP pages.

Designer Guidelines

  • The "buttons" and "simple" skins should only be used for radio buttons, and not for checkboxes.
  • Labels should be concise and clearly indicate the action that will follow when option is selected. If needed use headings to group selection options.

Developer Guidelines

  • It's fine to have an Option Set can with just one option, particularly if the Option Set makes it easier to do the necessary page layout.
  • If your Option Set is created after the DOMready event, you will need initialize it by triggering an initializeControl event on it.
  • When using the "detailed" option for the standard skin, only the actual label for the input should use the <label> tag. Any other option-set-contents elements (such as price or quantity) should use another appropriate tag such as <div>.
  • If there are any controls other than the radio button or checkbox inside an option (e.g. a text field or a dropdown):
    • Place the class option-set-inner-control on those inner controls. This will ensure that the Option Set behaves correctly when an inner control is clicked on.
    • You cannot use the label tag for the option-set-contents element, since a label cannot have another form element inside it. Instead, put the visible text of the label inside a span with an id, and give the radio/checkbox an aria-labelledby attribute whose value is that id.
  • For now, the Option Set may use the CSS class "checked" to indicate a checked state. This class is often used as part of a polyfill for older versions of IE, and will be removed when we drop support for those IE versions. Therefore, you should not use it to verify the checked state of the control. Instead, use the checked property of the underlying input tag.

Accessibility Guidelines

  • If there is more than one input in the Option Set, the outer element that has class option-set must also have a role attribute. If the Option Set is a set of radio buttons, it should have role="radiogroup". If it is an Option Set of checkboxes, it should have role="group".
    • The OptionSet API used to recommend a fieldset tag for the outer element. However, due to a bug in Chrome, this caused problems when using display: flex with the control. We now recommend that you do not use the fieldset tag.
  • The outer element that has class option-set must have an aria-labelledby attribute whose value is the id of the element that acts as a title for the Option Set (typically, a heading right above the Option Set.) If the Option Set does not have a visible title, then instead it needs an aria-label attribute whose value is a descriptive title of the Option Set; this text must be localized, as some browsers will read it to the user.
  • Each individual option-set-option-wrapper should also have a role attribute. For Option Sets of radio buttons, this should be role="radio". For Option Sets of checkboxes, use role="checkbox".
  • If a checkbox or radio button is a required field before the user can submit the page, add the attribute aria-required="true" to the input.

Site Examples

Option Set is used to pick a size on product pages such as the Yard signs page.

Paginator

A Paginator allows for navigation across a range of pages of related content, and also indicates a user's position within that range.

Developer Guidelines

  • Paginator is a simple set of controls with no actual pagination logic behind them. The page that uses it will need to:
    • attach the URLs and/or handle any clicks to the Previous and Next buttons
    • attach a change handler to the input field, taking the user to the specified page when the input's value is changed
  • If the user is at the first or last page, the Previous or Next button should be disabled accordingly:
    • If your Paginator uses <a> tags, change the Prev/Next button to a <span> tag and add class paginator-button-disabled.
    • If your Paginator uses <button> tags, disable the button as you normally would for a button, by adding the attribute disabled="disabled".
  • Paginator buttons can use either <a> or <button> tags. Use <a> tags if a click takes the user to a new page; use <button> tags if a click loads new content into the same page.

Accessibility Guidelines

  • Any aria-label values will need to be localized, since they will be presented to the user by screen readers and assistive devices.

Pagination Buttons

using <a> tags

using <button> tags

showing the "Previous" button disabled, because we are on page 1:


Design Specs

  • Use a max of 6 numeric links.
  • Always include a link back to the first page in the series, e.g. 1 ... 4 5 6 ... 18

Developer Guidelines

  • Pagination buttons are a simple set of buttons with no actual pagination logic behind them. The page that uses them will need to attach the URLs and/or handle any clicks to the buttons. It will also need to disable the Previous and Next buttons if the user is at the first or last page in the list.
  • Pagination Buttons can use either <a> or <button> tags. Use <a> tags if a click takes the user to a new page; use <button> tags if a click loads new content into the same page.
  • If the user is at the first or last page, the adjacent Previous or Next button should be disabled. If your Pagination Buttons uses <a> tags, change the Prev/Next button to a <span> tag and add class pagination-button-disabled. If your Pagination Buttons uses <button> tags, disable the button as you normally would, by adding the attribute disabled="disabled".

Accessibility Guidelines

  • Any aria-label values will need to be localized, since they will be read out loud by screen readers and assistive devices.
  • Indicate the current page by adding the attribute aria-current="true" to the button. If you are using <a> tags, this button should be a <span> tag (since the user does not need a clickable link to the current page).

SEO Considerations

  • Be sure to have only one unique URL for the first page, especially when the user clicks on the "1" link.

Price Bar

The Price Bar displays price information and related content during product flow.

using a dropdown:

Banner Text 1
Banner Text 2
$123.45 $67.89
Inc. VAT

using a textbutton that launches a modal dialog:

Banner Text 1
Banner Text 2
$123.45 $67.89
Inc. VAT

using neither:

Banner Text 1
Banner Text 2
$123.45 $67.89
Inc. VAT

Older, deprecated API:

Banner Text 1
Banner Text 2
$123.45 $67.89
Inc. VAT
Banner Text 1
Banner 2
Banner Text 3
$123.45
Inc. VAT

"show-banner" option

By default, the banner segments will be hidden on Small and Extra-Small screens. However, an adaptive design might require that for these screens, the banner be shown elsewhere on the page, separate from the regular Price Bar.

In this case, you can create a second Price Bar in a second location on the page, and add the "show-banner" option, which will force that Price Bar to show its banner (and only its banner) on all screens.

Banner Text 1
Banner 2
Banner Text 3

Designer Guidelines

  • Banner icons should be 30 pixels tall.

Developer Guidelines

  • The Price Bar is typically pinned or sticky to the top or the bottom of the page. The component can't do this automatically, because it doesn't know which element you want it to be pinned to, so you will need to pin it yourself. Typically this involves:
    • If you want the bar pinned to the bottom of the window, place it in the page HTML as a direct child of the body tag or the .site-main element, and give the Price Bar position: fixed or position: sticky in your CSS, along with an appropriate CSS value such as bottom: 0. If you use position: fixed, you will likely want to place some empty space at the bottom of that parent element so that the Price Bar does not overlap other page content when the page is scrolled down all the way.
    • If you want the bar sticky to the top of the window, place it in the page HTML as a direct child of the .site-main element, and give the Price Bar position: sticky in your CSS, along with an appropriate CSS value such as top: 0.
    • You can also place a Price Bar inside a modal dialog, using instructions similar to those above.

Accessibility Guidelines

  • Remember that any Dropdown inside a Price Bar is still bound by the Dropdown's accessibility considerations — notably, that the dropdown needs an accessible labeling element. The above example uses a <label> tag, plus the visually-hidden class to hide it from screens.

Price Block

The price block provides a standard display for the purchase price, plus optional additional information.

Price:
$56.78 (incl. VAT) With current selections
Price:
$56.78 $12.34 (incl. VAT) With current selections

Popover

A popover is a small container of secondary content that appears when a user clicks on a trigger element. The popover appears next to the trigger, pointing to the trigger to show that the popover’s contents are contextual.

Popovers are less disruptive than a modal dialog, and allow the user to continue browsing the page, closing as soon as the user clicks on anything else on the page.

The popover will automatically position itself, trying to avoid having its contents go off-screen, and it will typically have its arrowhead pointing to the center of the element that triggered it. You can specify its preferred orientation (above, below, to the left of, or to the right of the trigger).

Default (tooltip)

The default version of a popover acts like a tooltip, except that it shows up on click rather than on hover. A "tooltip" popover provides additional information, but cannot contain any interactive elements.

Dialog version

If the popover has any interactive elements, it's acting not as a tooltip, but rather as a (modeless) dialog, so the triggering element needs to specify the data-popover-role="dialog" attribute. This allows the popover to provide the proper accessibility support.

Any element inside the tooltip with class popover-close will close the popover when clicked.

"full-bleed" skin

Setting data-popover-skin="full-bleed" on the triggering element will add the "full-bleed" skin to the popover. This skin removes the padding around the popover's contents.

Designer Guidelines

Do

  • Use to show additional information at a contextual level.
  • Keep content brief and small. Popovers have a maximum width of 375px.

Don't

  • Expect to have precise control over the popover's position or the arrowhead's position.
  • Remove the arrowhead that points to the element from which it launched.
  • Place any critical information in a popover, since search engines can't see any information that requires user interaction to view.

Developer Guidelines

  • If the popover contains any interactive elements, the triggering element needs to specify the data-popover-role="dialog" attribute.
  • Content inside the <template> tag does not exist as an element in the DOM tree (as with any <template> tag), so will not be available to JavaScript until the popover has been triggered. If you need the content to be available before the popover has been triggered, use an <aside> tag instead of a <template> tag.
  • If the <template> tag has an id, that id will not be passed on to the popover once created; the id stays associated with the <template>. Instead, if you need to give the popover a particular id, give the triggering element a data-popover-id attribute; its value will be added to the popover as its id.
  • The trigger element must be accessible and clickable via keyboard. If it is not normally keyboard-accessible, you will need to make it so using the accessibility-keyboard-clickable feature.
  • Dialog popovers need an appropriate label for the dialog. If the popover has an internal heading, then the popover-content tag should have an attribute aria-labelledby whose value is the id of the heading. If the popover does not have a heading, then the popover-content tag needs an aria-label attribute whose value acts as a title for the dialog; the text for this value must be localized, since some browsers will read it to the user.

SEO Considerations

  • To be accessible to Googlebot, Popover content should be part of the page's source HTML on the server.
  • Do not place important content that we want to rank inside a popover, since this content may be deprecated by search engine bots, as the content is semi-hidden.

Preloader Graphic

A visual element that shows an operation is in progress.

Default version

Large version

Extra-Large version

Inline version

Shipping Cost: Loading... for two-day delivery

legacy .GIF version

with "center" option

inside a Textbutton

You can put a Preloader inside a Textbutton to show that the page is readying a response to the button being clicked; the preloader will take on a special appearance inside a Textbutton. You should disable the button while the Preloader is showing, to prevent the user from trying to click the button again.

Developer Guidelines

  • While the UI Library package also includes a preloader .GIF for legacy reasons, we recommend using it only when absolutely necessary (e.g. there's no other choice but to do the preloader as a background image). The Preloader Graphic component is preferable because it loads faster than the .GIF, and has crisper edges (because it uses vector graphics).

Accessibility Guidelines

  • To support accessibility, the component needs an inner span with class visually-hidden, whose contents are localized text that describe what is happening (e.g. "Loading...")

Progress bar

A determinate indicator that informs the user the percentage to completion of a system operation.

Usage

Use when uploading or downloading large files or a longer system operation.

Design Guidelines

When customizing the Progress component via themes, you can add a border or drop shadow around the bar, but be aware that some browsers (including Chrome and Safari) can be inconsistent about the width, making it appear thicker on some sides.

Developer Guidelines

If you need to change the value of the progress bar, you will need to use the function setProgressValue() on the <progress> DOM node, e.g. setProgressValue(myProgressBarNode, 23); This function will update both the progress bar and the numeric label.

Progressive Image

A Progressive Image improves the user's perceived page load time by deferring the loading of large images. Each Progressive Image contains both a low-res placeholder image that is part of the initial HTML, plus a second, full-resolution image that loads at a later time.

"immediate" version

The "immediate" option makes the page load the full image as soon as possible, typically at the DOMready event. This is useful for images "above the fold" at the top of the page.

Example immediate image

"eager" version

The "eager" option makes the page load the full image as soon as the page reaches the "load" event. This is useful for images that are near the top of the page.

Example eager image

default version

A default Progressive Image loads only when it scrolls into the viewport.

Example progressive image

Developer Guidelines

  • Progessive Image can (and should) be used with other image types such as Responsive Image and Fluid Image. Progressive Image controls when and how the image loads, while Responsive and Fluid Image control how the image displays.
  • The vanilla JS (visage-core) version of this component will attempt to run at the DOM load event, which can occur before some React components are ready, especially if you are using Gatsby. Pages using React should use the React version of this component instead.

Promo bar

A promo bar contains a promotional message, typically a promo code plus other promotional information. It is used directly above a hero.

Up to 50% off business cards with code BIZSAVE View Details

Up to 50% off business cards

Code: BIZSAVE

View Details

Example promo bar with only one segment that has text that has a very long message

using the "holiday" skin

Up to 50% off holiday cards

Code: HOLIDAY

View Details

Developer Considerations

  • Each segment of the promo bar should be its own <p> tag that is a direct child of the promo bar. The promo bar automatically puts a small amount of spacing between each segment.
  • The Promo Bar will try not to put a line break in the middle of a segment, and will instead try to put breaks between segments. If you want the promo bar's copy to line-break normally, place all the content inside a single segment.

Promo code

A promo code is a code that the user can enter to receive a discount at checkout.

default

using "text-color-white"

"white" skin

Designer Guidelines

  • If the promo code has a label, it should say "Code:" and not "Promo Code:".
  • Display a promo code with an offer.
  • Make the code easy to remember, and easy to input in the promo drawer and at checkout.
  • Make the promo code live text whenever possible, so that users can cut and paste.

Developer Considerations

  • To present colored text inside a promo code, use the typographic classes that set color.

Radio button

Radio buttons are almost never intended to be used on their own. Instead, they should be used within an Selection Set, so that they have a standard label and standard layout.

Developer Guidelines

  • Radio buttons are typically used inside a Selection Set component, and not on their own.

Accessibility Guidelines

  • If not used inside a Selection Set, the radio buttons should either be inside:
    • a fieldset, or
    • an element with the attribute role="radiogroup". This wrapper element must have an aria-labelledby attribute whose value is the id of the element that acts as a title for the radio group — or, if the group does not have a visible title, an aria-label attribute whose value is a descriptive title of the radio group. The value of aria-label must be localized, as some browsers will read it to the user.
  • If a radio button is a required field before the user can submit the page, add the attribute aria-required="true" to the input.

Range

A range input lets users pick a numeric value along a track using a handle.

disabled version

Designer Guidelines

  • Use value labels and tick marks when users need to know exact numeric settings.
  • When modifying a Range using themes, while you can adjust the track's border width and color, be aware that the browsers interpret the border width differently. Some browsers draw the border inside the track (thus making the rest of the track shorter as the border gets thicker), some draw it outside the track, and some don't draw it at all.
  • Edge 17 and 18 do not support changes to Range via themes. These browsers will always get the default Vistaprint brand look for this component.

Developer Guidelines

  • Our Range component puts Vistaprint styling on top of the native range input, so you can use any of that HTML's element's properties, such as min, max, and step.
  • When modifying a Range using themes, be aware that you can't adjust the overall margin or padding of the component, because the browsers are remarkably inconsistent about which parts of the range input they allow CSS to change. You can, however, adjust the total height of the component using --visage-range-height, and if you make this number taller than the height of the thumb, you will get extra whitespace around the thumb and track.

Range Slider

This is the API for the old platform only. You should not use it on the current platform.

A range slider is a control that uses a handle to let users adjust value or pick a range of values along a track. The lesser value is placed on the left or bottom and the greater value to the right or the top.

Single Handle

Double Handle

Disabled version

Version initialized after page load

Changing the value via JavaScript

Usage

  • There are two sliders, single-handle and double-handle; both have a disabled option (if needed).
  • Use a single handle when adjusting a single value such as volume.
  • Use a double handle when adjusting between a value range such as a filtering for price.
  • Typically, use a disabled slider if slider's value is dependent upon a condition not yet met.

Designer Guideliness

Use value labels and tick marks when users need to know exact numeric settings.

Developer Guidelines

  • If your Range Slider is created after the DOM is ready, you will need to explicitly initialize it using the jQuery initializeRangeSlider() function, e.g. $(".my-range-slider").initializeRangeSlider().

Site Examples

  • The Banners page uses a range slider to show banner sizes.
  • Ratings and Reviews

    Ratings and Reviews provide customer-submitted reviews of our products, to inspire consumer confidence.

    inline ratings

    Rated 4.23 out of 5 stars
    3724 Reviews Write a Review
    of respondents would recommend this to a friend

    configuration options for Ratings and Reviews

    • Ask a Question: Adding class ratings-and-reviews-hide-ask-a-question to the outer wrapper (the one with class ratings-and-reviews) will hide the "Ask a Question" button.

    Developer Guidelines

    • Ratings and Reviews are provided by a third-party, and comes with a default set of visuals. The UI Library overrides these with its own stylesheet.

    SEO Considerations

    • Ratings & Reviews should be rendered on the server side as part of the page's source HTML, not loaded dynamically.
    • Average ratings, best ratings, and number of ratings should be displayed on the page to be eligible on Structured Data.
    • Ratings & Reviews should be integrated into Structured Data in order to enrich snippet shown on SERP (Search Engine Result Pages) and maximize CTR + Clicks.
    • At least one single complete review should be added to the Structured Data declaration to make it complete.
    • Contact the Organic Search team for a Structured Data JSON Script you can use as a reference for integration, and be aware of the Schema.org Review Declaration.

    Secondary Tile

    Secondary tiles are used for presenting secondary pieces of information on a page, such as accessories or product options.

    Default secondary tile:

    sample image

    Tile name

    sample image

    Tile name

    sample image
    New

    Tile with badge above

    sample image

    Tile with price

    100 Starting at €10.99 Inc. VAT
    sample image

    Tile with promo message badge

    60% off

    Secondary tiles that are links:

    If the tile is an <a> tag, then all such tiles in the same grid row will be equalized, so that they have the same visible height.

    The tile name should use the underlined "CTA" link only if the tile name has no other accompanying information (no price, badge, etc).

    If the tile doesn't have a CTA link on it, we recommend adding class secondary-tile-shadow-hover to give the tile a drop shadow when hovered over, to provide some affordance that the tile is clickable.

    Horizontal Secondary Tiles

    sample image

    Tile name

    Tile description goes here

    sample image

    Tile name

    Tile description goes here
    Tile description goes here
    Tile description goes here
    Tile description goes here

    sample image

    Tile name with no description

    sample image
    Tile with bullet list
    • Bullet list inside the description
    • Bullet list inside the description
    sample image

    Tile name with price

    Included
    Tile description goes here
    sample image
    Recommended Tile with badge and price
    $1.23
    Tile description goes here
    sample image
    Recommended Tile with with no description
    $1.23
    sample image

    Tile that launches a panel dialog

    $3.00
    Qty

    Secondary Tiles as <label> tags

    Designer Guidelines

    • Secondary Tiles are used for secondary choices, such as product options or accessories. (If you are choosing from a list of products, use a Standard Tile instead.)
    • If a vertical Secondary Tile contains only the tile name and no other details, it should use the underlined "CTA link" look.

    Accessibility Guidelines

    • If a sequence of tiles is semantically a list, as is usually the case (e.g. a list of products), then the layout grid elements around the tiles should use ul and li tags, so that the tiles are grouped semantically into a list. Use <ul class="row"> and <li class="N"> for the grid elements around the tiles.
    • If the secondary tiles are acting as a set of radio buttons, the wrapper element around the tiles (e.g. the row element) needs the attribute role="radiogroup", plus an aria-labelledby property whose value is the id of the element that labels the set of radio buttons (e.g. the heading for that page section).
    • A Secondary Tile may include a secondary-tile-labeled-input with a button that shows the currently selected value and, when clicked, opens a dialog. These buttons must have:
      • an aria-labelledby attribute whose value is the id of the associated label
      • a span with class visually-hidden inside the button, whose contents provide instruction to the user about what clicking the button does. For instance, this span might say "(Click to change selection)".

    Standard Hero

    We use heroes to show our most important content and grab the user's attention in a visual way. Heroes are positioned at the top of the page to lead the additional POV and content for the rest of the page. The Standard Hero represents the usual visual treatment for heroes on our site.

    with "full width image" option:

    Hero title here

    The standard look. You still need to explicitly specify the "full width image" option, for backwards-compatibility reasons.

    (Optional) A footnote can go below the button.

    sample image

    Using "text-right" option

    Adding the "text-right" option aligns the text box to the right.

    sample image

    Using "text-center" option

    Adding the "text-center" option aligns the text box to the center, and also makes the contents of that box centered.

    sample image

    Using "text-center" option and the "holiday" skin

    Some description goes here.

    sample image

    Using "text-center" option and the "text-align-bottom" option

    Some description goes here.

    sample image

    using "staggered" option

    This option makes the image and text box staggered.

    sample image

    using "staggered" option and "text-right" option

    This option makes the image and text box staggered.

    sample image

    using "text-transparent-background" option

    Keep the description short!

    sample image

    (Optional) text with class "strong" plus "mt-0 mb-2"

    using "short" option

    plus the "text-transparent-background" option.

    (Optional) A footnote can go below the button.

    sample image
    These hero options are deprecated. They still work for now, but we will be removing them in the future, so you should stop using them, and change any Hero instances that use them.

    using "inverse" skin:

    Hero heading

    This skin is now redundant, and thus has been deprecated.

    sample image

    with "text-align-top" option:

    Hero title

    This option is deprecated, as we no longer want to use top-aligned text.

    sample image

    Heroes that are not using class .standard-hero-full-width-image

    An older style of hero did not specify a full-width image, often having multiple background images instead.
    As of Visage 3.0, this style is now deprecated, and will be removed from the code soon. At that point, these heroes may only display one background image, and/or may have their text and text background colors change.

    Some hero heading that wraps

    This standard hero description also wraps onto two lines, or maybe even onto three lines.

    sample image

    with "text-right" option:

    Some hero with text on right

    This standard hero has its text on the right-hand side.

    sample image

    with "inverse" skin:

    sample image

    Some hero heading

    A standard hero description.

    sample image

    using "menu" skin:

    Some hero heading that wraps

    sample image

    with no background image under the text:

    Some hero heading that wraps

    This standard hero description also wraps onto two lines, or maybe even onto three lines.

    sample image

    with "text-align-top" option:

    Top-aligned text

    A standard hero description.

    sample image

    Designer Guidelines

    • The height of the hero is normally determined by the height of the text. The product image may be clipped if it is too tall or too wide to fit.
    • Keep headlines and descriptions short! If the text is too long, it may make the hero awkwardly tall on smaller screens.
    • Short, wide images (such as the ones used for full-width heroes) may not look great on Extra-Small screens such as phones. You may want to consider providing an alternate image for Extra-Small screens, and having the page adaptively send that alternate image if the user's session is on a phone.

    Developer Guidelines

    • Standard Heroes should touch the edges of the browser window (as long as your screen width is less than 1920px), so they should not be used inside Bounded Content.
      • Exception: when used outside of the hero zone as a narrow banner, you should use Bounded Content and the layout grid. See "narrow" banners, below.
    • Standard Heroes should use Fluid Image instead of Responsive Image; Responsive Images may not always properly crop or stretch.
    • The Standard Hero provides a visual treatment for Extra-Small screens (such as phones), but that may not be the ideal visual experience for your particular campaign. If the user's session is on a phone, your page may want to consider adaptively sending users a different component (which might even be a different Standard Hero component!) or alternate product image.

    Accessibility Guidelines

    • If the "highlights" over the image do not convey necessary information, add aria-hidden="true" to the highlights element. This will hide the highlights from assistive technologies.

    SEO Considerations

    • If the title on the hero is the main title of the page, put it in a h1 tag. If it is not the page title, use whatever tag is appropriate for the page structure.
    • Standard Heroes should contain only HTML text, rather than having the text embedded into the image.
    • Like any image, Standard Hero images need appropriate alt text about what's shown in the image.

    Standard Hero as a "narrow" banner

    Standard Hero can be used outside of the page's hero zone to create a narrow banner in the middle of a page. To do so, add the "narrow" option, which will adjust the hero's layout and typography to better fit a narrow width. Then place the Standard Hero inside a layout grid element.

    Overline

    Banner title

    This banner uses the "narrow" options, plus the "text-center" and "text-align-bottom" options.

    sample image
    Overline

    Banner title

    This banner also adds the "staggered" option to the previous list.

    sample image

    Banner title

    This banner is showing the "transparent-background" option.

    sample image

    Developer Guidelines

    • Unlike regular Standard Heroes, when used as a mid-page banner, these should be placed inside Bounded Content and inside a grid element.

    Hero with Left-Hand Navigation

    This combination places a Left-Hand Navigation component over part of the hero, spilling over into the area below the hero. The content below the hero is shifted over to accommodate it.

    Hero using "text-transparent-background" option

    Hero description goes here.

    sample image

    Designer Guidelines

    • The left-hand navigation will be hidden on Extra-Small screens.
    • This combination is designed to work only with the hero layout shown above: with the hero text just to the right of the left nav, with that text left-aligned, and with a single background iamge.

    Selection Set

    A Selection Set is a series of radio buttons or checkboxes (aka "selections"), though they may have the look of other elements. For instance, a mutually exclusive set of Standard Tiles would be a Selection Set.

    Selection Set of Standard Tiles

    Selection Set of Secondary Tiles (horizontal)

    Selection Set of Secondary Tiles (vertical)

    Selection Set of arbitary text

    Selection Set with "buttons" skin

    Selection Set with "buttons-with-images" skin

    Selection Set with "simple-column" skin (and "show-inputs" option)

    The "show-inputs" option will cause the underlying <input> element (the actual radio button or checkbox) to be displayed rather than hidden. Combining this with the "simple-column" skin will create a columnar layout of the inputs and their labels.

    Shown using checkboxes instead of radios:

    Designer Guidelines

    • When using the "buttons with images" skin, the images should be no taller than 30 pixels.

    Developer Guidelines

    • You can put the selection-set class onto a grid row element, if the selections that the user is choosing from are spread out among the columns inside that row. For instance, if you are presenting a row of Standard Tiles to choose from, the row can also act as the selection-set element.
    • You can use checkboxes instead of radio buttons inside a Selection Set. Just use type="checkbox" instead of type="radio" on the input tag.
    • You cannot place another form element (such as an <input> tag) inside the <label> tag.

    Accessibility Guidelines

    • If there is more than one input in the Selection Set, the outer element that has class selection-set must also have a role attribute. If the Selection Set is a set of radio buttons, it should have role="radiogroup". If it is an Selection Set of checkboxes, it should have role="group".
    • The outer element that has class selection-set must have an aria-labelledby attribute whose value is the id of the element that acts as a title for the Selection Set (typically, a heading right above the Selection Set.) If the Selection Set does not have a visible title, then instead it needs an aria-label attribute whose value is a descriptive title of the Selection Set; this text must be localized, as some browsers will read it to the user.
    • If a checkbox or radio button is a required field before the user can submit the page, add the attribute aria-required="true" to the input.

    Spacing

    While Visage components may have their own internal spacing, the spacing classes allow you to add specific spacing between page elements.

    The spacing classes follow the format {property}{sides}-{size}, where:

    • property is either m for margin (external spacing), p for padding (internal spacing).
    • sides is empty for all four sides, b for bottom, t for top, y for y-axis (both top and bottom), l for left, r for right, and x for x-axis (both left and right).
    • size is a size number between 1 and 12; see table below.
      • For margin only, there is also a size 0, which will cancel out that margin and set it to zero. This can be useful if a component already has margin that you don't want.
      • Sizes 8 through 12 are only available for top and bottom. (If you need more horizontal spacing than size 7, use the layout grid instead.)

    For instance, to put margin size 5 on the top and bottom of an element, use class my-5.

    Examples

    m-1
    pt-2
    mb-3
    pl-4
    mr-5
    px-6
    my-7
    pb-8
    mb-9
    pb-10
    mb-11
    pb-12

    Auto

    There are some additional choices for margins:

    • mx-auto sets the x-axis (left and right margins) to auto. This can be used to horizontally center a block element.
    • ml-auto and mr-auto set the left- and right-hand margins to auto. These can be useful with flex-based layouts.
    mx-auto
    ml-auto
    mr-auto

    Developer Guidelines

    • All else equal, use margin instead of padding.
      All else equal, use bottom spacing instead of top spacing.
    • You can use more than one of these classes per element, but don't use two classes that set the same property on the same side. For instance, my-3 mt-5 is a bad idea, because they are both trying to set the top margin. But mt-3 p-5 is fine, as is my-3 mx-5.
    • In many cases, you can put any of these classes straight onto a Visage component. However, some components will have their own padding and margin, and so adding the spacing classes can cause the component to deform or behave incorrectly. It is always safer to wrap the component in a wrapper element, or wrap the component's content with a wrapper element, and put the spacing class on the wrapper instead.
      Exception: you cannot put any of these spacing classes onto grid elements; instead, put the spacing on a container inside the grid element.

    Square Image Container

    A Square Image Container creates a square element that centers a Fluid Image inside it, and stretches the image to fill the width or height of the square as appropriate for its aspect ratio.

    Example image
    Example image
    Example image
    Example image

    Developer Guidelines

    Square Image Container should only use Fluid Images and not Responsive Images.

    Standard Section

    Use the Standard Section to wrap major sections of the page, to provide margin at the bottom of that major section, so that its contents do not run up against the section that follows it. For instance, it might be used to wrap a page's hero so that the hero doesn't touch the content that follows it.

    Standard Section adds 32 pixels of margin at the bottom. You can also pick the "mini" option, which will give you 16 pixels instead.

    Do not use Standard Section just to add some spacing somewhere! Use it only to wrap major sections of a page, as part of the page's document structure. Using it improperly can cause accessibility issues for some assistive devices.
    This is the first Standard Section.
    Its contents will be set apart from what comes after it by a 32px margin.
    This is the second Standard Section. There is a visual gap between the two sections, provided automatically by the Standard Section component. (Here the gap is shown in grey, so you can see it; normally the gap will be transparent.)
    This is a Standard Section with the "super" option, which adds extra spacing at the bottom (32px).
    This is a Standard Section with the "mini" option, which adds spacing at the bottom, but less (16px).
    Here's the element that comes last.

    Designer Guidelines

    Standard Section is intended to wrap major sections of the page, and should not be used to adjust spacing for smaller page elements. (Using it improperly can cause a accessibility issues for some assistive devices.)

    Some components may have their own bottom margin or spacing, which may interact with the Standard Section's bottom margin.

    Developer Guidelines

    Standard Section is intended to wrap major sections of the page. If you just need to add some spacing around an element, use the Spacing system instead.

    Accessibility Guidelines

    Assistive technologies such as screen readers construct a document outline based on the HTML for the page. Therefore, only use Standard Section for major sections of the page, or the page may be presented incorrectly to assistive technologies.

    Standard Tile

    The Standard Tile may be used for promoting products, or for other instances where an image should be followed by descriptive text.

    Standard Tiles using the horizontal option:

    Standard Tiles that aren't links:

    sample image

    Tile that isn't a link

    This is a tile that's not a link, such as informational tiles in Resource Center pages. It has no CTA at the bottom.

    sample image

    Horizontal tile that isn't a link

    This whole tile is not a link.

    shown inside Card Containers:

    These Card Containers are using the "even height" option so that every tile on the same row has the same height, and the "bordered" option to give them a visible border.

    shown inside a Card Set:

    Designer Guidelines

    • Standard Tiles must have an image and a tile name. Other sub-elements (such as description, promo code, etc) are optional.
    • Horizontal tiles should use minimal text. The text area (to the right of the image) should not be taller than the image.
    • For SEO reasons, Standard Tiles for products should not just display a product's title, but should also include information about the product. Exception: it is okay to hide this information on mobile. (Please contact the Organic Search team with any questions.)
    • Special notes on color swatch usage:
      • Tiles with color swatches should be at least 3 columns wide on the layout grid.
      • Tiles with color swatches should use a limited set of other optional tile elements. The most common use is in conjunction with ratings and pricing.

    Developer Guidelines

    • The "CTA" link should be a <button> tag, since the entire tile is a link, or is inside a link. This prevents nested <a> tags, which are prohibited by HTML.

    Accessibility Guidelines

    • If a sequence of tiles is semantically a list, as is usually the case (e.g. a list of products), then the layout grid elements around the tiles should use ul and li tags, so that the tiles are grouped semantically into a list. Use <ul class="row"> and <li class="col-N"> for the grid elements around the tiles.
    • Tile images have specific requirement for alt attributes:
      • The tile's image should use an empty alt attribute if there is nearby HTML text that presents the same content as the description of the image — which is usually the case for Standard Tiles, since the tile name immediately follows the image, and typically describes the image. (Using an empty alt attribute prevents screen readers from saying the same thing twice in a row: "Business Cards... Business Cards.")
      • SEO may require that a tile image's alt attribute not be empty (per the above), so that the image shows up better in image searches. In this case, if the image and the tile name are both inside the same hyperlink, you can put role="presentation" aria-hidden="true" onto the image. This will hide the image entirely from assistive technologies, but not from screens or search engines.

    Step Indicator

    A Step Indicator is a navigational element that shows the user's progress in a series of steps or pages within a design or order flow.

    Use a step indicator to break up tasks into manageable steps, which helps the user avoid information overload and assists in decision-making.

    On mobile devices, implement adaptive design and use an Accordion instead of Step Indicator to indicate progress. (The Step Indicator will not automatically adjust to an Accordion!)

    1. Step 1 T-Shirt Type
    2. Step 2 Style
    3. Step 3 Placement
    4. Step 4 Finish

    with a clickable <a> tag to go to a previous step:

    1. Step 1 T-Shirt Type
    2. Step 2 Style
    3. Step 3 Placement
    4. Step 4 Finish

    with a clickable <button> tag to go to a previous step:

    1. Step 2 Style
    2. Step 3 Placement
    3. Step 4 Finish

    on the first step:

    1. Step 1 T-Shirt Type
    2. Step 2 Style
    3. Step 3 Placement
    4. Step 4 Finish

    on the last step:

    using step values:

    1. Step 1 T-Shirt Type Women
    2. Step 2 Style Long-Sleeved
    3. Step 3 Placement
    4. Step 4 Finish

    showing what happens when the Step Indicator content is wider than the available area:

    1. Step 1 Milestone Birthday Invitations
    2. Step 2 Style
    3. Step 3 Placement
    4. Step 4 Finish
    5. Step 5 Other Birthday Invitation Products For You To Consider
    6. Step 6 C'mon, You Know You Want To Buy Some More Stuff

    Do

    • Use an Accordion on Extra-Small screens instead of a Step Indicator.
    • Use on product page configurators.

    Don't

    • Use a Step Indicator to show a series of steps unless it also shows the user’s current position in that series.

    Developer Guidelines

    • All past steps should have class step-past on them. The immediate previous step should also get class step-previous.
    • All future steps should have class step-future on them. The immediate next step should also get class step-next.
    • If you use a <button> tag inside one of the steps, you'll need to apply the class link to the button to make it look like a link.
    • If you use a <button> tag inside one of the steps, you'll need to apply the class link to the button to make it look like a link.

    Accessibility Guidelines

    • The current step needs the aria-current="step" attribute on it.
    • If a step is clickable, use an a tag if you just need a link to another URL, or a <button> tag with class link if you need to perform an in-page action such as a JavaScript event.

    Table

    Tables organize data into columns and rows to make information easier to scan.

    "simple" skin:

    Example table heading, using class "text-left" and "text-size-4"
    Qty Greyscale grid Color grid
    1 $X.XX $X.XX
    5 $XX.XX $XX.XX
    10 $XX.XX $XX.XX
    50 $XXX.XX $XXX.XX
    Example table heading for a table with two-line text, and which is wrapped in a "table scroll container"
    Quantity Small Unit cost Medium Unit cost Large Unit cost
    1 $X.XX $X.XX $X.XX $X.XX $X.XX $X.XX
    5 $XX.XX $XX.XX $XX.XX $XX.XX $XX.XX $XX.XX
    50 $XXXX.XX $XX.XX $XXXX.XX $XX.XX $XXXX.XX $XX.XX

    "comparison" skin:

    Example table heading, using class "text-left" and "text-size-4"
    Style

    Tri-fold

    Ideal for larger menus and displaying additional information like images.

    Long

    Ideal for smaller menus, food trucks, and restaurants with a more limited selection.

    Size A standard 8.5" x 11" sheet folded three times, offering six separate panels. A flat sheet of 3.6" x 8.5" paper. Double-sided, full-color printing available.
    Paper Stock Standard glossy, Premium glossy Standard glossy, Premium matte, Premium recycled

    Designer Guidelines

    • Tables do not display well on phones. Limit the number of columns.

    Developer Guidelines

    • The <table> tag should only be used for tabular display of data, such as a pricing table. It should not be used to lay out page content into rows and columns; use the layout grid for that.
    • The table's title (e.g. a heading tag) should be inside a <caption> tag that sits as the first child of the <table> tag. By default, caption contents horizontally centered; you can use the class text-left on the contents to make them left-aligned.
    • Wrapping a table in an element with class table-scroll-container will allow it to horizontally scroll, if the table's content is wider than the available width.

    Accessibility Guidelines

    • The <table> tag should only be used for tabular display of data, such as a pricing table. It should not be used for page layout!
    • If a <th> tag is a row header rather than a column header, be sure to include scope="row". If your table has both row and column headers, the column headers will need scope="col".

    SEO Considerations

    • Each major table should intregrate structured data, to let Google understand what the table is about. Use this JSON Script as a model. (Contact the Organic Search team with any questions.)

    Tabs

    Use tabs to organize and navigate between different types of related content at the same level of hierarchy, in the same viewing area on a page.

    Tab headers will not line-wrap if there is not enough space to display them all. Instead, the user will be able scroll them horizontally. A slight gradient will appear at the right edge to indicate there is hidden content.

    default Tabs

    Use this to toggle between high priority content. Placements include the returning customer homepage and product pages on desktop.

    Tab 1 content, which should be the default for this set of Tabs.
    Tab 2 content, which is not the default for this set of Tabs.
    Tab 3 content, which you should not be able to see because this tab is disabled.
    Tab 4 content, which is not the default for this set of Tabs.

    with "fixed-width-headers" option

    With this option, the tab headers all have a fixed width of 240px. Use this to toggle between high priority content. Placements include product pages on mobile.

    Tab 1 content, which should be the default for this set of Tabs.
    Tab 2 content, which is not the default for this set of Tabs.
    Tab 3 content, which you should not be able to see because this tab is disabled.
    Tab 4 content, which is not the default for this set of Tabs.

    with "center-headers" option

    Tab 1 content, which should be the default for this set of Tabs.
    Tab 2 content, which is not the default for this set of Tabs.
    Tab 3 content, which you should not be able to see because this tab is disabled.
    Tab 4 content, which is not the default for this set of Tabs.

    with "center-headers" and "full" options

    Tab 1 content, which should be the default for this set of Tabs.
    Tab 2 content, which is not the default for this set of Tabs.
    Tab 3 content, which you should not be able to see because this tab is disabled.
    Tab 4 content, which is not the default for this set of Tabs.

    with "sticky-headers" option

    This option makes the headers sticky to the top of the screen if the tabs content is tall.

    Tab 1 content, which should be the default for this set of Tabs.
    Tab 2 content, which is not the default for this set of Tabs.
    Tab 3 content, which you should not be able to see because this tab is disabled.
    Tab 4 content, which is not the default for this set of Tabs.

    with "wrap-headers" option

    This option makes the headers wrap to the next line if there isn't enough room.

    Tab 1 content, which should be the default for this set of Tabs.
    Tab 2 content, which is not the default for this set of Tabs.
    Tab 3 content, which you should not be able to see because this tab is disabled.
    Tab 4 content, which is not the default for this set of Tabs.
    "thumbnails-under" skin

    Note: the API for this skin is different from normal; it places the contents before the headers.

    This skin is intended for tab sets that show a large image in each tab panel, with thumbnails of the images as the tab headers. For instance, on a product page, the tab panels might show product images, with thumbnails of those images as the tab headers.

    sample image Tab 1 content, which is not the default tab for this container.
    sample image Tab 2 content, which should be the default tab for this tab container, because it's been specified as selected in the HTML.
    sample image Tab 3 content, which you should not be able to see because this tab is disabled.
    sample image Tab 4 content, which is not the default tab for this container.

    Do

    • Use concise copy for tab headers — one or two words.

    Don't

    • Nest one set of tabs inside another.
    • Use more than one row of tabs.

    Developer Guidelines

    • The radio button associated with the default tab should have the property checked="checked".
    • You can disable a tab by putting the disabled property onto the radio button associated with that tab.

    Accessibility Guidelines

    • The tabs-headers element must have role="tablist".
    • Each input inside tabs-headers must have role="tab" and an aria-controls property whose value is the id of the tab panel that it goes with.
    • Inside tabs-contents, each tab panel must have role="tabpanel" and an aria-labelledby attributes whose value is the id of the label in tabs-headers that the tab panel goes with.

    SEO Considerations

    • Content within any tab that's not the default tab is readable by Googlebot, but not SEO-friendly. Googlebot considers content you put behind these tabs as less important for users and for organic visibility (ranking). All major content must appear on the default tab; other tabs must contain less important information, since they will be deprecated by Googlebot in terms of ranking.
    • Whenever possible, instead of displaying the content behind a tab, use anchor links that point to a different location within the same page.

    Text input

    A text field enables users to input or edit alpha-numerical information.

    Text inputs with label above, and with error message
    This outdated API places the error message inside the label, which is not correct placement.

    Text input with button

    Note: "text input with button" is deprecated, because the button will overlap the input field (which also means the total width of the control is determined by the input field itself). Use "text input with button beside" instead (see below).

    Text input with button beside

    A text input and a button can be grouped together. The input should then use the "floating label" functionality, where the label appears to sit inside the input, shifting once the user enters text.

    Text input with icon inset

    using the "searchbar" skin:
    using textbuttons instead of Control Icons:

    Text inputs with floating label

    This functionality is now deprecated, except when used for "Text input with button beside", above.

    Textarea

    with options "full-width" and "resize-vertical"

    The "resize-vertical" option limits resizing to vertical, prohibiting horizontal resizing.

    Designer Guidelines

    • Where possible, assist the user with placeholder text to provide examples of what to enter.
    • If a "floating label" is too long for the input, it will ellipse the text. (This is a guardrail to prevent page layout from deforming.) Ellipsed text not a good user experience, so you should be careful not to let this happen; keep floating label text short.
    • For Textarea, the "resize-vertical" option does not work in Edge 18 and older, so your page's UX cannot rely on it, and must still be usable without it.

    Developer Guidelines

    • Inputs default to a width of 100%, filling up their container — this is a best practice for responsive design. If you need to limit an input's width, constrain its container, e.g. by putting it into a grid element of a certain number of columns.
    • For the <input> tag, always use a value for type that is appropriate for the input's function. For instance, if the input represents a search field, use type="search" rather than type="text".

    Accessibility Guidelines

    • See the Accessibility Guidelines for Forms.

    Title Block

    The title block is a wrapper for the page title which properly distances the title (and optional subtitle) from the content below. It does not set the font size of the title, which is up to the individual page; it only sets spacing between elements.

    Example Page Title

    Example content that comes next in the page, below the title block

    Example Page Title

    Example Page Subtitle

    Example content that comes next in the page, below the title block

    SEO Considerations

    • The page's main title should always be in an h1 tag, and should appear on the DOM before any h2 or other heading tag.
    • You should have only one h1 tag per page. (You can have multiple h2 and other heading tags, as long as the structure is relevant for both users and search engines.)

    Thumbnails Hero

    The Thumbnail Hero lets the user see large images by clicking on one of a series of inset thumbnail images. A content box is overlaid on top of the hero to provide additional text or controls.

    Toggle Switch

    Toggle switches are digital on/off switches. They prompt users to choose between two mutually exclusive options, and always have a default value. Toggles should provide immediate results, giving users the freedom to control their preferences as needed.

    Show guidelines:
    Include VAT:

    Don't

    • Use a Toggle Switch to toggle between two states that aren't semantically "on" and "off". Instead, consider a Buttonbar or other treatment.

    Developer Guidelines

    • To determine or set whether the toggle switch is on or off, use the aria-checked attribute of the button. A value of true means that the switch is on.
    • The Toggle Switch must have an aria-labelledby attribute whose value is the id of the element that labels the switch. If the page design does not call for a visible label for the switch, you will need to create a labelling element anyway, and then use the visibility-hidden class to make the labelling element hidden on screens.
    • The "on" and "off" text will not be presented by screen readers and some assistive technologies. If the purpose and function of the switch are not obvious without that text, you may need to add visually hidden text (using class .visually-hidden) to the switch's labelling element to make the purpose of the switch more clear.

    Type

    Our primary font is Mark Pro Medium and our secondary font is Mark Pro Light. We use typography to clearly present design and content that adheres to responsive design and accessibility standards. We include typographic style guides so that fonts are used as intended for a consistent user experience.

    Body text

    This is standard body text for the site. Etenim, siste, me iuva, auscultaque. Gelu redivit cum inventione novissima. Nescioquid me constringit. Fluo ceu hasta baleanarum necandarum noctu et quotidie. Umquam hoc desistetne? Ego dubito. Lucernis restinctis luceam. Ad ultimum flecto microphonem ut vandal. Scenam illumino et ineptum incero etsi candelam faciam.

    This is body text with class "strong".

    This is body text with class "body-large".

    This is body text with class "small" and "strong".

    Headings

    h1 tag

    h2 tag

    h3 tag

    h4 tag

    h5 tag
    h6 tag

    For comparison, here is a paragraph of regular body text. Etenim, siste, me iuva, auscultaque. Gelu redivit cum inventione novissima. Nescioquid me constringit. Fluo ceu hasta baleanarum necandarum noctu et quotidie. Umquam hoc desistetne? Ego dubito. Lucernis restinctis luceam. Ad ultimum flecto microphonem ut vandal. Scenam illumino et ineptum incero etsi candelam faciam.

    Text Sizes

    A heading or paragraph can override its default font size by specifying one of these classes:

    text-size-1 (font 36px/line height 44px)

    text-size-2 (font 24px/line height 32px)

    text-size-3 (font 20px/line height 28px)

    text-size-4 (font 18px/line height 26px)

    text-size-5 (font 16px/line height 24px)

    text-size-6 (font 14px/line height 20px)

    These text sizes are only for marketing use inside hero zones:

    text-size-A (font 28px/line height 36px)

    text-size-B (font 28px/line height 36px)

    Text alignment

    Default text

    .text-center

    .text-right

    Pricing

    List prices use the class .list-price, which normally looks the same as normal text.

    Inside a .comparative-pricing block, its appearance changes: .list-price .discount-price

    A full .pricing block may also include offer information and/or a tax message:
    100 Starting at €10.99 €8.99 Inc. VAT
    (This block may get context-specific styling in certain contexts, e.g. inside a Standard Tile.)

    The .discount-price class can also be used by itself (outside of a comparative pricing block) to indicate price savings, e.g.:
    You saved $12.34!

    Text color

    Default text is charcoal.

    .text-color-dark-grey

    .text-color-holiday

    .text-color-pink

    .text-color-brand-blue

    .text-color-white

    .knockout

    .error

    .alert

    Semantic classes like "error" and "alert" should only be used for error and alert messages, not for arbitrarily changing text to a certain color.

    Overline

    An "overline" is text that goes right above a heading, providing broader-level context for the heading, often to indicate the product category of the product described by the heading.

    Overline

    An h3 heading

    Text utility classes

    .all-caps

    Do

    • Use Mark Pro Light for all body and legal copy.
    • Use Mark Pro Medium for headlines, sub-titles, product titles, promos and captions.
    • Use the various type sizes appropriately to keep content hierarchy on the page.

    Don't

    • Use any additional fonts other than Mark Pro Medium and Light in designs.
    • Introduce new type sizes.

    Designer Guidelines

    • The optimal line length for your body text is 50-60 characters per line, including spaces. If a line is too short, readers have to travel back too quickly, breaking their rhythm — and if a line is too long, it makes it difficult for the readers' eyes to focus, and they will not be able to gauge where lines start and end.

    Developer Guidelines

    • First, choose which heading tag to use (h1 through h6) based on the semantic structure of the page's content. Then apply the text size class that matches the intended visual look. Any text size class can be used on any heading tag!
    • For SEO reasons, each page should contain only one h1, and it should be the page title.
    • Text styles can be combined. For instance, this section is both .text-size-3 and .all-caps.

    Accessibility Guidelines

    • Heading tags must follow the semantic structure of the page. The page title (and only) the page title) should be an h1. The next level of heading for the page should be an h2, and so on.
    • Heading tags should only be used for text that's actually a heading, not just because the text needs to be a particular size! If the text is not a heading, use another tag (like p or div) and apply a text size class to it.
    • Text and background must meet a 4.5:1 color contrast ratio. Text should use $charcoal or $dark-grey on a white background. All other colors fall below the minimum contrast ratio when used on white. Likewise, white can be used for text used on dark backgrounds.

    Uncustomizable Markup

    The "Uncustomizable Markup" component is a wrapper to put around any content where we don't have the ability to customize the HTML markup, and thus can't add UI Library classes to the HTML tags. This component gives some UI Library standard look-and-feel to the HTML tags in that content.

    The following content is inside an Uncustomizable Markup component:

    • Plain HTML bullet list that doesn't use the stylized-list class
    • Plain HTML bullet list that doesn't use the stylized-list class
    • Plain HTML bullet list that wraps
      onto two lines

    1. Plain HTML ordered list that doesn't use the stylized-list class
    2. Plain HTML ordered list that doesn't use the stylized-list class
    3. Plain HTML ordered list that wraps
      onto two lines
    Table header Table header Table header
    This table has thead and tbody tags. Table data Table data
    Table data Table data Table data

    Developer Guidelines

    • This component should be placed around any output from the rich text editor of a CMS, if that CMS doesn't allow us to add CSS classes to the editor's content such as bullet lists. This applies to Sitecore, Contentful, and others.

    Video

    Video refers to moving images with or without sound, not motion graphics such as animated gifs. Video can be an effective way to add value when content is complicated or detailed, and is a good conveyor for experiential merchandising.

    Designer Guidelines

    • Don't use video for video's sake. A video must add to the experience, and be equal or greater then the user effort to view the video.
    • Videos can launch from a variety of container sizes, text links, or buttons when played within a modal dialog. If not using a modal dialog, the minimum width of the container should be 460px; on a phone, it should be full-width.
    • Ambient/background hero video is discouraged, as it can distract the user from the purpose of the page, and adds to load time. Use only when warranted (i.e. it enhances the understanding of content or a concept).
    • Do not rely on video as the sole source of a piece of information.
    • Keep videos between 1 to 3 minutes, since those show higher engagement rates.
    • Avoid autoplay, and/or use automute. If autoplaying videos, be mindful of the impact on page load time.
    • Always consult with the Organic Search team when adding video, so they can help optimize the video's implemention for search engines.
    • Encode between 3-4 mbps when not using a third-party encoder service.

    Developer Notes

    • Always give the user control over the video.
    • Be mindful about delivering video content on cellular networks.

    Accessibility Guidelines

    • All videos that have dialogue must have localized closed captions/transcriptions, for hearing-impaired users.
    • When possible, give a description (teaser) of the video along with the play button.

    SEO Considerations

    • Videos with transcriptions are much more findable by search engines.
    • Whenever a video is hosted on the Vistaprint website itself, we should have a declaration of the video object via Structured Data to maximize understanding from Googlebot (and potentially make it more visible on SERP). Use the JSON-LD script below as a reference:

    Resources

    Setup

    In the new (2019-) post-monolith platform, there are a few pieces of content that are needed on all pages to provide Visage branding and support:

    The <html> tag

    The <html> tag must have a lang attribute whose value is the language tag for that locale's language and region, using the language and region subtags. For instance, the language tag for Irish English would be en-IE, while the language tag for United States Spanish would be es-US.

    Head (at the top of the <head> tag, right after the <title> tag):

    JavaScript (at the bottom of the <body> tag):

    Per component:

    The above will provide you with the core components, but many components will have additional CSS and JS dependencies. These will be listed on that component's page.

    In the New Platform, use the listed dependencies — don't add files that are for the legacy platform, or this may cause significant display issues. Legacy files to avoid include (but are not limited to):

    • ui-library-basic.css
    • responsive-grid.css
    • responsive-image.css
    • textbutton.vistaprint.css
    • typography.vistaprint.css

    Page basics:

    Pages in the new platform need a need a single, consistent set of HTML tags and CSS classes for wrapping major elements of the page, to provide standard layout and to support any behaviors we want to be consistent across the site:

    Your individual environment may already be providing some of these tags; if so, do not duplicate them.

    React

    We provide a library of React wrappers for Visage components; the React library has its own set of React-specific setup instructions. See more in the React viewer.

    Static Globals

    The Visage package provides static globals for @importing into your application's stylesheets; this includes variables, mixins, breakpoints, and other functions for maintaining Vistaprint's look and feel in your application. See the UI Library Usage page on Confluence for more information.

    Intercompatibility

    Visage is specifically developed to capture and support Vistaprint's brand, rather than be a framework for creating any possible site. As such, many of its features are Vistaprint-specific.

    Visage is not designed to be intercompatible with many third-party component frameworks, such as Bootstrap. (Adding Bootstrap to a Vistaprint page will cause display errors on many components, including the layout grid and some basic typography!) Adding two frameworks to a page is also a big performance hit. If you need a piece of functionality from another framework that Visage doesn't yet offer, please contact Bauhaus to get it added.

    In the old (pre-2019) monolith-based platform, the content proxy is the easiest way to get the UI Library core static files onto your page.

    If you do not use the content proxy:

    In the legacy package:

    Use VP.UILibrary.Components.CoreStaticFiles()

    In VP.UILibraryClient:

    Use the <ui-library-files> tag helper.

    Themes

    A Visage theme allows a micro-site (or visually distinct sub-section of a site) to customize some of Visage's visuals. These two sections below have identical HTML and use identical Visage components, but one of them uses a Visage theme to provide a specialized look:

    Visage default

    Masks

    Free Shipping • Arrives within 2-3 weeks

    See prices for bulk orders

    *This date is an estimate. Due to high demand, we're experiencing delays. If this item is combined with other items, it may ship later.

    Vistaprint® was founded to help small business owners create expertly designed, up-to-date custom marketing—the assortment of products they need to look and feel professional, prepared, and plugged in.

    Millions of customers also stay connected with their loved ones thanks to Vistaprint’s easy-to-create photo canvas wall décor, mugs, and other photo gifts.

    Custom theme

    Masks

    Free Shipping • Arrives within 2-3 weeks

    See prices for bulk orders

    *This date is an estimate. Due to high demand, we're experiencing delays. If this item is combined with other items, it may ship later.

    Vistaprint® was founded to help small business owners create expertly designed, up-to-date custom marketing—the assortment of products they need to look and feel professional, prepared, and plugged in.

    Millions of customers also stay connected with their loved ones thanks to Vistaprint’s easy-to-create photo canvas wall décor, mugs, and other photo gifts.

    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 instead of MarkPro

    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 - a theme that turns text and borders to light colors, so that components can be used on dark backgrounds. It does not actually set the background color; that part is up to you. Note: the Dark theme is deliberately scoped, and will only apply to elements inside a wrapper with class theme-dark; this prevents it from changing global elements like the header and footer. Remember also to provide accessibility support: make sure that your elements have a 4.5:1 color contrast ratio against their backgrounds.

    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-core 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:

    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:

    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.:

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

    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:

    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:

    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?

    Currently, Visage allows a theme to adjust many of the visuals for:

    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!

    Visage Versions

    To use a specific version of the Visage library, visit the link below for that version of the viewer, and then use the reference URLs provided there.

    Note: this list shows only the versions older than the one you're currently viewing. To ensure you are getting the most up-to-date list of possible versions, visit the viewer at the "Evergreen" URL above.

    Contact Us

    If you think you could make this content even better, please reach out to the Bauhaus team!

    About Visage

    This site is to share our work-in-progress, offer access to Visage resources, and provide a channel for you to collaborate with the Bauhaus team. Together, we'll build a set of tools and expressions to rapidly deploy a consistent and desirable vistaprint.com experience.

    Our mission: "We capture and publicize Vistaprint's brand and design vision to make it easy to create a consistent, intuitive, and scalable experience on the Vistaprint site at speed."

    What does this mean for you?

    • Create pages entirely using the Visage system
    • Enable more collaboration
    • Provide a onsistent user experience
    • Reduce design and development time
    • Iterate rapidly from prototypes to test
    • Use components to build templates that can be used strategically
    • Easily allow site-wide visual updates (e.g. rebranding, shifts in Web trends)

    Collaboration Process

    A critical part of any design system is its maintenance and adaptability. It is through participation that components stay up-to-date, design and development evolve with best practices, and the real needs of Vistaprint continue to be addressed. We want to collaborate with you to add to, or modify, the Visage system to address your page's design needs.

    Want to add and/or modify a component? Confluence has the details on collaborating with us on a new design. Please reach out to the team!

    Loading...