JSFiddle - React, Tailwind, and code Playground

by Caleb Wong

HTML

<div class="tabs_container">
    <ul class="toc">
        <li><a href="#test1">test1</a></li>
        <li><a href="#test2">test2</a></li>
    </ul>
    <div class="content" id="_test1">
        test 1
    </div>
    <div class="content" id="_test2">
        test 2
    </div>
</div>

CSS

.tabs_container ul.toc {
    list-style: none;
    margin: 0;
    padding: 0;
}
 
.tabs_container ul.toc li {
    float: left;
    margin: 7px 4px 2px 0 !important;
    list-style-type: none !important;
    border:none;
}
 
.tabs_container ul.toc li a {
    display: block;
    background-color: #293A70;
    color: #fff;
    text-decoration: none;
    white-space: nowrap;
    text-align: center;
    padding: 3px;
    border: 2px solid #ccc;
    position: relative;
}
 
.tabs_container ul.toc li a:selected,
.tabs_container ul.toc li a:visited { outline: none; }
 
.tabs_container ul.toc li.current a {
    background-color: #B23428;
    color: #fff;
    padding:2px;
}
 
.tabs_container ul.toc li a span {
    display: block;
    font-weight: bold;
    line-height: 1em;
    white-space: nowrap;
    padding-right: 0px;
}
 
.tabs_container div.content {
    padding: 5px 7px 0px 7px;
    clear: both;
}
 
/* arrows (no IE < 8) */
.tabs_container ul.toc li.current a, .tabs_container ul.toc li a:hover {
    background-color: #fff;
    color: #293A70;
    border: 2px solid #293A70;
    padding: 3px;
}
 
.tabs_container ul.toc li.current a:after, .tabs_container ul.toc a:before {
    top: 100%;
    border: solid transparent;
    content: " ";
    height: 0;
    width: 0;
    position: absolute;
    pointer-events: none;
}
 
.tabs_container ul.toc li.current a:after {
    border-color: rgba(136, 183, 213, 0);
    border-top-color: #fff;
    border-width: 10px;
    left: 50%;
    margin-left: -10px;
}
 
.tabs_container ul.toc li.current a:before {
    border-color: rgba(194, 225, 245, 0);
    border-top-color: #293A70;
    border-width: 13px;
    left: 50%;
    margin-left: -13px;
}

JavaScript

Tabs = {
  // Changes to the tab with the specified ID.
  GoTo: function (contentId, skipReplace) {
     
    // Change current active tab
    $('.toc li.current').removeClass('current');
    $('.toc li a[href="#' + contentId + '"]').parent().addClass('current');
     
    // Change current active content
    $('.tabs_container .content').hide();
    $('.tabs_container .content').filter('#_' + contentId).show();
   
    // Change the address bar.
    if (!skipReplace) window.location.replace("#" + contentId);
  },
 
  Init: function () {
 
    var contentId,
      tabList = [],
      hash = window.location.hash.substring(1);
      // Hash starts with second character
      // Underscore in "_hash" content ID parameter prevents scroll on load
     
    // Array of tabs 
    $('.tabs_container .toc li a').each(function(){
      tabList.push($(this).attr('href').split('#')[1]);
    });
     
    // If there's a URL hash and it's in the array, activate it
    if ( (window.location.hash) && ($.inArray(hash,tabList) != -1) ) {
      contentId = hash;
    }
    // If the URL hash is not in the array, activate the first tab
    else {
      contentId = $('.toc li a:first').attr('href').split('#')[1];
    }
     
    if (contentId) Tabs.GoTo(contentId, true);
     
    // Attach onclick event to all the anchor links in the table of contents.
    $(".toc li a").click(function(){
      // Get the name of the anchor of the link that was clicked.
      Tabs.GoTo(this.hash.substring(1));
      return false;
    });
 
    // Attach onclick event to content links pointing to other tabs
    $('.tabs_container .content a[href*="#"]').each(function(){
        var linkHash = $(this).attr('href').split('#')[1];
        if ($.inArray(linkHash,tabList) != -1) {
            $(this).on('click', function(){
                Tabs.GoTo(linkHash, false)
            });
        }
    });
  }
};
 
// Hook up the ready event to the tab initialization function
$(document).ready(function () {...