{"id":355894,"date":"2021-11-15T07:32:13","date_gmt":"2021-11-15T15:32:13","guid":{"rendered":"https:\/\/css-tricks.com\/?p=355894"},"modified":"2021-11-15T07:32:16","modified_gmt":"2021-11-15T15:32:16","slug":"defining-and-applying-ui-themes-using-the-mimcss-css-in-js-library","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/defining-and-applying-ui-themes-using-the-mimcss-css-in-js-library\/","title":{"rendered":"Defining and Applying UI Themes Using the Mimcss CSS-in-JS Library"},"content":{"rendered":"\n

Theming UI refers to the ability to perform a change in visual styles in a consistent manner that defines the \u201clook and feel\u201d of a site. Swapping color palettes, \u00e0 la dark mode or some other means, is a good example. From the user\u2019s perspective, theming involves changing visual styles, whether it\u2019s with UI for selecting a theme style, or the site automatically respecting the user\u2019s color theme preference at the OS-level. From the developer\u2019s perspective, tools used for theming should be easy-to-use and define themes at develop-time, before applying them at runtime.<\/p>\n\n\n\n

This article describes how to approach theming with Mimcss<\/a>, a CSS-in-JS library, using class inheritance\u2014a method that should be intuitive for most developer as theming is usually about overriding CSS property values, and inheritance is perfect for those overrides.<\/p>\n\n\n\n\n\n\n\n

Full discloser:<\/strong> I am the author of Mimcss. If you consider this a shameless promotion, you are not far from the truth. Nevertheless, I really do believe that the theming technique we\u2019re covering in this article is unique, intuitive and worth exploring.<\/p>\n\n\n

General theming considerations<\/h3>\n\n\n

Styling in web UI is implemented by having HTML elements reference CSS entities (classes, IDs, etc.). Since both HTML and CSS are dynamic in nature, changing visual representation can be achieved by one of the following methods:<\/p>\n\n\n\n

  1. Changing the CSS selector of an HTML element, such as a different class name or ID.<\/li>
  2. Changing actual CSS styling for that HTML element while preserving the selector.<\/li><\/ol>\n\n\n\n

    Depending on the context, one method can be more efficient than another. Themes are usually defined by a limited number of style entities. Yes, themes are more than just a collection of colors and fonts\u2014they can define paddings, margins, layouts, animations and so on . However, it seems that the number of CSS entities defined by a theme might be less than a number of HTML elements referencing these entities, especially if we are talking about heavy widgets such as tables, trees or code editors. With this assumption, when we want to change a theme, we\u2019d rather replace style definitions than go over the HTML elements and (most likely) change the values of their class<\/code> attributes.<\/p>\n\n\n

    Theming in plain CSS<\/h3>\n\n\n

    In regular CSS, one way theming is supported is by using alternate stylesheets<\/a>. This allows developers to link up multiple CSS files in the HTML <head><\/code>:<\/p>\n\n\n\n

    <link href=\"default.css\" rel=\"stylesheet\" type=\"text\/css\" title=\"Default Style\">\n<link href=\"fancy.css\" rel=\"alternate stylesheet\" type=\"text\/css\" title=\"Fancy\">\n<link href=\"basic.css\" rel=\"alternate stylesheet\" type=\"text\/css\" title=\"Basic\"><\/code><\/pre>\n\n\n\n

    Only one of the above stylesheets can be active at any given time and browsers are expected to provide the UI through which the user chooses a theme name taken from the values of the <link><\/code> element\u2019s title<\/code> attribute. The CSS rule names (i.e. class names) within the alternative stylesheets are expected to be identical, like:<\/p>\n\n\n\n

    \/* default.css *\/\n.element {\n  color: #fff;\n}\n\n\/* basic.css *\/\n.element {\n  color: #333;\n}<\/code><\/pre>\n\n\n\n

    This way, when the browser activates a different stylesheet, no HTML changes are required. The browser just recalculates styles (and layout) and repaints the page based on the \u201cwinning\u201d values, as determined by The Cascade<\/a>.<\/p>\n\n\n\n

    Alternate stylesheets, unfortunately, are not well-supported by mainstream browsers and, in some of them, work only with special extensions. As we will see later, Mimcss builds upon the idea of alternate stylesheets, but leverages it in a pure TypeScript framework.<\/p>\n\n\n

    Theming in CSS-in-JS<\/h3>\n\n\n

    There are too many CSS-in-JS libraries<\/a> out there, and there is no way we can completely cover how theming works in CSS-in-JS in a single post to do it justice. As far as CSS-in-JS libraries that are tightly integrated with React (e.g. Styled Components<\/a>), theming is implemented on the ThemeProvider<\/code> component and the Context API, or on the withTheme<\/code> higher-order component. In both cases, changing a theme leads to re-rendering. As far as CSS-in-JS libraries that are framework-agnostic, theming is achieved via proprietary mechanisms, if theming is even supported at all.<\/p>\n\n\n\n

    The majority of the CSS-in-JS libraries\u2014both React-specific and framework-agnostic\u2014are focused on \u201cscoping\u201d style rules to components and thus are mostly concerned with creating unique names for CSS entities (e.g. CSS classes). In such environments, changing a theme necessarily means changing the HTML. This goes against the alternative stylesheets approach described above, in which theming is achieved by just changing the styles.<\/p>\n\n\n\n

    Here is where Mimcss library is different. It tries to combine the best of both theming worlds. On one hand, Mimcss follows the alternate stylesheets approach by defining multiple variants of stylesheets with identically named CSS entities. On the other hand, it offers the object-oriented approach and powerful TypeScript typing system with all the advantages of CSS-in-JS dynamic programming and type safety.<\/p>\n\n\n

    Theming in Mimcss<\/h3>\n\n\n

    Mimcss is in that latter group of CSS-in-JS libraries in that it\u2019s framework-agnostic. But it\u2019s also created with the primary objective of allowing everything that native CSS allows in a type-safe manner, while leveraging the full power of the TypeScript\u2019s typing system. In particular, Mimcss uses TypeScript classes to mimic the native CSS stylesheet files. Just as CSS files contain rules, the Mimcss Style Definition<\/em> classes contain rules.<\/p>\n\n\n\n

    Classes open up the opportunity to use class inheritance to implement theming. The general idea is that a base class declares CSS rules used by the themes while derived classes provide different style property values for these rules. This is very similar to the native alternative stylesheets approach: activate a different theme class and, without any changes to the HTML code, the styles change.<\/p>\n\n\n\n

    But first, let\u2019s very briefly touch on how styles are defined in Mimcss.<\/p>\n\n\n

    Mimcss basics<\/h3>\n\n\n

    Stylesheets in Mimcss are modeled as Style Definition classes, which define CSS rules as their properties. For example:<\/p>\n\n\n\n

    import * as css from \"mimcss\"\n\nclass MyStyles extends css.StyleDefinition\n{\n  significant = this.$class({\n    color: \"orange\",\n    fontStyle: \"italic\"\n  })\n\n  critical = this.$id({\n    color: \"red\",\n    fontWeight: 700\n  })\n}<\/code><\/pre>\n\n\n\n

    The Mimcss syntax tries to be as close to regular CSS as possible. It is slightly more verbose, of course; after all, it is pure TypeScript that doesn\u2019t require any plug-ins or pre-processing. But it still follows regular CSS patterns: for every rule, there is the rule name (e.g. significant<\/code>), what type of rule it is (e.g. $class<\/code>), and the style properties the rule contains.<\/p>\n\n\n\n

    In addition to CSS classes and IDs, style definition properties can define other CSS rules, e.g. tags, keyframes, custom CSS properties, style rules with arbitrary selectors, media, @font-face, counters, and so on. Mimcss also supports nested rules including those with pseudo classes and pseudo-elements.<\/p>\n\n\n\n

    After a style definition class is defined, the styles should be activated:<\/p>\n\n\n\n

    let styles = css.activate(MyStyles);<\/code><\/pre>\n\n\n\n

    Activating styles creates an instance of the style definition class and writes the CSS rules to the DOM. In order to use the styles, we reference the instance\u2019s properties in our HTML rendering code:<\/p>\n\n\n\n

    render()\n{\n  return <div>\n    <p className={styles.significant.name}>\n      This is a significant paragraph.\n    <\/p>\n    <p id={styles.critical.name}>\n      This is a critical paragraph.\n    <\/p>\n  <\/div>\n}<\/code><\/pre>\n\n\n\n

    We use styles.significant.name<\/code> as a CSS class name. Note that the styles.significant<\/code> property is not a string, but an object that has the name<\/code> property and the CSS class name. The property itself also provides access to the CSS Object Model rule, which allows direct rule manipulation; this, however, is outside of the scope of this article (although Louis Lazaris has a great article on it<\/a>).<\/p>\n\n\n\n

    If the styles are no longer needed, they can be deactivated which removes them from the DOM:<\/p>\n\n\n\n

    css.deactivate(styles);<\/code><\/pre>\n\n\n\n

    The CSS class and ID names are uniquely generated by Mimcss. The generation mechanism is different in development and production versions of the library. For example, for the significant<\/code> CSS class, the name is generated as MyStyles_significant<\/code> in the development version, and as something like n2<\/code> in the production version. The names are generated when the style definition class is activated for the first time and they remain the same no matter how many times the class is activated and deactivated. How the names are generated depends on in what class they were first declared and this becomes very important when we start inheriting style definitions.<\/p>\n\n\n

    Style definition inheritance<\/h3>\n\n\n

    Let’s look at a simple example and see what Mimcss does in the presence of inheritance:<\/p>\n\n\n\n

    class Base extends css.StyleDefinition\n{\n  pad4 = this.$class({ padding: 4 })\n}\nclass Derived extends Base\n{\n  pad8 = this.$class({ padding: 8 })\n}\nlet derived = css.activate(Derived);<\/code><\/pre>\n\n\n\n

    Nothing surprising happens when we activate the Derived<\/code> class: the derived<\/code> variable provides access to both the pad4<\/code> and the pad8<\/code> CSS classes. Mimcss generates a unique CSS class name for each of these properties. The names of the classes are Base_pad4<\/code> and Derived_pad8<\/code> in the development version of the library.<\/p>\n\n\n\n

    Interesting things start happening when the Derived<\/code> class overrides a property from the base class:<\/p>\n\n\n\n

    class Base extends css.StyleDefinition\n{\n  pad = this.$class({ padding: 4 })\n}\nclass Derived extends Base\n{\n  pad = this.$class({ padding: 8 })\n}\nlet derived = css.activate(Derived);<\/code><\/pre>\n\n\n\n

    There is a single name generated for the derived.pad.name<\/code> variable. The name is Base_pad<\/code>; however, the style is { padding: 8px }<\/code>. That is, the name is generated using the name of the base class, while the style is taken from the derived class.<\/p>\n\n\n\n

    Let’s try another style definition class that derives from the same Base<\/code> class:<\/p>\n\n\n\n

    class AnotherDerived extends Base\n{\n  pad = this.$class({ padding: 16 })\n}\nlet anotherDerived = css.activate(AnotherDerived);<\/code><\/pre>\n\n\n\n

    As expected, the anotherDerived.pad.name<\/code> has the value of Base_pad<\/code> and the style is { padding: 16px }<\/code>. Thus, no matter how many different derived classes we may have, they all use the same name for the inherited properties, but different styles are assigned to them. This is the key Mimcss feature that allows us to use style definition inheritance for theming.<\/p>\n\n\n

    Creating themes in Mimcss<\/h3>\n\n\n

    The main idea of theming in Mimcss is to have a theme declaration class that declares several CSS rules, and to have multiple implementation classes that are derived from the declaration while overriding these rules by providing actual styles values. When we need CSS class names, as well as other named CSS entities in our code, we can use the properties from the theme declaration class. Then we can activate either this or that implementation class and, voil\u00e0<\/em>, we can completely change the styling of our application with very little code.<\/p>\n\n\n\n

    Let\u2019s consider a very simple example that nicely demonstrates the overall approach to theming in Mimcss.: a theme simply defines the shape and style of an element\u2019s border.<\/p>\n\n\n\n

    First, we need to create the theme declaration class. Theme declarations are classes that derive from the ThemeDefinition<\/code> class, which itself derives from the StyleDefinition<\/code> class (there is an explanation why we need the ThemeDefinition<\/code> class and why themes should not derive directly from the StyleDefinition<\/code> class, but this is a topic for another day).<\/p>\n\n\n\n

    class BorderTheme extends css.ThemeDefinition\n{\n  borderShape = this.$class()\n}<\/code><\/pre>\n\n\n\n

    The BorderTheme<\/code> class defines a single CSS class, borderShape<\/code>. Note that we haven\u2019t specified any styles for it. We are using this class only to define the borderShape<\/code> property type, and let Mimcss create a unique name for it. In a sense, it is a lot like a method declaration in an interface\u2014it declares its signature, which should be implemented by the derived classes.<\/p>\n\n\n\n

    Now let\u2019s define two actual themes\u2014using SquareBorderTheme<\/code> and RoundBorderTheme<\/code> classes\u2014that derive from the BorderTheme<\/code> class and override the borderShape<\/code> property by specifying different style parameters.<\/p>\n\n\n\n

    class SquareBorderTheme extends BorderTheme\n{\n  borderShape = this.$class({\n    border: [\"thin\", \"solid\", \"green\"],\n    borderInlineStartWidth: \"thick\"\n  })\n}\n\nclass RoundBorderTheme extends BorderTheme\n{\n  borderShape = this.$class({\n    border: [\"medium\", \"solid\", \"blue\"],\n    borderRadius: 8 \/\/ Mimcss will convert 8 to 8px\n  })\n}<\/code><\/pre>\n\n\n\n

    TypeScript ensures that the derived classes can only override a property using the same type that was declared in the base class which, in our case, is an internal Mimcss type used for defining CSS classes. That means that developers cannot use the borderShape<\/code> property to mistakenly declare a different CSS rule because it leads to a compilation error.<\/p>\n\n\n\n

    We can now activate one of the themes as the default theme:<\/p>\n\n\n\n

    let theme: BorderTheme = css.activate(SquareBorderTheme);<\/code><\/pre>\n\n\n\n

    When Mimcss first activates a style definition class, it generates unique names for all of CSS entities defined in the class. As we have seen before, the name generated for the borderShape<\/code> property is generated once and will be reused when other classes deriving from the BorderTheme<\/code> class are activated.<\/p>\n\n\n\n

    The activate<\/code> function returns an instance of the activated class, which we store in the theme<\/code> variable of type BorderTheme<\/code>. Having this variable tells the TypeScript compiler that it has access to all the properties from the BorderTheme<\/code>. This allows us to write the following rendering code for a fictional component:<\/p>\n\n\n\n

    render()\n{\n  return <div>\n    <input type=\"text\" className={theme.borderShape.name} \/>\n  <\/div>\n}<\/code><\/pre>\n\n\n\n

    All that is left to write is the code that allows the user to choose one of the two themes and activate it.<\/p>\n\n\n\n

    onToggleTheme()\n{\n  if (theme instanceof SquareBorderTheme)\n    theme = css.activate(RoundBorderTheme);\n  else\n    theme = css.activate(SquareBorderTheme);\n}<\/code><\/pre>\n\n\n\n

    Note that we didn\u2019t have to deactivate the old theme. One of the features of the ThemeDefinition<\/code> class (as opposed to the StyleDefintion<\/code> class) is that for every theme declaration class, it allows only a single theme to be active at the same time. That is, in our case, either RoundBorderTheme<\/code> or SquareBorderTheme<\/code> can be active, but never both. Of course, for multiple theme hierarchies, multiple themes can be simultaneously active. That is, if we have another hierarchy with the ColorTheme<\/code> declaration class and the derived DarkTheme<\/code> and LightTheme<\/code> classes, a single ColorTheme<\/code>-derived class can be co-active with a single BorderTheme<\/code>-derived class. However, DarkTheme<\/code> and LightTheme<\/code> cannot be active at the same time.<\/p>\n\n\n

    Referencing Mimcss themes<\/h3>\n\n\n

    In the example we just looked at, we used a theme object directly but themes frequently define elements like colors, sizes, and fonts that can be referenced by other style definitions. This is especially useful for separating the code that defines themes from the code that defines styles for a component that only wants to use the elements defined by the currently active theme.<\/p>\n\n\n\n

    CSS custom properties are perfect for declaring elements from which styles can be built. So, let\u2019s define two custom properties in our themes: one for the foreground color, and one for the background color. We can also create a simple component and define a separate style definition class for it. Here is how we define the theme declaration class:<\/p>\n\n\n\n

    class ColorTheme extends css.ThemeDefinition\n{\n  bgColor = this.$var( \"color\")\n  frColor = this.$var( \"color\")\n}<\/code><\/pre>\n\n\n\n

    The $var<\/code> method defines a CSS custom property. The first parameter specifies the name of the CSS style property, which determines acceptable property values. Note that we don\u2019t specify the actual values here; in the declaration class, we only want Mimcss to create unique names for the custom CSS properties (e.g. --n13<\/code>) while the values are specified in the theme implementation classes, which we do next.<\/p>\n\n\n\n

    class LightTheme extends ColorTheme\n{\n  bgColor = this.$var( \"color\", \"white\")\n  frColor = this.$var( \"color\", \"black\")\n}\n\nclass DarkTheme extendsBorderTheme\n{\n  bgColor = this.$var( \"color\", \"black\")\n  frColor = this.$var( \"color\", \"white\")\n}<\/code><\/pre>\n\n\n\n

    Thanks to the Mimcss (and of course TypeScript\u2019s) typing system, developers cannot mistakenly reuse, say, the bgColor<\/code> property with a different type; nor they can specify values that are not acceptable for a color type. Doing so would immediately produce a compilation error, which may save developers quite a few cycles (one of the declared goals of Mimcss).<\/p>\n\n\n\n

    Let\u2019s define styles for our component by referencing the theme\u2019s custom CSS properties:<\/p>\n\n\n\n

    class MyStyles extends css.StyleDefinition\n{\n  theme = this.$use(ColorTheme)\n\n  container = this.$class({\n    color: this.theme.fgColor,\n    backgroundColor: this.theme.bgColor,\n  })\n}<\/code><\/pre>\n\n\n\n

    The MyStyles<\/code> style definition class references the ColorTheme<\/code> class by calling the Mimcss $use<\/code> method. This returns an instance of the ColorTheme<\/code> class through which all its properties can be accessed and used to assign values to CSS properties.<\/p>\n\n\n\n

    We don\u2019t need to write the var()<\/code> function invocation because it\u2019s already done by Mimcss when the $var<\/code> property is referenced. In effect, the CSS class for the container<\/code> property creates the following CSS rule (with uniquely generated names, of course):<\/p>\n\n\n\n

    .container {\n  color: var(--fgColor);\n  backgroundColor: var(--bgColor);\n}<\/code><\/pre>\n\n\n\n

    Now we can define our component (in pseudo-React style):<\/p>\n\n\n\n

    class MyComponent extends Component\n{\n  private styles = css.activate(MyStyles);\n\n  componentWillUnmount()\n  {\n    css.deactivate(this.styles);\n  }\n\n  render()\n  {\n    return <div className={this.styles.container.name}>\n      This area will change colors depending on a selected theme.\n    <\/div>\n  }\n}<\/code><\/pre>\n\n\n\n

    Note one important thing in the above code: our component is completely decoupled from the classes that implement actual themes. The only class our component needs to know about is the theme declaration class ColorTheme<\/code>. This opens a door to easily “externalize” creation of themes\u2014they can be created by third-party vendors and delivered as regular JavaScript packages. As long as they derive from the ColorTheme<\/code> class, they can be activated and our component reflects their values.<\/p>\n\n\n\n

    Imagine creating a theme declaration class for, say, Material Design<\/a> styles along with multiple theme classes that derive from this class. The only caveat is that since we are using an existing system, the actual names of the CSS properties cannot be generated by Mimcss\u2014they must be the exact names that the Material Design system uses (e.g. --mdc-theme--primary<\/code>). Thankfully, for all named CSS entities, Mimcss provides a way to override its internal name generation mechanism and use an explicitly provided name. Here is how it can be done with Material Design CSS properties:<\/p>\n\n\n\n

    class MaterialDesignThemeBase extends css.ThemeDefinition\n{\n  primary = this.$var( \"color\", undefined, \"mdc-theme--primary\")\n  onPrimary = this.$var( \"color\", undefined, \"mdc-theme--on-primary\")\n  \/\/ ...\n}<\/code><\/pre>\n\n\n\n

    The third parameter in the $var<\/code> call is the name, which is given to the CSS custom property. The second parameter is set to undefined<\/code> meaning we aren\u2019t providing any value for the property since this is a theme declaration, and not a concrete theme implementation.<\/p>\n\n\n\n

    The implementation classes do not need to worry about specifying the correct names because all name assignments are based on the theme declaration class:<\/p>\n\n\n\n

    class MyMaterialDesignTheme extends MaterialDesignThemeBase\n{\n  primary = this.$var( \"color\", \"lightslategray\")\n  onPrimary = this.$var( \"color\", \"navy\")\n  \/\/ ...\n}<\/code><\/pre>\n\n\n

    Multiple themes on one page<\/h3>\n\n\n

    As mentioned earlier, only a single theme implementation can be active from among the themes derived from the same theme declaration class. The reason is that different theme implementations define different values for the CSS rules with the same names. Thus, if multiple theme implementations were allowed to be active at the same time, we would have multiple definitions of identically-named CSS rules. This is, of course, a recipe for disaster.<\/p>\n\n\n\n

    Normally, having a single theme active at a time is not a problem at all\u2014it is likely what we want in most cases. Themes usually define the overall look and feel of the entire page and there is no need to have different page sections to use different themes. What if, however, we are in that rare situation where we do need to apply different themes to different parts of our page? For example, what if before a user chooses a light or dark theme, we want to allow them to compare the two modes side-by-side?<\/p>\n\n\n\n

    The solution is based on the fact that custom CSS properties can be redefined under CSS rules. Since theme definition classes usually contain a lot of custom CSS properties, Mimcss provides an easy way to use their values from different themes under different CSS rules.<\/p>\n\n\n\n

    Let\u2019s consider an example where we need to display two elements using two different themes on the same page. The idea is to create a style definition class for our component so that we could write the following rendering code:<\/p>\n\n\n\n

    public render()\n{\n  return <div>\n    <div className={this.styles.top.name}>\n      This should be black text on white background\n    <\/div>\n    <div className={this.styles.bottom.name}>\n      This should be white text on black background\n    <\/div>\n  <\/div>\n}<\/code><\/pre>\n\n\n\n

    We need to define the CSS top<\/code> and bottom<\/code> classes so that we redefine the custom properties under each of them taking values from different themes. We essentially want to have the following CSS:<\/p>\n\n\n\n

    .block {\n  backgroundColor: var(--bgColor);\n  color: var(--fgColor);\n}\n\n.block.top {\n  --bgColor: while;\n  --fgColor: black;\n}\n\n.block.bottom {\n  --bgColor: black;\n  --fgColor: white;\n}<\/code><\/pre>\n\n\n\n

    We use the block<\/code> class for optimization purposes and to showcase how Mimcss handles inheriting CSS styles, but it is optional.<\/p>\n\n\n\n

    Here is how this is done in Mimcss:<\/p>\n\n\n\n

    class MyStyles extends css.StyleDefinition\n{\n  theme = this.$use(ColorTheme)\n\n  block = this.$class({\n    backgroundColor: this.theme.bgColor,\n    color: this.theme.fgColor\n  })\n\n  top = this.$class({\n    \"++\": this.block,\n    \"--\": [LightTheme],\n  })\n\n  bottom = this.$class({\n    \"++\": this.block,\n    \"--\": [DarkTheme],\n  })\n}<\/code><\/pre>\n\n\n\n

    Just as we did previously, we reference our ColorTheme<\/code> declaration class. Then we define a helper block<\/code> CSS class, which sets the foreground and background colors using the custom CSS properties from the theme. Then we define the top<\/code> and bottom<\/code> classes and use the \"++\"<\/code> property to indicate that they inherit<\/em> from the block<\/code> class. Mimcss supports several methods of style inheritance; the \"++\"<\/code> property simply appends the name of the referenced class to our class name. That is, the value returned by the styles.top.name<\/code> is \"top block\"<\/code> where we\u2019re combining the two CSS classes (the actual names are randomly generated, so it would be something like \"n153 n459\"<\/code>).<\/p>\n\n\n\n

    Then we use the \"--\"<\/code> property to set values of the custom CSS variables. Mimcss supports several methods of redefining custom CSS properties in a ruleset; in our case, we just reference a corresponding theme definition class. This causes Mimcss to redefine all custom CSS properties found in the theme class with their corresponding values.<\/p>\n\n\n

    What do you think?<\/h3>\n\n\n

    Theming in Mimcss is intentionally based on style definition inheritance. We looked at exactly how this works, where we get the best of both theming worlds: the ability to use alternate stylesheets alongside the ability to swap out CSS property values using an object-oriented approach.<\/p>\n\n\n\n

    At runtime, Mimcss applies a theme without changing the HTML whatsoever. At build-time, Mimcss leverages the well-tried and easy-to-use class inheritance technique. Please check out the Mimcss documentation<\/a> for a much deeper dive on the things we covered here. You can also visit the Mimcss Playground<\/a> where you can explore a number of examples and easily try your own code.<\/p>\n\n\n\n

    And, of course, tell me what you think of this approach! This has been my go-to solution for theming and I\u2019d like to continue making it stronger based on feedback from developers like yourself.<\/p>\n","protected":false},"excerpt":{"rendered":"

    Theming UI refers to the ability to perform a change in visual styles in a consistent manner that defines the […]<\/p>\n","protected":false},"author":286838,"featured_media":287344,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"inline_featured_image":false,"c2c_always_allow_admin_comments":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"Defining and Applying UI Themes Using the Mimcss CSS-in-JS Library by Michael Michlin","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_share_on_mastodon":"0","_share_on_mastodon_status":"%title% %permalink%"},"categories":[4],"tags":[1535,17249,18719],"class_list":["post-355894","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-articles","tag-css-in-js","tag-inheritance","tag-theming"],"acf":{"show_toc":"No"},"share_on_mastodon":{"url":"","error":""},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/css-tricks.com\/wp-content\/uploads\/2019\/05\/squiggle-multicolor-2.svg","jetpack-related-posts":[{"id":254332,"url":"https:\/\/css-tricks.com\/css-custom-properties-theming\/","url_meta":{"origin":355894,"position":0},"title":"CSS Custom Properties and Theming","author":"Chris Coyier","date":"May 1, 2017","format":false,"excerpt":"We posted not long ago about the difference between native CSS variables (custom properties) and preprocessor variables. There are a few esoteric things preprocessor variables can do that native variables cannot, but for the most part, native variables can do the same things. But, they are more powerful because of\u2026","rel":"","context":"In "Articles"","block_context":{"text":"Articles","link":"https:\/\/css-tricks.com\/category\/articles\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":288127,"url":"https:\/\/css-tricks.com\/material-theming-making-material-your-own\/","url_meta":{"origin":355894,"position":1},"title":"Material Theming: Making Material Your Own!","author":"Una Kravets","date":"June 3, 2019","format":false,"excerpt":"The web is a beautiful, expressive medium that\u2019s evolved over time as trends and technology have changed. Moments of delight and flair are what set companies apart from one another. At the same time, today\u2019s top products rely on scalable, component-based design systems to efficiently develop a coherent brand. And\u2026","rel":"","context":"In "Articles"","block_context":{"text":"Articles","link":"https:\/\/css-tricks.com\/category\/articles\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2019\/05\/google-material.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2019\/05\/google-material.png?fit=1200%2C600&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2019\/05\/google-material.png?fit=1200%2C600&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2019\/05\/google-material.png?fit=1200%2C600&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2019\/05\/google-material.png?fit=1200%2C600&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":325393,"url":"https:\/\/css-tricks.com\/color-theming-with-css-custom-properties-and-tailwind\/","url_meta":{"origin":355894,"position":2},"title":"Color Theming with CSS Custom Properties and Tailwind","author":"Michelle Barker","date":"November 19, 2020","format":false,"excerpt":"Custom properties not only enable us to make our code more efficient, but allow us to work some real magic with CSS too. One area where they have huge potential is theming. At Atomic Smash we use Tailwind CSS, a utility class framework, for writing our styles. In this article,\u2026","rel":"","context":"In "Articles"","block_context":{"text":"Articles","link":"https:\/\/css-tricks.com\/category\/articles\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/11\/tailwind-custom-properties-color-theming.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/11\/tailwind-custom-properties-color-theming.png?fit=1200%2C600&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/11\/tailwind-custom-properties-color-theming.png?fit=1200%2C600&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/11\/tailwind-custom-properties-color-theming.png?fit=1200%2C600&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/11\/tailwind-custom-properties-color-theming.png?fit=1200%2C600&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":359033,"url":"https:\/\/css-tricks.com\/personalize-it\/","url_meta":{"origin":355894,"position":3},"title":"Personalize it!","author":"Una Kravets","date":"December 22, 2021","format":false,"excerpt":"Ensuring accessibility is a clear path to making your website better. When you make your site accessible, you grow your audience, improve the experience for all people using it (not just those with accessibility needs), and you get SEO benefits as well. Along the same lines, preference-query customization is another\u2026","rel":"","context":"In "2021 End-of-Year Thoughts"","block_context":{"text":"2021 End-of-Year Thoughts","link":"https:\/\/css-tricks.com\/category\/2021-end-of-year-thoughts\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/12\/G3-vugcmBuc3YZ1R6tls18nK7PGkfEOsUXUD7hyussUQs8LYiz-mp4iAccN5g6GT_O451LP3J4b1PkvKd4kbKYXfCMPU3iVpY5IDXf2yGXPeSgW_f401v99ZhgBF3gtLvW87hIcdemdPGByih2rHgHemsEEjxCU4JYaK_t-kWhA920IA.jpg?fit=1200%2C535&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/12\/G3-vugcmBuc3YZ1R6tls18nK7PGkfEOsUXUD7hyussUQs8LYiz-mp4iAccN5g6GT_O451LP3J4b1PkvKd4kbKYXfCMPU3iVpY5IDXf2yGXPeSgW_f401v99ZhgBF3gtLvW87hIcdemdPGByih2rHgHemsEEjxCU4JYaK_t-kWhA920IA.jpg?fit=1200%2C535&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/12\/G3-vugcmBuc3YZ1R6tls18nK7PGkfEOsUXUD7hyussUQs8LYiz-mp4iAccN5g6GT_O451LP3J4b1PkvKd4kbKYXfCMPU3iVpY5IDXf2yGXPeSgW_f401v99ZhgBF3gtLvW87hIcdemdPGByih2rHgHemsEEjxCU4JYaK_t-kWhA920IA.jpg?fit=1200%2C535&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/12\/G3-vugcmBuc3YZ1R6tls18nK7PGkfEOsUXUD7hyussUQs8LYiz-mp4iAccN5g6GT_O451LP3J4b1PkvKd4kbKYXfCMPU3iVpY5IDXf2yGXPeSgW_f401v99ZhgBF3gtLvW87hIcdemdPGByih2rHgHemsEEjxCU4JYaK_t-kWhA920IA.jpg?fit=1200%2C535&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/12\/G3-vugcmBuc3YZ1R6tls18nK7PGkfEOsUXUD7hyussUQs8LYiz-mp4iAccN5g6GT_O451LP3J4b1PkvKd4kbKYXfCMPU3iVpY5IDXf2yGXPeSgW_f401v99ZhgBF3gtLvW87hIcdemdPGByih2rHgHemsEEjxCU4JYaK_t-kWhA920IA.jpg?fit=1200%2C535&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":271218,"url":"https:\/\/css-tricks.com\/dark-theme-in-a-day\/","url_meta":{"origin":355894,"position":4},"title":"Dark theme in a day","author":"Robin Rendle","date":"May 21, 2018","format":false,"excerpt":"Marcin Wichary has written a great piece that dives into how he used CSS Variables to create a night mode and high contrast theme in an app. There\u2019s so many neat tricks about how to use CSS Variables (Chris has also looked at theming) as well as how to organize\u2026","rel":"","context":"In "Links"","block_context":{"text":"Links","link":"https:\/\/css-tricks.com\/category\/links\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/05\/dark-theme-in-a-day.jpg?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/05\/dark-theme-in-a-day.jpg?fit=1200%2C600&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/05\/dark-theme-in-a-day.jpg?fit=1200%2C600&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/05\/dark-theme-in-a-day.jpg?fit=1200%2C600&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/05\/dark-theme-in-a-day.jpg?fit=1200%2C600&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":259251,"url":"https:\/\/css-tricks.com\/using-custom-properties-modify-components\/","url_meta":{"origin":355894,"position":5},"title":"Using Custom Properties to Modify Components","author":"Robin Rendle","date":"August 18, 2017","format":false,"excerpt":"Instead of using custom properties to style whole portions of a website\u2019s interface I think we should use them to customize and modify tiny components. Here\u2019s why. Whenever anyone mentions CSS custom properties they often talk about the ability to theme a website\u2019s interface in one fell swoop. For example,\u2026","rel":"","context":"In "Articles"","block_context":{"text":"Articles","link":"https:\/\/css-tricks.com\/category\/articles\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/355894","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/users\/286838"}],"replies":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/comments?post=355894"}],"version-history":[{"count":10,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/355894\/revisions"}],"predecessor-version":[{"id":356648,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/355894\/revisions\/356648"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/media\/287344"}],"wp:attachment":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/media?parent=355894"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/categories?post=355894"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/tags?post=355894"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}