Viewports for responsive UIs

UI components can respond to device width. Chromatic makes it easy to visual test these cases with the viewports parameter. This helps you define one or more viewport sizes to capture. Using viewports requires Storybook 4.0 or later.


Viewports for a story

To set a viewport, simply specify one or more screen widths to the chromatic.viewports parameter:

storiesOf('MyComponent', module)
  .add('story', () => <MyComponent with="props" />, {
    chromatic: { viewports: [320, 1200] },
  });

When Chromatic captures your story, it will create two snapshots on your build, with the browser set at each viewports. These viewports will be treated separately, with independent baselines and distinct approvals.


Viewports for all stories of a component

Thanks to Storybook’s built in parameter API, you can also target viewport at a group of stories or even your entire Storybook. To apply a set of viewports to all a component’s stories, use:

storiesOf('MyComponent', module)
  .addParameters({
    chromatic: { viewports: [320, 1200] },
  })
  .add('story', () => <MyComponent with="props" />);
  .add('second story', () => <MyComponent with="other-props" />);

FAQ

What viewports can I choose?

A viewport can be any whole number between 320 and 1800 pixels.

Can I control the height of the browser?

As we take a full screenshot of the component (even if it flows off the screen), it typically doesn’t make any difference what height the browser has when taking screenshots. If this isn’t the case for you application, please let us know.

Why is my content being cut off vertically?

Make sure there are no elements which are inadvertantly cutting off content through the use of overflow or height styles.

For elements that have relative height styles based on the size of the viewport (such as height: 100vh), all content nested under that element will show up in a screenshot unless either overflow: hidden or overflow: scroll is used to hide what is outside of that element (and therefore outside of the viewport).

When Chromatic takes a screenshot for an element that has a viewport-relative height as well as styling to hide/scroll the overflow, a default viewport height of 900px will be used.

What if I have a modal component that doesn’t have a width or height?

If your component infers its dimensions from the layout of the surrounding DOM elements (e.g., it’s a modal that uses position:fixed), you can set the height of that component’s stories using a decorator.

.addDecorator(storyFn => (
  <div style={{ width: '1200px', height: '800px' }}>
    This is a decorator for modals and such {storyFn()}
  </div>
))
.add('story with dimensions', () => (
  <YourComponent/>
));

How do I assign viewports to my entire Storybook?

We don’t recommend this in most cases because each viewport is treated independently and snapshots must be approved as such. But if you really want to assign viewports for an entire Storybook use addParameters() in your .storybook/config.js:

import { configure, addParameters } from '@storybook/react'; // <- substitute react with your app layer

// Be careful doing this!
addParameters({
  chromatic: { viewports: [320, 1200] },
});