Bootstrap 4:Responsive Web Design
上QQ阅读APP看书,第一时间看更新

Creating a settings page

Moving on with our web app example, it is time to create a settings page for the application. We have already created a link for this in the navigation bar, inside the button group. Do you remember?

So, in the same folder as that of the web app HTML file, create another one named settings.html and update the link at the navigation bar:

<div id="nav-options" class="btn-group pull-right hidden-xs">
  <button type="button" class="btn btn-default dropdown-toggle thumbnail" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
    <img src="imgs/jon.png">
  </button>
  <ul class="dropdown-menu">
    <li><a href="#">Profile</a></li>
 <li><a href="settings.html">Setting</a></li>
    <li role="separator" class="divider"></li>
    <li><a href="#">Logout</a></li>
  </ul>
</div>

In this page, we use the same template that we used in the web application, copying the navigation bar, the grid layout, and the left-hand side #profile column. So, the settings page will look like this:

Creating a settings page

Now we will add some content to this page. Our main goal here is to use some other navigation Bootstrap components that will be handy for us.

Pills of stack

The first navigation menu that we will use here is Pills, using the vertical stack option. Pills are a Bootstrap component used to create menus that can be horizontal or vertical. Many web apps use them for side menus, just as we will soon do.

The basic usage for navigation components is the use of the .nav class followed by another one regarding the navigation option. In our case, we will use the .nav-pills class to create the desired effect in conjunction with the .nav-stacked class to vertically stack the pills. Create a .card element just after #profile and add the code related to the pills navigation:

<div id="profile-settings" class="card">
  <ul class="nav nav-pills nav-stacked">
    <li role="presentation" class="active">
      <a href="#">
        Account
        <span class="glyphicon glyphicon-chevron-right pull-right" aria-hidden="true"></span>
      </a>
    </li>
    <li role="presentation">
      <a href="#">
        Security
        <span class="glyphicon glyphicon-chevron-right pull-right" aria-hidden="true"></span>
      </a>
    </li>
    <li role="presentation">
      <a href="#">
        Notifications
        <span class="glyphicon glyphicon-chevron-right pull-right" aria-hidden="true"></span>
      </a>
    </li>
    <li role="presentation">
      <a href="#">
        Design
        <span class="glyphicon glyphicon-chevron-right pull-right" aria-hidden="true"></span>
      </a>
    </li>
  </ul>
</div>

In the CSS file, also add the following rule:

.row .card + .card {
  margin-top: 2rem;
}

With this, every .card element followed by another .card element will automatically create a margin, because of the use of the + selector. Open the settings page, and you will see the result like what is shown in the following screenshot:

Pills of stack

Basically, we created a list with the mentioned classes: .nav, .nav-pills, and .nav-stacked. The list is composed of four items, containing a link and a left arrow icon. To place the arrows at the right-hand side, we again used the .pull-right helper together with the .glyphicon-chevron-right icon. In the first item, we added the .active class, which turned this item blue and changed the colors of both the text and the icon.

This is almost awesome! It just needs some adjustments in the CSS to look perfect. Let's use some :nth-child selectors to style some elements based on their position, such as the first item in the menu (:first-child) and the last item (:last-child). Add the following CSS:

#profile-settings .nav-stacked li {
  border-bottom: 1px solid #e5e5e5;
  margin: 0;
}

#profile-settings .nav-stacked a {
  border-radius: 0;
}

#profile-settings .nav-stacked li:first-child a {
  border-radius: 0.4rem 0.4rem 0 0;
}


#profile-settings .nav-stacked li:last-child {
  border-bottom: 0;
}



#profile-settings .nav-stacked li:last-child a {
  border-radius: 0 0 0.4rem 0.4rem;
}

We just removed unwanted margins and the border radius, while adding a border bottom to all elements in the list, except the last one. This is because of the #profile-settings .nav-stacked li:last-child selector, where we a specific rule only for the last item element.

We also changed border-radius for the first element and the last element to create a rounded border in the pill list. The .nav-pill menu will appear like what is shown in the next screenshot:

Pills of stack

Tabs in the middle

In the #main column, we must create a tab option with the settings content. Bootstrap also offers a tabs component with the navigation components. First, we will work with the markup and CSS style and use it with JavaScript.

Therefore, inside the #main tag, place the following markup, corresponding to the Bootstrap tabs:

<ul id="account-tabs" class="nav nav-tabs nav-justified">
  <li role="presentation" class="active">
    <a href="#account-user">User info</a>
  </li>
  <li role="presentation">
    <a href="#account-language">Language</a>
  </li>
  <li role="presentation">
    <a href="#account-mobile">Mobile</a>
  </li>
</ul>

Just like the Pills, to use tabs, create a list with the .nav and .nav-tabs classes. We used the .nav-justified class as well to make the tabs equally distributed over the component.

Moreover, we populated the list with some items. Each link of the item contains an identifier, which will be used to link each tab to the corresponding content. Keep that information at the moment.

Let's add some CSS rules to keep the same border colors that we are using:

#account-tabs > li {
  border-bottom: 0.1rem solid #e5e5e5;
}

#account-tabs a {
  border-bottom: 0;
}

#account-tabs li.active {
  border-bottom: 0;
}

Refresh the web page and you should see it like this:

Tabs in the middle

Adding the tab content

To add the tab content, we use the named tab panes. Each tab must be placed in an element with the .tab-pane class and have the corresponding identifier in the tab component. After the tab list, add the HTML code for the tab panes:

 <ul id="account-tabs" class="nav nav-tabs nav-justified">
  <li role="presentation" class="active">
    <a href="#account-user">User info</a>
  </li>
  <li role="presentation">
    <a href="#account-language">Language</a>
  </li>
  <li role="presentation">
    <a href="#account-mobile">Mobile</a>
  </li>
</ul>

<div class="tab-content">
 <div role="tabpanel" class="tab-pane active" id="account-user">
 User info tab pane
 </div>
 <div role="tabpanel" class="tab-pane" id="account-language">
 Language tab pane
 </div>
 <div role="tabpanel" class="tab-pane" id="account-mobile">
 Mobile tab pane
 </div>
</div>

Refresh the web page and you will see only the content of #account-user appearing, although clicking on other tabs will not cause any switch between them. This is because we have not initialized the component through JavaScript yet.

Using the Bootstrap tabs plugin

We can initialize the tabs with simple JavaScript code, like what is presented next. However, we will do that in a smarter way using data markup:

$('#account-tabs a').click(function (e) {
  e.preventDefault()
  $(this).tab('show')
})

For data markup, we must add the data-toggle="tab" attribute on the link elements, inside the list. Change the list markup for the following:

<ul id="account-tabs" class="nav nav-tabs nav-justified">
  <li role="presentation" class="active">
    <a href="#account-user" data-toggle="tab">User info</a>
  </li>
  <li role="presentation">
    <a href="#account-language" data-toggle="tab">Language</a>
  </li>
  <li role="presentation">
    <a href="#account-mobile" data-toggle="tab">Mobile</a>
  </li>
</ul>

Note

If you are using pills, add the data-toggle="pill" attribute, just as we did for tabs.

Refresh the web browser and switch between the tabs. It works like a charm! To make it even fancier, add the .fade class to each .tab-pane to create a fade effect when changing tabs.

Creating content in the user info tab

Inside the .tab-pane identified by #account-user, let's add some content. Since it is a configuration menu, we will create a form to set the user settings. Again, we will work with some forms in Bootstrap. Do you remember how to use them?

In the form, we will have three inputs (name, username, and e-mail) followed by a button to save the changes. We will use the .form-horizontal class to make each form input next its label and stacked by each other. So, place the following code inside the #account-user element:

<div id="account-user" role="tabpanel" class="tab-pane active" >
  <form class="form-horizontal">
    <div class="form-group">
      <label class="col-sm-3 control-label">Name</label>
      <div class="col-sm-9">
        <input type="text" class="form-control" value="Jonny Doo">
      </div>
    </div>
    <div class="form-group">
      <label class="col-sm-3 control-label">Username</label>
      <div class="col-sm-9">
        <div class="input-group">
          <div class="input-group-addon">@</div>
          <input type="text" class="form-control" value="jonnydoo">
        </div>
      </div>
    </div>
    <div class="form-group">
      <label class="col-sm-3 control-label">Email</label>
      <div class="col-sm-9">
        <input type="email" class="form-control" value="jonnydoo@dogmail.com">
      </div>
    </div>
    <div class="form-group">
      <div class="col-sm-offset-3 col-sm-9">
        <button type="submit" class="btn btn-primary">
          Save changes
        </button>
      </div>
    </div>
  </form>
</div>

Break through the code, we set the labels to fill a quarter of the form row, while the input fills the rest. We again used the input groups to add the @ sign before the username field.

Each label has the .col-sm-3 class and the input the .col-sm-9 class. As we said, the forms respect the grid system layout, so we can apply the same classes here. We also added the .col-sm-offset-3 class to the submit button for a correct offset.

Right now, the page should look like the following screenshot. Isn't it looking nicer?

Creating content in the user info tab

CSS turn! We must make it look prettier, so let's play with some paddings. However, before anything, add the class to .card to the .tab-content. Next, let's fix the borders and margins in .tab-content by adding some padding and some negative margin, as follows:

#main .tab-content {
  padding: 2em;
  margin-top: -0.1rem;
}

Then, remove the border from the tab list and change the z-index of the tabs:

#account-tabs > li {
  border-bottom: 0;
}

#account-tabs {
  position: relative;
  z-index: 99;
}

Finally, remove the margin from the save changes button using another nth recipe, as follows:

#main .form-horizontal .form-group:last-child {
  margin-bottom: 0;
}

Nice! Refresh the web app and see the result, like this:

Creating content in the user info tab

With these changes, we have made the form from .tab-content look like a card. We also added some margins and padding to correct the designs. Lastly, with the margin top and z-index, we make the selected tab blend correctly with the content.

The stats column

To finalize the settings page, we must fill the right column of the web app. To do this, we will create a menu that presents some general statistics about the user.

In order to do that, we will use the Bootstrap List group component. List group is powerful in Bootstrap as it can seem similar to Bootstrap Cards, but it has more specific options for menu list generation, such as headers, disabled items, and much more.

So let's start doing this! Create the HTML markup at the #right-content element:

<div id="right-content" class="col-md-3 hidden-sm hidden-xs">
  <ul class="list-group">
    <li class="list-group-item list-group-item-info">
      Dog stats
    </li>
    <li class="list-group-item">
      Number of day rides
    </li>
    <li class="list-group-item">
      Captured mice
    </li>
    <li class="list-group-item">
      Postmen frightened
    </li>
    <li class="list-group-item">
      Always alert badge
    </li>
  </ul>
</div>

It is a simple list and we just added the .list-group class to the list, while adding the .list-group-item class for each item in the list. For the first item, we used the .list-group-item-info contextual color class to make it blue, according to the Bootstrap contextual colors.

Before we continue, we have to change the colors of the borders from list group to respect the same border color that we have been using:

.list-group-item {
  border-color: #e5e5e5;
}

The result that you should see right know is like the one presented in the next screenshot. List groups is a very handy component that we can use to achieve almost the same effect that we got using Pills, but here we are using fewer CSS rules.

The stats column

Labels and badges

Labels and badges are Bootstrap components that can easily highlight some text or information. They can be used in any place, as we did in the navigation bar, on the notification item.

Just like most of Bootstrap's components, labels follow the contextual colors of Bootstrap, while badges do not have this option. To consolidate their utilization, let's add some of them to the right menu, regarding the statistics, because after all we want to know our stats!

It will be pretty easy since we have worked with this before. For the three first items, we will use labels, and for the last one, we will use a badge with an icon. Just add the highlighted code to the current .list-group:

<div id="right-content" class="col-md-3 hidden-sm hidden-xs">
  <ul class="list-group">
    <li class="list-group-item list-group-item-info">
      Dog stats
    </li>
    <li class="list-group-item">
      Number of day rides
 <span class="label label-success">3</span>
    </li>
    <li class="list-group-item">
      Captured mice
 <span class="label label-danger">87</span>
    </li>
    <li class="list-group-item">
      Postmen frightened
 <span class="label label-default">2</span>
    </li>
    <li class="list-group-item">
      Always alert badge
 <span class="badge glyphicon glyphicon-star" aria-hidden="true">
 </span>
    </li>
  </ul>
</div>

We must pay attention to some points here. The first is that we used the .label class together with the contextual color class, like this: .label-*. Here, * is the name of the contextual class.

The second thing is that if you refresh your web page right now, you will see that Bootstrap does have a CSS for aligning all badges on the right, but it does not apply the same rule for labels. So, add the next CSS:

#right-content .list-group .label {
  float: right;
}

The third point is that we used badges and icons in the same span. This is possible, and then we just need to adjust the CSS render:

#right-content .list-group .label {
  padding: 0.3rem 0.6rem;
}

#right-content .list-group .badge.glyphicon-star {
  background-color: #f0ad4e;
  padding: 0.4rem;
  padding-left: 0.5rem;
}

By adding these rules, we adjusted the padding for the labels, adjusted the padding for the badge, and correctly set the yellow background for the star badge. See the result in the browser; it must look like this:

Labels and badges

Cool! We've done another page for our web app. The stats menu looks cute. We will not cover the other page settings menus in this book, since they follow almost the same structure that we showed in this example. Try doing that as homework.