<ul class="tab">
<li><a href="#tab1" class="tab__item btn is-current">01</a></li>
<li><a href="#tab2" class="tab__item btn">02</a></li>
<li><a href="#tab3" class="tab__item btn">03</a></li>
<li><a href="#tab4" class="tab__item btn">04</a></li>
</ul>
<div class="tab__content">
<div class="tab__content-item is-enter" id="tab1">01のテキストが入ります。01のテキストが入ります。01のテキストが入ります。01のテキストが入ります。01のテキストが入ります。01のテキストが入ります。01のテキストが入ります。01のテキストが入ります。01のテキストが入ります。01のテキストが入ります。01のテキストが入ります。01のテキストが入ります。01のテキストが入ります。01のテキストが入ります。01のテキストが入ります。01のテキストが入ります。</div>
<div class="tab__content-item" id="tab2">02のテキストが入ります。02のテキストが入ります。02のテキストが入ります。02のテキストが入ります。</div>
<div class="tab__content-item" id="tab3">03のテキストが入ります。03のテキストが入ります。03のテキストが入ります。03のテキストが入ります。03のテキストが入ります。03のテキストが入ります。03のテキストが入ります。03のテキストが入ります。03のテキストが入ります。03のテキストが入ります。03のテキストが入ります。<br>03のテキストが入ります。03のテキストが入ります。03のテキストが入ります。03のテキストが入ります。03のテキストが入ります。03のテキストが入ります。03のテキストが入ります。03のテキストが入ります。03のテキストが入ります。03のテキストが入ります。03のテキストが入ります。</div>
<div class="tab__content-item" id="tab4">04のテキストが入ります。04のテキストが入ります。04のテキストが入ります。04のテキストが入ります。04のテキストが入ります。04のテキストが入ります。04のテキストが入ります。04のテキストが入ります。04のテキストが入ります。</div>
</div>
.tab {
display: flex;
}
.tab__item {
display: block;
margin-right: 1px;
}
.tab__item.is-current {
background: #555;
color: #fff;
}
.tab__content {
position: relative;
background: #555;
color: #fff;
}
.tab__content.is-change-active {
transition: height 0.3s;
overflow: hidden;
}
.tab__content-item {
display: none;
padding: 16px;
}
.tab__content-item.is-enter {
display: block;
}
.tab__content-item.is-enter-active {
position: absolute;
opacity: 0;
transition: opacity 0.3s;
}
.tab__content-item.is-enter-to {
opacity: 1;
}
.tab__content-item.is-leave-active {
position: absolute;
opacity: 1;
transition: opacity 0.3s;
}
.tab__content-item.is-leave-to {
opacity: 0;
}
.tab {
display: flex;
&__item {
display: block;
margin-right: 1px;
&.is-current {
background: $color_sub;
color: $color_opposite;
}
}
&__content {
position: relative;
background: $color_sub;
color: $color_opposite;
&.is-change-active {
transition: height $speed_fast;
overflow: hidden;
}
&-item {
display: none;
padding: $space_lg;
&.is-enter {
display: block;
}
&.is-enter-active {
position: absolute;
opacity: 0;
transition: opacity $speed_fast;
}
&.is-enter-to {
opacity: 1;
}
&.is-leave-active {
position: absolute;
opacity: 1;
transition: opacity $speed_fast;
}
&.is-leave-to {
opacity: 0;
}
}
}
}
(function() {
const tabItems = document.querySelectorAll('.tab__item');
const tabContentEl = document.querySelector('.tab__content');
const tabContentItems = document.querySelectorAll('.tab__content-item');
if(!tabContentEl) {return;}
let changeFlag = false;
transitionSet(tabContentItems);
tabItems.forEach(item => {
item.addEventListener('click', (e) => {
e.preventDefault();
// 切り替え時にクリックした場合、もしくは現在表示されているタブをクリックした場合は処理しない
if(changeFlag || item.classList.contains('is-current')) {return;}
changeFlag = true;
changeTab(item);
changeTabContent(item);
});
});
function changeTab(item) {
tabItems.forEach(item => {
item.classList.remove('is-current');
});
item.classList.add('is-current');
}
function changeTabContent(item) {
let currentTab = document.querySelector('.tab__content-item.is-enter');
let nextTab = document.querySelector(item.getAttribute('href'));
// position:absolute時にレイアウトが崩れないよう、切り替え時のみwidth・heightを固定
tabContentEl.style.width = `${tabContentEl.clientWidth}px`;
tabContentEl.style.height = `${tabContentEl.clientHeight}px`;
// 切り替え時のクラスを付与
tabContentEl.classList.add('is-change-active');
currentTab.classList.add('is-leave-active');
nextTab.classList.add('is-enter', 'is-enter-active');
let nextTabHeight = nextTab.scrollHeight;
setTimeout(() => {
tabContentEl.style.height = `${nextTabHeight}px`;
currentTab.classList.add('is-leave-to');
nextTab.classList.add('is-enter-to');
});
}
function transitionSet(items) {
tabContentEl.addEventListener('transitionend', () => {
// 切り替え時のwidth・height固定を解除
tabContentEl.style.width = '';
tabContentEl.style.height = '';
tabContentEl.classList.remove('is-change-active');
changeFlag = false;
});
items.forEach(item => {
item.addEventListener('transitionend', () => {
if(item.classList.contains('is-leave-active')) {
item.classList.remove('is-enter', 'is-leave-active', 'is-leave-to');
}
if(item.classList.contains('is-enter-active')) {
item.classList.remove('is-enter-active', 'is-enter-to');
}
});
});
}
}());