Bootstrap 4 Tab to Accordion. How to?

Duc Manh Nguyen picture Duc Manh Nguyen · Dec 15, 2017 · Viewed 22.6k times · Source

I googled and found how to make Bootstrap 3 tab to accordion in responsive here Bootstrap 3 tab to accordion, but I'm using Bootstrap 4 and I don't know how to convert it to Bootstrap 4 tab to accordion. Please help me.

Thanks!

Answer

dferenc picture dferenc · Dec 16, 2017

As indicated in the comments, the original answer was written for Bootsrap 4 Beta 2. The released Bootstrap 4 version requires two changes in the markup/css. Hence the update.

In Bootstrap 4 you can achieve that functionality with the following markup.
(As the built-in snippet viewer mixes up things sometimes when css @media queries involved, I've created a Codepen too.)

Compared to BS 4 Beta 2 there are these two required changes:

  • First, the way the tabs are hidden are changed: Earlier .tab-panes opacity was managed by the .fade class, but in the released verion it is the .fade:not(.show) selector, which has higher precedence. So, to override the opacity .tab-pane needed to be changed to .tab-content > .tab-pane in the css.
  • Second, the handling of collapsible groups are changed as well. Previously it was the toggle button which required the data-parent attribute. However since the release version data-parent needs to go onto the collapsible element.

The updated code for Bootstrap 4.1.3 is like so:

HTML

<div class="container">
    <ul id="tabs" class="nav nav-tabs" role="tablist">
        <li class="nav-item">
            <a id="tab-A" href="#pane-A" class="nav-link active" data-toggle="tab" role="tab">–A–</a>
        </li>
        <li class="nav-item">
            <a id="tab-B" href="#pane-B" class="nav-link" data-toggle="tab" role="tab">–B–</a>
        </li>
        <li class="nav-item">
            <a id="tab-C" href="#pane-C" class="nav-link" data-toggle="tab" role="tab">–C–</a>
        </li>
    </ul>


    <div id="content" class="tab-content" role="tablist">
        <div id="pane-A" class="card tab-pane fade show active" role="tabpanel" aria-labelledby="tab-A">
            <div class="card-header" role="tab" id="heading-A">
                <h5 class="mb-0">
                    <!-- Note: `data-parent` removed from here -->
                    <a data-toggle="collapse" href="#collapse-A" aria-expanded="true" aria-controls="collapse-A">
                        Collapsible Group Item A
                    </a>
                </h5>
            </div>

            <!-- Note: New place of `data-parent` -->
            <div id="collapse-A" class="collapse show" data-parent="#content" role="tabpanel" aria-labelledby="heading-A">
                <div class="card-body">
                    [Tab content A]
                </div>
            </div>
        </div>

        <div id="pane-B" class="card tab-pane fade" role="tabpanel" aria-labelledby="tab-B">
            <div class="card-header" role="tab" id="heading-B">
                <h5 class="mb-0">
                    <a class="collapsed" data-toggle="collapse" href="#collapse-B" aria-expanded="false" aria-controls="collapse-B">
                        Collapsible Group Item B
                    </a>
                </h5>
            </div>
            <div id="collapse-B" class="collapse" data-parent="#content" role="tabpanel" aria-labelledby="heading-B">
                <div class="card-body">
                    [Tab content B]
                </div>
            </div>
        </div>

        <div id="pane-C" class="card tab-pane fade" role="tabpanel" aria-labelledby="tab-C">
            <div class="card-header" role="tab" id="heading-C">
                <h5 class="mb-0">
                    <a class="collapsed" data-toggle="collapse" href="#collapse-C" aria-expanded="false" aria-controls="collapse-C">
                        Collapsible Group Item C
                    </a>
                </h5>
            </div>
            <div id="collapse-C" class="collapse" role="tabpanel" data-parent="#content" aria-labelledby="heading-C">
                <div class="card-body">
                    [Tab content C]
                </div>
            </div>
        </div>
    </div>
</div>

CSS

.nav-tabs {
    display:none;
}

@media(min-width:768px) {
    .nav-tabs {
        display: flex;
    }

    .card {
        border: none;
    }

    .card .card-header {
        display:none;
    }  

    .card .collapse{
        display:block;
    }
}

@media(max-width:767px){
    /* 
     * Changed selector to `.tab-content > .tab-pane` in order to override `.fade:not(.show)`
     * In BS4 Beta `.tab-pane`s were rendered hidden by just `.fade`
     */
    .tab-content > .tab-pane {
        display: block;
        opacity: 1;
    }
}

Original answer for Bootstrap 4 Beta 2:
Codepen

.nav-tabs {
    display:none;
}

@media(min-width:768px) {
    .nav-tabs {
        display: flex;
    }

    .card {
        border: none;
    }

    .card .card-header {
        display:none;
    }  

    .card .collapse{
        display:block;
    }
}

@media(max-width:767px){
    .tab-pane {
        display: block !important;
        opacity: 1;
    }
}
<div class="container">
    <ul id="tabs" class="nav nav-tabs" role="tablist">
        <li class="nav-item">
            <a id="tab-A" href="#pane-A" class="nav-link active" data-toggle="tab" role="tab">–A–</a>
        </li>
        <li class="nav-item">
            <a id="tab-B" href="#pane-B" class="nav-link" data-toggle="tab" role="tab">–B–</a>
        </li>
        <li class="nav-item">
            <a id="tab-C" href="#pane-C" class="nav-link" data-toggle="tab" role="tab">–C–</a>
        </li>
    </ul>


    <div id="content" class="tab-content" role="tablist">
        <div id="pane-A" class="card tab-pane fade show active" role="tabpanel" aria-labelledby="tab-A">
            <div class="card-header" role="tab" id="heading-A">
                <h5 class="mb-0">
                    <a data-toggle="collapse" href="#collapse-A" data-parent="#content" aria-expanded="true"
                        aria-controls="collapse-A">
                        Collapsible Group Item A
                    </a>
                </h5>
            </div>
            <div id="collapse-A" class="collapse show" role="tabpanel" aria-labelledby="heading-A">
                <div class="card-body">
                    [Tab content A]
                </div>
            </div>
        </div>

        <div id="pane-B" class="card tab-pane fade" role="tabpanel" aria-labelledby="tab-B">
            <div class="card-header" role="tab" id="heading-B">
                <h5 class="mb-0">
                    <a class="collapsed" data-toggle="collapse" href="#collapse-B" data-parent="#content" aria-expanded="false"
                        aria-controls="collapse-B">
                        Collapsible Group Item B
                    </a>
                </h5>
            </div>
            <div id="collapse-B" class="collapse" role="tabpanel" aria-labelledby="heading-B">
                <div class="card-body">
                    [Tab content B]
                </div>
            </div>
        </div>

        <div id="pane-C" class="card tab-pane fade" role="tabpanel" aria-labelledby="tab-C">
            <div class="card-header" role="tab" id="heading-C">
                <h5 class="mb-0">
                    <a class="collapsed" data-toggle="collapse" href="#collapse-C" data-parent="#content" aria-expanded="false"
                        aria-controls="collapse-C">
                        Collapsible Group Item C
                    </a>
                </h5>
            </div>
            <div id="collapse-C" class="collapse" role="tabpanel" aria-labelledby="heading-C">
                <div class="card-body">
                    [Tab content C]
                </div>
            </div>
        </div>
    </div>
</div>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js"></script>