Skip to main contentCarbon Design System

2. Building pages

Now that we have our app using the UI Shell, it’s time to build a few static pages. In this step, we’ll become comfortable with the Carbon grid and various Carbon components.

Preview

A preview of what you’ll build:

Fork, clone and branch

This tutorial has an accompanying GitHub repository called carbon-tutorial-web-components that we’ll use as a starting point for each step. If you haven’t forked and cloned that repository yet, and haven’t added the upstream remote, go ahead and do so by following the [step 1 instructions](previous step.

Branch

With your repository all set up, let’s check out the branch for this tutorial step’s starting point.

git fetch upstream
git checkout -b step-2 upstream/step-2

Note: This builds on top of step 1, but be sure to check out the upstream step 2 branch because it includes the static assets required to get through this step.

Build and start app

Install the app’s dependencies (in case you’re starting fresh in your current directory and not continuing from the previous step):

pnpm i

Then, start the app:

pnpm dev

You should see something similar to where the previous step left off.

Add landing page grid

Let’s add our grid elements to our

LandingPage
page component.

Now the Carbon grid does not currently exist in web component form. This may be because it is difficult to apply a CSS grid when traversing the shadow DOM of a grid and column component. This leaves us with writing our grid and columns out long hand, writing the styles ourselves, or using javascript utility to add classes to our columns.

For the purposes of this tutorial the classes are written out long hand. In

In

index.html
replace
LANDING PAGE
with

<div class="page page-landing cds--css-grid cds--css-grid--full-width">
<div class="page-landing__banner cds--css-grid-column cds--col-span-100">
1
</div>
<div class="page-landing__r2 cds--css-grid-column cds--col-span-100">
<div class="cds--subgrid cds--subgrid--full-wide">
<div
class="page-landing__tab-content cds--css-grid-column cds--sm:col-span-4 cds--md:col-span-4 cds--lg:col-span-7">
7/16

Grid education There are many options for the Carbon Grid. For more information review 2x Grid on the Carbon Design System website. If apply classes manually it is also well worth checking out the CSS Grid Demo to

Then import the grid styles in

style.scss
.

@use '@carbon/styles/scss/grid';

In order to use the grid, we need to wrap everything in a

cds--css-grid
. Because we’re building with the new CSS Grid, we won’t be using typical rows. We have used a combination of
cds--css-grid-column
classes to create our layout.

The CSS Grid is a 16 column grid. The column widths and positions are specified using a combination of

cds--BP:col-span-N
and
cds--BP:col-start-N
classes. Where BP is the Carbon breakpoint and N is column count or starting position. For example,
<div class="cds-lg:col-start-9 cds-lg:col-span-8" >
means the column will start at column 9 and span 8 columns when the large (lg) breakpoint is active. large breakpoint.

We’ve included the designs for this tutorial app in the

design.figma
file found as a top-level file in the
carbon-tutorial
repository. But, if you don’t have Figma installed and available to inspect the design, we’ll provide screenshots.

Landing page grid

Landing page grid

Pro tip:

SHIFT-G
toggles the layout in Figma.

Build landing page

We’ll start adding HTML elements and components by row.

First row

Banner vertical spacing

Banner vertical spacing

In our first row we’ll need a

Breadcrumb
component. First, let’s import the components we need.

import '@carbon/web-components/es/components/breadcrumb/index';

We can now add our component to the first row, replace the content of the

div
with class
page-landing__banner
with:

<cds-breadcrumb noTrailingSlash aria-label="Page navigation">
<cds-breadcrumb-item>
<a href="./">Getting started</a>
</cds-breadcrumb-item>
</cds-breadcrumb>
<h1 class="page-landing__heading">Design &amp; build with Carbon</h1>

Second row

In our second row we’ll need

Tabs
and
Button
components. Add the following import:

import '@carbon/web-components/es/components/tabs/index';

The tabs come next going inside

page-landing__r2
and before the sub
cds--subgrid
.

<cds-tabs value="about" class="page-landing__tabs">
<cds-tab id="tab-about" value="about" target="panel-about">About</cds-tab>
<cds-tab id="tab-design" value="design" target="panel-design">Design</cds-tab>
<cds-tab id="tab-develop" value="develop" target="panel-develop"
>Develop</cds-tab
>
</cds-tabs>

Each of the

cds-tab
components has a
target
attribute. This is used to identify the content visible when that tab is selected.

Wrap the subgrid element immediately after the closing

</cds-tabs>
with the following. This is where we will place our first tab panel.

<div id="panel-about" role="tabpanel" aria-labelledby="tab-about">
... grid element is here
</div>

Replace the content of the first column

7/16
with:

<h3 class="page-landing__subheading">What is Carbon?</h3>
<p class="page-landing__p">
Carbon is IBM’s open-source design system for digital products and
experiences. With the IBM Design Language as its foundation, the system
consists of working code, design tools and resources, human interface
guidelines, and a vibrant community of contributors.
</p>
<cds-button>Learn more</cds-button>

The second column content

8/16
is replaced with:

<img
class="page-landing__illo"
src="./tab-illo.png"
alt="Carbon illustration"
width="640"
height="498" />

The

tab-illo.png
image is already located in the
public
folder.

After the closing

</div>
of
id="panel-about"
, still inside
page-landing__r2
we add two further tab panels. This one

<div id="panel-design" role="tabpanel" aria-labelledby="tab-design">
<div class="cds--subgrid cds--subgrid--full-wide">
<div
class="cds--css-grid-column cds--sm:col-span-4 cds--md:col-span-8 cds--lg:col-span-16">
<div class="page-landing__tab-content">
<p class="page-landing__p">
Rapidly build beautiful and accessible experiences. The Carbon kit
contains all resources you need to get started.
</p>

and

<div id="panel-develop" role="tabpanel" aria-labelledby="tab-develop">
<div class="cds--subgrid cds--subgrid--full-wide">
<div
class="cds--css-grid-column cds--sm:col-span-4 cds--md:col-span-8 cds--lg:col-span-16">
<div class="page-landing__tab-content">
<p class="page-landing__p">
Carbon provides components and styles for all. Whether using Vanilla,
Web Components, React, or another reactive library, you can build with
Carbon.

Third row

Here we replace all four columns entirely adding some offsets for medium and large column sizes after the first column.

<div
class="page-landing__label cds--css-grid-column cds--sm:col-span-4 cds--md:col-span-2 cds--lg:col-span-4">
The principles
</div>
<div
class="page-landing__title cds--css-grid-column cds--sm:col-span-4 cds--md:col-span-6 cds--md:col-start-3 cds--lg:col-span-4 cds--lg:col-start-5">
Carbon is open
</div>
<div

Style landing page

First row

Row one styling is fairly straight forward with some typography and positional adjustment so to align it with our other content.

.page {
padding: 0;
> * {
padding-inline: $spacing-06;
margin: 0;
}
}

Second row

The styling for the second row adds further layout and typography changes. It also positions the image and prevents it from causing horizontal overflow. In order to make use of the Carbon SCSS mixin

breakpoint-down
we also add the breakpoint import to our list of
@use
near the top of the file.

@use '@carbon/styles/scss/breakpoint' as *; /* add near top of file */
.page-landing__illo {
max-width: 100%;
float: inline-end;
height: auto;
}
@include breakpoint-down(md) {

Third row

.page-landing__r3 {
padding-block: $spacing-09;
background: $layer-01;
}

Ta-da! You should see a step 2 complete landing page! Now we can move on to the repo page.

Build repo page

Add a grid to contain our content

Now in our

repositories
page we will first add a grid wrapping
REPOSITORIES PAGE

<div class="page page-repositories cds--css-grid cds--css-grid--full-width">
<div class="repo-page__r1 cds--css-grid-column cds--col-span-100">
REPOSITORIES PAGE
</div>
</div>

Add a minimal amount of styling to move our content away from the edge of the page in

style.scss
.

.repo-page__r1 {
padding-block: $spacing-05;
}

Adding a table

Before we can add the table we need to import the web component. As this is only used in our

repositories.html
page lets create a new script file
repos.js
and then add.

import '@carbon/web-components/es/components/data-table/index.js';

We need to include this file in

repositories.html
which we can do by adding the following next to the script tag that includes
main.js
.

<script type="module" src="/repos.js"></script>

Next we add the table header and column titles to replace the text

REPOSITORIES PAGE

<cds-table expandable>
<cds-table-header-title slot="title"
>Carbon Repositories</cds-table-header-title
>
<cds-table-header-description slot="description"
>A collection of public Carbon repositories.</cds-table-header-description
>
<cds-table-head>
<cds-table-header-row>

The table header should already be visible on the repositories page.

Now we can add the rows replacing

Table body goes here
with:

<cds-table-row>
<cds-table-cell>Repo 1</cds-table-cell>
<cds-table-cell>Date</cds-table-cell>
<cds-table-cell>Date</cds-table-cell>
<cds-table-cell>123</cds-table-cell>
<cds-table-cell>456</cds-table-cell>
<cds-table-cell>Links</cds-table-cell>
</cds-table-row>
<cds-table-expanded-row>Repo description</cds-table-expanded-row>

Using HTML templates

With the app running we can see that the repositories page now hosts a table. However, it is not realistic to populate a table with hard coded data way so we’ll refactor to build the table from data.

This involves the use of HTML Templates, take a look at W3 Schools if you need a quick refresh.

In

index.html
remove the contents of the
<cds-table-body>
tag and return it to
Table body goes here
.

Then before the end of the html tag and after the body closing tag add the following to define our table row template.

<template id="template--table-row">
<cds-table-row>
<cds-table-cell key="name">Repo 1</cds-table-cell>
<cds-table-cell key="created">Date</cds-table-cell>
<cds-table-cell key="updated">Date</cds-table-cell>
<cds-table-cell key="openIssues">123</cds-table-cell>
<cds-table-cell key="stars">456</cds-table-cell>
<cds-table-cell key="links">Links</cds-table-cell>
</cds-table-row>

Next in

repos.js
add the following data that we will use to populate the table rows.

// cds-table-row data
let data = [
{
name: 'Repo A',
created: 'Date',
updated: 'Date',
openIssues: 123,
stars: 456,
links: 'Links',

Next we create the function

updateTable
and make a call to it to populate add our rows.

const updateTable = () => {
const tableRowTemplate = document.querySelector(
'template#template--table-row'
);
const tableBody = document.querySelector('cds-table-body');
if (tableBody && tableRowTemplate) {
tableBody.innerHTML = '';
// iterate over data and render rows
data.forEach((row) => {

Verify that the table rows are being generated by changing the data and running the app.

Congratulations! We’ve now created our static repo page!

Push to GitHub

That is it you are done. Just one more push to save your completion of step 2.

Git commit and push

First, stage and commit all of your changes:

git add --all && git commit -m "feat(tutorial): complete step 2"

Then, push to your repository:

git push -u origin step-2

Note: If your Git remote protocol is HTTPS instead of SSH, you may be prompted to authenticate with GitHub when you push changes. If your GitHub account has two-factor authentication enabled, we recommend that you follow these instructions to create a personal access token for the command line. That lets you use your token instead of password when performing Git operations over HTTPS.