For theme authors

How a theme works with Formulize UI: giving the tokens its values, loading the stylesheet, and keeping its own rules from getting in the way of the classes.

Giving the tokens values

Formulize UI sets a neutral default for every token. A theme gives them its own values in a :root rule, and the colours and font set on the Appearance page then override the theme's.

  • Set the tokens, rather than restyling the classes: every class is built on them, so the theme's look reaches all of them at once, and the Appearance page keeps working.
  • The sizes are in rem, so the Appearance page's Text and interface size setting scales them. Keep a theme's own sizes in rem too.

In the theme's stylesheet

:root {
  --fz-color-accent: #0f5e9c;
  --fz-color-accent-hover: #0b4a7a;
  --fz-color-accent-soft: #e7f0f8;
  --fz-font-sans: "Source Sans 3", system-ui, sans-serif;
  --fz-radius-lg: 0.25rem;
}

Loading the stylesheet

Formulize adds formulize-ui.css to its own pages. A theme adds it to every other page by calling formulize_uiStylesheetLink() in its theme.html, before the theme's own stylesheet.

  • The function returns nothing on a page that already has the stylesheet, so it is never loaded twice.
  • The order matters: formulize-ui.css first, then Formulize's own stylesheet, then the theme's. Where a theme rule and a class have the same weight, the theme wins.

In theme.html, in the head

<{php}>
require_once XOOPS_ROOT_PATH . '/modules/formulize/include/functions.php';
echo formulize_uiStylesheetLink();
<{/php}>
<link rel="stylesheet" type="text/css" media="all" href="<{$icms_imageurl}>css/style.css" />

Keeping theme rules out of the way

Every public class is a single class selector, with no !important, so a utility or a modifier can always adjust it. A theme keeps that working by not outweighing the classes.

  • Give the theme's own classes the theme's prefix, such as lyris-, never fz-.
  • When styling Formulize's own markup, wrap the selector in :where(), which gives it no weight, so a class added to that markup still wins.
  • A rule that styles every element of a kind, such as every button or every checkbox, would also restyle the Formulize UI components. Add :where(:not([class*="fz-"])) to it: it skips any element with a Formulize UI class, and adds no weight, so the rule otherwise works as before.

In the theme's stylesheet

/* Formulize's own markup: no weight, so classes added to it still win */
:where(#formulize-list-of-entries) td {
  padding: 0.5rem 0.75rem;
}

/* Every button, except the Formulize UI ones */
button:where(:not([class*="fz-"])),
input[type="submit"]:where(:not([class*="fz-"])) {
  min-width: 8rem;
  border-radius: 0;
}