Skip to main content

Application Breakpoints

General

Assemble by default handles 5 breakpoints:

  • xs: for sizes 375px to 499
  • sm: for sizes 500px to 767
  • md: for sizes 768px to 1024
  • lg: for sizes 1025px to 1439
  • xl: for sizes 1440px and above

Working with breakpoints on code

Assemble handle the breakpoints and sizes of application/components in two different layers:

  • Server side: with the middleware.ts Middleware file, that gets the userAgent info and set it in the request Headers so they are available to use any time from the x-assemble-useragent header
  • Client-side: with the useMediaQuery.tsx hook which will return an object with
    • mediaQuery: the associated mediaQuery/breakpoint based on the client-side window innerWidth and the values defined above
    • size: the associated size based on the calculated mediaQuery. Check calculateSize function inside the hook to see the mapping states.

Working with breakpoints in CSS

Assemble Web has a defaultVariables.css files inside app dir that includes a per breakpoint definition of variables for the variables with per-breakpoint value.

With this, we avoid bloating the CSS inner files with mediaQuery rules and also reduce the amount of styles to apply for each style.

Warning

Design System tokens (see Working with Figma Design Tokens below) includes a per breakpoint token by default, but developers can map a set of variables using this utility to reduce CSS files for components if needed

The Design System tokens from Figma define three breakpoints by default

  • mobile for sizes up to 767px
  • tablet for sizes 768px to 1024px
  • desktop for sizes 1025px and above

In addition to the 5 breakpoints defined above, defaultVariables.css also contains media queries that correspond to the Figma mobile / tablet / desktop breakpoints. CSS variables that are breakpoint-specific should be defined in these media queries for use in the relevant stylesheets. This is particularly important for use with server-rendered cases where the Javascript-calculated breakpoints from the useMediaQuery hook won't work. I.e. because useMediaQuery can only measure the viewport on the client side, and defaults to large for SSR components.

The defaultVariables.css stylesheet is also the home for any application-wide breakpoint-specific style definitions, which can be added to the relevant media queries within the file. Other viewport-specific definitions such as the number of cards visible in a rail (which will be used in the card sizing calculations in the Card component) also belong in defaultVariables.css.

Example

Breakpoint-specific CSS variables that are not already covered by the Design Tokens can be added to the media queries in defaultVariables.css:

/* Mobile viewports */
@media only screen and (width < 768px) {
:root {
--rail-padding: 16px;
}
}

/* Tablet viewports */
@media only screen and (width >= 768px) and (width < 1025px) {
:root {
--rail-padding: 32px;
}
}

/* Desktop viewports */
@media only screen and (width >= 1025px) {
:root {
--rail-padding: 64px;
}
}
.rail {
margin-left: var(--rail-padding);
}

Working with Figma Design Tokens

Assemble Web uses Design Tokens provided by Figma. The Design Tokens provide style definitions for the UI elements that are covered by the Figma designs. These Design System tokens define three breakpoints by default:

  • mobile for sizes up to 767px
  • tablet for sizes 768px to 1024px
  • desktop for sizes 1025px and above

In addition to the 5 breakpoints defined above in Application Breakpoints, defaultVariables.css also contains media queries that correspond to the Figma mobile / tablet / desktop breakpoints. CSS variables that are breakpoint-specific should be defined in these media queries for use in the relevant stylesheets. This is particularly important for use with server-rendered cases where the Javascript-calculated breakpoints from the useMediaQuery hook won't work. I.e. because useMediaQuery can only measure the viewport on the client side, and defaults to large for SSR components.

Note

The token:transform script will also generate the necessary CSS media queries from all Design Tokens that are specific to mobile / tablet / desktop, so there is no need to create separate entries within the defaultVariables.css media queries for entries that already exist within variables.css (automatically generated by the token:transform script).

Token Breakpoint Customization

If you use Figma design tokens with different breakpoints to those in the above example, you'll need to update the breakpoint configuration in the token:transform script, contained in the file /tokens/helpers/build-output-variables.mjs. The default configuration is:

const breakpoints = Object.entries({
mobile: 0,
tablet: 768,
desktop: 1025,
});

This translates to:

  • mobile 0 to 767px
  • tablet 767px to 1024px
  • desktop 1025px and above

If your Design Tokens use the default Assemble xs / sm / md / lg / xl breakpoints, for example, then the breakpoint config would become:

const breakpoints = Object.entries({
xs: 0,
sm: 500,
md: 768,
lg: 1025,
xl: 1440,
});

For this to work, the Figma Design token breakpoints need to be named xs / sm / md / lg / xl instead of mobile / tablet / desktop. The token:transform script would then output 5 media queries in variables.css.

Working Without Design Tokens

If your project does not use Figma Design Tokens, then you'll have no variables.css file available. The Assemble Web CSS definitions use the Design Token variables defined in variables.css. But each Design Token instance should also have a fallback value that is used in the case where the CSS variable is missing. For example:

width: var(--button-sizing-label-max-width-desktop, 200px);

--button-sizing-label-max-width-desktop comes from variables.css, and the fallback value of 200px is used when variables.css or --button-sizing-label-max-width-desktop is missing.

In order to support different viewport sizes when no variables.css media queries are available, it's therefore important to add the viewport-specific definitions either in defaultVariables.css, or within the stylesheets for the individual views / components affected.

Alternatively, the components in the src/components/simple folder accept a size prop, which accepts the values "large", "medium" or "small" by default. The size prop can also be used to specify the required size of the rendered component, in proportion to the viewport size if necessary.

Example

The breakpoint-specific Design tokens can be assigned to a CSS variable in media queries. For the case of the rail padding, we create a CSS variable that uses the mobile Design Token for the mobile viewport, tablet Design token for tablets, desktop Design Token for desktops. Then in the stylesheet for the rail component, we only need a single rail padding property defined:

/* Mobile viewports */
@media only screen and (width < 768px) {
:root {
--rail-padding: var(--rail-padding-left-mobile);
}
}

/* Tablet viewports */
@media only screen and (width >= 768px) and (width < 1025px) {
:root {
--rail-padding: var(--rail-padding-left-tablet);
}
}

/* Desktop viewports */
@media only screen and (width >= 1025px) {
:root {
--rail-padding: var(--rail-padding-left-desktop);
}
}
.rail {
margin-left: var(--rail-padding);
}

How to update breakpoints

If you need to update the breakpoint values you will need to update the following files:

  • src/dataModels/mediaQueries.ts
  • src/dataModels/__tests__/useMediaQuery.test.tsx
  • src/app/defaultVariables.css