Categories
Bootstrap HTML

Bootstrap 5 — Manipulating Tabs with JavaScript

Bootstrap 5 is in alpha when this is written and it’s subject to change.

Bootstrap is a popular UI library for any JavaScript apps.

In this article, we’ll look at how to manipulate navs with JavaScript with Bootstrap 5.

Using Data Attributes

We can add the data-toggle='tab' to add the links to show content when we click it.

For example, we can write:

<ul class="nav nav-tabs" id="tab">
  <li class="nav-item">
    <a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" >Home</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" >Profile</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" id="messages-tab" data-toggle="tab" href="#messages">Messages</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link" id="settings-tab" data-toggle="tab" href="#settings" >Settings</a>
  </li>
</ul>

<div class="tab-content">
  <div class="tab-pane active" id="home">Lorem ipsum dolor sit amet, consectetur adipiscing elit. </div>

  <div class="tab-pane" id="profile"> Nam at neque orci. In vehicula metus eu euismod rhoncus.</div>

  <div class="tab-pane" id="messages">Pellentesque pharetra ligula sed efficitur ultricies. </div>

  <div class="tab-pane" id="settings">Quisque et congue metus, id rutrum purus. </div>
</div>

We have the data-toggle attribute set to tab to make the links open content.

JavaScript

We can add click listeners to tabs with the addEventListener method.

For example, we can write:

const triggerTabList = [...document.querySelectorAll('#myTab a'];
triggerTabList.forEach((triggerEl) => {
  const tabTrigger = new bootstrap.Tab(triggerEl)

  triggerEl.addEventListener('click', (e) => {
    e.preventDefault()
    tabTrigger.show()
  })
})

We create the tab objects with the bootstrap.Tab constructor.

Then we attach click listeners to them with the addEventListener method.

Then we call show inside the click listener callback to show the content.

Fade Effect

We can add a fade effect to each .tab-pane with the .fade class.

For example, we can write:

<ul class="nav nav-tabs" id="tab">
  <li class="nav-item">
    <a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" >Home</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" >Profile</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" id="messages-tab" data-toggle="tab" href="#messages">Messages</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link" id="settings-tab" data-toggle="tab" href="#settings" >Settings</a>
  </li>
</ul>

<div class="tab-content">
  <div class="tab-pane fade active" id="home">Lorem ipsum dolor sit amet, consectetur adipiscing elit. </div>

  <div class="tab-pane fade" id="profile"> Nam at neque orci. In vehicula metus eu euismod rhoncus.</div>

  <div class="tab-pane fade" id="messages">Pellentesque pharetra ligula sed efficitur ultricies. </div>

  <div class="tab-pane fade" id="settings">Quisque et congue metus, id rutrum purus. </div>
</div>

After adding the .fade class, we’ll see the fade effect when we click on the tab links.

In addition to the show method, there’s also the dispose method to destroys an element’s tav.

getInstance gets the tab instance.

Events

Tabs fire a few events.

hide.bs.tab is emitted on the currently active tab when we hide it.

show.bs.tab is emitted on the to be shown tab when we click on it.

hidden.bs.tab is emitted on the previous active tab is we hid that tab.

shown.bs.tab is emitted when we’ve shown the newly active tab.

Conclusion

We can manipulate tabs with JavaScript.

They can be shown or hidden.

And we can listen to various events emitted.

Categories
Bootstrap HTML

Bootstrap 5 — List Groups and Scrollspys

Bootstrap 5 is in alpha when this is written and it’s subject to change.

Bootstrap is a popular UI library for any JavaScript apps.

In this article, we’ll look at how to add scrollspys with list groups and more with Bootstrap 5.

List Group and Scrollspys

We can use list groups as navigation component for scrollspys.

For example, we can write:

<div class='row'>
  <div class='col-3'>
    <div id="list-example" class="list-group">
      <a class="list-group-item list-group-item-action" href="#list-item-1">Item 1</a>
      <a class="list-group-item list-group-item-action" href="#list-item-2">Item 2</a>
      <a class="list-group-item list-group-item-action" href="#list-item-3">Item 3</a>
      <a class="list-group-item list-group-item-action" href="#list-item-4">Item 4</a>
    </div>
  </div>

<div data-spy="scroll" data-target="#list-example" data-offset="0" class='col-9' style='max-height: 300px; overflow-y: scroll'>
    <h4 id="list-item-1">Item 1</h4>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent tempus turpis augue, aliquam egestas nunc semper sit amet. Vivamus vel euismod eros. Fusce aliquam vitae nisi quis suscipit. Nullam rutrum convallis dui, a pharetra nulla dapibus eget. In diam justo, finibus in commodo fermentum, maximus sit amet tellus. </p>
    <h4 id="list-item-2">Item 2</h4>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent tempus turpis augue, aliquam egestas nunc semper sit amet. Vivamus vel euismod eros. Fusce aliquam vitae nisi quis suscipit. Nullam rutrum convallis dui, a pharetra nulla dapibus eget. In diam justo, finibus in commodo fermentum, maximus sit amet tellus. </p>
    <h4 id="list-item-3">Item 3</h4>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent tempus turpis augue, aliquam egestas nunc semper sit amet. Vivamus vel euismod eros. Fusce aliquam vitae nisi quis suscipit. Nullam rutrum convallis dui, a pharetra nulla dapibus eget. In diam justo, finibus in commodo fermentum, maximus sit amet tellus. </p>
    <h4 id="list-item-4">Item 4</h4>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent tempus turpis augue, aliquam egestas nunc semper sit amet. Vivamus vel euismod eros. Fusce aliquam vitae nisi quis suscipit. Nullam rutrum convallis dui, a pharetra nulla dapibus eget. In diam justo, finibus in commodo fermentum, maximus sit amet tellus. </p>
  </div>
</div>

We have the list group on the left side to show the entry that we’ve scrolled to.

The right side has the content.

We set the overflow-y to scroll and have the IDs match the href of the links on the list group.

The data-target is set to the ID of the list group.

JavaScript

We can add scrollspys with the bootstrap.ScrollSpy constructor.

For example, we can write:

const scrollSpy = new bootstrap.ScrollSpy(document.getElementById('content'), {
  target: '#list-example'
})

We can then call the refresh method on it to refresh the scrollspy:

const dataSpyList = [...document.querySelectorAll('[data-spy="scroll"]')];

dataSpyList.forEach((dataSpyEl) => {
  bootstrap.ScrollSpy.getInstance(dataSpyEl)
    .refresh()
})

We get the scrollspy element and call refresh on them.

Events

The activate.bs.scrollspy event is emitted whenever a new item is activated on a scrollspy.

And we can listen to it by writing:

const scrollSpyEl = document.querySelector('[data-spy="scroll"]')
scrollSpyEl.addEventListener('activate.bs.scrollspy', () => {
  //...
})

Conclusion

We can use list groups with scrollspys.

Also, we can use JavaScript to manipulate them.

Categories
Bootstrap HTML

Bootstrap 5 — List Groups and JavaScript

Bootstrap 5 is in alpha when this is written and it’s subject to change.

Bootstrap is a popular UI library for any JavaScript apps.

In this article, we’ll look at how to manipulate list groups with JavaScript with Bootstrap 5.

JavaScript Behavior

If we add the JavaScript Bootstrap 5 files, we can do more with list groups.

For instance, we can add a navbar that can display some content when we click it.

We can write:

<div class="row">
  <div class="col-4">
    <div class="list-group" id="list-tab">
      <a class="list-group-item list-group-item-action active" id="list-home-list" data-toggle="list" href="#list-home">Home</a>

      <a class="list-group-item list-group-item-action" id="list-profile-list" data-toggle="list" href="#list-profile">Profile</a>

      <a class="list-group-item list-group-item-action" id="list-messages-list" data-toggle="list" href="#list-messages">Messages</a>

      <a class="list-group-item list-group-item-action" id="list-settings-list" data-toggle="list" href="#list-settings">Settings</a>
    </div>
  </div>

  <div class="col-8">
    <div class="tab-content" id="nav-tabContent">
      <div class="tab-pane fade show active" id="list-home">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>

      <div class="tab-pane fade" id="list-profile">Proin non libero congue lectus pharetra dictum quis ut eros. Nunc ac eleifend risus. In vitae arcu tincidunt, eleifend velit id, cursus nibh.</div>

      <div class="tab-pane fade" id="list-messages">Vestibulum hendrerit urna dictum, vulputate quam et, faucibus sapien.</div>

      <div class="tab-pane fade" id="list-settings">Suspendisse in mauris non diam facilisis aliquet eget ac nisi.</div>
    </div>
  </div>
</div>

We added a list group as the navigation bar on the left side.

The data-toggle attribute on each a element lets us choose which panel to show on the right side.

The id of the div on the right side should match the value in the data-toggle so that it can open.

Using Data Attributes

We can also just use the data-toggle='list' on an element with the href so that we don’t need JavaScript to display the content when we click on the list group item.

For instance, we can write:

<div class="row">
  <div class="col-4">
    <div class="list-group" id="myList" role="tablist">
      <a class="list-group-item list-group-item-action active" data-toggle="list" href="#home">Home</a>
      <a class="list-group-item list-group-item-action" data-toggle="list" href="#profile">Profile</a>
      <a class="list-group-item list-group-item-action" data-toggle="list" href="#messages">Messages</a>
      <a class="list-group-item list-group-item-action" data-toggle="list" href="#settings">Settings</a>
    </div>
  </div>

  <div class="col-8">
    <div class="tab-content">
      <div class="tab-pane active" id="home">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>
      <div class="tab-pane" id="profile">Proin non libero congue lectus pharetra dictum quis ut eros. Nunc ac eleifend risus. In vitae arcu tincidunt, eleifend velit id, cursus nibh.</div>
      <div class="tab-pane" id="messages"> Donec nec elit vel ex pellentesque pellentesque. Sed commodo tellus at enim vulputate ornare.</div>
      <div class="tab-pane" id="settings">Pellentesque vel elit ut libero hendrerit dictum a in dolor.</div>
    </div>
  </div>
</div>

We have the list group with the data-toggle='list' attribute to show the content when we click on the links.

Then on the right side, we created a div with the tab-content class.

id is set to values of the href in the links without the pound sign.

JavaScript Tabs

We can use the bootstrap.Tab constructor to let us show tabs when they’re clicked.

For example, we can write:

const triggerTabList = \[...document.querySelectorAll('.list-tab a')\];
triggerTabList.forEach((triggerEl) => {
  const tabTrigger = new bootstrap.Tab(triggerEl);
  triggerEl.addEventListener('click', (e) => {
    e.preventDefault()
    tabTrigger.show()
  })
})

to do that.

We just add click listeners to all the trigger elements in the list group.

Also, we can show a tab with the show method.

For example, given the following HTML:

<div class="row">
  <div class="col-4">
    <div class="list-group" id="list-tab">
      <a class="list-group-item list-group-item-action active" id="list-home-list" data-toggle="list" href="#list-home">Home</a>

      <a class="list-group-item list-group-item-action" id="list-profile-list" data-toggle="list" href="#list-profile">Profile</a>

      <a class="list-group-item list-group-item-action" id="list-messages-list" data-toggle="list" href="#list-messages">Messages</a>

      <a class="list-group-item list-group-item-action" id="list-settings-list" data-toggle="list" href="#list-settings">Settings</a>
    </div>
  </div>

  <div class="col-8">
    <div class="tab-content" id="nav-tabContent">
      <div class="tab-pane fade show active" id="list-home">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>

      <div class="tab-pane fade" id="list-profile">Proin non libero congue lectus pharetra dictum quis ut eros. Nunc ac eleifend risus. In vitae arcu tincidunt, eleifend velit id, cursus nibh.</div>

      <div class="tab-pane fade" id="list-messages">Vestibulum hendrerit urna dictum, vulputate quam et, faucibus sapien.</div>

      <div class="tab-pane fade" id="list-settings">Suspendisse in mauris non diam facilisis aliquet eget ac nisi.</div>
    </div>
  </div>
</div>

Then we can show the last tab with JavaScript by writing:

const lastTabEl = document.querySelector('#list-tab a:last-child')
const lastTab = new bootstrap.Tab(lastTabEl)

lastTab.show()

We get the link for the last tab and pass ghat to the bootstrap.Tab constructor.

Then we call show to show the tab.

Events

List groups also emit a few events.

They’re:

  1. hide.bs.tab — emitted when a tab is hiding
  2. show.bs.tab — emitted when a tab is showing
  3. hidden.bs.tab — emitted when a tab is hidden
  4. shown.bs.tab — emitted when a tab is shown

Conclusion

We can use JavaScript to manipulate tabs.

Categories
Bootstrap HTML

Bootstrap 5 — Helpers

Bootstrap 5 is in alpha when this is written and it’s subject to change.

Bootstrap is a popular UI library for any JavaScript apps.

In this article, we’ll look at some Bootstrap 5 helper classes.

Clearfix

Clearfix lets us easily clear floated content in a container.

To add it, we add the .clearfix class to the parent element.

It can also be used as a mixin.

For example, we can write:

.element {
  @include clearfix;
}

And we can use it in HTML by writing:

<div class="bg-info clearfix">
  <button type="button" class="btn btn-secondary float-left">floated left</button>
  <button type="button" class="btn btn-secondary float-right">floated right</button>
</div>

Colored Links

We can add colored links with the .link-* classes to colorize links.

For example, we can write:

<a href="#" class="link-primary">Primary</a>
<a href="#" class="link-secondary">Secondary</a>
<a href="#" class="link-success">Success</a>
<a href="#" class="link-danger">Danger</a>
<a href="#" class="link-warning">Warning</a>
<a href="#" class="link-info">Info</a>
<a href="#" class="link-light">Light</a>
<a href="#" class="link-dark">Dark</a>

to add the links.

Embeds

Bootstrap 5 comes with a component to create responsive video or slideshow embeds based on the width of the parent.

They’re applied directly to the iframe , embded , video , and object .

And we don’t need to add frameborder='0' to remove the border.

For example, we can write:

<div class="embed-responsive embed-responsive-16by9">
  <iframe class="embed-responsive-item" src="https://www.youtube.com/embed/IA7REQxohV4" title="YouTube video" allowfullscreen></iframe>
</div>

We have the title to set the title.

allowfullscreen lets us show the video in full screen mode.

Aspect Ratios

We can change the aspect ratios of the embeds.

To do that, we add some classes:

<div class="embed-responsive embed-responsive-21by9">
  <iframe class="embed-responsive-item" src="https://www.youtube.com/embed/IA7REQxohV4" title="YouTube video" allowfullscreen></iframe>
</div>

We have the embed-responsive-* class to change the aspect ratio.

Also, we can change the embed to other ratios:

<div class="embed-responsive embed-responsive-16by9">
  <iframe class="embed-responsive-item" src="https://www.youtube.com/embed/IA7REQxohV4" title="YouTube video" allowfullscreen></iframe>
</div>

<div class="embed-responsive embed-responsive-4by3">
  <iframe class="embed-responsive-item" src="https://www.youtube.com/embed/IA7REQxohV4" title="YouTube video" allowfullscreen></iframe>
</div>

<div class="embed-responsive embed-responsive-1by1">
  <iframe class="embed-responsive-item" src="https://www.youtube.com/embed/IA7REQxohV4" title="YouTube video" allowfullscreen></iframe>
</div>

We can change the ratio to 16 x9, 4×3, or 1×1.

Position

Bootstrap 5 also comes with helpers for changing positions.

For example, we can write:

<div class="fixed-top">...</div>

to make the position of the div fixed to the top.

Also, we can write:

<div class="fixed-bottom">...</div>

to make it fixed to the bottom.

We can also make it position: sticky with the .sticky-top class:

<div class="sticky-top">...</div>

And we can make that responsive:

<div class="sticky-sm-top">Stick small or wider</div>

<div class="sticky-md-top">Stick medium or wider</div>

<div class="sticky-lg-top">Stick large or wider</div>

<div class="sticky-xl-top">Stick extra large or wider</div>

Screen Readers

There’re utility classes for screen readers.

Bootstrap 5 comes with the sr-only class to make the text available to screen readers only.

For example, we can write:

<h2 class="sr-only">screen readers</h2>

.sr-only-focusable shows the element only when it’s focused:

<a class="sr-only-focusable" href="#content">main content</a>

Stretched Link

We can make the link stretched with the .stretched-link class.

For example, we can write:

<div class="card" style="width: 20rem;">
  <img src="http://placekitten.com/200/200" class="card-img-top" alt="cat">
  <div class="card-body">
    <h5 class="card-title">Card with stretched link</h5>
    <p class="card-text">
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent tempus turpis augue, aliquam egestas nunc semper sit amet. Vivamus vel euismod eros. Fusce aliquam vitae nisi quis suscipit. Nullam rutrum convallis dui, a pharetra nulla dapibus eget. In diam justo, finibus in commodo fermentum, maximus sit amet tellus. .</p>
    <a href="#" class="btn btn-primary stretched-link">Go somewhere</a>
  </div>
</div>

Since we have the stretch-link class on the link, it’ll be stretched to the width of the card.

The containing block has the position: relative , so we don’t have to add it to make the link stretch.

We’ve to add position: relative to most components to make the link stretch.

We can do that by writing:

<div class="d-flex position-relative">
  <img src="http://placekitten.com/200/200" class="flex-shrink-0 mr-3" alt="cat">
  <div>
    <h5 class="mt-0">Custom component with stretched link</h5>
    <p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent tempus turpis augue, aliquam egestas nunc semper sit amet. Vivamus vel euismod eros. Fusce aliquam vitae nisi quis suscipit. Nullam rutrum convallis dui, a pharetra nulla dapibus eget. In diam justo, finibus in commodo fermentum, maximus sit amet tellus. </p>
    <a href="#" class="stretched-link">Go</a>
  </div>
</div>

We added the position-relative class to the container div to make the link stretch.

Conclusion

Bootstrap 5 provides us with various helpers for styling.

Categories
Bootstrap HTML

Bootstrap 5 — Customizing Navs

Bootstrap 5 is in alpha when this is written and it’s subject to change.

Bootstrap is a popular UI library for any JavaScript apps.

In this article, we’ll look at how to customize navs with Bootstrap 5.

JavaScript Behavior

We can also customize navs to our needs.

For example, we can write:

<ul class="nav nav-tabs" id="myTab" role="tablist">
  <li class="nav-item" role="presentation">
    <a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link" id="contact-tab" data-toggle="tab" href="#contact" role="tab" aria-controls="contact" aria-selected="false">Contact</a>
  </li>
</ul>

<div class="tab-content" id="myTabContent">
  <div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam at neque orci. In vehicula metus eu euismod rhoncus. Pellentesque pharetra ligula sed efficitur ultricies. Quisque et congue metus, id rutrum purus. Maecenas finibus efficitur mauris, quis varius enim elementum a. Phasellus vel aliquet diam. Proin tincidunt eros pellentesque mauris laoreet, nec ullamcorper magna vulputate. Suspendisse potenti. Nullam lobortis ultricies nunc id vulputate. Curabitur pulvinar, lorem ac tempus lobortis, tortor tortor dignissim enim, quis tempor est lacus ut augue. Sed tincidunt lectus urna, ac aliquet velit suscipit a. Nullam tempus sem id nibh vulputate, nec ultricies lorem porttitor. Sed pharetra lacinia odio non sodales.
  </div>

  <div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">Mauris ullamcorper ornare dui at bibendum. Duis sed quam ac purus tincidunt aliquet. Suspendisse potenti. Praesent vitae turpis dui. Fusce ut tincidunt est, ut sagittis mi. Sed euismod pharetra pulvinar. Morbi at facilisis quam. Vestibulum sagittis arcu sit amet scelerisque vestibulum. Nulla nisl libero, ornare et facilisis et, tempus sagittis massa. Sed tincidunt metus non ex ornare, eu elementum lorem sagittis. Nam a sapien eleifend, dignissim purus sit amet, ultrices neque. Suspendisse imperdiet purus eu posuere pellentesque. Nulla facilisi.
  </div>

  <div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">Mauris suscipit metus at felis maximus, a sagittis libero ornare. Sed eu placerat mauris. Cras venenatis, magna sed efficitur tristique, nibh diam mattis neque, non pellentesque turpis nibh in sapien. Proin porttitor sodales risus sit amet imperdiet. Aenean quis pretium sem, quis maximus purus. Pellentesque vestibulum elementum dui ut ultrices. Suspendisse potenti.
  </div>
</div>

We have the tab component by adding the li s with our own structure.

Also, we can add tabs with pills:

<ul class="nav nav-pills mb-3" id="pills-tab" role="tablist">
  <li class="nav-item" role="presentation">
    <a class="nav-link active" id="pills-home-tab" data-toggle="pill" href="#pills-home" role="tab" aria-controls="pills-home" aria-selected="true">Home</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link" id="pills-profile-tab" data-toggle="pill" href="#pills-profile" role="tab" aria-controls="pills-profile" aria-selected="false">Profile</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link" id="pills-contact-tab" data-toggle="pill" href="#pills-contact" role="tab" aria-controls="pills-contact" aria-selected="false">Contact</a>
  </li>
</ul>
<div class="tab-content" id="pills-tabContent">
  <div class="tab-pane fade show active" id="pills-home" role="tabpanel" aria-labelledby="pills-home-tab">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam at neque orci. In vehicula metus eu euismod rhoncus. </div>

  <div class="tab-pane fade" id="pills-profile" role="tabpanel" aria-labelledby="pills-profile-tab">Pellentesque pharetra ligula sed efficitur ultricies. Quisque et congue metus, id rutrum purus.</div>

  <div class="tab-pane fade" id="pills-contact" role="tabpanel" aria-labelledby="pills-contact-tab">Curabitur pulvinar, lorem ac tempus lobortis, tortor tortor dignissim enim, quis tempor est lacus ut augue.
  </div>
</div>

We add the nav link with pills with the .nav-pills class.

Then we have the content.

The ID of the divs with the class .tab-pane have to match the URLs of the href .

We can also add vertical pills:

<div class="row">
  <div class="col-3">
    <div class="nav flex-column nav-pills" id="v-pills-tab" role="tablist" aria-orientation="vertical">
      <a class="nav-link active" id="v-pills-home-tab" data-toggle="pill" href="#v-pills-home" role="tab" aria-controls="v-pills-home" aria-selected="true">Home</a>

      <a class="nav-link" id="v-pills-profile-tab" data-toggle="pill" href="#v-pills-profile" role="tab" aria-controls="v-pills-profile" aria-selected="false">Profile</a>

      <a class="nav-link" id="v-pills-messages-tab" data-toggle="pill" href="#v-pills-messages" role="tab" aria-controls="v-pills-messages" aria-selected="false">Messages</a>

      <a class="nav-link" id="v-pills-settings-tab" data-toggle="pill" href="#v-pills-settings" role="tab" aria-controls="v-pills-settings" aria-selected="false">Settings</a>
    </div>
  </div>

  <div class="col-9">
    <div class="tab-content" id="v-pills-tabContent">
      <div class="tab-pane fade show active" id="v-pills-home" role="tabpanel" aria-labelledby="v-pills-home-tab">urabitur pulvinar, lorem ac tempus lobortis, tortor tortor dignissim enim, quis tempor est lacus ut augue.</div>

      <div class="tab-pane fade" id="v-pills-profile" role="tabpanel" aria-labelledby="v-pills-profile-tab">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam at neque orci.  </div>

      <div class="tab-pane fade" id="v-pills-messages" role="tabpanel" aria-labelledby="v-pills-messages-tab">In vehicula metus eu euismod rhoncus. Pellentesque pharetra ligula sed efficitur ultricies. </div>

      <div class="tab-pane fade" id="v-pills-settings" role="tabpanel" aria-labelledby="v-pills-settings-tab">Proin tincidunt eros pellentesque mauris laoreet, nec ullamcorper magna vulputate. </div>
    </div>
  </div>
</div>

We have the nav links in the nav in the .col-3 class.

The items are in a div with the .nav-pills class.

flex-column makes the vertical.

Also, we have the right column with the divs with the .tab-pane class to add the content to display when we click on the links.

If the href matches the ID of the tab-pane divs, then the content will be shown when we add the classes.

Conclusion

We can layout tabs and content our way.

The tabs can be vertically and put the content beside it.