Design system with GeneratePresss and GenerateBlocks: Responsive-Fluid Typography

thisbit
8 min readFeb 22, 2022

--

NOTE: There is a video version of this tutorial on the bottom of the article.

As part of refactoring/redesigning the website for a university department, I am building a design system that will help the editorial team manage the website content and layouts and better communicate how the website should work visually, semantically, and functionally. In addition to this, I have recently posted a poll in the GeneratePress Community FaceBook group as to what would be most interesting to make tutorials about. The Design System in GeneratePress and GenerateBlocks option won by a landslide. As any design system is too complex to describe in a single post, I will break this into chapters. This first chapter is about the Global Colors and Typographic Scale in GeneratePress.

I plan to do this as an iterative process where design and development feed off each other. I have built some components, set the typographic scales for desktop and touch, and made several page layouts in Figma. I now have enough design problems solved to begin development and build a minimum viable solution (MVP ha-ha). In future iterations, I will add more features and details. A big challenge for me in this process is the lack of solid design restrictions in the WordPress block editor, but I think there is enough to satisfy some basic needs.

The global colors

Color palette comprised of 5 colors: primary-dark, primary-light, secondaty-dark, secondary-light and accent.
This is my current color pallete.

I have defined 5 colors in my color palette section within the Figma file. This translates nicely to the GeneratePress customizer color section. However, I want my names to be:

  • primary-dark
  • primary-light
  • secondary-dark
  • secondary-light
  • accent

while GeneratePress names their colors:

  • contrast
  • contrast-2
  • base
  • base-2
  • accent

How to change this so that my color names make sense to me? 🙂 Luckily, Tom Usborne has us covered. The following function creates new CSS variables and assigns them desired values.

Setting the custom color palette with a custom naming.

A PhP function that allows one to set new names and corresponding values to the global colors.
Get code: https://generatepress.com/forums/topic/changing-global-colors-programatically/#post-2122087

The results of this function are visible in the customizer like so.

Code pallete in the GeneratePress customizer, hovering over a color sample shows the new color name.
Color name in the customizer is visible on mouse hover

Setting the new defaults for the color picker UI

However, when applying the colors to various site elements, there is one tweak one would still want so that the thing works as it works with the default names.

Customizer default color button inserts GeneratePress default names regardless of the changes we applied through a function.
Default button brings back the GeneratePress default namin cheme for colors

When we choose a property of an element, for example, an “Entry meta” text color, click on the button with the label “Default”, the color that gets applied is a GeneratePress default “contrast-2” color. This is unfortunate, but the same as above, GeneratePress has us covered.

A PhP function that allows one to set the new color names as default CSS variables per site element property, each corresponding to the customizer option.
Get code: https://generatepress.com/forums/topic/changing-global-colors-programatically/page/2/#post-2124898

Here we can set the desired CSS variable for every element in the customizer to what you want it to be. With this, we have achieved the desired result, the colors in the color palette now have custom names and values, and they are set to be the defaults, so customizer functionality is not lost.

Typographic scale

I have designed two type-scales, one per desktop and one for touch devices.
A detail of a Figma file, where I have set up two typographic scales, one for Desktop one for Touch.

Design decisions

For my typographic styles, I have made several decisions. We will be using only one font family, and we will use only the “normal” width or the 400, with its cursive companion 400i. We are using the Work Sans typeface provided by Google, and this typeface looks most expressive in this width. Adding more widths would hinder its style. Following this, a decision was made to use a strongly contrasted typographic scale to make up for the single-width system. I opted for the “perfect fourth” ratio of 1.333 for the desktop design and a “major third” with a more subtle ratio of 1.250. Small screens do not fare well with strong contrasts. I will be using the same type scale for both mobile and tablet designs because the tablet will simply use two of the columns present in mobile, essentially providing the same space for type columns.

WordPress setup

I am enqueuing the fonts from a local directory in the child theme for performance and privacy reasons, as a recent legal case has shown Google fonts are used by Google to track your users. To achieve this I made a dedicated stylesheet called “typography.css” which is enqueued both in the front side and in the block editor to achieve the same style in both views. I decided not to upload fonts via the media manager, because fonts are an essential part of the site design and should not be accessible to all editors of the site. Other than that I followed the guidelines provided by GeneratePress.

A PhP code snippet, showing how to enqueue the typography.css to both the front end and the editor view.
https://gist.github.com/thisbit/a9daa67056484f580905b3b1d5892f14/edit

Once we have done this, we can choose the local version of the font in the customizer for the front end, and add .editor-styles-wrapper { font-family: “Work Sans”, sans-serif;} to the “typography.css” file to have the typeface render in the editor too.

Setting up the non-flexible type sizes

I like to start with the standard type sizes for two reasons. One, it is easier for me to work “around” these values when I set the fixed sizes first and two, it provides a fallback for older browsers that do not yet support the clamp() function, or the flexible type feature. To set up the static font sizes we will use the REM values based on 16px base size.

Perfect fourth 1.333, type scale for desktop, and major third 1.250, type scale for touch devices

A web app, aptly called Type Scale provides a simple visual interface to set and see the type-scale one may want to use. I like to use this for my designs. The interface does all the calculations in a click and provides both the preview and the values for the font-size property for your site. From here on, we can simply apply the REM values from the web app to our Html elements like so.

A CSS code snippet setting font-size properties to fixed values that we generated in the Type Scale web app.

Wrap the code into @media() for desktop, open another above it for mobile and paste the new values. If this was all we wanted, we might as well have done it the customizer right?

Adding “the flexible” in the flexible type scale.

Flexible type can be achieved in multiple ways, but the underlying logic is the same. We want to have the typography change its size according to the size, or width to be more exact, of the browser viewport. The larger the screen, the larger the type should be. In CSS we can achieve this using a unit that is a fraction of a browser viewport width. The viewport-with unit, or VW. The simplest flexible type system would then go something like this.

CSS code snippet, setting the H1 font-size property to 1vw

Combined with the @media() queries this could be a decent solution. However, what we miss there are some guardrails, as well as controls for the pace of size change. The web standard for this is a clamp() function. It takes three parameters, min, optimal, and max using the following syntax.

CSS code snippet. First line shows how the clamp function is structured, with the values minimal, optimal and maximum values. The second line shows a font property of h1 element, defined as minimum 2.75rem, optimum 1vw and maximum as 3.35rem.

We now know H1 will never go smaller than 2.75rem and never larger than 3.35rem and it will try to be equal to 1vw while the resulting value is between the min and max values. Usually, though the clamp functions look something like this in practice.

CSS code snippet, showing a font-size of h1 defined with a more complex clamp function, with optimal size part defined as a calculation in a nested calc function.

Instead of a simple fraction of browser viewport for the $optimal value, there is a nested calc() function that calculates the max value, viewport width difference, etc. All in all, this one is a bit of a mind twist. 🙂

Responsive font calculator

But there is a web app that can help us construct these clamp functions without much effort.

Responsive font calculator web app, a display of the form with filled in values: selector, property, size range from and to, viewport from and to, css method clamp, and options comments and safari fix selected.
En example of a Responsive type calculator form filled in.

We simply fill in the fields, choose units and a method and get the CSS code to achieve our responsive/fluid typesetting. Let’s look at a code example that works for me.

CSS code snippet showing h1 and h2 font size definitions applied both to front end and the editor, with first static font size defined, then the flexible clamp size defined, then the safari bug fix applied.

I use multiple selectors to enable the same styles for all h1 occurrences: for the front, for the block editor core/heading version, and GenerateBlocks headline version. Then I set the non-flexible size for older browsers that do not understand clamp(), then I use the flexible type definition and finally fix the Safari bug.

The procedure I follow is that the $max size of the h2 is a bit smaller than the $min size of the h1 and I do this for each type size in the type scale. This in turn makes all the type sizes change size proportionally to each other, thus retaining the type-scale ratio.

An animated display of the flexible type in action, showing how the type scale shrinks and enlarges in size corresponding to viewport size changes.
The finished flexible type-scale.

Finally, I apply vertical spacing to all the content elements. With the exception of <li> (list item) elements, I use the same value for the line height and the margin-bottom property. Worth noting is that the line-height property should always be expressed without the units of measurement, while the margin-bottom should use em units, NOT rem. If done this way both values inherit their flexible values in proportion with the font-size property and scale accordingly.

That’s it. 🚀 🔥 🎉
Thanks for reading.
Oh, and here is the youtube version of this tutorial.

A video tutorial version of this article.

--

--

thisbit

I branch into visual arts, visual communications, web dev, and teaching. Here I write about UX/UI and web dev mostly. YT https://tinyurl.com/24784589