Material Components (MDC) help developers implement Material Design. Created by a team of engineers and UX designers at Google, MDC features dozens of beautiful and functional UI components and is available for Android, iOS, web and Flutter.

material.io/develop

Material Components for the web (MDC Web) are framework-agnostic, built using regular JavaScript. This helps make MDC Web work seamlessly with your development process. These components can be installed as needed to help make agile design improvements in your existing app.

What you'll build

In this codelab, you'll replace some existing components in a form with ones provided by MDC Web:

MDC Web components in this codelab

What you'll need

How would you rate your level of experience with web development?

Novice Intermediate Proficient

Download the starter codelab app

Download starter app

The starter app is located in the material-components-web-codelabs-master/mdc-111/starter directory. Be sure to cd into that directory before you start.

...or clone it from GitHub

To clone this codelab from GitHub, run the following commands:

git clone https://github.com/material-components/material-components-web-codelabs
cd material-components-web-codelabs/mdc-111/starter

Install project dependencies

From the starter directory (material-components-web-codelabs/mdc-111/starter), run:

npm install

You will see a lot of activity and at the end, your terminal should show a successful install:

Run the starter app

In the starter directory, run:

npm start

The webpack-dev-server will start. Point your browser to http://localhost:8080/ to see the page.

Success! You should see the app's shipping address form:

Install MDC Button

Press Ctrl+C to kill the development server. Then, install the MDC Button NPM package and restart the server:

npm install @material/button@0.40.0
npm start

Import the CSS

At the top of _theme.scss, delete the .crane-button { ... } block, and add the following in its place:

$mdc-theme-primary: $crane-primary-color;

@import "@material/button/mdc-button";

Update the markup

In index.html, remove the crane-button class from the <button> element, and add the mdc-button and mdc-button--raised classes:

<button type="submit" class="mdc-button mdc-button--raised">Save</button>

Add the ripple

MDC Buttons can be used without JavaScript. However, adding an interactive ripple to the button creates a richer user experience.

Press Ctrl+C to kill the development server. Then run:

npm install @material/ripple@0.40.0
npm start

Add the following import statement to the top of app.js:

import {MDCRipple} from '@material/ripple';

To instantiate the ripple on the button, add the following to the bottom of app.js:

new MDCRipple(document.querySelector('.mdc-button'));

Import Roboto font

By default, Material Design uses Roboto for component typefaces.

In index.html, import the Roboto Web font by adding the following to the <head> element:

<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700">

Reload the page, and you should see something like this:

The button now displays subtle ripple effect as visual feedback when pressed.

The MDC Select component wraps a native HTML <select> element. Use it wherever you would normally use a <select>. Let's update the "State" field.

Install MDC Node module

Press Ctrl+C to kill the development server. Then run:

npm install @material/select@0.40.0
npm start

Import the CSS

Add the following to _theme.scss, just after the button import:

@import "@material/select/mdc-select";

Update markup

Locate the <select> element in index.html. Replace the crane-input class with mdc-select__native-control:

<select class="mdc-select__native-control" id="crane-state-input" required>

Just below the closing </select> tag, replace the crane-label class with mdc-floating-label:

<label class="mdc-floating-label" for="crane-state-input">

Then add the following markup immediately after the label:

<div class="mdc-line-ripple"></div>

Finally, add the following tags around the <select> element (but inside the crane-field element):

<div class="mdc-select">
  ...
</div>

The resulting markup should look like this:

<div class="crane-field">
  <div class="mdc-select">
    <select class="mdc-select__native-control" id="crane-state-input" required>
      <option value="" selected></option>
      <option value="AL">Alabama</option>
      ...
      <option value="WI">Wisconsin</option>
      <option value="WY">Wyoming</option>
    </select>
    <label class="mdc-floating-label" for="crane-state-input">
      State
    </label>
    <div class="mdc-line-ripple"></div>
  </div>
</div>

Import the JS

Add the following import statement to the top of app.js:

import {MDCSelect} from '@material/select';

To instantiate the select, add the following to the bottom of app.js:

new MDCSelect(document.querySelector('.mdc-select'));

Reload the page, which should now look like this:

The MDC Select component presents a list of options for the user in a familiar format, but with modern styling.

Material Design text fields have major usability gains over plain <input> elements. They are designed to be easy to identify within complicated content, and display subtle visual feedback when the user interacts with them.

Install MDC Node module

Press Ctrl+C to kill the development server. Then run:

npm install @material/textfield@0.40.0
npm start

Add the CSS

Add the following to _theme.scss, just after the select import:

@import "@material/textfield/mdc-text-field";

Update the markup

In index.html, locate the <input> element for the "Name" field. Replace the crane-input class with mdc-text-field__input:

<input class="mdc-text-field__input" id="crane-name-input" type="text" required autofocus>

Next, replace the crane-label class with mdc-floating-label:

<label class="mdc-floating-label" for="crane-name-input">

Then add the following markup immediately after the label:

<div class="mdc-line-ripple"></div>

Finally, wrap all 3 elements with the following:

<div class="mdc-text-field">
  ...
</div>

The resulting markup should look like this:

<div class="crane-field">
  <div class="mdc-text-field">
    <input class="mdc-text-field__input" id="crane-name-input"
           type="text" required autofocus>
    <label class="mdc-floating-label" for="crane-name-input">
      Name
    </label>
    <div class="mdc-line-ripple"></div>
  </div>
</div>

Repeat the same procedure for all other <input> elements on the page.

The markup for the "Address", "City" and "ZIP Code" fields should look like this:

<div class="crane-field">
  <div class="mdc-text-field">
    <input class="mdc-text-field__input" id="crane-address-input" type="text" required>
    <label class="mdc-floating-label" for="crane-address-input">
      Address
    </label>
    <div class="mdc-line-ripple"></div>
  </div>
</div>
<div class="crane-field">
  <div class="mdc-text-field">
    <input class="mdc-text-field__input" id="crane-city-input" type="text" required>
    <label class="mdc-floating-label" for="crane-city-input">
      City
    </label>
    <div class="mdc-line-ripple"></div>
  </div>
</div>
<div class="crane-field">
  <div class="mdc-text-field">
    <input class="mdc-text-field__input" id="crane-zip-code-input"
            type="text" required minlength="5" maxlength="5" pattern="[0-9]*">
    <label class="mdc-floating-label" for="crane-zip-code-input">
      ZIP Code
    </label>
    <div class="mdc-line-ripple"></div>
  </div>
</div>

You can now remove the .crane-label and .crane-input styles from app.scss, which are no longer used.

Import the JS

Add the following import statement to the top of app.js:

import {MDCTextField} from '@material/textfield';

To instantiate the text fields, add the following to the bottom of app.js:

const textFieldElements = [].slice.call(document.querySelectorAll('.mdc-text-field'));
textFieldElements.forEach((textFieldEl) => {
  new MDCTextField(textFieldEl);
});

Reload the page, which should now look like this:

The text fields have now all been updated to use Material Theming.

You've replaced some common components (text fields, select, and button) without doing a complete redesign of your app. Great job!

Other components that can also make a big difference include the top app bar and navigation drawer.

Next steps

You can explore even more components in MDC Web by visiting the MDC Web catalog.

If you are interested in using MDC Web with a particular framework, head over to MDC-112: Integrating MDC with Web Frameworks.

I was able to complete this codelab with a reasonable amount of time and effort

Strongly agree Agree Neutral Disagree Strongly disagree

I would like to continue using Material Components in the future

Strongly agree Agree Neutral Disagree Strongly disagree