1
0
Fork 0
mirror of https://github.com/twbs/bootstrap.git synced 2022-11-09 12:25:43 -05:00

Tabs/Scrollspy/.nav/.list-group/.active independent of markup (<nav>, .nav-item, <li> etc...)

This commit is contained in:
Pierre Vanduynslager 2017-04-02 05:21:04 -04:00 committed by Johann-S
parent 5142de7e59
commit 91b62941af
11 changed files with 829 additions and 121 deletions

View file

@ -332,6 +332,12 @@
overflow: auto;
}
.scrollspy-example-2 {
position: relative;
height: 350px;
overflow: auto;
}
// Helpers
.bd-example > {
.bg-primary,

View file

@ -167,3 +167,195 @@ Add nearly any HTML within, even for linked list groups like the one below, with
</a>
</div>
{% endexample %}
## JavaScript behavior
Use the tab JavaScript plugin—include it individually or through the compiled `bootstrap.js` file—to extend our list group to create tabbable panes of local content.
<div class="bd-example" role="tabpanel">
<div class="row">
<div class="col-4">
<div class="list-group" id="list-tab" role="tablist">
<a class="list-group-item list-group-item-action active" id="list-home-list" data-toggle="tab" href="#list-home" role="tab" aria-controls="home">Home</a>
<a class="list-group-item list-group-item-action" id="list-profile-list" data-toggle="tab" href="#list-profile" role="tab" aria-controls="profile">Profile</a>
<a class="list-group-item list-group-item-action" id="list-messages-list" data-toggle="tab" href="#list-messages" role="tab" aria-controls="messages">Messages</a>
<a class="list-group-item list-group-item-action" id="list-settings-list" data-toggle="tab" href="#list-settings" role="tab" aria-controls="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" role="tabpanel" aria-labelledby="list-home-list">
<p>Velit aute mollit ipsum ad dolor consectetur nulla officia culpa adipisicing exercitation fugiat tempor. Voluptate deserunt sit sunt nisi aliqua fugiat proident ea ut. Mollit voluptate reprehenderit occaecat nisi ad non minim tempor sunt voluptate consectetur exercitation id ut nulla. Ea et fugiat aliquip nostrud sunt incididunt consectetur culpa aliquip eiusmod dolor. Anim ad Lorem aliqua in cupidatat nisi enim eu nostrud do aliquip veniam minim.</p>
</div>
<div class="tab-pane fade" id="list-profile" role="tabpanel" aria-labelledby="list-profile-list">
<p>Cupidatat quis ad sint excepteur laborum in esse qui. Et excepteur consectetur ex nisi eu do cillum ad laborum. Mollit et eu officia dolore sunt Lorem culpa qui commodo velit ex amet id ex. Officia anim incididunt laboris deserunt anim aute dolor incididunt veniam aute dolore do exercitation. Dolor nisi culpa ex ad irure in elit eu dolore. Ad laboris ipsum reprehenderit irure non commodo enim culpa commodo veniam incididunt veniam ad.</p>
</div>
<div class="tab-pane fade" id="list-messages" role="tabpanel" aria-labelledby="list-messages-list">
<p>Ut ut do pariatur aliquip aliqua aliquip exercitation do nostrud commodo reprehenderit aute ipsum voluptate. Irure Lorem et laboris nostrud amet cupidatat cupidatat anim do ut velit mollit consequat enim tempor. Consectetur est minim nostrud nostrud consectetur irure labore voluptate irure. Ipsum id Lorem sit sint voluptate est pariatur eu ad cupidatat et deserunt culpa sit eiusmod deserunt. Consectetur et fugiat anim do eiusmod aliquip nulla laborum elit adipisicing pariatur cillum.</p>
</div>
<div class="tab-pane fade" id="list-settings" role="tabpanel" aria-labelledby="list-settings-list">
<p>Irure enim occaecat labore sit qui aliquip reprehenderit amet velit. Deserunt ullamco ex elit nostrud ut dolore nisi officia magna sit occaecat laboris sunt dolor. Nisi eu minim cillum occaecat aute est cupidatat aliqua labore aute occaecat ea aliquip sunt amet. Aute mollit dolor ut exercitation irure commodo non amet consectetur quis amet culpa. Quis ullamco nisi amet qui aute irure eu. Magna labore dolor quis ex labore id nostrud deserunt dolor eiusmod eu pariatur culpa mollit in irure.</p>
</div>
</div>
</div>
</div>
</div>
{% highlight html %}
<div class="row">
<div class="col-4">
<div class="list-group" id="list-tab" role="tablist">
<a class="list-group-item list-group-item-action active" id="list-home-list" data-toggle="list" href="#list-home" role="tab" aria-controls="home">Home</a>
<a class="list-group-item list-group-item-action" id="list-profile-list" data-toggle="list" href="#list-profile" role="tab" aria-controls="profile">Profile</a>
<a class="list-group-item list-group-item-action" id="list-messages-list" data-toggle="list" href="#list-messages" role="tab" aria-controls="messages">Messages</a>
<a class="list-group-item list-group-item-action" id="list-settings-list" data-toggle="list" href="#list-settings" role="tab" aria-controls="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" role="tabpanel" aria-labelledby="list-home-list">...</div>
<div class="tab-pane fade" id="list-profile" role="tabpanel" aria-labelledby="list-profile-list">...</div>
<div class="tab-pane fade" id="list-messages" role="tabpanel" aria-labelledby="list-messages-list">...</div>
<div class="tab-pane fade" id="list-settings" role="tabpanel" aria-labelledby="list-settings-list">...</div>
</div>
</div>
</div>
{% endhighlight %}
### Using data attributes
You can activate a list group navigation without writing any JavaScript by simply specifying `data-toggle="list"` or on an element. Use these data attributes on `.list-group-item`.
<div role="tabpanel">
{% highlight html %}
<!-- List group -->
<div class="list-group" id="myList" role="tablist">
<a class="list-group-item list-group-item-action active" data-toggle="list" href="#home" role="tab">Home</a>
<a class="list-group-item list-group-item-action" data-toggle="list" href="#profile" role="tab">Profile</a>
<a class="list-group-item list-group-item-action" data-toggle="list" href="#messages" role="tab">Messages</a>
<a class="list-group-item list-group-item-action" data-toggle="list" href="#settings" role="tab">Settings</a>
</div>
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane active" id="home" role="tabpanel">...</div>
<div class="tab-pane" id="profile" role="tabpanel">...</div>
<div class="tab-pane" id="messages" role="tabpanel">...</div>
<div class="tab-pane" id="settings" role="tabpanel">...</div>
</div>
{% endhighlight %}
</div>
### Via JavaScript
Enable tabbable list item via JavaScript (each list item needs to be activated individually):
{% highlight js %}
$('#myList a').click(function (e) {
e.preventDefault()
$(this).tab('show')
})
{% endhighlight %}
You can activate individual list item in several ways:
{% highlight js %}
$('#myList a[href="#profile"]').tab('show') // Select tab by name
$('#myList a:first').tab('show') // Select first tab
$('#myList a:last').tab('show') // Select last tab
$('#myList li:eq(2) a').tab('show') // Select third tab (0-indexed)
{% endhighlight %}
### Fade effect
To make tabs panel fade in, add `.fade` to each `.tab-pane`. The first tab pane must also have `.show` to make the initial content visible.
{% highlight html %}
<div class="tab-content">
<div class="tab-pane fade show active" id="home" role="tabpanel">...</div>
<div class="tab-pane fade" id="profile" role="tabpanel">...</div>
<div class="tab-pane fade" id="messages" role="tabpanel">...</div>
<div class="tab-pane fade" id="settings" role="tabpanel">...</div>
</div>
{% endhighlight %}
### Methods
#### $().tab
Activates a list item element and content container. Tab should have either a `data-target` or an `href` targeting a container node in the DOM.
{% highlight html %}
<div class="list-group" id="myList" role="tablist">
<a class="list-group-item list-group-item-action active" data-toggle="list" href="#home" role="tab">Home</a>
<a class="list-group-item list-group-item-action" data-toggle="list" href="#profile" role="tab">Profile</a>
<a class="list-group-item list-group-item-action" data-toggle="list" href="#messages" role="tab">Messages</a>
<a class="list-group-item list-group-item-action" data-toggle="list" href="#settings" role="tab">Settings</a>
</div>
<div class="tab-content">
<div class="tab-pane active" id="home" role="tabpanel">...</div>
<div class="tab-pane" id="profile" role="tabpanel">...</div>
<div class="tab-pane" id="messages" role="tabpanel">...</div>
<div class="tab-pane" id="settings" role="tabpanel">...</div>
</div>
<script>
$(function () {
$('#myList a:last').tab('show')
})
</script>
{% endhighlight %}
#### .tab('show')
Selects the given list item and shows its associated pane. Any other list item that was previously selected becomes unselected and its associated pane is hidden. **Returns to the caller before the tab pane has actually been shown** (i.e. before the `shown.bs.tab` event occurs).
{% highlight js %}
$('#someListItem').tab('show')
{% endhighlight %}
### Events
When showing a new tab, the events fire in the following order:
1. `hide.bs.tab` (on the current active tab)
2. `show.bs.tab` (on the to-be-shown tab)
3. `hidden.bs.tab` (on the previous active tab, the same one as for the `hide.bs.tab` event)
4. `shown.bs.tab` (on the newly-active just-shown tab, the same one as for the `show.bs.tab` event)
If no tab was already active, then the `hide.bs.tab` and `hidden.bs.tab` events will not be fired.
<table class="table table-bordered table-striped table-responsive">
<thead>
<tr>
<th style="width: 150px;">Event Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>show.bs.tab</td>
<td>This event fires on tab show, but before the new tab has been shown. Use <code>event.target</code> and <code>event.relatedTarget</code> to target the active tab and the previous active tab (if available) respectively.</td>
</tr>
<tr>
<td>shown.bs.tab</td>
<td>This event fires on tab show after a tab has been shown. Use <code>event.target</code> and <code>event.relatedTarget</code> to target the active tab and the previous active tab (if available) respectively.</td>
</tr>
<tr>
<td>hide.bs.tab</td>
<td>This event fires when a new tab is to be shown (and thus the previous active tab is to be hidden). Use <code>event.target</code> and <code>event.relatedTarget</code> to target the current active tab and the new soon-to-be-active tab, respectively.</td>
</tr>
<tr>
<td>hidden.bs.tab</td>
<td>This event fires after a new tab is shown (and thus the previous active tab is hidden). Use <code>event.target</code> and <code>event.relatedTarget</code> to target the previous active tab and the new active tab, respectively.</td>
</tr>
</tbody>
</table>
{% highlight js %}
$('a[data-toggle="list"]').on('shown.bs.tab', function (e) {
e.target // newly activated tab
e.relatedTarget // previous active tab
})
{% endhighlight %}

View file

@ -199,20 +199,12 @@ When using a `<nav>`-based navigation, be sure to include `.nav-item` on the anc
For equal-width elements, use `.nav-justified`. All horizontal space will be occupied by nav links, but unlike the `.nav-fill` above, every nav item will be the same width.
{% example html %}
<ul class="nav nav-pills nav-justified">
<li class="nav-item">
<a class="nav-link active" href="#">Active</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Longer nav link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#">Disabled</a>
</li>
</ul>
<nav class="nav nav-pills nav-justified">
<a class="nav-link active" href="#">Active</a>
<a class="nav-link" href="#">Longer nav link</a>
<a class="nav-link" href="#">Link</a>
<a class="nav-link disabled" href="#">Disabled</a>
</nav>
{% endexample %}
Similar to the `.nav-fill` example using a `<nav>`-based navigation, be sure to include `.nav-item` on the anchors.
@ -322,21 +314,205 @@ Use the tab JavaScript plugin—include it individually or through the compiled
</li>
</ul>
<div class="tab-content" id="myTabContent">
<div role="tabpanel" class="tab-pane fade show active" id="home" aria-labelledBy="home-tab">
<div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
</div>
<div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledBy="profile-tab">
<div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">
<p>Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park.</p>
</div>
<div class="tab-pane fade" id="dropdown1" role="tabpanel" aria-labelledBy="dropdown1-tab">
<div class="tab-pane fade" id="dropdown1" role="tabpanel" aria-labelledby="dropdown1-tab">
<p>Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.</p>
</div>
<div class="tab-pane fade" id="dropdown2" role="tabpanel" aria-labelledBy="dropdown2-tab">
<div class="tab-pane fade" id="dropdown2" role="tabpanel" aria-labelledby="dropdown2-tab">
<p>Trust fund seitan letterpress, keytar raw denim keffiyeh etsy art party before they sold out master cleanse gluten-free squid scenester freegan cosby sweater. Fanny pack portland seitan DIY, art party locavore wolf cliche high life echo park Austin. Cred vinyl keffiyeh DIY salvia PBR, banh mi before they sold out farm-to-table VHS viral locavore cosby sweater. Lomo wolf viral, mustache readymade thundercats keffiyeh craft beer marfa ethical. Wolf salvia freegan, sartorial keffiyeh echo park vegan.</p>
</div>
</div>
</div>
{% highlight html %}
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-expanded="true">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile">Profile</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
Dropdown
</a>
<div class="dropdown-menu">
<a class="dropdown-item" id="dropdown1-tab" href="#dropdown1" role="tab" data-toggle="tab" aria-controls="dropdown1">@fat</a>
<a class="dropdown-item" id="dropdown2-tab" href="#dropdown2" role="tab" data-toggle="tab" aria-controls="dropdown2">@mdo</a>
</div>
</li>
</ul>
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">...</div>
<div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">...</div>
<div class="tab-pane fade" id="dropdown1" role="tabpanel" aria-labelledby="dropdown1-tab">...</div>
<div class="tab-pane fade" id="dropdown2" role="tabpanel" aria-labelledby="dropdown2-tab">...</div>
</div>
{% endhighlight %}
To help fit your needs, this works with `<ul>`-based markup, as shown above, as well as `<nav>`-based markup shown below.
<div class="bd-example bd-example-tabs" role="tabpanel">
<div class="nav nav-tabs" id="nav-tab" role="tablist">
<a class="nav-link active" id="nav-home-tab" data-toggle="tab" href="#nav-home" role="tab" aria-controls="home" aria-expanded="true">Home</a>
<a class="nav-link" id="nav-profile-tab" data-toggle="tab" href="#nav-profile" role="tab" aria-controls="profile">Profile</a>
<div class="dropdown">
<a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
Dropdown
</a>
<div class="dropdown-menu">
<a class="dropdown-item" id="nav-dropdown1-tab" href="#nav-dropdown1" role="tab" data-toggle="tab" aria-controls="dropdown1">@fat</a>
<a class="dropdown-item" id="nav-dropdown2-tab" href="#nav-dropdown2" role="tab" data-toggle="tab" aria-controls="dropdown2">@mdo</a>
</div>
</div>
</div>
<div class="tab-content" id="nav-tabContent">
<div class="tab-pane fade show active" id="nav-home" role="tabpanel" aria-labelledby="nav-home-tab">
<p>Et et consectetur ipsum labore excepteur est proident excepteur ad velit occaecat qui minim occaecat veniam. Fugiat veniam incididunt anim aliqua enim pariatur veniam sunt est aute sit dolor anim. Velit non irure adipisicing aliqua ullamco irure incididunt irure non esse consectetur nostrud minim non minim occaecat. Amet duis do nisi duis veniam non est eiusmod tempor incididunt tempor dolor ipsum in qui sit. Exercitation mollit sit culpa nisi culpa non adipisicing reprehenderit do dolore. Duis reprehenderit occaecat anim ullamco ad duis occaecat ex.</p>
</div>
<div class="tab-pane fade" id="nav-profile" role="tabpanel" aria-labelledby="nav-profile-tab">
<p>Nulla est ullamco ut irure incididunt nulla Lorem Lorem minim irure officia enim reprehenderit. Magna duis labore cillum sint adipisicing exercitation ipsum. Nostrud ut anim non exercitation velit laboris fugiat cupidatat. Commodo esse dolore fugiat sint velit ullamco magna consequat voluptate minim amet aliquip ipsum aute laboris nisi. Labore labore veniam irure irure ipsum pariatur mollit magna in cupidatat dolore magna irure esse tempor ad mollit. Dolore commodo nulla minim amet ipsum officia consectetur amet ullamco voluptate nisi commodo ea sit eu.</p>
</div>
<div class="tab-pane fade" id="nav-dropdown1" role="tabpanel" aria-labelledby="nav-dropdown1-tab">
<p>Sint sit mollit irure quis est nostrud cillum consequat Lorem esse do quis dolor esse fugiat sunt do. Eu ex commodo veniam Lorem aliquip laborum occaecat qui Lorem esse mollit dolore anim cupidatat. Deserunt officia id Lorem nostrud aute id commodo elit eiusmod enim irure amet eiusmod qui reprehenderit nostrud tempor. Fugiat ipsum excepteur in aliqua non et quis aliquip ad irure in labore cillum elit enim. Consequat aliquip incididunt ipsum et minim laborum laborum laborum et cillum labore. Deserunt adipisicing cillum id nulla minim nostrud labore eiusmod et amet. Laboris consequat consequat commodo non ut non aliquip reprehenderit nulla anim occaecat. Sunt sit ullamco reprehenderit irure ea ullamco Lorem aute nostrud magna.</p>
</div>
<div class="tab-pane fade" id="nav-dropdown2" role="tabpanel" aria-labelledby="nav-dropdown2-tab">
<p>Proident incididunt esse qui ea nisi ullamco aliquip nostrud velit sint duis. Aute culpa aute cillum sit consectetur mollit minim non reprehenderit tempor. Occaecat amet consectetur aute esse ad ullamco ad commodo mollit reprehenderit esse in consequat. Mollit minim do consectetur pariatur irure non id ea dolore occaecat adipisicing consectetur est aute magna non.</p>
</div>
</div>
</div>
{% highlight html %}
<div class="nav nav-tabs" id="myTab" role="tablist">
<a class="nav-link active" id="nav-home-tab" data-toggle="tab" href="#nav-home" role="tab" aria-controls="nav-home" aria-expanded="true">Home</a>
<a class="nav-link" id="nav-profile-tab" data-toggle="tab" href="#nav-profile" role="tab" aria-controls="nav-profile">Profile</a>
<div class="dropdown">
<a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
Dropdown
</a>
<div class="dropdown-menu">
<a class="dropdown-item" id="nav-dropdown1-tab" href="#nav-dropdown1" role="tab" data-toggle="tab" aria-controls="nav-dropdown1">@fat</a>
<a class="dropdown-item" id="nav-dropdown2-tab" href="#nav-dropdown2" role="tab" data-toggle="tab" aria-controls="nav-dropdown2">@mdo</a>
</div>
</div>
</div>
<div class="tab-content" id="nav-tabContent">
<div class="tab-pane fade show active" id="nav-home" role="tabpanel" aria-labelledby="nav-home-tab">...</div>
<div class="tab-pane fade" id="nav-profile" role="tabpanel" aria-labelledby="nav-profile-tab">...</div>
<div class="tab-pane fade" id="nav-dropdown1" role="tabpanel" aria-labelledby="nav-dropdown1-tab">...</div>
<div class="tab-pane fade" id="nav-dropdown2" role="tabpanel" aria-labelledby="nav-dropdown2-tab">...</div>
</div>
{% endhighlight %}
The tabs plugin also works with pills.
<div class="bd-example bd-example-tabs" role="tabpanel">
<ul class="nav nav-pills mb-3" id="pills-tab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="pills-home-tab" data-toggle="pill" href="#pills-home" role="tab" aria-controls="pills-home" aria-expanded="true">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" id="pills-profile-tab" data-toggle="pill" href="#pills-profile" role="tab" aria-controls="pills-profile" aria-expanded="true">Profile</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">Dropdown</a>
<div class="dropdown-menu">
<a class="dropdown-item" id="pills-dropdown1-tab" href="#pills-dropdown1" role="tab" data-toggle="pill" aria-controls="pills-dropdown1">@fat</a>
<a class="dropdown-item" id="pills-dropdown2-tab" href="#pills-dropdown2" role="tab" data-toggle="pill" aria-controls="pills-dropdown2">@mdo</a>
</div>
</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">
<p>Consequat occaecat ullamco amet non eiusmod nostrud dolore irure incididunt est duis anim sunt officia. Fugiat velit proident aliquip nisi incididunt nostrud exercitation proident est nisi. Irure magna elit commodo anim ex veniam culpa eiusmod id nostrud sit cupidatat in veniam ad. Eiusmod consequat eu adipisicing minim anim aliquip cupidatat culpa excepteur quis. Occaecat sit eu exercitation irure Lorem incididunt nostrud.</p>
</div>
<div class="tab-pane fade" id="pills-profile" role="tabpanel" aria-labelledby="pills-profile-tab">
<p>Ad pariatur nostrud pariatur exercitation ipsum ipsum culpa mollit commodo mollit ex. Aute sunt incididunt amet commodo est sint nisi deserunt pariatur do. Aliquip ex eiusmod voluptate exercitation cillum id incididunt elit sunt. Qui minim sit magna Lorem id et dolore velit Lorem amet exercitation duis deserunt. Anim id labore elit adipisicing ut in id occaecat pariatur ut ullamco ea tempor duis.</p>
</div>
<div class="tab-pane fade" id="pills-dropdown1" role="tabpanel" aria-labelledby="pills-dropdown1-tab">
<p>Est quis nulla laborum officia ad nisi ex nostrud culpa Lorem excepteur aliquip dolor aliqua irure ex. Nulla ut duis ipsum nisi elit fugiat commodo sunt reprehenderit laborum veniam eu veniam. Eiusmod minim exercitation fugiat irure ex labore incididunt do fugiat commodo aliquip sit id deserunt reprehenderit aliquip nostrud. Amet ex cupidatat excepteur aute veniam incididunt mollit cupidatat esse irure officia elit do ipsum ullamco Lorem. Ullamco ut ad minim do mollit labore ipsum laboris ipsum commodo sunt tempor enim incididunt. Commodo quis sunt dolore aliquip aute tempor irure magna enim minim reprehenderit. Ullamco consectetur culpa veniam sint cillum aliqua incididunt velit ullamco sunt ullamco quis quis commodo voluptate. Mollit nulla nostrud adipisicing aliqua cupidatat aliqua pariatur mollit voluptate voluptate consequat non.</p>
</div>
<div class="tab-pane fade" id="pills-dropdown2" role="tabpanel" aria-labelledby="nav-dropdown2-tab">
<p>Tempor anim aliquip qui nisi sit minim ex in cupidatat ipsum adipisicing. Ad non magna anim id ullamco do dolor sit adipisicing nulla exercitation. Qui Lorem eiusmod sint in laboris pariatur est adipisicing non sunt occaecat in mollit culpa sit. Aliquip id duis do do quis mollit ut duis. Non dolor reprehenderit do esse nostrud deserunt non eiusmod minim anim sit voluptate ipsum. Nulla elit aliqua do sunt labore velit anim nisi dolor nostrud consectetur fugiat ex qui velit ex tempor. Do cillum qui anim aliquip id cillum duis ex laboris tempor incididunt sint dolor ullamco tempor. Fugiat laboris enim anim veniam aliquip cillum irure.</p>
</div>
</div>
</div>
{% highlight html %}
<ul class="nav nav-pills mb-3" id="pills-tab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="pills-home-tab" data-toggle="pill" href="#pills-home" role="tab" aria-controls="pills-home" aria-expanded="true">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" id="pills-profile-tab" data-toggle="pill" href="#pills-profile" role="tab" aria-controls="pills-profile" aria-expanded="true">Profile</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">Dropdown</a>
<div class="dropdown-menu">
<a class="dropdown-item" id="pills-dropdown1-tab" href="#pills-dropdown1" role="tab" data-toggle="pill" aria-controls="pills-dropdown1">@fat</a>
<a class="dropdown-item" id="pills-dropdown2-tab" href="#pills-dropdown2" role="tab" data-toggle="pill" aria-controls="pills-dropdown2">@mdo</a>
</div>
</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">...</div>
<div class="tab-pane fade" id="pills-profile" role="tabpanel" aria-labelledby="pills-profile-tab">...</div>
<div class="tab-pane fade" id="pills-dropdown1" role="tabpanel" aria-labelledby="pills-dropdown1-tab">...</div>
<div class="tab-pane fade" id="pills-dropdown2" role="tabpanel" aria-labelledby="pills-dropdown2-tab">...</div>
</div>
{% endhighlight %}
And with vertical pills.
<div class="bd-example bd-example-tabs" role="tabpanel">
<div class="row">
<div class="col-3">
<div class="nav flex-column nav-pills" id="v-pills-tab" role="tablist">
<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-expanded="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-expanded="true">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-expanded="true">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-expanded="true">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">
<p>Cillum ad ut irure tempor velit nostrud occaecat ullamco aliqua anim Lorem sint. Veniam sint duis incididunt do esse magna mollit excepteur laborum qui. Id id reprehenderit sit est eu aliqua occaecat quis et velit excepteur laborum mollit dolore eiusmod. Ipsum dolor in occaecat commodo et voluptate minim reprehenderit mollit pariatur. Deserunt non laborum enim et cillum eu deserunt excepteur ea incididunt minim occaecat.</p>
</div>
<div class="tab-pane fade" id="v-pills-profile" role="tabpanel" aria-labelledby="v-pills-profile-tab">
<p>Culpa dolor voluptate do laboris laboris irure reprehenderit id incididunt duis pariatur mollit aute magna pariatur consectetur. Eu veniam duis non ut dolor deserunt commodo et minim in quis laboris ipsum velit id veniam. Quis ut consectetur adipisicing officia excepteur non sit. Ut et elit aliquip labore Lorem enim eu. Ullamco mollit occaecat dolore ipsum id officia mollit qui esse anim eiusmod do sint minim consectetur qui.</p>
</div>
<div class="tab-pane fade" id="v-pills-messages" role="tabpanel" aria-labelledby="v-pills-messages-tab">
<p>Fugiat id quis dolor culpa eiusmod anim velit excepteur proident dolor aute qui magna. Ad proident laboris ullamco esse anim Lorem Lorem veniam quis Lorem irure occaecat velit nostrud magna nulla. Velit et et proident Lorem do ea tempor officia dolor. Reprehenderit Lorem aliquip labore est magna commodo est ea veniam consectetur.</p>
</div>
<div class="tab-pane fade" id="v-pills-settings" role="tabpanel" aria-labelledby="v-pills-settings-tab">
<p>Eu dolore ea ullamco dolore Lorem id cupidatat excepteur reprehenderit consectetur elit id dolor proident in cupidatat officia. Voluptate excepteur commodo labore nisi cillum duis aliqua do. Aliqua amet qui mollit consectetur nulla mollit velit aliqua veniam nisi id do Lorem deserunt amet. Culpa ullamco sit adipisicing labore officia magna elit nisi in aute tempor commodo eiusmod.</p>
</div>
</div>
</div>
</div>
</div>
{% highlight html %}
<div class="nav flex-column nav-pills" id="v-pills-tab" role="tablist">
<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-expanded="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-expanded="true">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-expanded="true">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-expanded="true">Settings</a>
</div>
<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">...</div>
<div class="tab-pane fade" id="v-pills-profile" role="tabpanel" aria-labelledby="v-pills-profile-tab">...</div>
<div class="tab-pane fade" id="v-pills-messages" role="tabpanel" aria-labelledby="v-pills-messages-tab">...</div>
<div class="tab-pane fade" id="v-pills-settings" role="tabpanel" aria-labelledby="v-pills-settings-tab">...</div>
</div>
{% endhighlight %}
### Using data attributes
You can activate a tab or pill navigation without writing any JavaScript by simply specifying `data-toggle="tab"` or `data-toggle="pill"` on an element. Use these data attributes on `.nav-tabs` or `.nav-pills`.
@ -344,7 +520,7 @@ You can activate a tab or pill navigation without writing any JavaScript by simp
<div role="tabpanel">
{% highlight html %}
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" data-toggle="tab" href="#home" role="tab">Home</a>
</li>

View file

@ -5,21 +5,57 @@ description: Documentation and examples for the scrollspy plugin with Bootstrap'
group: components
---
Automatically update nav targets based on scroll position.
## Contents
* Will be replaced with the ToC, excluding the "Contents" header
{:toc}
{% callout warning %}
#### Requires Bootstrap nav or list-group
Scrollspy requires the use of a [Bootstrap nav component]({{ site.baseurl }}/components/navs#base-nav) or [Bootstrap list group component]({{ site.baseurl }}/components/list-group/#contents) for proper highlighting of active links / items.
When used with the nav component, it supports both the `<nav>` and `<ul>` markup and in both cases the element that receives the `.active` class is the `.list-group-item`.
When used with the list group component, the element that receives the `.active` class is the `.nav-link`.
{% highlight html %}
<ul class="nav">
<li class="nav-item">
<a class="nav-link active" href="#target-id">Item</a>
</li>
</ul>
{% endhighlight %}
{% highlight html %}
<nav class="nav">
<a class="nav-link active" href="#target-id">Item</a>
</nav>
{% endhighlight %}
{% endcallout %}
{% callout warning %}
#### Requires relative positioning
No matter the implementation method, scrollspy requires the use of `position: relative;` on the element you're spying on. In most cases this is the `<body>`. When scrollspying on elements other than the `<body>`, be sure to have a `height` set and `overflow-y: scroll;` applied.
{% endcallout %}
## Example in navbar
The ScrollSpy plugin is for automatically updating nav targets based on scroll position. Scroll the area below the navbar and watch the active class change. The dropdown sub items will be highlighted as well.
Scroll the area below the navbar and watch the active class change. The dropdown sub items will be highlighted as well.
<div class="bd-example">
<nav id="navbar-example2" class="navbar navbar-light bg-faded">
<a class="navbar-brand" href="#">Navbar</a>
<ul class="nav nav-pills">
<li class="nav-item"><a class="nav-link" href="#fat">@fat</a></li>
<li class="nav-item"><a class="nav-link" href="#mdo">@mdo</a></li>
<li class="nav-item">
<a class="nav-link" href="#fat">@fat</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#mdo">@mdo</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">Dropdown</a>
<div class="dropdown-menu">
@ -47,17 +83,173 @@ The ScrollSpy plugin is for automatically updating nav targets based on scroll p
</div>
</div>
{% highlight html %}
<nav id="navbar-example2" class="navbar navbar-light bg-faded">
<a class="navbar-brand" href="#">Navbar</a>
<ul class="nav nav-pills">
<li class="nav-item">
<a class="nav-link" href="#fat">@fat</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#mdo">@mdo</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">Dropdown</a>
<div class="dropdown-menu">
<a class="dropdown-item" href="#one">one</a>
<a class="dropdown-item" href="#two">two</a>
<div role="separator" class="dropdown-divider"></div>
<a class="dropdown-item" href="#three">three</a>
</div>
</li>
</ul>
</nav>
<div data-spy="scroll" data-target="#navbar-example2" data-offset="0">
<h4 id="fat">@fat</h4>
<p>...</p>
<h4 id="mdo">@mdo</h4>
<p>...</p>
<h4 id="one">one</h4>
<p>...</p>
<h4 id="two">two</h4>
<p>...</p>
<h4 id="three">three</h4>
<p>...</p>
</div>
{% endhighlight %}
## Example with sub-nav
The ScrollSpy plugin also works with nested `.nav`s. If a sub-`.nav` is `.active`, it's parents will also be `.active`. Scroll the area next to the navbar and watch the active class change.
<div class="bd-example">
<div class="row">
<div class="col-4">
<nav id="navbar-example3" class="navbar navbar-light bg-faded flex-column">
<a class="navbar-brand" href="#">Navbar</a>
<nav class="nav nav-pills flex-column">
<a class="nav-link" href="#item-1">Item 1</a>
<nav class="nav nav-pills flex-column">
<a class="nav-link ml-3 my-1" href="#item-1-1">Item 1-1</a>
<a class="nav-link ml-3 my-1" href="#item-1-2">Item 1-2</a>
</nav>
<a class="nav-link" href="#item-2">Item 2</a>
<a class="nav-link" href="#item-3">Item 3</a>
<nav class="nav nav-pills flex-column">
<a class="nav-link ml-3 my-1" href="#item-3-1">Item 3-1</a>
<a class="nav-link ml-3 my-1" href="#item-3-2">Item 3-2</a>
</nav>
</nav>
</nav>
</div>
<div class="col-8">
<div data-spy="scroll" data-target="#navbar-example3" data-offset="0" class="scrollspy-example-2">
<h4 id="item-1">Item 1</h4>
<p>Ex consequat commodo adipisicing exercitation aute excepteur occaecat ullamco duis aliqua id magna ullamco eu. Do aute ipsum ipsum ullamco cillum consectetur ut et aute consectetur labore. Fugiat laborum incididunt tempor eu consequat enim dolore proident. Qui laborum do non excepteur nulla magna eiusmod consectetur in. Aliqua et aliqua officia quis et incididunt voluptate non anim reprehenderit adipisicing dolore ut consequat deserunt mollit dolore. Aliquip nulla enim veniam non fugiat id cupidatat nulla elit cupidatat commodo velit ut eiusmod cupidatat elit dolore.</p>
<h5 id="item-1-1">Item 1-1</h5>
<p>Amet tempor mollit aliquip pariatur excepteur commodo do ea cillum commodo Lorem et occaecat elit qui et. Aliquip labore ex ex esse voluptate occaecat Lorem ullamco deserunt. Aliqua cillum excepteur irure consequat id quis ea. Sit proident ullamco aute magna pariatur nostrud labore. Reprehenderit aliqua commodo eiusmod aliquip est do duis amet proident magna consectetur consequat eu commodo fugiat non quis. Enim aliquip exercitation ullamco adipisicing voluptate excepteur minim exercitation minim minim commodo adipisicing exercitation officia nisi adipisicing. Anim id duis qui consequat labore adipisicing sint dolor elit cillum anim et fugiat.</p>
<h5 id="item-1-2">Item 2-2</h5>
<p>Cillum nisi deserunt magna eiusmod qui eiusmod velit voluptate pariatur laborum sunt enim. Irure laboris mollit consequat incididunt sint et culpa culpa incididunt adipisicing magna magna occaecat. Nulla ipsum cillum eiusmod sint elit excepteur ea labore enim consectetur in labore anim. Proident ullamco ipsum esse elit ut Lorem eiusmod dolor et eiusmod. Anim occaecat nulla in non consequat eiusmod velit incididunt.</p>
<h4 id="item-2">Item 2</h4>
<p>Quis magna Lorem anim amet ipsum do mollit sit cillum voluptate ex nulla tempor. Laborum consequat non elit enim exercitation cillum aliqua consequat id aliqua. Esse ex consectetur mollit voluptate est in duis laboris ad sit ipsum anim Lorem. Incididunt veniam velit elit elit veniam Lorem aliqua quis ullamco deserunt sit enim elit aliqua esse irure. Laborum nisi sit est tempor laborum mollit labore officia laborum excepteur commodo non commodo dolor excepteur commodo. Ipsum fugiat ex est consectetur ipsum commodo tempor sunt in proident.</p>
<h4 id="item-3">Item 3</h4>
<p>Quis anim sit do amet fugiat dolor velit sit ea ea do reprehenderit culpa duis. Nostrud aliqua ipsum fugiat minim proident occaecat excepteur aliquip culpa aute tempor reprehenderit. Deserunt tempor mollit elit ex pariatur dolore velit fugiat mollit culpa irure ullamco est ex ullamco excepteur.</p>
<h5 id="item-3-1">Item 3-1</h5>
<p>Deserunt quis elit Lorem eiusmod amet enim enim amet minim Lorem proident nostrud. Ea id dolore anim exercitation aute fugiat labore voluptate cillum do laboris labore. Ex velit exercitation nisi enim labore reprehenderit labore nostrud ut ut. Esse officia sunt duis aliquip ullamco tempor eiusmod deserunt irure nostrud irure. Ullamco proident veniam laboris ea consectetur magna sunt ex exercitation aliquip minim enim culpa occaecat exercitation. Est tempor excepteur aliquip laborum consequat do deserunt laborum esse eiusmod irure proident ipsum esse qui.</p>
<h5 id="item-3-2">Item 3-2</h5>
<p>Labore sit culpa commodo elit adipisicing sit aliquip elit proident voluptate minim mollit nostrud aute reprehenderit do. Mollit excepteur eu Lorem ipsum anim commodo sint labore Lorem in exercitation velit incididunt. Occaecat consectetur nisi in occaecat proident minim enim sunt reprehenderit exercitation cupidatat et do officia. Aliquip consequat ad labore labore mollit ut amet. Sit pariatur tempor proident in veniam culpa aliqua excepteur elit magna fugiat eiusmod amet officia.</p>
</div>
</div>
</div>
</div>
{% highlight html %}
<nav id="navbar-example3" class="navbar navbar-light bg-faded">
<a class="navbar-brand" href="#">Navbar</a>
<nav class="nav nav-pills flex-column">
<a class="nav-link" href="#item-1">Item 1</a>
<nav class="nav nav-pills flex-column">
<a class="nav-link ml-3 my-1" href="#item-1-1">Item 1-1</a>
<a class="nav-link ml-3 my-1" href="#item-1-2">Item 1-2</a>
</nav>
<a class="nav-link" href="#item-2">Item2</a>
<a class="nav-link" href="#item-3">Item3</a>
<nav class="nav nav-pills flex-column">
<a class="nav-link ml-3 my-1" href="#item-3-1">Item 3-1</a>
<a class="nav-link ml-3 my-1" href="#item-3-2">Item 3-2</a>
</nav>
</nav>
</nav>
<div data-spy="scroll" data-target="#navbar-example3" data-offset="0">
<h4 id="item-1">Item 1</h4>
<p>...</p>
<h5 id="item-1-1">Item 1-1</h5>
<p>...</p>
<h5 id="item-1-2">Item 2-2</h5>
<p>...</p>
<h4 id="item-2">Item 2</h4>
<p>...</p>
<h4 id="item-3">Item 3</h4>
<p>...</p>
<h5 id="item-3-1">Item 3-1</h5>
<p>...</p>
<h5 id="item-3-2">Item 3-2</h5>
<p>...</p>
</div>
{% endhighlight %}
## Example with list-group
The ScrollSpy plugin also works with a `.list-group`. Scroll the area next to the list group and watch the active class change.
<div class="bd-example">
<div class="row">
<div class="col-4">
<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">Item2</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 class="col-8">
<div data-spy="scroll" data-target="#list-example" data-offset="0" class="scrollspy-example">
<h4 id="list-item-1">Item 1</h4>
<p>Ex consequat commodo adipisicing exercitation aute excepteur occaecat ullamco duis aliqua id magna ullamco eu. Do aute ipsum ipsum ullamco cillum consectetur ut et aute consectetur labore. Fugiat laborum incididunt tempor eu consequat enim dolore proident. Qui laborum do non excepteur nulla magna eiusmod consectetur in. Aliqua et aliqua officia quis et incididunt voluptate non anim reprehenderit adipisicing dolore ut consequat deserunt mollit dolore. Aliquip nulla enim veniam non fugiat id cupidatat nulla elit cupidatat commodo velit ut eiusmod cupidatat elit dolore.</p>
<h4 id="list-item-2">Item 2</h4>
<p>Quis magna Lorem anim amet ipsum do mollit sit cillum voluptate ex nulla tempor. Laborum consequat non elit enim exercitation cillum aliqua consequat id aliqua. Esse ex consectetur mollit voluptate est in duis laboris ad sit ipsum anim Lorem. Incididunt veniam velit elit elit veniam Lorem aliqua quis ullamco deserunt sit enim elit aliqua esse irure. Laborum nisi sit est tempor laborum mollit labore officia laborum excepteur commodo non commodo dolor excepteur commodo. Ipsum fugiat ex est consectetur ipsum commodo tempor sunt in proident.</p>
<h4 id="list-item-3">Item 3</h4>
<p>Quis anim sit do amet fugiat dolor velit sit ea ea do reprehenderit culpa duis. Nostrud aliqua ipsum fugiat minim proident occaecat excepteur aliquip culpa aute tempor reprehenderit. Deserunt tempor mollit elit ex pariatur dolore velit fugiat mollit culpa irure ullamco est ex ullamco excepteur.</p>
<h4 id="list-item-4">Item 4</h4>
<p>Quis anim sit do amet fugiat dolor velit sit ea ea do reprehenderit culpa duis. Nostrud aliqua ipsum fugiat minim proident occaecat excepteur aliquip culpa aute tempor reprehenderit. Deserunt tempor mollit elit ex pariatur dolore velit fugiat mollit culpa irure ullamco est ex ullamco excepteur.</p>
</div>
</div>
</div>
</div>
{% highlight html %}
<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">Item2</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 data-spy="scroll" data-target="#list-example" data-offset="0" class="scrollspy-example">
<h4 id="list-item-1">Item 1</h4>
<p>...</p>
<h4 id="list-item-2">Item 2</h4>
<p>...</p>
<h4 id="list-item-3">Item 3</h4>
<p>...</p>
<h4 id="list-item-4">Item 4</h4>
<p>...</p>
</div>
{% endhighlight %}
## Usage
### Requires Bootstrap nav
Scrollspy currently requires the use of a [Bootstrap nav component]({{ site.baseurl }}/components/navs/) for proper highlighting of active links.
### Requires relative positioning
No matter the implementation method, scrollspy requires the use of `position: relative;` on the element you're spying on. In most cases this is the `<body>`. When scrollspying on elements other than the `<body>`, be sure to have a `height` set and `overflow-y: scroll;` applied.
### Via data attributes
To easily add scrollspy behavior to your topbar navigation, add `data-spy="scroll"` to the element you want to spy on (most typically this would be the `<body>`). Then add the `data-target` attribute with the ID or class of the parent element of any Bootstrap `.nav` component.

View file

@ -45,18 +45,15 @@ const ScrollSpy = (($) => {
const ClassName = {
DROPDOWN_ITEM : 'dropdown-item',
DROPDOWN_MENU : 'dropdown-menu',
NAV_LINK : 'nav-link',
NAV : 'nav',
ACTIVE : 'active'
}
const Selector = {
DATA_SPY : '[data-spy="scroll"]',
ACTIVE : '.active',
LIST_ITEM : '.list-item',
LI : 'li',
LI_DROPDOWN : 'li.dropdown',
NAV_LIST_GROUP : '.nav, .list-group',
NAV_LINKS : '.nav-link',
LIST_ITEMS : '.list-group-item',
DROPDOWN : '.dropdown',
DROPDOWN_ITEMS : '.dropdown-item',
DROPDOWN_TOGGLE : '.dropdown-toggle'
@ -81,6 +78,7 @@ const ScrollSpy = (($) => {
this._scrollElement = element.tagName === 'BODY' ? window : element
this._config = this._getConfig(config)
this._selector = `${this._config.target} ${Selector.NAV_LINKS},`
+ `${this._config.target} ${Selector.LIST_ITEMS},`
+ `${this._config.target} ${Selector.DROPDOWN_ITEMS}`
this._offsets = []
this._targets = []
@ -259,9 +257,11 @@ const ScrollSpy = (($) => {
$link.closest(Selector.DROPDOWN).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE)
$link.addClass(ClassName.ACTIVE)
} else {
// todo (fat) this is kinda sus...
// recursively add actives to tested nav-links
$link.parents(Selector.LI).find(`> ${Selector.NAV_LINKS}`).addClass(ClassName.ACTIVE)
// Set triggered link as active
$link.addClass(ClassName.ACTIVE)
// Set triggered links parents as active
// With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
$link.parents(Selector.NAV_LIST_GROUP).prev(`${Selector.NAV_LINKS}, ${Selector.LIST_ITEMS}`).addClass(ClassName.ACTIVE)
}
$(this._scrollElement).trigger(Event.ACTIVATE, {

View file

@ -42,14 +42,10 @@ const Tab = (($) => {
}
const Selector = {
A : 'a',
LI : 'li',
DROPDOWN : '.dropdown',
LIST : 'ul:not(.dropdown-menu), ol:not(.dropdown-menu), nav:not(.dropdown-menu), .list-group:not(.dropdown-menu)',
FADE_CHILD : '> .nav-item .fade, > .list-group-item .fade, > .fade',
NAV_LIST_GROUP : '.nav, .list-group',
ACTIVE : '.active',
ACTIVE_CHILD : '> .nav-item > .active, > .list-group-item > .active, > .active',
DATA_TOGGLE : '[data-toggle="tab"], [data-toggle="pill"]',
DATA_TOGGLE : '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',
DROPDOWN_TOGGLE : '.dropdown-toggle',
DROPDOWN_ACTIVE_CHILD : '> .dropdown-menu .active'
}
@ -87,7 +83,7 @@ const Tab = (($) => {
let target
let previous
const listElement = $(this._element).closest(Selector.LIST)[0]
const listElement = $(this._element).closest(Selector.NAV_LIST_GROUP)[0]
const selector = Util.getSelectorFromElement(this._element)
if (listElement) {
@ -152,11 +148,10 @@ const Tab = (($) => {
// private
_activate(element, container, callback) {
const active = $(container).find(Selector.ACTIVE_CHILD)[0]
const active = $(container).find(Selector.ACTIVE)[0]
const isTransitioning = callback
&& Util.supportsTransitionEnd()
&& (active && $(active).hasClass(ClassName.FADE)
|| Boolean($(container).find(Selector.FADE_CHILD)[0]))
&& (active && $(active).hasClass(ClassName.FADE))
const complete = () => this._transitionComplete(
element,
@ -182,9 +177,6 @@ const Tab = (($) => {
_transitionComplete(element, active, isTransitioning, callback) {
if (active) {
$(active).removeClass(ClassName.ACTIVE)
if ($(active).hasClass('list-group-item')) {
$(active).find('a.nav-link').removeClass(ClassName.ACTIVE)
}
const dropdownChild = $(active.parentNode).find(
Selector.DROPDOWN_ACTIVE_CHILD
@ -198,9 +190,6 @@ const Tab = (($) => {
}
$(element).addClass(ClassName.ACTIVE)
if ($(element.parentNode).hasClass('list-group-item')) {
$(element.parentNode).addClass(ClassName.ACTIVE)
}
element.setAttribute('aria-expanded', true)
if (isTransitioning) {

View file

@ -205,6 +205,80 @@ $(function () {
.then(function () { done() })
})
QUnit.test('should add the active class to the correct element (nav markup)', function (assert) {
assert.expect(2)
var navbarHtml =
'<nav class="navbar">'
+ '<nav class="nav">'
+ '<a class="nav-link" id="a-1" href="#div-1">div 1</a>'
+ '<a class="nav-link" id="a-2" href="#div-2">div 2</a>'
+ '</nav>'
+ '</nav>'
var contentHtml =
'<div class="content" style="overflow: auto; height: 50px">'
+ '<div id="div-1" style="height: 100px; padding: 0; margin: 0">div 1</div>'
+ '<div id="div-2" style="height: 200px; padding: 0; margin: 0">div 2</div>'
+ '</div>'
$(navbarHtml).appendTo('#qunit-fixture')
var $content = $(contentHtml)
.appendTo('#qunit-fixture')
.bootstrapScrollspy({ offset: 0, target: '.navbar' })
var done = assert.async()
var testElementIsActiveAfterScroll = function (element, target) {
var deferred = $.Deferred()
var scrollHeight = Math.ceil($content.scrollTop() + $(target).position().top)
$content.one('scroll', function () {
assert.ok($(element).hasClass('active'), 'target:' + target + ', element' + element)
deferred.resolve()
})
$content.scrollTop(scrollHeight)
return deferred.promise()
}
$.when(testElementIsActiveAfterScroll('#a-1', '#div-1'))
.then(function () { return testElementIsActiveAfterScroll('#a-2', '#div-2') })
.then(function () { done() })
})
QUnit.test('should add the active class to the correct element (list-group markup)', function (assert) {
assert.expect(2)
var navbarHtml =
'<nav class="navbar">'
+ '<div class="list-group">'
+ '<a class="list-group-item" id="a-1" href="#div-1">div 1</a>'
+ '<a class="list-group-item" id="a-2" href="#div-2">div 2</a>'
+ '</div>'
+ '</nav>'
var contentHtml =
'<div class="content" style="overflow: auto; height: 50px">'
+ '<div id="div-1" style="height: 100px; padding: 0; margin: 0">div 1</div>'
+ '<div id="div-2" style="height: 200px; padding: 0; margin: 0">div 2</div>'
+ '</div>'
$(navbarHtml).appendTo('#qunit-fixture')
var $content = $(contentHtml)
.appendTo('#qunit-fixture')
.bootstrapScrollspy({ offset: 0, target: '.navbar' })
var done = assert.async()
var testElementIsActiveAfterScroll = function (element, target) {
var deferred = $.Deferred()
var scrollHeight = Math.ceil($content.scrollTop() + $(target).position().top)
$content.one('scroll', function () {
assert.ok($(element).hasClass('active'), 'target:' + target + ', element' + element)
deferred.resolve()
})
$content.scrollTop(scrollHeight)
return deferred.promise()
}
$.when(testElementIsActiveAfterScroll('#a-1', '#div-1'))
.then(function () { return testElementIsActiveAfterScroll('#a-2', '#div-2') })
.then(function () { done() })
})
QUnit.test('should add the active class correctly when there are nested elements at 0 scroll offset', function (assert) {
assert.expect(6)
var times = 0
@ -212,7 +286,7 @@ $(function () {
var navbarHtml = '<nav id="navigation" class="navbar">'
+ '<ul class="nav">'
+ '<li><a id="a-1" class="nav-link" href="#div-1">div 1</a>'
+ '<ul>'
+ '<ul class="nav">'
+ '<li><a id="a-2" class="nav-link" href="#div-2">div 2</a></li>'
+ '</ul>'
+ '</li>'
@ -246,6 +320,86 @@ $(function () {
testActiveElements()
})
QUnit.test('should add the active class correctly when there are nested elements (nav markup)', function (assert) {
assert.expect(6)
var times = 0
var done = assert.async()
var navbarHtml = '<nav id="navigation" class="navbar">'
+ '<nav class="nav">'
+ '<a id="a-1" class="nav-link" href="#div-1">div 1</a>'
+ '<nav class="nav">'
+ '<a id="a-2" class="nav-link" href="#div-2">div 2</a>'
+ '</nav>'
+ '</nav>'
+ '</nav>'
var contentHtml = '<div class="content" style="position: absolute; top: 0px; overflow: auto; height: 50px">'
+ '<div id="div-1" style="padding: 0; margin: 0">'
+ '<div id="div-2" style="height: 200px; padding: 0; margin: 0">div 2</div>'
+ '</div>'
+ '</div>'
$(navbarHtml).appendTo('#qunit-fixture')
var $content = $(contentHtml)
.appendTo('#qunit-fixture')
.bootstrapScrollspy({ offset: 0, target: '#navigation' })
function testActiveElements() {
if (++times > 3) { return done() }
$content.one('scroll', function () {
assert.ok($('#a-1').hasClass('active'), 'nav item for outer element has "active" class')
assert.ok($('#a-2').hasClass('active'), 'nav item for inner element has "active" class')
testActiveElements()
})
$content.scrollTop($content.scrollTop() + 10)
}
testActiveElements()
})
QUnit.test('should add the active class correctly when there are nested elements (list-group markup)', function (assert) {
assert.expect(6)
var times = 0
var done = assert.async()
var navbarHtml = '<nav id="navigation" class="navbar">'
+ '<div class="list-group">'
+ '<a id="a-1" class="list-group-item" href="#div-1">div 1</a>'
+ '<div class="list-group">'
+ '<a id="a-2" class="list-group-item" href="#div-2">div 2</a>'
+ '</div>'
+ '</div>'
+ '</nav>'
var contentHtml = '<div class="content" style="position: absolute; top: 0px; overflow: auto; height: 50px">'
+ '<div id="div-1" style="padding: 0; margin: 0">'
+ '<div id="div-2" style="height: 200px; padding: 0; margin: 0">div 2</div>'
+ '</div>'
+ '</div>'
$(navbarHtml).appendTo('#qunit-fixture')
var $content = $(contentHtml)
.appendTo('#qunit-fixture')
.bootstrapScrollspy({ offset: 0, target: '#navigation' })
function testActiveElements() {
if (++times > 3) { return done() }
$content.one('scroll', function () {
assert.ok($('#a-1').hasClass('active'), 'nav item for outer element has "active" class')
assert.ok($('#a-2').hasClass('active'), 'nav item for inner element has "active" class')
testActiveElements()
})
$content.scrollTop($content.scrollTop() + 10)
}
testActiveElements()
})
QUnit.test('should clear selection if above the first section', function (assert) {
assert.expect(3)
var done = assert.async()

View file

@ -46,7 +46,7 @@ $(function () {
QUnit.test('should activate element by tab id', function (assert) {
assert.expect(2)
var tabsHTML = '<ul class="tabs">'
var tabsHTML = '<ul class="nav">'
+ '<li><a href="#home">Home</a></li>'
+ '<li><a href="#profile">Profile</a></li>'
+ '</ul>'
@ -62,7 +62,7 @@ $(function () {
QUnit.test('should activate element by tab id', function (assert) {
assert.expect(2)
var pillsHTML = '<ul class="pills">'
var pillsHTML = '<ul class="nav nav-pills">'
+ '<li><a href="#home">Home</a></li>'
+ '<li><a href="#profile">Profile</a></li>'
+ '</ul>'
@ -78,7 +78,7 @@ $(function () {
QUnit.test('should activate element by tab id in ordered list', function (assert) {
assert.expect(2)
var pillsHTML = '<ol class="pills">'
var pillsHTML = '<ol class="nav nav-pills">'
+ '<li><a href="#home">Home</a></li>'
+ '<li><a href="#profile">Profile</a></li>'
+ '</ol>'
@ -108,19 +108,19 @@ $(function () {
assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'home')
})
QUnit.test('should activate element by tab id in list-group', function (assert) {
QUnit.test('should activate element by tab id in list group', function (assert) {
assert.expect(2)
var ulHTML = '<ul class="list-group">' +
'<li class="list-group-item"><a href="#home">Home</a></li>' +
'<li class="list-group-item"><a href="#profile">Profile</a></li>' +
'</ul>'
var tabsHTML = '<div class="list-group">' +
'<a href="#home">Home</a>' +
'<a href="#profile">Profile</a>' +
'</div>'
$('<ul><li id="home"></li><li id="profile"></div></li>').appendTo('#qunit-fixture')
$('<nav><div id="home"></div><div id="profile"></div></nav>').appendTo('#qunit-fixture')
$(ulHTML).find('li:last a').bootstrapTab('show')
$(tabsHTML).find('a:last').bootstrapTab('show')
assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'profile')
$(ulHTML).find('li:first a').bootstrapTab('show')
$(tabsHTML).find('a:first').bootstrapTab('show')
assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'home')
})
@ -128,7 +128,7 @@ $(function () {
assert.expect(1)
var done = assert.async()
$('<div class="tab"/>')
$('<div class="nav"/>')
.on('show.bs.tab', function (e) {
e.preventDefault()
assert.ok(true, 'show event fired')
@ -182,7 +182,7 @@ $(function () {
assert.expect(2)
var done = assert.async()
var dropHTML = '<ul class="drop">'
var dropHTML = '<ul class="drop nav">'
+ '<li class="dropdown"><a data-toggle="dropdown" href="#">1</a>'
+ '<ul class="dropdown-menu">'
+ '<li><a href="#1-1" data-toggle="tab">1-1</a></li>'
@ -210,7 +210,7 @@ $(function () {
assert.expect(2)
var done = assert.async()
var tabsHTML = '<ul class="tabs">'
var tabsHTML = '<ul class="nav">'
+ '<li><a href="#home">Home</a></li>'
+ '<li><a href="#profile">Profile</a></li>'
+ '</ul>'
@ -241,7 +241,7 @@ $(function () {
assert.expect(1)
var done = assert.async()
var tabsHTML = '<ul class="tabs">'
var tabsHTML = '<ul class="nav">'
+ '<li><a href="#home">Home</a></li>'
+ '<li><a href="#profile">Profile</a></li>'
+ '</ul>'
@ -266,7 +266,7 @@ $(function () {
assert.expect(2)
var done = assert.async()
var tabsHTML = '<ul class="tabs">'
var tabsHTML = '<ul class="nav">'
+ '<li><a href="#home">Home</a></li>'
+ '<li><a href="#profile">Profile</a></li>'
+ '</ul>'

View file

@ -10,10 +10,13 @@
</style>
</head>
<body data-spy="scroll" data-target=".navbar" data-offset="70">
<div class="container">
<nav class="navbar fixed-top navbar-dark bg-inverse">
<a class="navbar-brand" href="#">Scrollspy test</a>
<ul class="nav navbar-nav">
<nav class="navbar navbar-expand-md navbar-inverse bg-inverse fixed-top">
<a class="navbar-brand" href="#">Scrollspy test</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="#fat">@fat</a>
</li>
@ -23,18 +26,18 @@
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="dropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>
<div class="dropdown-menu" aria-labelledby="dropdown">
<a class="dropdown-item" href="#one">one</a>
<a class="dropdown-item" href="#two">two</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#three">three</a>
<a class="dropdown-item" href="#one">One</a>
<a class="dropdown-item" href="#two">Two</a>
<a class="dropdown-item" href="#three">Three</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link" href="#final">Final</a>
</li>
</ul>
</nav>
</div>
</nav>
<div class="container">
<h2 id="fat">@fat</h2>
<p>Ad leggings keytar, brunch id art party dolor labore. Pitchfork yr enim lo-fi before they sold out qui. Tumblr farm-to-table bicycle rights whatever. Anim keffiyeh carles cardigan. Velit seitan mcsweeney's photo booth 3 wolf moon irure. Cosby sweater lomo jean shorts, williamsburg hoodie minim qui you probably haven't heard of them et cardigan trust fund culpa biodiesel wes anderson aesthetic. Nihil tattooed accusamus, cred irony biodiesel keffiyeh artisan ullamco consequat.</p>
<p>Ad leggings keytar, brunch id art party dolor labore. Pitchfork yr enim lo-fi before they sold out qui. Tumblr farm-to-table bicycle rights whatever. Anim keffiyeh carles cardigan. Velit seitan mcsweeney's photo booth 3 wolf moon irure. Cosby sweater lomo jean shorts, williamsburg hoodie minim qui you probably haven't heard of them et cardigan trust fund culpa biodiesel wes anderson aesthetic. Nihil tattooed accusamus, cred irony biodiesel keffiyeh artisan ullamco consequat.</p>

View file

@ -71,7 +71,7 @@
</ul>
<div class="tab-content" role="tablist">
<div class="tab-pane fade in active" id="home2" role="tabpanel">
<div class="tab-pane fade show active" id="home2" role="tabpanel">
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
</div>
@ -178,7 +178,7 @@
</nav>
<div class="tab-content" role="tabpanel">
<div role="tabpanel" class="tab-pane fade active" id="home5">
<div role="tabpanel" class="tab-pane fade show active" id="home5">
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
</div>
@ -196,42 +196,34 @@
</div>
</div>
<h4>Tabs with list group (with fade)</h4>
<ul class="list-group" role="tablist">
<li class="list-group-item active">
<a class="nav-link active" data-toggle="tab" href="#home6" role="tab">Home</a>
</li>
<li class="list-group-item">
<a class="nav-link" data-toggle="tab" href="#profile6" role="tab">Profile</a>
</li>
<li class="list-group-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="dropdown6" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>
<div class="dropdown-menu" aria-labelledby="dropdown6">
<a class="dropdown-item" data-toggle="tab" href="#fat6" role="tab">@fat</a>
<a class="dropdown-item" data-toggle="tab" href="#mdo6" role="tab">@mdo</a>
<h4>Tabs with list-group (with fade)</h4>
<div class="row">
<div class="col-4">
<div class="list-group" id="list-tab" role="tablist">
<a class="list-group-item list-group-item-action active" id="list-home-list" data-toggle="tab" href="#list-home" role="tab" aria-controls="home">Home</a>
<a class="list-group-item list-group-item-action" id="list-profile-list" data-toggle="tab" href="#list-profile" role="tab" aria-controls="profile">Profile</a>
<a class="list-group-item list-group-item-action" id="list-messages-list" data-toggle="tab" href="#list-messages" role="tab" aria-controls="messages">Messages</a>
<a class="list-group-item list-group-item-action" id="list-settings-list" data-toggle="tab" href="#list-settings" role="tab" aria-controls="settings">Settings</a>
</div>
</li>
</ul>
<div class="tab-content" role="tabpanel">
<div role="tabpanel" class="tab-pane active" id="home6">
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
</div>
<div role="tabpanel" class="tab-pane fade" id="profile6">
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
</div>
<div class="tab-pane fade" id="fat6" role="tabpanel">
<p>Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.</p>
<p>Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.</p>
</div>
<div class="tab-pane fade" id="mdo6" role="tabpanel">
<p>Trust fund seitan letterpress, keytar raw denim keffiyeh etsy art party before they sold out master cleanse gluten-free squid scenester freegan cosby sweater. Fanny pack portland seitan DIY, art party locavore wolf cliche high life echo park Austin. Cred vinyl keffiyeh DIY salvia PBR, banh mi before they sold out farm-to-table VHS viral locavore cosby sweater. Lomo wolf viral, mustache readymade thundercats keffiyeh craft beer marfa ethical. Wolf salvia freegan, sartorial keffiyeh echo park vegan.</p>
<p>Trust fund seitan letterpress, keytar raw denim keffiyeh etsy art party before they sold out master cleanse gluten-free squid scenester freegan cosby sweater. Fanny pack portland seitan DIY, art party locavore wolf cliche high life echo park Austin. Cred vinyl keffiyeh DIY salvia PBR, banh mi before they sold out farm-to-table VHS viral locavore cosby sweater. Lomo wolf viral, mustache readymade thundercats keffiyeh craft beer marfa ethical. Wolf salvia freegan, sartorial keffiyeh echo park vegan.</p>
<div class="col-8">
<div class="tab-content" id="nav-tabContent">
<div class="tab-pane fade show active" id="list-home" role="tabpanel" aria-labelledby="list-home-list">
<p>Velit aute mollit ipsum ad dolor consectetur nulla officia culpa adipisicing exercitation fugiat tempor. Voluptate deserunt sit sunt nisi aliqua fugiat proident ea ut. Mollit voluptate reprehenderit occaecat nisi ad non minim tempor sunt voluptate consectetur exercitation id ut nulla. Ea et fugiat aliquip nostrud sunt incididunt consectetur culpa aliquip eiusmod dolor. Anim ad Lorem aliqua in cupidatat nisi enim eu nostrud do aliquip veniam minim.</p>
</div>
<div class="tab-pane fade" id="list-profile" role="tabpanel" aria-labelledby="list-profile-list">
<p>Cupidatat quis ad sint excepteur laborum in esse qui. Et excepteur consectetur ex nisi eu do cillum ad laborum. Mollit et eu officia dolore sunt Lorem culpa qui commodo velit ex amet id ex. Officia anim incididunt laboris deserunt anim aute dolor incididunt veniam aute dolore do exercitation. Dolor nisi culpa ex ad irure in elit eu dolore. Ad laboris ipsum reprehenderit irure non commodo enim culpa commodo veniam incididunt veniam ad.</p>
</div>
<div class="tab-pane fade" id="list-messages" role="tabpanel" aria-labelledby="list-messages-list">
<p>Ut ut do pariatur aliquip aliqua aliquip exercitation do nostrud commodo reprehenderit aute ipsum voluptate. Irure Lorem et laboris nostrud amet cupidatat cupidatat anim do ut velit mollit consequat enim tempor. Consectetur est minim nostrud nostrud consectetur irure labore voluptate irure. Ipsum id Lorem sit sint voluptate est pariatur eu ad cupidatat et deserunt culpa sit eiusmod deserunt. Consectetur et fugiat anim do eiusmod aliquip nulla laborum elit adipisicing pariatur cillum.</p>
</div>
<div class="tab-pane fade" id="list-settings" role="tabpanel" aria-labelledby="list-settings-list">
<p>Irure enim occaecat labore sit qui aliquip reprehenderit amet velit. Deserunt ullamco ex elit nostrud ut dolore nisi officia magna sit occaecat laboris sunt dolor. Nisi eu minim cillum occaecat aute est cupidatat aliqua labore aute occaecat ea aliquip sunt amet. Aute mollit dolor ut exercitation irure commodo non amet consectetur quis amet culpa. Quis ullamco nisi amet qui aute irure eu. Magna labore dolor quis ex labore id nostrud deserunt dolor eiusmod eu pariatur culpa mollit in irure.</p>
</div>
</div>
</div>
</div>
</div>
<script src="../../../docs/assets/js/vendor/jquery-slim.min.js"></script>
<script src="../../dist/util.js"></script>
<script src="../../dist/tab.js"></script>

View file

@ -26,7 +26,6 @@
}
}
//
// Tabs
//
@ -34,10 +33,15 @@
.nav-tabs {
border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;
.nav-item {
.nav-item,
.nav-link {
margin-bottom: -$nav-tabs-border-width;
}
.nav-item .nav-link {
margin-bottom: 0;
}
.nav-link {
border: $nav-tabs-border-width solid transparent;
@include border-top-radius($nav-tabs-border-radius);
@ -76,12 +80,12 @@
.nav-pills {
.nav-link {
@include border-radius($nav-pills-border-radius);
}
.nav-link.active,
.nav-item.show .nav-link {
color: $nav-pills-active-link-color;
background-color: $nav-pills-active-link-bg;
&.active,
.show & {
color: $nav-pills-active-link-color;
background-color: $nav-pills-active-link-bg;
}
}
}