Styling and theming with rmwc: React + Material Design
There are a couple of good material design libraries out there, and I’m going to build a basic site with
create-react-app to test out how to really make them work. Material design released a new version of their web components, and we’re going to look at a few React libraries that will help us use them.
Material Components for Web is a set of user interface components that help developers build web apps with material…material.io
These components were written in SASS and JS. There are various ways to customize them and build your design. We’re going to look at
rmwc today and show what it’s like to use it.
As it says in the description, this is a thin wrapper on top of Google’s work, which is nice to keep things in place and in sync.
The basic idea
Google’s framework itself works by extensive
CSS classes that you put onto your
HTML elements. Overall themes can be customized using
CSS variables to change, for example, the theme colors. You can also get into the
SCSS itself to change how things are generated. This is how most of the demonstration pages of the components are customized.
here are the full examples of how the catalog is used as provided by the Google mothership. material-components-web.appspot.com
Basically though, we are going to bring in the material
css, add the correct
css classes to style our components, and use regular
css to help lay things out. If we want to go crazy we can start using the
rmwc library basically bridges the gap between the
DOM tweaking stuff that React and the Material design library does.
Create the app
yarn add rmwc webfontloader react-helmet
src/index.js lets make sure that we include
css that’s included from the
material-components-web. Also, lets pull in some fonts from Google, both Roboto as well as the Material Design Icons.
Add some components
Lets add a quick Toolbar on the top of the page, putting this file in
src/navbar.js. A few things to note here:
- Everything is exported from
rmwcdirectly, its clear where to import from. (This is a preview of
material-uiwhich I’ll cover later.)
- We’re using the Material UI Icon fonts, and this is done using ligatures. What this means is that we pass in the name of the icon (“menu”, “print”, and “account_circle”) that will be rendered as text until the font is loaded. At that point, the text will be replaced as an icon, so it’s a nice experience.
Now lets throw in a quick
login.js which shows an example of how to pop up a dialog, put a form it in with a couple of text fields. Couple of notes here:
handleChangeis a function that returns a function that, when called as part of an
- I was having trouble using all of the
Dialogcomponents to make a custom Dialog as specified in the docs so I’m doing this body trick of passing in a function. This seems like a bug.
Let’s also create a
drawer.js file that we can use as a sliding nav menu. This is ripped directly from the docs and doesn’t do anything, but it’s fun to have in there.
Lets build out a basic feed page so we can get some stuff on the screen.
Now we can tie it all together with an updated
App.js. Here we are tying our components together
And finally, lets get some basic
css in place so that the Drawer doesn’t take up any vertical space when closed. (Also, I’m sure I could be using flex box better, but I’m learning as I go.)
That’s a lot of boiler plate to get through! But we have the basics of something simple, so lets start playing around with what can be done. This is what you should see:
CSS Custom Properties
One simple way to change the colors and look and feed of things is to use CSS Custom Properties. Basically, we’ll inject some specific CSS rules and it will change the primary, accent, and other colors of the site. These variables are documented in the material design site, and this method means that we’ll need to set each one individually, the light and dark variants aren’t calculated.
Lets change our feed item to use
react-helment to set some styles dynamically. I’m going to pass in the primary and secondary color options to each feed item, and when you click a button there, it passes it up to the main feed component to inject it into the head element using react-helmet. I picked the colors using the material design color picker, which is a fun tool that helps you understand the theming options.
And here’s an example of what that looks like:
So with the basic setup, you have access to the CSS file that comes pre-generated with the material-components-web package, CSS variables that help set overall colors and theming options, and you’re own CSS file that you can use to do layout and specific design tweaks. What if that’s not enough?
(If you are running on a Chromebook, follow the instructions here to get
node-sass to install correctly.) Otherwise we start with the instructions from the
First we add node-sass and a utility package to our environment
yarn add node-sass-chokidar node-run-app
package.json we change the scripts around to watch and process our scss files.
"build-css": "node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/",
"watch-css": "npm run build-css && node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/ --watch --recursive",
"start-js": "react-scripts start",
"start": "npm-run-all -p watch-css start-js",
"build-js": "react-scripts build",
"build": "npm-run-all build-css build-js",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
index.js lets remove the line that imports the compiled sass file from the material-web-components directory, just delete
Now lets rename
index.scss and at the top add:
$mdc-theme-primary: #9c27b0; // Purple 500
$mdc-theme-secondary: #ffab40; // Orange A200
$mdc-theme-background: #fff; // White
App.js lets go back to the
feed_basic import, so we don’t override the theme using css variables. This is what you should get:
Now you have full access to building your own version of the
material-web-components using the
sass functionality that it was built with!
You can find the final code here.
Where does that leave us
Building off of the google work directly is pretty cool. There are a lot of other tools that are included that help make sense of what material design is, and what it can do for you.
Here are a few awesome things that also come from the Material design mother ship:
- Material Design Color Tool
- Remixer — Collaborate on app design in real-time
- Gallery — Design workflow
- Resizer — An interactive viewer that helps designers test material design breakpoints across desktop, mobile, and tablet.
- Device Metrics
- Stage — Define dynamic interfaces with interactive motion
Next time we’ll look at how to do the same thing with http://material-ui-next.com/