An Exploration of Theme Styles

Customization is king. If something can be changed, it most likely will be. Giving users the tools to create their own custom experiences is crucial to the success of any platform, and theming is just one facet of that in Reaction.

A theme brings a unified look and feel to an application through visual components, such as templates, styles, layouts, and color schemes. In Reaction, themes are a subset of plugins that focus on modifying the appearance and UX of the platform. We've been exploring different ways to go about this.

In this post, we'll be going through the three different options for styling themes, evaluating the pros and cons of each, and previewing our very own theme editor, which presents a possible solution to the problems of the current landscape.

The Problem

Some people might want to style things locally. Others might want to style just a few things really quickly. Some people might want to use different UI frameworks, while others might want to make their own theme entirely. And that's the problem: there are 50 different approaches to styling, and not every platform provides a solution for all of them.

How do we create a theme editor that suits everyone’s needs?

Different Strokes

In our current environment, there are typically three different ways to go about building a theme.

Plain old CSS

Skip all the fancy stuff and build your theme with just CSS. When writing CSS, you don't have to preprocess the markup before you can use it. However, you'll have a rough time once the complexity of your style sheets grow.

If you plan on making some quick overrides, CSS is a good choice. Otherwise, you'll probably want more power.

Here is an example of CSS:

:root {
  --component-bg: #ff00ff;
}

.my-component {
  background-color: var(--component-bg);
}

Preprocessors

Preprocessors like SASS, LESS, and Sylus are fantastic tools that give us more control over CSS, as well as access to features not present in the CSS spec, while still compiling down to standard CSS.

Here is an example of SCSS:

$component-bg: #ff00ff;

.my-component {
  background-color: $component-bg
}

These preprocessed languages are very identical to vanilla CSS. The disadvantage of these tools may not be as apparent at first glance. Your SCSS or LESS may still need to be built, and will eventually just become CSS. Once it's built, you cannot change the properties dynamically. Most of the time, this works, but in some cases, you'll have to assume direct control.

If you're going to go with the plain ol' CSS or preprocessor route, simply drop your CSS / LESS files in the custom/client directory at the base of the app, or create your own package.

CSS in JS

CSS in JS is an approach to styling where a CSS-like object is placed in our JavaScript source and applied directly to the elements as inline styles. The following example is a very basic approach to CSS in JS with regards to React components:

import React, { Component } from "react";

const styles = {  
  base: {
    backgroundColor: "#ff00ff"
  }
};

class MyComponent extends Component {  
  render() {
    return (
      <div style={styles.base}>{"My Component!"}</div>
    );
  }
}

Some may do a double take at this approach, since it's certainly uncommon. Not only is there a substantial amount of styling involved with CSS in JavaScript Source, but you're also using inline styles. I mean, what is this? An HTML email?!

However, this approach really shines when you need the upmost control for your components. With this approach, you stop thinking of your style sheets as static assets, and more like dynamic properties, which you can use to manipulate the appearance of objects on screen. This can be especially helpful for dynamically-changing colors, font sizes, and dimensions of an element onscreen, all of which change based on incoming data from user interaction.

There are disadvantages to this approach, but also many benefits to theming. Take, for example, this comparison between SCSS and JSON:

// SCSS
.my-component {
  background-color: $component-bg
}


// JS
const styles = {  
  myComponent: {
    backgroundColor: componentBg // Where componentBg is a JS variable
  }
}

There's not much difference in syntax, but what you get from the JS version is the ability to dynamically manipulate styles for components on the fly. Attributes stored elsewhere, like a database, for example, can be loaded on the layout for a specific page, all without having to preprocess another static version of your stylesheet.

For your React components, you can use import and Radium to help with auto-prefixing and media queries.

Now wouldn't it be handy to have an extendible platform that supports all three styling options?

Adding Themes in Reaction

With Reaction in mind, we aim to allow as many different possibilities for theming. We want to provide options for those who prefer plain CSS, preprocessors, or even React components. To learn more about creating a theme in Reaction, visit our docs.

As a developer, this is all well and good when you're working on your local machine. But what about theming when your shop is already live? Our soon-to-come theme editor is going to solve that problem next.

A Preview of our Theme Editor

The theme editor will give users a way to build or modify their themes through an interface in the Reaction Admin. It sits somewhere between the three approaches listed above: CSS, preprocessers, and CSS in JS.

It works by taking a CSS file, converting it to JSON using postcss-js, and building a user interface to edit that JSON file. On save, that JSON is converted back to CSS and stored in the database. When the theme is published, we take all of the styles related to that theme, and publish them for the shop.

The key here is simplicity. CSS is the simplest of all the approaches, and here, the CSS file is only used to give the editor its UI. In this case, all other quality of life improvements come from the editor, not the preprocessor. So, to make it as easy as possible to build the UI for the theme editor, we went with CSS.

Here's an example of the file structure for the theme editor:

/**
 * @theme base
 * @label Buttons
 * @component button
 * @name button
 * @author Reaction Commerce
 * @url https://reactioncommerce.com
 */

.rui.button {
  /**
   * @label Button
   */
  background-color: --;
  color: --;
}

.rui.button:hover {
  /**
   * @label Button Hover (Mouse Over)
   */
  background-color: --;
  color: --;
}

.rui.button:active {
  /**
   * @label Button Active (On Click)
   */
   background-color: --;
   color: --;
}

Okay, but what does this really mean?

Now, not only will you have many options to style your shop, but you'll also be able to theme more intuitively. If you have a static theme, you can use standard CSS, SCSS, LESS or some other preprocessor to customize the look and feel. Or, if you're building or importing a theme, you'll soon be able to customize it through our dashboard Theme Editor. Making layout adjustments, updating branding in your marketplace, and changing colors for seasonal promotions is about to get a whole lot easier.

Conclusion

There are many different ways to theme: plain ol' CSS, preprocessors, and React components. Which one is right for you? It all boils down to the type of experience you're looking to have. Regardless, with many different approaches toward achieving your goals, the sky's the limit.

Wanna contribute to our themes? We're going to be working on our marketplace functionality in the coming months, and we encourage you to build and take part. Learn more via GitHub.

comments powered by Disqus