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 |
What are Material Design and Material Components for the Web?
Material Design is a system for building bold and beautiful digital products. By uniting style, branding, interaction, and motion under a consistent set of principles and components, product teams can realize their greatest design potential.
For desktop and the mobile web, Material Components Web (MDC Web) unites design and engineering with a library of components for creating consistency across apps and websites. MDC Web components each live in their own node modules, so as the Material Design system evolves, these components can be easily updated to ensure consistent pixel-perfect implementation and adherence to Google's front-end development standards. MDC is also available for Android, iOS, and Flutter.
In this codelab, you'll build a login page using several of MDC Web's components.
What you'll build
This codelab is the first of three codelabs that will guide you through building an app called Shrine, an e-commerce website that sells clothing and home goods. It will demonstrate how you can customize components to reflect any brand or style using MDC Web.
In this codelab, you'll build a login page for Shrine that contains:
- Two text fields, one for entering a username and the other for a password
- Two buttons, one for "Cancel" and one for "Next"
- The name of the website (Shrine)
- An image of Shrine's logo
MDC Web components in this codelab
- Text field
- Button
- Ripple
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
We're always looking to improve our tutorials. 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 within the material-components-web-codelabs-master/mdc-101/starter
directory. Be sure to cd
into that directory before beginning.
...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-101/starter
Install project dependencies
From the starter directory, run:
npm install
You will see a lot of activity and at the end, your terminal should show a successful install:
If it doesn't, run npm audit fix
.
Run the starter app
In the same directory, run:
npm start
The webpack-dev-server
will start. Point your browser to http://localhost:8080/ to see the page.
Success! The starter code for Shrine's login page should be running in your browser. You should see the name "Shrine" and the Shrine logo just below it.
Take a look at the code
Metadata in index.html
In the starter directory, open index.html
with your favorite code editor. It should contain this:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Shrine (MDC Web Example App)</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" sizes="192x192" href="https://material.io/static/images/simple-lp/favicons/components-192x192.png">
<link rel="shortcut icon" href="https://material.io/static/images/simple-lp/favicons/components-72x72.png">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/normalize/6.0.0/normalize.min.css">
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700" rel="stylesheet">
<link rel="stylesheet" href="bundle-login.css">
</head>
<body class="shrine-login">
<section class="header">
<svg class="shrine-logo" ...>
...
</svg>
<h1>SHRINE</h1>
</section>
<form action="home.html">
</form>
<script src="bundle-login.js" async></script>
</body>
</html>
Here, a <link>
tag is used to load the bundle-login.css
file which was generated by webpack, and a <script>
tag includes the bundle-login.js
file. In addition, we include normalize.css for consistent cross-browser rendering, as well as the Roboto font from Google Fonts.
Custom styles in login.scss
MDC Web components are styled using mdc-*
CSS classes, such as the class mdc-text-field
. (MDC Web treats its DOM structure as part of its public API.)
In general, it's recommended that you make custom style modifications to components using your own classes. You might have noticed some custom CSS classes in the HTML above, such as shrine-logo
. These styles are defined in login.scss
to add basic styles to the page.
Open login.scss
and you'll see the following styles for the login page:
@import "./common";
.header {
text-align: center;
}
.shrine-logo {
width: 150px;
height: 150px;
padding-top: 80px;
fill: currentColor;
}
Now that you're familiar with the starter code, let's implement our first component.
3. Add text fields
To begin, we'll add two text fields to our login page, where people will be able to enter their username and password. We'll use the MDC Text Field component, which includes built-in functionality that displays a floating label and activates a touch ripple.
Install the MDC Text Field
MDC Web components are published via NPM packages. To install the package for the text field component, run:
npm install @material/textfield@^6.0.0
Add the HTML
In index.html
, add the following inside the <form>
element in the body:
<label class="mdc-text-field mdc-text-field--filled username">
<span class="mdc-text-field__ripple"></span>
<input type="text" class="mdc-text-field__input" aria-labelledby="username-label" name="username">
<span class="mdc-floating-label" id="username-label">Username</span>
<span class="mdc-line-ripple"></span>
</label>
<label class="mdc-text-field mdc-text-field--filled password">
<span class="mdc-text-field__ripple"></span>
<input type="password" class="mdc-text-field__input" aria-labelledby="password-label" name="password">
<span class="mdc-floating-label" id="password-label">Password</span>
<span class="mdc-line-ripple"></span>
</label>
The MDC Text Field DOM structure is composed of several parts:
- The main element,
mdc-text-field
- Subelements
mdc-text-field__ripple,
mdc-text-field__input
,mdc-floating-label
, andmdc-line-ripple
Add the CSS
In login.scss
, add the following import statement after the existing import:
@import "@material/textfield/mdc-text-field";
In the same file, add the following styles to align and center the text fields:
.username,
.password {
display: flex;
margin: 20px auto;
width: 300px;
}
Add the JavaScript
Open up login.js
, which is currently empty. Add the following code to import and instantiate the Text Fields:
import {MDCTextField} from '@material/textfield';
const username = new MDCTextField(document.querySelector('.username'));
const password = new MDCTextField(document.querySelector('.password'));
Add HTML5 validation
Text Fields express if the field input is valid or contains an error, by using attributes provided by HTML5's form validation API.
You should:
- Add the
required
attribute to themdc-text-field__input
elements of both the Username and Password text fields - Set the
minlength
attribute of themdc-text-field__input
element of the Password text field to"8"
Adjust the two <label class="mdc-text-field mdc-text-field--filled">
elements to look like this:
<label class="mdc-text-field mdc-text-field--filled username">
<span class="mdc-text-field__ripple"></span>
<input type="text" class="mdc-text-field__input" aria-labelledby="username-label" name="username" required>
<span class="mdc-floating-label" id="username-label">Username</span>
<span class="mdc-line-ripple"></span>
</label>
<label class="mdc-text-field mdc-text-field--filled password">
<span class="mdc-text-field__ripple"></span>
<input type="password" class="mdc-text-field__input" aria-labelledby="password-label" name="password" required minlength="8">
<span class="mdc-floating-label" id="password-label">Password</span>
<span class="mdc-line-ripple"></span>
</label>
Refresh the page at http://localhost:8080/. You should now see a page with two text fields for Username and Password!
Click on the text fields to check out the floating label animation and the line ripple animation (the bottom border line that ripples outwards):
4. Add buttons
Next, we'll add two buttons to our login page: "Cancel" and "Next." We'll use the MDC Button component, along with the MDC Ripple component, to complete the iconic Material Design ink ripple effect.
Install MDC Button
To install the package for the button component, run:
npm install @material/button@^6.0.0
Add the HTML
In index.html
, add the following below the closing tag of the <label class="mdc-text-field mdc-text-field--filled password">
element:
<div class="button-container">
<button type="button" class="mdc-button cancel">
<div class="mdc-button__ripple"></div>
<span class="mdc-button__label">
Cancel
</span>
</button>
<button class="mdc-button mdc-button--raised next">
<div class="mdc-button__ripple"></div>
<span class="mdc-button__label">
Next
</span>
</button>
</div>
For the "Cancel" button, we're using the default button style. However, the "Next" button uses a raised style variant, which is indicated by the mdc-button--raised
class.
To easily align them later, we wrap the two mdc-button
elements in a <div>
element.
Add the CSS
In login.scss
, add the following import statement after the existing imports:
@import "@material/button/mdc-button";
To align the buttons and add a margin around them, add the following styles to login.scss
:
.button-container {
display: flex;
justify-content: flex-end;
width: 300px;
margin: auto;
}
.button-container button {
margin: 3px;
}
Add an ink ripple to the buttons
When the user touches or clicks a button, it should display feedback in the form of an ink ripple. The ink ripple component requires JavaScript, so we'll add that to the page.
To install the package for the ripple component, run:
npm install @material/ripple@^6.0.0
At the top of login.js
, add the following import statement:
import {MDCRipple} from '@material/ripple';
To instantiate the ripples, add the following to login.js
:
new MDCRipple(document.querySelector('.cancel'));
new MDCRipple(document.querySelector('.next'));
Because we don't need to retain a reference to the ripple instance, there's no need to assign it to a variable.
That's it! Refresh the page. An ink ripple will display when you click each button.
Fill in the text fields with valid values, and press the "NEXT" button. You did it! You'll continue working on this page in MDC-102.
5. Recap
Using basic HTML markup and just a few lines of CSS and JavaScript, the Material Components for the web library has helped you create a beautiful login page that conforms to the Material Design guidelines, and looks and behaves consistently across all devices.
Next steps
Text Field, Button, and Ripple are three core components in the MDC Web library, but there are many more! You can also explore the rest of the components in MDC Web.
You can head over to MDC-102: Material Design Structure and Layout to learn about the navigation drawer and image list. Thanks for trying Material Components. We hope you enjoyed this codelab!