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

In codelabs MDC-101 and MDC-102, you used Material Components (MDC) to build the basics of an app called Shrine, an e-commerce app that sells clothing and home goods. This app's user flow starts with a login screen, which then takes the user to a home screen containing products.

Material Design recently expanded to give designers and developers increased flexibility to express their product's brand. In this code lab, you'll use MDC to customize the Shrine app to reflect the brand's unique style in more ways than ever before.

What you'll build

In this codelab, you'll customize Shrine to reflect its brand using:

MDC Web components and subsystems used in this codelab

What you'll need

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

Novice Intermediate Proficient

Continuing from MDC-102?

If you completed MDC-102, your code should be ready to go for this codelab. Skip to step 3: Change the color.

Download the starter codelab app

Download starter app

The starter app is located within the material-components-web-codelabs-master/mdc-103/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-103/starter

Install project dependencies

From the starter directory material-components-web-codelabs/mdc-103/starter (it should be your current directory if you follow the above step), 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 same 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 Shrine's login page running in your browser. Fill in the Username and Password fields, and click the "Next" button to go to the home page. It should display a navigation drawer on the left, next to a grid of product images.

While the navigation drawer is functional, let's make it match the Shrine brand by changing its color, elevation, and typography.

This color theme has been created by a designer with custom colors (shown in the image below). It contains colors that have been selected from Shrine's brand and applied to the Material Theme Editor, which has expanded them to create a fuller palette. (These colors aren't from the 2014 Material color palettes.)

Let's change the color of the Shrine app's navigation drawer to reflect that color scheme.

Override the theme colors

Create a new file named _variables.scss, containing the following:

$mdc-theme-primary: #FEDBD0;
$mdc-theme-on-primary: #442C2E;
$mdc-theme-secondary: #FEEAE6;
$mdc-theme-on-secondary: #442C2E;
$mdc-theme-surface: #FFFBFA;
$mdc-theme-on-surface: #442C2E;
$mdc-theme-background: #FFFFFF;
$mdc-theme-on-background: #442C2E;

Then import it at the very top of _common.scss:

@import "./variables";

Add CSS styling to the navigation drawer

In home.scss, add the following import statement after the existing imports:

@import "@material/ripple/mixins";

Then add the following styles, creating the .shrine-drawer class:

.shrine-drawer {
  @include mdc-drawer-fill-color-accessible(primary);
  // Drawer defaults to a higher z-index, but we aren't overlaying it over anything
  @include mdc-drawer-z-index(0);

  text-transform: uppercase;

  .mdc-list {
    margin: 70px 5px auto 5px;
  }

  .mdc-list-item {
    border-radius: 6px;
    justify-content: center;
  }

  // This needs 3-class specificity to override MDC Drawer styles
  .mdc-list .mdc-list-item {
    @include mdc-states-activated(#fff);
  }
}

Refresh the page at http://localhost:8080/home.html. Your home screen should now look like this:

Let's change the color of the login screen to match our color scheme.

Add CSS styling to the login page

In login.scss, add the following lines:

.shrine-login {
  background-color: $mdc-theme-background;
  color: $mdc-theme-on-background;
}

.cancel {
  @include mdc-button-ink-color(on-primary);
}

Also, add the following mixin invocations inside the .username, .password CSS selector:

.username,
.password {
  &:not(.mdc-text-field--invalid) {
    @include mdc-text-field-label-color(on-primary);
  }
  &.mdc-text-field--focused:not(.mdc-text-field--invalid)  {
    @include mdc-text-field-label-color(on-primary);
  }
  ...
}

Refresh the page at http://localhost:8080/. Your login screen should now look like this:

In addition to color changes, your designer has also given you specific typography to use on the site. Let's add that to the navigation drawer too.

To install the package for Typography, run:

npm install @material/typography@0.39.0

Add the CSS for typography

In home.scss, add the following import statement after the existing imports:

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

Then add the following mixin invocation to the shrine-title class:

.shrine-title {
  @include mdc-typography(headline6);
  ...
}

Next, let's style the drawer items.

Add a line separator

In home.html, add the following just under the <a ...>Featured</a> list item:

<li class="shrine-select-item-divider mdc-list-divider" role="separator"></li>

Add the following styles to home.scss:

.shrine-select-item-divider {
  display: block;
  border-bottom-color: #EAA4A4;
  border-bottom-width: 2px;
  width: 50px;
  position: relative;
  top: -8px;
}

// This needs 2-class specificity to override MDC Drawer styles
.shrine-drawer .shrine-select-item-divider {
  margin: 0 auto;
}

Adjust the image items and labels

To adjust the items and labels, add the following styles to home.scss within the .product-list selector:

.product-list {
  ...

  .mdc-image-list__supporting {
    justify-content: center;
  }

  .mdc-image-list__item {
    padding: 10px;
  }

  .mdc-image-list__label {
    @include mdc-typography(subtitle2);
  }
}

Refresh the page. Your home screen should now look like this:

Now that you've styled the page with Shrine's specific coloring and typography, let's look at the image list showing Shrine's products. Let's draw attention to the products by giving them more emphasis.

To install the package for Elevation, run:

npm install @material/elevation@0.40.0

Add the import statement

In home.scss, add the following line after the last import statement:

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

Wrap the image list with a new div

In home.html, add the following markup around the <ul> element:

<div class="shrine-body">
 <ul...>
</div>

Change elevation using Sass mixins

In home.scss, add the following:

.shrine-body {
  @include mdc-elevation(4);

  display: block;
  overflow: auto;
  z-index: 0; // Elevate over the drawer
}

Impressive! You've added a shadow to the left edge of the white surface behind the image list items, so that it appears to float slightly above the navigation.

Next, let's change the layout to show images at different aspect ratios and sizes, so that each image looks unique against the others.

Modify the HTML

In home.html, update the mdc-image-list element to contain the mdc-image-list--masonry class:

<ul class="mdc-image-list mdc-image-list--masonry product-list">

Add images

In home.html, change each img element's src attribute to match the images located in the assets folder. Then, update the label text for each image. When completed, it should look like this:

    <ul class="mdc-image-list mdc-image-list--masonry product-list">
      <li class="mdc-image-list__item">
        <img class="mdc-image-list__image" src="assets/ginger-scarf.jpg">
        <div class="mdc-image-list__supporting">
          <span class="mdc-image-list__label">Ginger scarf</span>
        </div>
      </li>
      <li class="mdc-image-list__item">
        <img class="mdc-image-list__image" src="assets/blue-stone-mug.jpg">
        <div class="mdc-image-list__supporting">
          <span class="mdc-image-list__label">Blue stone mug</span>
        </div>
      </li>
      <li class="mdc-image-list__item">
        <img class="mdc-image-list__image" src="assets/cerise-scallop.jpg">
        <div class="mdc-image-list__supporting">
          <span class="mdc-image-list__label">Cerise scallop tee</span>
        </div>
      </li>
      <li class="mdc-image-list__item">
        <img class="mdc-image-list__image" src="assets/chambray-napkins.jpg">
        <div class="mdc-image-list__supporting">
          <span class="mdc-image-list__label">Chambray napkins</span>
        </div>
      </li>
      <li class="mdc-image-list__item">
        <img class="mdc-image-list__image" src="assets/fine-lines.jpg">
        <div class="mdc-image-list__supporting">
          <span class="mdc-image-list__label">Fine lines tee</span>
        </div>
      </li>
      <li class="mdc-image-list__item">
        <img class="mdc-image-list__image" src="assets/garden-strand.jpg">
        <div class="mdc-image-list__supporting">
          <span class="mdc-image-list__label">Garden strand</span>
        </div>
      </li>
      <li class="mdc-image-list__item">
        <img class="mdc-image-list__image" src="assets/gatsby-hat.jpg">
        <div class="mdc-image-list__supporting">
          <span class="mdc-image-list__label">Gatsby hat</span>
        </div>
      </li>
      <li class="mdc-image-list__item">
        <img class="mdc-image-list__image" src="assets/gilt-desk-trio.jpg">
        <div class="mdc-image-list__supporting">
          <span class="mdc-image-list__label">Gilt desk trio</span>
        </div>
      </li>
      <li class="mdc-image-list__item">
        <img class="mdc-image-list__image" src="assets/kitchen-quattro.jpg">
        <div class="mdc-image-list__supporting">
          <span class="mdc-image-list__label">Kitchen quattro</span>
        </div>
      </li>
      <li class="mdc-image-list__item">
        <img class="mdc-image-list__image" src="assets/seabreeze-sweater.jpg">
        <div class="mdc-image-list__supporting">
          <span class="mdc-image-list__label">Seabreeze sweater</span>
        </div>
      </li>
      <li class="mdc-image-list__item">
        <img class="mdc-image-list__image" src="assets/shrug-bag.jpg">
        <div class="mdc-image-list__supporting">
          <span class="mdc-image-list__label">Shrug bag</span>
        </div>
      </li>
      <li class="mdc-image-list__item">
        <img class="mdc-image-list__image" src="assets/stella-sunglasses.jpg">
        <div class="mdc-image-list__supporting">
          <span class="mdc-image-list__label">Stella sunglasses</span>
        </div>
      </li>
      <li class="mdc-image-list__item">
        <img class="mdc-image-list__image" src="assets/surf-and-perf.jpg">
        <div class="mdc-image-list__supporting">
          <span class="mdc-image-list__label">Surf and perf shirt</span>
        </div>
      </li>
      <li class="mdc-image-list__item">
        <img class="mdc-image-list__image" src="assets/vagabond-sack.jpg">
        <div class="mdc-image-list__supporting">
          <span class="mdc-image-list__label">Vagabond sack</span>
        </div>
      </li>
      <li class="mdc-image-list__item">
        <img class="mdc-image-list__image" src="assets/walter-henley.jpg">
        <div class="mdc-image-list__supporting">
          <span class="mdc-image-list__label">Walter henley (white)</span>
        </div>
      </li>
      <li class="mdc-image-list__item">
        <img class="mdc-image-list__image" src="assets/weave-keyring.jpg">
        <div class="mdc-image-list__supporting">
          <span class="mdc-image-list__label">Weave keyring</span>
        </div>
      </li>
    </ul>

Update the CSS

In home.scss, remove the mdc-image-list-standard-columns(4) mixin and replace it with the following mixin:

@include mdc-image-list-masonry-columns(4);

Then add the following padding values to the product-list class in home.scss:

.product-list {
  ...
  padding: 80px 100px 0;
}

Your code should now match the code included in the complete/ folder.

One final request from your designer is to create a dark theme for Shrine, for users who may want to view the text with more contrast. A dark theme also provides an opportunity for user testing: if more users select the dark theme, it might mean it's the preferred way to view your site.

Modify CSS

In _variables.scss, replace the variables you declared for the primary theme with the following:

$mdc-theme-primary: #FFCF44;
$mdc-theme-on-primary: #33333D;
$mdc-theme-secondary: #FFCF44;
$mdc-theme-on-secondary: #FFFFFF;
$mdc-theme-surface: #33333D;
$mdc-theme-on-surface: #FFFFFF;
$mdc-theme-background: #33333D;
$mdc-theme-on-background: #FFFFFF;

In login.scss, remove the mixins in the .username, .password selector. It should look like the following:

.username,
.password {
  display: block;
  width: 300px;
  margin: 20px auto;
}

Additionally, update the mdc-button-ink-color mixin invocation in the .cancel class:

@include mdc-button-ink-color(on-surface);

In home.scss, add the following rules to the .home class:

background-color: $mdc-theme-background;
color: $mdc-theme-on-background;

Within the .shrine-drawer selector, update the mdc-drawer-fill-color-accessible invocation, and add a rule to override the border:

@include mdc-drawer-fill-color-accessible(surface);
...
border-right-width: 0;

Change the colors used in the .shrine-select-item-divider selector by replacing the border-bottom-color property with the mdc-theme-prop mixin:

.shrine-select-item-divider {
  @include mdc-theme-prop(border-bottom-color, primary);
  ...
}

Finally, remove the mdc-elevation mixin used earlier under the .shrine-body selector.

Build and run. The dark theme login page should now appear in your browser.

Now navigate to http://localhost:8080/home.html to see changes to the home.html page.

You've now created an app that resembles your designer's specifications.

Next steps

You've now used the following MDC components: theme, typography, elevation, and shape. You can explore more components and subsystems in the MDC Web Catalog.

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