1. Introduction
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
- Button
- Select
- Text field
What you'll need
- A recent version of Node.js (which comes bundled with npm, a JavaScript package manager).
- The sample code (to be downloaded in the next step)
- Basic knowledge of HTML, CSS, and JavaScript
How would you rate your level of experience with web development?
2. Set up your development environment
Download the starter codelab 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:
3. Update the button
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 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, add the mdc-button
and mdc-button--raised
classes, and nest the label within a <span>
element with the mdc-button__label
class:
<button type="submit" class="mdc-button mdc-button--raised">
<div class="mdc-button__ripple"></div>
<span class="mdc-button__label">Save</span>
</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 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.
4. Update the select element
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 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>
Right above the <select>
tag, add the following markup for the MDC Select component's drop-down arrow:
<i class="mdc-select__dropdown-icon"></i>
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">
<i class="mdc-select__dropdown-icon"></i>
<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.
5. Update the text fields
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 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 _theme.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.
6. Recap
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.