Skip to main contentCarbon Design System

2. Building pages

Now that we have a Vue 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.


A preview of what you’ll build:

Fork, clone and branch

This tutorial has an accompanying GitHub repository called carbon-tutorial-vue 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.


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 vue-step-2 upstream/vue-step-2

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):


Then, start the app:

yarn serve

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

Install grid

In our last step we added our styles, component and icon packages. Now that we’re building the pages with grid, we need to install one more Carbon package. Stop your development environment (CTRL-C) and:

yarn add @carbon/grid

In _carbon.scss, we need to configure our grid to use 16 columns instead of the default 12 columns. We do this by adding grid-columns-16: true in our $feature-flags.

$feature-flags: (
grid-columns-16: true

Run yarn serve so we can begin building.

Add landing page grid

Let’s add our grid elements to LandingPage.vue.

In order to use the grid, we need to wrap everything in a <div class="bx--grid">. We can continue to make rows by adding a <div class="bx--row"> inside the grid, as well as make columns within those rows by adding <div class="bx--col-[breakpoint]-[size]">.

Our column sizes are specified by the number of columns they’ll be spanning. If we use bx--col-lg-4, it means it’ll span 4 of the 16 columns. If we use bx--col-lg-8 it means it’ll span 8 of the 16 columns, and so on.

We’ve included the designs for this tutorial app in the design.sketch file found as a top-level file in the carbon-tutorial-vue repository. But, if you don’t have Sketch installed and available to inspect the design, we’ll provide screenshots.

Landing page grid

Landing page grid

We’ll break this down into three rows. The first row with the gray background doesn’t appear to need any columns. The second row with the white background looks like it has two columns of different widths. The third row with the gray background looks like it has four columns of equal width.

We’ll make rows like so:

<div class="bx--grid bx--grid--full-width landing-page">
<div class="bx--row landing-page__banner">
<div class="bx--col-lg-16">1</div>
<div class="bx--row landing-page__r2">
<div class="bx--col-md-4 bx--col-lg-7">7/16</div>
<div class="bx--col-md-4 bx--offset-lg-1 bx--col-lg-8">8/16</div>

We added a class of bx--grid--full-width to the grid container since our rows need to expand the whole page without any margins. We also added some custom classes like landing-page, landing-page__banner, landing-page__r2, etc., which we will use later.

Also, take notice of the second row. The tab content only covers 7 columns at this large viewport to prevent overly-large line lengths, so we needed to add a 1 column offset bx--offset-lg-1 to second column to fill the full 16 columns in the grid. Then, both of those columns have bx--col-md-4 classes so they are of equal width at medium-sized viewports.

Build landing page

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

First row

In our first row we’ll use a CvBreadcrumb component.

We can now add our component to the first row, along with a header, like so:

<div class="bx--row landing-page__banner">
<div class="bx--col-lg-16">
<cv-breadcrumb noTrailingSlash>
<cv-link href="/">Getting started</cv-link>
<h1 class="landing-page__heading">Design &amp; build with Carbon</h1>

You may notice that the styles look off. Don’t worry, we’ll fix these later.

Second row

In our second row we’ll use CvTabs and CvButton components.

Modify the second row to use the Tab component.

<div class="bx--row landing-page__r2">
<div class="bx--col bx--no-gutter">
<cv-tabs selected="0">
<cv-tab label="About">
<div class="bx--grid bx--grid--no-gutter bx--grid--full-width">
<div class="bx--row landing-page__tab-content">
<div class="bx--col-md-4 bx--col-lg-7">7/16</div>
<div class="bx--col-md-4 bx--offset-lg-1 bx--col-lg-8">8/16</div>

Hold up! If you were to run DAP to check for accessibility violations, you’d see Multiple navigation landmarks must have unique labels specified with aria-label or aria-labelledby because both the CvBreadcrumb and CvTabs components use <nav> elements. To fix, add aria-label to the CvBreadcrumb opening tag:

<cv-breadcrumb noTrailingSlash aria-label="Page navigation">

Same goes for the CvTabs opening tag:

<cv-tabs selected="0" aria-label="Tab navigation">

Give yourself a pat on the back if you actually ran the DAP tool. We’ll install the DAP tool in a later step, so don’t worry if you didn’t.

Next, we’ll need to add a styling override to move the tabs to the right on large viewports. Create a file _carbon-overrides.scss in src/views/LandingPage with this declaration block.

.landing-page__r2 .bx--tabs__nav {
right: 0;

Then in LandingPage.vue add a style section with this import.

<style lang="scss">
@import "./carbon-overrides";