Contextually-aware web components

The secret is CSS custom properties, a.k.a. “broadcast” variables, which are like a radio station sending out a signal. Other elements can choose to “tune in” or not.

Kendall Totten
PatternFly Elements
4 min readAug 25, 2020

--

Before we dig in, let’s back up a bit and cover the general idea of contextually-aware components. In PatternFly Elements web components, all layout components (i.e. card, band, tabs, etc.) can change their background colors, so they must communicate information about that change so that nested content can make necessary updates to retain readability. We call this “context” and the three values PatternFly Element components currently support are “light”, “dark”, and “saturated”.

For example, if you place a pfe-cta (call-to-action) inside a pfe-card with a teal background, the CTA component needs to be aware of this new context in order to render the type in a color which is readable on that background. The same is true of other HTML elements such as paragraphs, headings, and links.

The text and the CTA in the teal card automatically change colors because of the on="saturated context, which then triggers broadcast variables in the CTAs.

How does context work?

  • On a layout component, such as pfe-card, if you set the pfe-color attribute to something like pfe-color="complement" this causes a bright background color to be set on the layout, like teal.
    <pfe-card pfe-color="complement"></pfe-card>
  • In those same layout components, when we set the styles for that background color, we should also set a —-theme variable like this:
  • The JavaScript in the layout component “sees” that variable and in turn prints the on attribute on the card. The final result is:
    <pfe-card pfe-color=”accent” on=”saturated”></pfe-card>. Also note that the--theme variable continues to cascade downwards, unless it’s overridden. This is why it’s important to update the --theme variable any time the background color is updated.
  • The CSS style block in the shadow DOM of pfe-card comes with a set of variables which are associated with the on attribute. This is where the “broadcast” variables come in. Remember, other HTML elements can choose to “tune in” (or use) these variables, or not.
  • Any element in the light DOM of the pfe-card, like paragraphs, can pick up the broadcast variables because the pfe-card component includes this property:color: var( — pfe-broadcasted — text,#333);
    In order for links to be styled properly, a global stylesheet must have styles like this a { color: var( — pfe-broadcasted — link, #06c);} (this can be found in pfe-base.css).
  • Other components, like pfe-cta, nested inside the card will also inherit the —-theme CSS variable (a.k.a. custom properties) because they also adhere to the standard cascade. The pfe-cta will “listen” for the value of —-theme and apply its own on attribute automatically, which can then be used, as needed, to change its own colors.
    <pfe-cta on=”saturated”>. Before & after:

Now if you are creating a new PFE component, you’ll want an easy way to set all this up. To do this with Sass functions, you can utilize the pfe-broadcasted function, and then pass in the name of the variable such as link or text.

Notice that the result is first a local variable, then a global broadcast variable (if present), and finally a fallback hex color.

Side note, if you haven’t yet, be sure to check out our related blog post about why we use empty local variables as theming hooks.

If you are building a “container” component that can contain other components, like a band, card, or tab set, then you will need to provide the value of the broadcasted variables. You can easily do this with the pfe-set-broadcast-theme mixin.

In this example, we are setting the background color of the pfe-tab-panel to a dark background color, so we also want to change the value of the broadcast variables. Include the pfe-set-broadcast-theme mixin, and in the first argument, pass in the context you need, either “light”, “dark”, or “saturated”, then the Sass mixin will return all the theme variables and fallback values you need.

That’s it! Contextual theming made easy! Kudos to @castastrophe for writing the awesome Sass mixins and functions that make all this much easier within PatternFly Elements.

If you have questions or feedback, we’d love to hear about it, either here on Medium or in the PatternFly Elements issue queue. Thanks for reading!

--

--

Kendall Totten
PatternFly Elements

Engineering Manager at Pinata. Design geek who loves @Arcio, photography, design, music, travel & food. bento.me/kendalltotten