Skip to content

Instantly share code, notes, and snippets.

@trinhtanloc789
Created November 1, 2019 08:51
Show Gist options
  • Save trinhtanloc789/b8fcccfd9add594001ede97012902600 to your computer and use it in GitHub Desktop.
Save trinhtanloc789/b8fcccfd9add594001ede97012902600 to your computer and use it in GitHub Desktop.
Tab Pill
<div class="tabs">
<ul>
<li><a href="#section1">Section 1</a></li>
<li><a href="#section2">Section 2</a></li>
<li><a href="#section3">Section 3</a></li>
<li><a href="#section4">Section 4</a></li>
<li><a href="#section5">Section 5</a></li>
</ul>
<section id="section1">
<h2>Section 1</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Perspiciatis, ullam natus tenetur molestiae commodi nesciunt, neque adipisci alias nostrum saepe inventore magnam. Molestias laboriosam, tempora quidem assumenda harum. Numquam, delectus.</p>
</section>
<section id="section2">
<h2>Section 2</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Perspiciatis, ullam natus tenetur molestiae commodi nesciunt, neque adipisci alias nostrum saepe inventore magnam. Molestias laboriosam, tempora quidem assumenda harum. Numquam, delectus.</p>
</section>
<section id="section3">
<h2>Section 3</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Perspiciatis, ullam natus tenetur molestiae commodi nesciunt, neque adipisci alias nostrum saepe inventore magnam. Molestias laboriosam, tempora quidem assumenda harum. Numquam, delectus.</p>
</section>
<section id="section4">
<h2>Section 4</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Perspiciatis, ullam natus tenetur molestiae commodi nesciunt, neque adipisci alias nostrum saepe inventore magnam. Molestias laboriosam, tempora quidem assumenda harum. Numquam, delectus.</p>
</section>
<section id="section5">
<h2>Section 5</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Perspiciatis, ullam natus tenetur molestiae commodi nesciunt, neque adipisci alias nostrum saepe inventore magnam. Molestias laboriosam, tempora quidem assumenda harum. Numquam, delectus.</p>
</section>
</div>
var Tabs = function($) {
return {
init: function() {
this.cacheDom();
this.setupAria();
this.appendIndicator();
this.bindEvents();
},
cacheDom: function() {
this.$el = $('.tabs');
this.$tabList = this.$el.find('ul');
this.$tab = this.$tabList.find('li');
this.$tabFirst = this.$tabList.find('li:first-child a');
this.$tabLink = this.$tab.find('a');
this.$tabPanel = this.$el.find('section');
this.$tabPanelFirstContent = this.$el.find('section > *:first-child');
this.$tabPanelFirst = this.$el.find('section:first-child');
this.$tabPanelNotFirst = this.$el.find('section:not(:first-of-type)');
},
bindEvents: function() {
this.$tabLink.on('click', function(){
this.changeTab();
this.animateIndicator($(event.currentTarget));
}.bind(this));
this.$tabLink.on('keydown', function() {
this.changeTabKey();
}.bind(this));
},
changeTab: function() {
var self = $(event.target);
event.preventDefault();
this.removeTabFocus();
this.setSelectedTab(self);
this.hideAllTabPanels();
this.setSelectedTabPanel(self);
},
animateIndicator: function(elem) {
var offset = elem.offset().left;
var width = elem.width();
var $indicator = this.$tabList.find('.indicator');
console.log(elem.width());
$indicator.transition({
x: offset,
width: elem.width()
})
},
appendIndicator: function() {
this.$tabList.append('<div class="indicator"></div>');
},
changeTabKey: function() {
var self = $(event.target),
$target = this.setKeyboardDirection(self, event.keyCode);
if ($target.length) {
this.removeTabFocus(self);
this.setSelectedTab($target);
}
this.hideAllTabPanels();
this.setSelectedTabPanel($(document.activeElement));
this.animateIndicator($target);
},
hideAllTabPanels: function() {
this.$tabPanel.attr('aria-hidden', 'true');
},
removeTabFocus: function(self) {
var $this = self || $('[role="tab"]');
$this.attr({
'tabindex': '-1',
'aria-selected': null
});
},
selectFirstTab: function() {
this.$tabFirst.attr({
'aria-selected': 'true',
'tabindex': '0'
});
},
setupAria: function() {
this.$tabList.attr('role', 'tablist');
this.$tab.attr('role', 'presentation');
this.$tabLink.attr({
'role': 'tab',
'tabindex': '-1'
});
this.$tabLink.each(function() {
var $this = $(this);
$this.attr('aria-controls', $this.attr('href').substring(1));
});
this.$tabPanel.attr({
'role': 'tabpanel'
});
this.$tabPanelFirstContent.attr({
'tabindex': '0'
});
this.$tabPanelNotFirst.attr({
'aria-hidden': 'true'
});
this.selectFirstTab();
},
setKeyboardDirection: function(self, keycode) {
var $prev = self.parents('li').prev().children('[role="tab"]'),
$next = self.parents('li').next().children('[role="tab"]');
switch (keycode) {
case 37:
return $prev;
break;
case 39:
return $next;
break;
default:
return false;
break;
}
},
setSelectedTab: function(self) {
self.attr({
'aria-selected': true,
'tabindex': '0'
}).focus();
},
setSelectedTabPanel: function(self) {
$('#' + self.attr('href').substring(1)).attr('aria-hidden', null);
},
};
}(jQuery);
Tabs.init();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.transit/0.9.12/jquery.transit.min.js"></script>
*:focus {
outline: 1px dotted blue;
}
.tabs > ul {
position: relative;
margin: 0;
padding: 0;
list-style: none;
border-bottom: 1px solid #ccc;
font-size: 0;
}
.tabs > ul .indicator {
display: block;
position: absolute;
bottom: 0;
left: 0;
height: 3px;
width: 20%;
background: #1E88E5;
-webkit-transform: translateZ(0) translateX(0);
transform: translateZ(0) translateX(0);
-webkit-transition: all 0.3s ease;
transition: all 0.3s ease;
}
.tabs > ul li {
display: inline-block;
font-size: 14px;
width: 20%;
}
.tabs > ul li a {
display: block;
position: relative;
overflow: hidden;
padding: 20px;
text-decoration: none;
text-align: center;
font-weight: bold;
color: black;
-webkit-transition: all 0.3s ease 0.4s;
transition: all 0.3s ease 0.4s;
}
.tabs > ul li a:before {
content: '';
display: block;
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
background: #1E88E5;
-webkit-transform: translateZ(0) translateY(100%);
transform: translateZ(0) translateY(100%);
-webkit-transition: all 0.3s ease 0.3s;
transition: all 0.3s ease 0.3s;
z-index: -1;
}
.tabs > ul li a[aria-selected] {
color: white;
}
.tabs > ul li a[aria-selected]:before {
-webkit-transform: translateZ(0) translateY(0);
transform: translateZ(0) translateY(0);
}
.tabs > section[aria-hidden="true"] {
display: none;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment