Maintaining a nimble front-end development environment with Material UI

Alicia Vissuet
rideOS
Published in
6 min readSep 5, 2019

At rideOS, we are always striving to improve our user experience, which includes our front-end interface. As we constantly update our services, we want to remain flexible while also maintaining consistency across our UI. Choosing a front-end framework that allowed us to do so was an important process in the development of our codebase. While we weighed our front-end framework options, we had several criteria for a library in mind.

First and foremost, we wanted something flexible and customizable. We organize our client-side codebase as a multi-package repository, so ideally, we also want the ability to share components and styles across applications. Sharing components allows us to remain consistent with styling and branding, but it also means that we want to maintain the ability to overwrite base styles with minimal effort as the need for individual customizations increases.

Previous Experimentations

Before fully committing to a library, we tested out a few options, one being Semantic UI. On paper, Semantic UI looked like a strong candidate for a few reasons — it is component-based, simple to use and is highly customizable. However, in practice, Semantic UI wasn’t the right fit as it was difficult to override Semantic UI’s built-in styling since everything inherited it’s default CSS properties. The Semantic UI library uses the !important property liberally, as well as other specificity selectors. At times, some of these CSS rules would leak into other, non-Semantic UI components that we were using as well. We needed a framework that allowed us to build custom components without inheriting CSS rules set by the framework as well as enabling us to easily customize the framework’s components through deeper levels of style specificity.

Shift to Material UI

Following experimentation with other libraries, we adopted another front-end styling framework earlier this year, Material UI (MUI). MUI is a React-specific front-end framework which offers an extensive list of easily customizable components that follow CSS rules and inherit methods generated by a base configuration object, referred to sometimes as the theme object. MUI dynamically injects CSS via CSS-in-JS, per component allowing us to keep styles contained within their components and easily create our own components without inheriting unwanted default CSS properties (solving the problem we were experiencing while using Semantic UI).

It is also worth mentioning that MUI allows users to easily follow the Material Design philosophy, part of which embodies the idea of surfaces, layers, and elevation. Material Design components are designed to feel like real world materials embodying physical principles such as light and movement.

Customizing MUI components

So how do we customize a MUI component? It depends on the level of customization that we are seeking. If we want to customize a component that is going to be re-used throughout the site, it is best to add the desired styles to our MUI theme object. However, for individual or unique customizations, MUI makes it easy to inject styles via the component by leveraging the following properties:

  • classes: MUI provides access to several styling APIs which allow developers to generate specialized style classes for unique situations.
  • className: Developers are then able to apply styling through class names generated by the MUI APIs or through other means on specific components. When approaching customizations in this manner, properties are persisted to the native element.
  • inline styles: Although we generally avoid this due to top-level specificity, it is still possible to directly apply CSS properties onto individual components via the styles property.

Let’s talk about creating a MUI theme object. When customizing a theme in MUI, one of the most basic styling choices is specifying a color palette. MUI will use the specified palette to globally assign the given colors to various components being used throughout the website.

The less information that is specified by the developer, the more is inferred by MUI. For example, if we are using a Button component and have not specified colors for that type of button, MUI will use the given color palette to determine how that button should look. MUI also allows for a deeper layer of specificity in detailing exactly how certain components look, while still maintaining thematic consistency. Here’s our button, let’s see how it changes as we work with the MUI theme object.

First we need to wrap our app in our MUI Theme:

Next, we can add our theme. We are going to leave this empty for now.

Here’s what our button looks like, which will now receive styling from our MUI theme.

An empty MUI theme means that Material UI will apply default styles and colors to our components. Our button will look like this:

MUI button component with default styling

Let’s add a basic palette to our MUI theme now.

A MUI theme with only a palette, but no component-specific styling, will apply our palette colors systematically to the components we use. Our button has now changed to reflect our palette:

MUI button with theme applied
MUI button with palette-specific colors

Finally, let’s add some specific styling to our button.

When receiving both a palette and component-specific styles, MUI uses the specific styling when possible and infer other, less-specified values from the palette and other defaults. Here’s how our Button component looks like now when rendered:

MUI button component with theme overrides

Maintaining styling consistencies with non-MUI components

Creating a MUI theme with specified values allows us to utilize MUI components that are styled exactly to our specifications. There are some cases in which we need our own, custom components that still maintain a sense of consistency with our MUI components. So how do we ensure these components look and feel similar to our MUI components?

One easy practice that we’ve adopted at rideOS is creating a configuration file that specifies a variety of style defaults that are shared across our websites (not to be confused with the MUI theme object).

In this configuration style, we describe a variety of default CSS properties that are used throughout our pages. This provides a few advantages. First, any time we make a systematic change to our website, an updated background color for example, this ensures we need to change that value in as few as places as possible which keeps our code nice and DRY. In addition, not only does our MUI theme receive values from this file, but so does any custom component that we create. This ensures that our components, whether custom or MUI provided, appear consistent throughout all of our web-pages.

Here is an example of a config file:

Now in our MUI Theme object, we can take our style properties from this file as appropriate:

Depending on the quantity of your web-pages, you could imagine this _constants.js file might get very large and potentially difficult to navigate. A solution to that is to break up the style declarations into files by category, i.e. _colors.js, _typography.js, _shape.js, etc. and then use the _constants.js file as the main source of export for each of these style constants. This makes it obvious to developers where things are living while maintaining the simplicity of a single import source for styles.

Now, if we have a custom component that does not use MUI, all we have to do is import our constants file and grab any value that is relevant to us. So easy!

Want to learn more about Material UI? Check out their docs: https://material-ui.com.

Both Mason Anders and Alicia Vissuet are a part of our front-end team and have been busy working on improvements to our web applications since they joined rideOS earlier this year. Mason and Alicia have different backgrounds, though coincidentally both are from Illinois and are both alumni of App Academy, a coding bootcamp in San Francisco. Diversity and inclusion are important aspects of the rideOS culture and rideOS makes a point to hire from a variety of backgrounds, including non-traditional career paths. Are you interested in joining rideOS? Checkout our current openings here: https://rideos.ai/careers.

--

--