Warning
You're browsing the documentation for an old version of Webiny. Consider upgrading your project to Webiny 5.41.x.
What You’ll Learn
  • what are some of the best practices when it comes to theme and styling development

Overview
anchor

Use Theme Object When Styling
anchor

When styling custom page layouts or page elements, visual elements like colors, typography and others should always be defined by relying on the theme object and the values it holds.

For example, instead of defining the background color for a page element with a hard-coded value, we should rely on the theme.styles.colors object and the colors it holds. For example:

This way, we can easily change the color of the page element by simply changing the color value in the theme object.

This is even more important when it comes to multi-theme projects, where we can have multiple theme objects, each holding different values for the same visual elements. In this case, we can easily switch between themes, without having to change the styling code.

For a multi-theme setup, please take a look at the existing Setup Theme Manager article.

Access Theme Object via React Context
anchor

The theme object should always be accessed via React context. For example, when creating styled components:

The theme object should not be accessed by directly importing the apps/theme/theme.tsexternal link file. This can lead to issues in multi-theme projects, where the theme object is not the same for all themes.

Accessing Typography Variants
anchor

When accessing typography variants, we can leverage the special stylesById getter function, like in the following example:

As we can see, the stylesById getter function accepts a typography variant ID as an argument, and returns a CSS object that defines the visual appearance of the typography variant. This way, we can easily access different typography variants, without having to manually traverse the styles.typography object.

UsemqUtility Function for Easier Responsive Styling
anchor

One of the tools that is recommended in Emotionexternal link library’s documentation portal is Facepaintexternal link. The library enables the developer to easily define CSS rules for multiple pre-defined breakpoints, for example:

With this 5.35.0 release, this library is included in the @webiny/app-page-builder-elementsexternal link package, enabling users to immediately use it, without the need to install it first. Furthermore, by importing the mq utility function, users can immediately start writing their per-breakpoint styles, because the function is already configured to follow the breakpoints defined in the themeexternal link. For example:

Need to define responsive styles for theme-level styles, like typography or colors? Responsive styles can also be defined via the theme object.

For more information, please refer to the Responsive Styles section.

Styling Custom Page Elements
anchor

Most often, styles for custom page elements are introduced via one or more standalone Emotion styled componentsexternal link, included with the page element code.

Usingstyles.elementsObject to Style Custom Page Elements
anchor

On top of the guidelines outlined in the Use Theme Object When Styling section, in order to provide theme-specific styles for custom page elements, we can also leverage the theme object’s styles.elements object.

The following example shows how we can provide different styles for an imaginary myCustomElement custom page element for different themes.

apps/theme/theme-light.ts
apps/theme/theme-dark.ts

Global Styles
anchor

Sometimes we might need to insert global CSS rules like resets or font faces. There are a couple of ways to do this.

The easiest way is to use Emotion’s Globalexternal link component, within a page layout React component. An example of this can be found in Static page page layout. From the Static.tsxexternal link file:

apps/theme/layouts/pages/Static.tsx

Note that, since the above global styles are added as part of the Static page page layout, they will only be applied to the pages that use this layout. Furthermore, note that these styles will only be applied when the page is being rendered on the public website, and not in the page editor. This is because the page editor only renders the page content, and not the page layout.

To resolve the above two issues, we can also introduce global styles via the global.scssexternal link file. By doing this, we’re ensuring:

  1. the styles are applied to all pages, regardless of the page layout used
  2. the styles are applied in both the public website and the page editor

Note that the global styles introduced via the global.scssexternal link file can also have a visual impact on the Admin application. If you’ll be using this approach, double check that the styles don’t affect the Admin application in unintended ways.

Alternatively, sometimes we may need to introduce global styles only on the page content (document) level. More on this in the following section.

Global Document Styles
anchor

Sometimes we may need to introduce global styles only on the page content (document) level. For example, by default, in the styles.elements.document object, we have the following styles that define how links, bold and italic text should look like:

apps/theme/theme.ts

With this approach, we can target anything that’s rendered within the page content (document) area. The styles will be applied to all pages, regardless of the page layout used. Furthermore, the styles will be applied in both the public website and the page editor.

Pages created via Page Builder’s page editor consist of multiple page elements, structured in a parent-child hierarchy. The document page element is always the top-most element in this hierarchy, similarly to how the <html> element is the top-most element in the DOM.